2 * Copyright (C) 2006-2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.am;
19 import com.android.internal.telephony.TelephonyIntents;
20 import com.google.android.collect.Lists;
21 import com.google.android.collect.Maps;
22 import com.android.internal.R;
23 import com.android.internal.annotations.GuardedBy;
24 import com.android.internal.app.AssistUtils;
25 import com.android.internal.app.DumpHeapActivity;
26 import com.android.internal.app.IAppOpsCallback;
27 import com.android.internal.app.IAppOpsService;
28 import com.android.internal.app.IVoiceInteractor;
29 import com.android.internal.app.ProcessMap;
30 import com.android.internal.app.SystemUserHomeActivity;
31 import com.android.internal.app.procstats.ProcessStats;
32 import com.android.internal.os.BackgroundThread;
33 import com.android.internal.os.BatteryStatsImpl;
34 import com.android.internal.os.IResultReceiver;
35 import com.android.internal.os.ProcessCpuTracker;
36 import com.android.internal.os.TransferPipe;
37 import com.android.internal.os.Zygote;
38 import com.android.internal.os.InstallerConnection.InstallerException;
39 import com.android.internal.util.ArrayUtils;
40 import com.android.internal.util.FastPrintWriter;
41 import com.android.internal.util.FastXmlSerializer;
42 import com.android.internal.util.MemInfoReader;
43 import com.android.internal.util.Preconditions;
44 import com.android.server.AppOpsService;
45 import com.android.server.AttributeCache;
46 import com.android.server.DeviceIdleController;
47 import com.android.server.IntentResolver;
48 import com.android.server.LocalServices;
49 import com.android.server.LockGuard;
50 import com.android.server.ServiceThread;
51 import com.android.server.SystemService;
52 import com.android.server.SystemServiceManager;
53 import com.android.server.Watchdog;
54 import com.android.server.am.ActivityStack.ActivityState;
55 import com.android.server.firewall.IntentFirewall;
56 import com.android.server.pm.Installer;
57 import com.android.server.statusbar.StatusBarManagerInternal;
58 import com.android.server.vr.VrManagerInternal;
59 import com.android.server.wm.WindowManagerService;
61 import org.xmlpull.v1.XmlPullParser;
62 import org.xmlpull.v1.XmlPullParserException;
63 import org.xmlpull.v1.XmlSerializer;
65 import android.Manifest;
66 import android.Manifest.permission;
67 import android.annotation.NonNull;
68 import android.annotation.UserIdInt;
69 import android.app.Activity;
70 import android.app.ActivityManager;
71 import android.app.ActivityManager.RunningTaskInfo;
72 import android.app.ActivityManager.StackId;
73 import android.app.ActivityManager.StackInfo;
74 import android.app.ActivityManager.TaskThumbnailInfo;
75 import android.app.ActivityManagerInternal;
76 import android.app.ActivityManagerInternal.SleepToken;
77 import android.app.ActivityManagerNative;
78 import android.app.ActivityOptions;
79 import android.app.ActivityThread;
80 import android.app.AlertDialog;
81 import android.app.AppGlobals;
82 import android.app.AppOpsManager;
83 import android.app.ApplicationErrorReport;
84 import android.app.ApplicationThreadNative;
85 import android.app.BroadcastOptions;
86 import android.app.Dialog;
87 import android.app.IActivityContainer;
88 import android.app.IActivityContainerCallback;
89 import android.app.IActivityController;
90 import android.app.IAppTask;
91 import android.app.IApplicationThread;
92 import android.app.IInstrumentationWatcher;
93 import android.app.INotificationManager;
94 import android.app.IProcessObserver;
95 import android.app.IServiceConnection;
96 import android.app.IStopUserCallback;
97 import android.app.ITaskStackListener;
98 import android.app.IUiAutomationConnection;
99 import android.app.IUidObserver;
100 import android.app.IUserSwitchObserver;
101 import android.app.Instrumentation;
102 import android.app.Notification;
103 import android.app.NotificationManager;
104 import android.app.PendingIntent;
105 import android.app.ProfilerInfo;
106 import android.app.admin.DevicePolicyManager;
107 import android.app.assist.AssistContent;
108 import android.app.assist.AssistStructure;
109 import android.app.backup.IBackupManager;
110 import android.app.usage.UsageEvents;
111 import android.app.usage.UsageStatsManagerInternal;
112 import android.appwidget.AppWidgetManager;
113 import android.content.ActivityNotFoundException;
114 import android.content.BroadcastReceiver;
115 import android.content.ClipData;
116 import android.content.ComponentCallbacks2;
117 import android.content.ComponentName;
118 import android.content.ContentProvider;
119 import android.content.ContentResolver;
120 import android.content.Context;
121 import android.content.DialogInterface;
122 import android.content.IContentProvider;
123 import android.content.IIntentReceiver;
124 import android.content.IIntentSender;
125 import android.content.Intent;
126 import android.content.IntentFilter;
127 import android.content.IntentSender;
128 import android.content.pm.ActivityInfo;
129 import android.content.pm.ApplicationInfo;
130 import android.content.pm.ConfigurationInfo;
131 import android.content.pm.IPackageDataObserver;
132 import android.content.pm.IPackageManager;
133 import android.content.pm.InstrumentationInfo;
134 import android.content.pm.PackageInfo;
135 import android.content.pm.PackageManager;
136 import android.content.pm.PackageManager.NameNotFoundException;
137 import android.content.pm.PackageManagerInternal;
138 import android.content.pm.ParceledListSlice;
139 import android.content.pm.PathPermission;
140 import android.content.pm.PermissionInfo;
141 import android.content.pm.ProviderInfo;
142 import android.content.pm.ResolveInfo;
143 import android.content.pm.ServiceInfo;
144 import android.content.pm.UserInfo;
145 import android.content.res.CompatibilityInfo;
146 import android.content.res.Configuration;
147 import android.content.res.Resources;
148 import android.database.ContentObserver;
149 import android.graphics.Bitmap;
150 import android.graphics.Point;
151 import android.graphics.Rect;
152 import android.location.LocationManager;
153 import android.net.Proxy;
154 import android.net.ProxyInfo;
155 import android.net.Uri;
156 import android.os.BatteryStats;
157 import android.os.Binder;
158 import android.os.Build;
159 import android.os.Bundle;
160 import android.os.Debug;
161 import android.os.DropBoxManager;
162 import android.os.Environment;
163 import android.os.FactoryTest;
164 import android.os.FileObserver;
165 import android.os.FileUtils;
166 import android.os.Handler;
167 import android.os.IBinder;
168 import android.os.IPermissionController;
169 import android.os.IProcessInfoService;
170 import android.os.IProgressListener;
171 import android.os.LocaleList;
172 import android.os.Looper;
173 import android.os.Message;
174 import android.os.Parcel;
175 import android.os.ParcelFileDescriptor;
176 import android.os.PersistableBundle;
177 import android.os.PowerManager;
178 import android.os.PowerManagerInternal;
179 import android.os.Process;
180 import android.os.RemoteCallbackList;
181 import android.os.RemoteException;
182 import android.os.ResultReceiver;
183 import android.os.ServiceManager;
184 import android.os.StrictMode;
185 import android.os.SystemClock;
186 import android.os.SystemProperties;
187 import android.os.Trace;
188 import android.os.TransactionTooLargeException;
189 import android.os.UpdateLock;
190 import android.os.UserHandle;
191 import android.os.UserManager;
192 import android.os.WorkSource;
193 import android.provider.Downloads;
194 import android.os.storage.IMountService;
195 import android.os.storage.MountServiceInternal;
196 import android.os.storage.StorageManager;
197 import android.provider.Settings;
198 import android.service.voice.IVoiceInteractionSession;
199 import android.service.voice.VoiceInteractionManagerInternal;
200 import android.service.voice.VoiceInteractionSession;
201 import android.telecom.TelecomManager;
202 import android.text.format.DateUtils;
203 import android.text.format.Time;
204 import android.text.style.SuggestionSpan;
205 import android.util.ArrayMap;
206 import android.util.ArraySet;
207 import android.util.AtomicFile;
208 import android.util.DebugUtils;
209 import android.util.DisplayMetrics;
210 import android.util.EventLog;
211 import android.util.Log;
212 import android.util.Pair;
213 import android.util.PrintWriterPrinter;
214 import android.util.Slog;
215 import android.util.SparseArray;
216 import android.util.TimeUtils;
217 import android.util.Xml;
218 import android.view.Display;
219 import android.view.Gravity;
220 import android.view.LayoutInflater;
221 import android.view.View;
222 import android.view.WindowManager;
225 import java.io.FileDescriptor;
226 import java.io.FileInputStream;
227 import java.io.FileNotFoundException;
228 import java.io.FileOutputStream;
229 import java.io.IOException;
230 import java.io.InputStreamReader;
231 import java.io.PrintWriter;
232 import java.io.StringWriter;
233 import java.lang.ref.WeakReference;
234 import java.nio.charset.StandardCharsets;
235 import java.util.ArrayList;
236 import java.util.Arrays;
237 import java.util.Collections;
238 import java.util.Comparator;
239 import java.util.HashMap;
240 import java.util.HashSet;
241 import java.util.Iterator;
242 import java.util.List;
243 import java.util.Locale;
244 import java.util.Map;
245 import java.util.Objects;
246 import java.util.Set;
247 import java.util.concurrent.atomic.AtomicBoolean;
248 import java.util.concurrent.atomic.AtomicLong;
250 import dalvik.system.VMRuntime;
252 import libcore.io.IoUtils;
253 import libcore.util.EmptyArray;
255 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
269 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270 import static android.content.pm.PackageManager.GET_PROVIDERS;
271 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
273 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
274 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
275 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
276 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
277 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
278 import static android.os.Process.PROC_CHAR;
279 import static android.os.Process.PROC_OUT_LONG;
280 import static android.os.Process.PROC_PARENS;
281 import static android.os.Process.PROC_SPACE_TERM;
282 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
283 import static android.provider.Settings.Global.DEBUG_APP;
284 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
286 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
287 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
288 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
289 import static android.provider.Settings.System.FONT_SCALE;
290 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
291 import static com.android.internal.util.XmlUtils.readIntAttribute;
292 import static com.android.internal.util.XmlUtils.readLongAttribute;
293 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
294 import static com.android.internal.util.XmlUtils.writeIntAttribute;
295 import static com.android.internal.util.XmlUtils.writeLongAttribute;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
328 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
352 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
354 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
355 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
356 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
357 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
358 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
359 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
360 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
361 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
362 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
365 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
367 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
370 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
371 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
372 import static org.xmlpull.v1.XmlPullParser.START_TAG;
374 public final class ActivityManagerService extends ActivityManagerNative
375 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
377 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
378 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
379 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
380 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
381 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
382 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
383 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
384 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
385 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
386 private static final String TAG_LRU = TAG + POSTFIX_LRU;
387 private static final String TAG_MU = TAG + POSTFIX_MU;
388 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
389 private static final String TAG_POWER = TAG + POSTFIX_POWER;
390 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
391 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
392 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
393 private static final String TAG_PSS = TAG + POSTFIX_PSS;
394 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
395 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
396 private static final String TAG_STACK = TAG + POSTFIX_STACK;
397 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
398 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
399 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
400 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
401 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
403 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
404 // here so that while the job scheduler can depend on AMS, the other way around
405 // need not be the case.
406 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
408 /** Control over CPU and battery monitoring */
409 // write battery stats every 30 minutes.
410 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
411 static final boolean MONITOR_CPU_USAGE = true;
412 // don't sample cpu less than every 5 seconds.
413 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
414 // wait possibly forever for next cpu sample.
415 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
416 static final boolean MONITOR_THREAD_CPU_USAGE = false;
418 // The flags that are set for all calls we make to the package manager.
419 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
421 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
423 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
425 // Amount of time after a call to stopAppSwitches() during which we will
426 // prevent further untrusted switches from happening.
427 static final long APP_SWITCH_DELAY_TIME = 5*1000;
429 // How long we wait for a launched process to attach to the activity manager
430 // before we decide it's never going to come up for real.
431 static final int PROC_START_TIMEOUT = 10*1000;
432 // How long we wait for an attached process to publish its content providers
433 // before we decide it must be hung.
434 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
436 // How long we will retain processes hosting content providers in the "last activity"
437 // state before allowing them to drop down to the regular cached LRU list. This is
438 // to avoid thrashing of provider processes under low memory situations.
439 static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
441 // How long we wait for a launched process to attach to the activity manager
442 // before we decide it's never going to come up for real, when the process was
443 // started with a wrapper for instrumentation (such as Valgrind) because it
444 // could take much longer than usual.
445 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
447 // How long to wait after going idle before forcing apps to GC.
448 static final int GC_TIMEOUT = 5*1000;
450 // The minimum amount of time between successive GC requests for a process.
451 static final int GC_MIN_INTERVAL = 60*1000;
453 // The minimum amount of time between successive PSS requests for a process.
454 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
456 // The minimum amount of time between successive PSS requests for a process
457 // when the request is due to the memory state being lowered.
458 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
460 // The rate at which we check for apps using excessive power -- 15 mins.
461 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
463 // The minimum sample duration we will allow before deciding we have
464 // enough data on wake locks to start killing things.
465 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
467 // The minimum sample duration we will allow before deciding we have
468 // enough data on CPU usage to start killing things.
469 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
471 // How long we allow a receiver to run before giving up on it.
472 static final int BROADCAST_FG_TIMEOUT = 10*1000;
473 static final int BROADCAST_BG_TIMEOUT = 60*1000;
475 // How long we wait until we timeout on key dispatching.
476 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
478 // How long we wait until we timeout on key dispatching during instrumentation.
479 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
481 // This is the amount of time an app needs to be running a foreground service before
482 // we will consider it to be doing interaction for usage stats.
483 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
485 // Maximum amount of time we will allow to elapse before re-reporting usage stats
486 // interaction with foreground processes.
487 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
489 // This is the amount of time we allow an app to settle after it goes into the background,
490 // before we start restricting what it can do.
491 static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
493 // How long to wait in getAssistContextExtras for the activity and foreground services
494 // to respond with the result.
495 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
497 // How long top wait when going through the modern assist (which doesn't need to block
498 // on getting this result before starting to launch its UI).
499 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
501 // Maximum number of persisted Uri grants a package is allowed
502 static final int MAX_PERSISTED_URI_GRANTS = 128;
504 static final int MY_PID = Process.myPid();
506 static final String[] EMPTY_STRING_ARRAY = new String[0];
508 // How many bytes to write into the dropbox log before truncating
509 static final int DROPBOX_MAX_SIZE = 192 * 1024;
510 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
511 // as one line, but close enough for now.
512 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
514 // Access modes for handleIncomingUser.
515 static final int ALLOW_NON_FULL = 0;
516 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
517 static final int ALLOW_FULL_ONLY = 2;
519 // Delay in notifying task stack change listeners (in millis)
520 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
522 // Necessary ApplicationInfo flags to mark an app as persistent
523 private static final int PERSISTENT_MASK =
524 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
526 // Intent sent when remote bugreport collection has been completed
527 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
528 "android.intent.action.REMOTE_BUGREPORT_FINISHED";
530 // Delay to disable app launch boost
531 static final int APP_BOOST_MESSAGE_DELAY = 3000;
532 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
533 static final int APP_BOOST_TIMEOUT = 2500;
535 // Used to indicate that a task is removed it should also be removed from recents.
536 private static final boolean REMOVE_FROM_RECENTS = true;
537 // Used to indicate that an app transition should be animated.
538 static final boolean ANIMATE = true;
540 // Determines whether to take full screen screenshots
541 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
542 public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
544 private static native int nativeMigrateToBoost();
545 private static native int nativeMigrateFromBoost();
546 private boolean mIsBoosted = false;
547 private long mBoostStartTime = 0;
549 /** All system services */
550 SystemServiceManager mSystemServiceManager;
552 private Installer mInstaller;
554 /** Run all ActivityStacks through this */
555 final ActivityStackSupervisor mStackSupervisor;
557 final ActivityStarter mActivityStarter;
559 /** Task stack change listeners. */
560 private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
561 new RemoteCallbackList<ITaskStackListener>();
563 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
565 public IntentFirewall mIntentFirewall;
567 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
568 // default actuion automatically. Important for devices without direct input
570 private boolean mShowDialogs = true;
571 private boolean mInVrMode = false;
573 // Whether we should use SCHED_FIFO for UI and RenderThreads.
574 private boolean mUseFifoUiScheduling = false;
576 BroadcastQueue mFgBroadcastQueue;
577 BroadcastQueue mBgBroadcastQueue;
578 // Convenient for easy iteration over the queues. Foreground is first
579 // so that dispatch of foreground broadcasts gets precedence.
580 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
582 BroadcastStats mLastBroadcastStats;
583 BroadcastStats mCurBroadcastStats;
585 BroadcastQueue broadcastQueueForIntent(Intent intent) {
586 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
587 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
588 "Broadcast intent " + intent + " on "
589 + (isFg ? "foreground" : "background") + " queue");
590 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
594 * Activity we have told the window manager to have key focus.
596 ActivityRecord mFocusedActivity = null;
599 * User id of the last activity mFocusedActivity was set to.
601 private int mLastFocusedUserId;
604 * If non-null, we are tracking the time the user spends in the currently focused app.
606 private AppTimeTracker mCurAppTimeTracker;
609 * List of intents that were used to start the most recent tasks.
611 final RecentTasks mRecentTasks;
614 * For addAppTask: cached of the last activity component that was added.
616 ComponentName mLastAddedTaskComponent;
619 * For addAppTask: cached of the last activity uid that was added.
621 int mLastAddedTaskUid;
624 * For addAppTask: cached of the last ActivityInfo that was added.
626 ActivityInfo mLastAddedTaskActivity;
629 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
631 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
634 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
636 String mDeviceOwnerName;
638 final UserController mUserController;
640 final AppErrors mAppErrors;
642 boolean mDoingSetFocusedActivity;
644 public boolean canShowErrorDialogs() {
645 return mShowDialogs && !mSleeping && !mShuttingDown
646 && mLockScreenShown != LOCK_SCREEN_SHOWN;
649 private static final class PriorityState {
650 // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
651 // the current thread is currently in. When it drops down to zero, we will no longer boost
652 // the thread's priority.
653 private int regionCounter = 0;
655 // The thread's previous priority before boosting.
656 private int prevPriority = Integer.MIN_VALUE;
659 static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
660 @Override protected PriorityState initialValue() {
661 return new PriorityState();
665 static void boostPriorityForLockedSection() {
666 int tid = Process.myTid();
667 int prevPriority = Process.getThreadPriority(tid);
668 PriorityState state = sThreadPriorityState.get();
669 if (state.regionCounter == 0 && prevPriority > -2) {
670 state.prevPriority = prevPriority;
671 Process.setThreadPriority(tid, -2);
673 state.regionCounter++;
676 static void resetPriorityAfterLockedSection() {
677 PriorityState state = sThreadPriorityState.get();
678 state.regionCounter--;
679 if (state.regionCounter == 0 && state.prevPriority > -2) {
680 Process.setThreadPriority(Process.myTid(), state.prevPriority);
684 public class PendingAssistExtras extends Binder implements Runnable {
685 public final ActivityRecord activity;
686 public final Bundle extras;
687 public final Intent intent;
688 public final String hint;
689 public final IResultReceiver receiver;
690 public final int userHandle;
691 public boolean haveResult = false;
692 public Bundle result = null;
693 public AssistStructure structure = null;
694 public AssistContent content = null;
695 public Bundle receiverExtras;
697 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
698 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
699 activity = _activity;
703 receiver = _receiver;
704 receiverExtras = _receiverExtras;
705 userHandle = _userHandle;
709 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
710 synchronized (this) {
714 pendingAssistExtrasTimedOut(this);
718 final ArrayList<PendingAssistExtras> mPendingAssistExtras
719 = new ArrayList<PendingAssistExtras>();
722 * Process management.
724 final ProcessList mProcessList = new ProcessList();
727 * All of the applications we currently have running organized by name.
728 * The keys are strings of the application package name (as
729 * returned by the package manager), and the keys are ApplicationRecord
732 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
735 * Tracking long-term execution of processes to look for abuse and other
738 final ProcessStatsService mProcessStats;
741 * The currently running isolated processes.
743 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
746 * Counter for assigning isolated process uids, to avoid frequently reusing the
749 int mNextIsolatedProcessUid = 0;
752 * The currently running heavy-weight process, if any.
754 ProcessRecord mHeavyWeightProcess = null;
757 * All of the processes we currently have running organized by pid.
758 * The keys are the pid running the application.
760 * <p>NOTE: This object is protected by its own lock, NOT the global
761 * activity manager lock!
763 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
766 * All of the processes that have been forced to be foreground. The key
767 * is the pid of the caller who requested it (we hold a death
770 abstract class ForegroundToken implements IBinder.DeathRecipient {
774 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
777 * List of records for processes that someone had tried to start before the
778 * system was ready. We don't start them at that point, but ensure they
779 * are started by the time booting is complete.
781 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
784 * List of persistent applications that are in the process
787 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
790 * Processes that are being forcibly torn down.
792 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
795 * List of running applications, sorted by recent usage.
796 * The first entry in the list is the least recently used.
798 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
801 * Where in mLruProcesses that the processes hosting activities start.
803 int mLruProcessActivityStart = 0;
806 * Where in mLruProcesses that the processes hosting services start.
807 * This is after (lower index) than mLruProcessesActivityStart.
809 int mLruProcessServiceStart = 0;
812 * List of processes that should gc as soon as things are idle.
814 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
817 * Processes we want to collect PSS data from.
819 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
821 private boolean mBinderTransactionTrackingEnabled = false;
824 * Last time we requested PSS data of all processes.
826 long mLastFullPssTime = SystemClock.uptimeMillis();
829 * If set, the next time we collect PSS data we should do a full collection
830 * with data from native processes and the kernel.
832 boolean mFullPssPending = false;
835 * This is the process holding what we currently consider to be
836 * the "home" activity.
838 ProcessRecord mHomeProcess;
841 * This is the process holding the activity the user last visited that
842 * is in a different process from the one they are currently in.
844 ProcessRecord mPreviousProcess;
847 * The time at which the previous process was last visible.
849 long mPreviousProcessVisibleTime;
852 * Track all uids that have actively running processes.
854 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
857 * This is for verifying the UID report flow.
859 static final boolean VALIDATE_UID_STATES = true;
860 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
863 * Packages that the user has asked to have run in screen size
864 * compatibility mode instead of filling the screen.
866 final CompatModePackages mCompatModePackages;
869 * Set of IntentSenderRecord objects that are currently active.
871 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
872 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
875 * Fingerprints (hashCode()) of stack traces that we've
876 * already logged DropBox entries for. Guarded by itself. If
877 * something (rogue user app) forces this over
878 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
880 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
881 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
884 * Strict Mode background batched logging state.
886 * The string buffer is guarded by itself, and its lock is also
887 * used to determine if another batched write is already
890 private final StringBuilder mStrictModeBuffer = new StringBuilder();
893 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
894 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
896 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
899 * Resolver for broadcast intents to registered receivers.
900 * Holds BroadcastFilter (subclass of IntentFilter).
902 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
903 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
905 protected boolean allowFilterResult(
906 BroadcastFilter filter, List<BroadcastFilter> dest) {
907 IBinder target = filter.receiverList.receiver.asBinder();
908 for (int i = dest.size() - 1; i >= 0; i--) {
909 if (dest.get(i).receiverList.receiver.asBinder() == target) {
917 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
918 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
919 || userId == filter.owningUserId) {
920 return super.newResult(filter, match, userId);
926 protected BroadcastFilter[] newArray(int size) {
927 return new BroadcastFilter[size];
931 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
932 return packageName.equals(filter.packageName);
937 * State of all active sticky broadcasts per user. Keys are the action of the
938 * sticky Intent, values are an ArrayList of all broadcasted intents with
939 * that action (which should usually be one). The SparseArray is keyed
940 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
941 * for stickies that are sent to all users.
943 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
944 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
946 final ActiveServices mServices;
948 final static class Association {
949 final int mSourceUid;
950 final String mSourceProcess;
951 final int mTargetUid;
952 final ComponentName mTargetComponent;
953 final String mTargetProcess;
961 // states of the source process when the bind occurred.
962 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
963 long mLastStateUptime;
964 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
965 - ActivityManager.MIN_PROCESS_STATE+1];
967 Association(int sourceUid, String sourceProcess, int targetUid,
968 ComponentName targetComponent, String targetProcess) {
969 mSourceUid = sourceUid;
970 mSourceProcess = sourceProcess;
971 mTargetUid = targetUid;
972 mTargetComponent = targetComponent;
973 mTargetProcess = targetProcess;
978 * When service association tracking is enabled, this is all of the associations we
979 * have seen. Mapping is target uid -> target component -> source uid -> source process name
980 * -> association data.
982 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
983 mAssociations = new SparseArray<>();
984 boolean mTrackingAssociations;
987 * Backup/restore process management
989 String mBackupAppName = null;
990 BackupRecord mBackupTarget = null;
992 final ProviderMap mProviderMap;
995 * List of content providers who have clients waiting for them. The
996 * application is currently being launched and the provider will be
997 * removed from this list once it is published.
999 final ArrayList<ContentProviderRecord> mLaunchingProviders
1000 = new ArrayList<ContentProviderRecord>();
1003 * File storing persisted {@link #mGrantedUriPermissions}.
1005 private final AtomicFile mGrantFile;
1007 /** XML constants used in {@link #mGrantFile} */
1008 private static final String TAG_URI_GRANTS = "uri-grants";
1009 private static final String TAG_URI_GRANT = "uri-grant";
1010 private static final String ATTR_USER_HANDLE = "userHandle";
1011 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1012 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1013 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1014 private static final String ATTR_TARGET_PKG = "targetPkg";
1015 private static final String ATTR_URI = "uri";
1016 private static final String ATTR_MODE_FLAGS = "modeFlags";
1017 private static final String ATTR_CREATED_TIME = "createdTime";
1018 private static final String ATTR_PREFIX = "prefix";
1021 * Global set of specific {@link Uri} permissions that have been granted.
1022 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1023 * to {@link UriPermission#uri} to {@link UriPermission}.
1026 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1027 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1029 public static class GrantUri {
1030 public final int sourceUserId;
1031 public final Uri uri;
1032 public boolean prefix;
1034 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1035 this.sourceUserId = sourceUserId;
1037 this.prefix = prefix;
1041 public int hashCode() {
1043 hashCode = 31 * hashCode + sourceUserId;
1044 hashCode = 31 * hashCode + uri.hashCode();
1045 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1050 public boolean equals(Object o) {
1051 if (o instanceof GrantUri) {
1052 GrantUri other = (GrantUri) o;
1053 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1054 && prefix == other.prefix;
1060 public String toString() {
1061 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1062 if (prefix) result += " [prefix]";
1066 public String toSafeString() {
1067 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1068 if (prefix) result += " [prefix]";
1072 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1073 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1074 ContentProvider.getUriWithoutUserId(uri), false);
1078 CoreSettingsObserver mCoreSettingsObserver;
1080 FontScaleSettingObserver mFontScaleSettingObserver;
1082 private final class FontScaleSettingObserver extends ContentObserver {
1083 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1085 public FontScaleSettingObserver() {
1087 ContentResolver resolver = mContext.getContentResolver();
1088 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1092 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1093 if (mFontScaleUri.equals(uri)) {
1094 updateFontScaleIfNeeded(userId);
1100 * Thread-local storage used to carry caller permissions over through
1101 * indirect content-provider access.
1103 private class Identity {
1104 public final IBinder token;
1105 public final int pid;
1106 public final int uid;
1108 Identity(IBinder _token, int _pid, int _uid) {
1115 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1118 * All information we have collected about the runtime performance of
1119 * any user id that can impact battery performance.
1121 final BatteryStatsService mBatteryStatsService;
1124 * Information about component usage
1126 UsageStatsManagerInternal mUsageStatsService;
1129 * Access to DeviceIdleController service.
1131 DeviceIdleController.LocalService mLocalDeviceIdleController;
1134 * Information about and control over application operations
1136 final AppOpsService mAppOpsService;
1139 * Current configuration information. HistoryRecord objects are given
1140 * a reference to this object to indicate which configuration they are
1141 * currently running in, so this object must be kept immutable.
1143 Configuration mConfiguration = new Configuration();
1146 * Current sequencing integer of the configuration, for skipping old
1149 int mConfigurationSeq = 0;
1151 boolean mSuppressResizeConfigChanges = false;
1154 * Hardware-reported OpenGLES version.
1156 final int GL_ES_VERSION;
1159 * List of initialization arguments to pass to all processes when binding applications to them.
1160 * For example, references to the commonly used services.
1162 HashMap<String, IBinder> mAppBindArgs;
1163 HashMap<String, IBinder> mIsolatedAppBindArgs;
1166 * Temporary to avoid allocations. Protected by main lock.
1168 final StringBuilder mStringBuilder = new StringBuilder(256);
1171 * Used to control how we initialize the service.
1173 ComponentName mTopComponent;
1174 String mTopAction = Intent.ACTION_MAIN;
1177 volatile boolean mProcessesReady = false;
1178 volatile boolean mSystemReady = false;
1179 volatile boolean mOnBattery = false;
1180 volatile int mFactoryTest;
1182 @GuardedBy("this") boolean mBooting = false;
1183 @GuardedBy("this") boolean mCallFinishBooting = false;
1184 @GuardedBy("this") boolean mBootAnimationComplete = false;
1185 @GuardedBy("this") boolean mLaunchWarningShown = false;
1186 @GuardedBy("this") boolean mCheckedForSetup = false;
1191 * The time at which we will allow normal application switches again,
1192 * after a call to {@link #stopAppSwitches()}.
1194 long mAppSwitchesAllowedTime;
1197 * This is set to true after the first switch after mAppSwitchesAllowedTime
1198 * is set; any switches after that will clear the time.
1200 boolean mDidAppSwitch;
1203 * Last time (in realtime) at which we checked for power usage.
1205 long mLastPowerCheckRealtime;
1208 * Last time (in uptime) at which we checked for power usage.
1210 long mLastPowerCheckUptime;
1213 * Set while we are wanting to sleep, to prevent any
1214 * activities from being started/resumed.
1216 * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
1218 * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
1219 * while in the sleep state until there is a pending transition out of sleep, in which case
1220 * mSleeping is set to false, and remains false while awake.
1222 * Whether mSleeping can quickly toggled between true/false without the device actually
1223 * display changing states is undefined.
1225 private boolean mSleeping = false;
1228 * The process state used for processes that are running the top activities.
1229 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1231 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1234 * Set while we are running a voice interaction. This overrides
1235 * sleeping while it is active.
1237 private IVoiceInteractionSession mRunningVoice;
1240 * For some direct access we need to power manager.
1242 PowerManagerInternal mLocalPowerManager;
1245 * We want to hold a wake lock while running a voice interaction session, since
1246 * this may happen with the screen off and we need to keep the CPU running to
1247 * be able to continue to interact with the user.
1249 PowerManager.WakeLock mVoiceWakeLock;
1252 * State of external calls telling us if the device is awake or asleep.
1254 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1257 * A list of tokens that cause the top activity to be put to sleep.
1258 * They are used by components that may hide and block interaction with underlying
1261 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1263 static final int LOCK_SCREEN_HIDDEN = 0;
1264 static final int LOCK_SCREEN_LEAVING = 1;
1265 static final int LOCK_SCREEN_SHOWN = 2;
1267 * State of external call telling us if the lock screen is shown.
1269 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1272 * Set if we are shutting down the system, similar to sleeping.
1274 boolean mShuttingDown = false;
1277 * Current sequence id for oom_adj computation traversal.
1282 * Current sequence id for process LRU updating.
1287 * Keep track of the non-cached/empty process we last found, to help
1288 * determine how to distribute cached/empty processes next time.
1290 int mNumNonCachedProcs = 0;
1293 * Keep track of the number of cached hidden procs, to balance oom adj
1294 * distribution between those and empty procs.
1296 int mNumCachedHiddenProcs = 0;
1299 * Keep track of the number of service processes we last found, to
1300 * determine on the next iteration which should be B services.
1302 int mNumServiceProcs = 0;
1303 int mNewNumAServiceProcs = 0;
1304 int mNewNumServiceProcs = 0;
1307 * Allow the current computed overall memory level of the system to go down?
1308 * This is set to false when we are killing processes for reasons other than
1309 * memory management, so that the now smaller process list will not be taken as
1310 * an indication that memory is tighter.
1312 boolean mAllowLowerMemLevel = false;
1315 * The last computed memory level, for holding when we are in a state that
1316 * processes are going away for other reasons.
1318 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1321 * The last total number of process we have, to determine if changes actually look
1322 * like a shrinking number of process due to lower RAM.
1324 int mLastNumProcesses;
1327 * The uptime of the last time we performed idle maintenance.
1329 long mLastIdleTime = SystemClock.uptimeMillis();
1332 * Total time spent with RAM that has been added in the past since the last idle time.
1334 long mLowRamTimeSinceLastIdle = 0;
1337 * If RAM is currently low, when that horrible situation started.
1339 long mLowRamStartTime = 0;
1342 * For reporting to battery stats the current top application.
1344 private String mCurResumedPackage = null;
1345 private int mCurResumedUid = -1;
1348 * For reporting to battery stats the apps currently running foreground
1349 * service. The ProcessMap is package/uid tuples; each of these contain
1350 * an array of the currently foreground processes.
1352 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1353 = new ProcessMap<ArrayList<ProcessRecord>>();
1356 * This is set if we had to do a delayed dexopt of an app before launching
1357 * it, to increase the ANR timeouts in that case.
1362 * Set if the systemServer made a call to enterSafeMode.
1367 * If true, we are running under a test environment so will sample PSS from processes
1368 * much more rapidly to try to collect better data when the tests are rapidly
1369 * running through apps.
1371 boolean mTestPssMode = false;
1373 String mDebugApp = null;
1374 boolean mWaitForDebugger = false;
1375 boolean mDebugTransient = false;
1376 String mOrigDebugApp = null;
1377 boolean mOrigWaitForDebugger = false;
1378 boolean mAlwaysFinishActivities = false;
1379 boolean mLenientBackgroundCheck = false;
1380 boolean mForceResizableActivities;
1381 boolean mSupportsMultiWindow;
1382 boolean mSupportsFreeformWindowManagement;
1383 boolean mSupportsPictureInPicture;
1384 boolean mSupportsLeanbackOnly;
1385 Rect mDefaultPinnedStackBounds;
1386 IActivityController mController = null;
1387 boolean mControllerIsAMonkey = false;
1388 String mProfileApp = null;
1389 ProcessRecord mProfileProc = null;
1390 String mProfileFile;
1391 ParcelFileDescriptor mProfileFd;
1392 int mSamplingInterval = 0;
1393 boolean mAutoStopProfiler = false;
1394 int mProfileType = 0;
1395 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1396 String mMemWatchDumpProcName;
1397 String mMemWatchDumpFile;
1398 int mMemWatchDumpPid;
1399 int mMemWatchDumpUid;
1400 String mTrackAllocationApp = null;
1401 String mNativeDebuggingApp = null;
1403 final long[] mTmpLong = new long[2];
1405 static final class ProcessChangeItem {
1406 static final int CHANGE_ACTIVITIES = 1<<0;
1407 static final int CHANGE_PROCESS_STATE = 1<<1;
1412 boolean foregroundActivities;
1415 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1416 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1418 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1419 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1421 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1422 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1424 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1425 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1428 * Runtime CPU use collection thread. This object's lock is used to
1429 * perform synchronization with the thread (notifying it to run).
1431 final Thread mProcessCpuThread;
1434 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1435 * Must acquire this object's lock when accessing it.
1436 * NOTE: this lock will be held while doing long operations (trawling
1437 * through all processes in /proc), so it should never be acquired by
1438 * any critical paths such as when holding the main activity manager lock.
1440 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1441 MONITOR_THREAD_CPU_USAGE);
1442 final AtomicLong mLastCpuTime = new AtomicLong(0);
1443 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1445 long mLastWriteTime = 0;
1448 * Used to retain an update lock when the foreground activity is in
1451 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1454 * Set to true after the system has finished booting.
1456 boolean mBooted = false;
1458 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1459 int mProcessLimitOverride = -1;
1461 WindowManagerService mWindowManager;
1462 final ActivityThread mSystemThread;
1464 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1465 final ProcessRecord mApp;
1467 final IApplicationThread mAppThread;
1469 AppDeathRecipient(ProcessRecord app, int pid,
1470 IApplicationThread thread) {
1471 if (DEBUG_ALL) Slog.v(
1472 TAG, "New death recipient " + this
1473 + " for thread " + thread.asBinder());
1476 mAppThread = thread;
1480 public void binderDied() {
1481 if (DEBUG_ALL) Slog.v(
1482 TAG, "Death received in " + this
1483 + " for thread " + mAppThread.asBinder());
1484 synchronized(ActivityManagerService.this) {
1485 appDiedLocked(mApp, mPid, mAppThread, true);
1490 static final int SHOW_ERROR_UI_MSG = 1;
1491 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1492 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1493 static final int UPDATE_CONFIGURATION_MSG = 4;
1494 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1495 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1496 static final int SERVICE_TIMEOUT_MSG = 12;
1497 static final int UPDATE_TIME_ZONE = 13;
1498 static final int SHOW_UID_ERROR_UI_MSG = 14;
1499 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1500 static final int PROC_START_TIMEOUT_MSG = 20;
1501 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1502 static final int KILL_APPLICATION_MSG = 22;
1503 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1504 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1505 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1506 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1507 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1508 static final int CLEAR_DNS_CACHE_MSG = 28;
1509 static final int UPDATE_HTTP_PROXY_MSG = 29;
1510 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1511 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1512 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1513 static final int REPORT_MEM_USAGE_MSG = 33;
1514 static final int REPORT_USER_SWITCH_MSG = 34;
1515 static final int CONTINUE_USER_SWITCH_MSG = 35;
1516 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1517 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1518 static final int PERSIST_URI_GRANTS_MSG = 38;
1519 static final int REQUEST_ALL_PSS_MSG = 39;
1520 static final int START_PROFILES_MSG = 40;
1521 static final int UPDATE_TIME = 41;
1522 static final int SYSTEM_USER_START_MSG = 42;
1523 static final int SYSTEM_USER_CURRENT_MSG = 43;
1524 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1525 static final int FINISH_BOOTING_MSG = 45;
1526 static final int START_USER_SWITCH_UI_MSG = 46;
1527 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1528 static final int DISMISS_DIALOG_UI_MSG = 48;
1529 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1530 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1531 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1532 static final int DELETE_DUMPHEAP_MSG = 52;
1533 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1534 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1535 static final int REPORT_TIME_TRACKER_MSG = 55;
1536 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1537 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1538 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1539 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1540 static final int IDLE_UIDS_MSG = 60;
1541 static final int SYSTEM_USER_UNLOCK_MSG = 61;
1542 static final int LOG_STACK_STATE = 62;
1543 static final int VR_MODE_CHANGE_MSG = 63;
1544 static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1545 static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1546 static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1547 static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1548 static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1549 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 69;
1550 static final int NOTIFY_VR_SLEEPING_MSG = 70;
1552 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1553 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1554 static final int FIRST_COMPAT_MODE_MSG = 300;
1555 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1557 static ServiceThread sKillThread = null;
1558 static KillHandler sKillHandler = null;
1560 CompatModeDialog mCompatModeDialog;
1561 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1562 long mLastMemUsageReportTime = 0;
1565 * Flag whether the current user is a "monkey", i.e. whether
1566 * the UI is driven by a UI automation tool.
1568 private boolean mUserIsMonkey;
1570 /** Flag whether the device has a Recents UI */
1571 boolean mHasRecents;
1573 /** The dimensions of the thumbnails in the Recents UI. */
1574 int mThumbnailWidth;
1575 int mThumbnailHeight;
1576 float mFullscreenThumbnailScale;
1578 final ServiceThread mHandlerThread;
1579 final MainHandler mHandler;
1580 final UiHandler mUiHandler;
1582 PackageManagerInternal mPackageManagerInt;
1584 // VoiceInteraction session ID that changes for each new request except when
1585 // being called for multiwindow assist in a single session.
1586 private int mViSessionId = 1000;
1588 final boolean mPermissionReviewRequired;
1590 final class KillHandler extends Handler {
1591 static final int KILL_PROCESS_GROUP_MSG = 4000;
1593 public KillHandler(Looper looper) {
1594 super(looper, null, true);
1598 public void handleMessage(Message msg) {
1600 case KILL_PROCESS_GROUP_MSG:
1602 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1603 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1604 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1609 super.handleMessage(msg);
1614 final class UiHandler extends Handler {
1615 public UiHandler() {
1616 super(com.android.server.UiThread.get().getLooper(), null, true);
1620 public void handleMessage(Message msg) {
1622 case SHOW_ERROR_UI_MSG: {
1623 mAppErrors.handleShowAppErrorUi(msg);
1624 ensureBootCompleted();
1626 case SHOW_NOT_RESPONDING_UI_MSG: {
1627 mAppErrors.handleShowAnrUi(msg);
1628 ensureBootCompleted();
1630 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1631 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1632 synchronized (ActivityManagerService.this) {
1633 ProcessRecord proc = (ProcessRecord) data.get("app");
1635 Slog.e(TAG, "App not found when showing strict mode dialog.");
1638 if (proc.crashDialog != null) {
1639 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1642 AppErrorResult res = (AppErrorResult) data.get("result");
1643 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1644 Dialog d = new StrictModeViolationDialog(mContext,
1645 ActivityManagerService.this, res, proc);
1647 proc.crashDialog = d;
1649 // The device is asleep, so just pretend that the user
1650 // saw a crash dialog and hit "force quit".
1654 ensureBootCompleted();
1656 case SHOW_FACTORY_ERROR_UI_MSG: {
1657 Dialog d = new FactoryErrorDialog(
1658 mContext, msg.getData().getCharSequence("msg"));
1660 ensureBootCompleted();
1662 case WAIT_FOR_DEBUGGER_UI_MSG: {
1663 synchronized (ActivityManagerService.this) {
1664 ProcessRecord app = (ProcessRecord)msg.obj;
1665 if (msg.arg1 != 0) {
1666 if (!app.waitedForDebugger) {
1667 Dialog d = new AppWaitingForDebuggerDialog(
1668 ActivityManagerService.this,
1671 app.waitedForDebugger = true;
1675 if (app.waitDialog != null) {
1676 app.waitDialog.dismiss();
1677 app.waitDialog = null;
1682 case SHOW_UID_ERROR_UI_MSG: {
1684 AlertDialog d = new BaseErrorDialog(mContext);
1685 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1686 d.setCancelable(false);
1687 d.setTitle(mContext.getText(R.string.android_system_label));
1688 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1689 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1690 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1694 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1696 AlertDialog d = new BaseErrorDialog(mContext);
1697 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1698 d.setCancelable(false);
1699 d.setTitle(mContext.getText(R.string.android_system_label));
1700 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1701 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1702 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1706 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1707 synchronized (ActivityManagerService.this) {
1708 ActivityRecord ar = (ActivityRecord) msg.obj;
1709 if (mCompatModeDialog != null) {
1710 if (mCompatModeDialog.mAppInfo.packageName.equals(
1711 ar.info.applicationInfo.packageName)) {
1714 mCompatModeDialog.dismiss();
1715 mCompatModeDialog = null;
1717 if (ar != null && false) {
1718 if (mCompatModePackages.getPackageAskCompatModeLocked(
1720 int mode = mCompatModePackages.computeCompatModeLocked(
1721 ar.info.applicationInfo);
1722 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1723 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1724 mCompatModeDialog = new CompatModeDialog(
1725 ActivityManagerService.this, mContext,
1726 ar.info.applicationInfo);
1727 mCompatModeDialog.show();
1734 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1735 synchronized (ActivityManagerService.this) {
1736 final ActivityRecord ar = (ActivityRecord) msg.obj;
1737 if (mUnsupportedDisplaySizeDialog != null) {
1738 mUnsupportedDisplaySizeDialog.dismiss();
1739 mUnsupportedDisplaySizeDialog = null;
1741 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1743 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1744 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1745 mUnsupportedDisplaySizeDialog.show();
1750 case START_USER_SWITCH_UI_MSG: {
1751 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1754 case DISMISS_DIALOG_UI_MSG: {
1755 final Dialog d = (Dialog) msg.obj;
1759 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1760 dispatchProcessesChanged();
1763 case DISPATCH_PROCESS_DIED_UI_MSG: {
1764 final int pid = msg.arg1;
1765 final int uid = msg.arg2;
1766 dispatchProcessDied(pid, uid);
1769 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1770 dispatchUidsChanged();
1776 final class MainHandler extends Handler {
1777 public MainHandler(Looper looper) {
1778 super(looper, null, true);
1782 public void handleMessage(Message msg) {
1784 case UPDATE_CONFIGURATION_MSG: {
1785 final ContentResolver resolver = mContext.getContentResolver();
1786 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1789 case GC_BACKGROUND_PROCESSES_MSG: {
1790 synchronized (ActivityManagerService.this) {
1791 performAppGcsIfAppropriateLocked();
1794 case SERVICE_TIMEOUT_MSG: {
1797 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1799 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1802 mServices.serviceTimeout((ProcessRecord)msg.obj);
1804 case UPDATE_TIME_ZONE: {
1805 synchronized (ActivityManagerService.this) {
1806 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1807 ProcessRecord r = mLruProcesses.get(i);
1808 if (r.thread != null) {
1810 r.thread.updateTimeZone();
1811 } catch (RemoteException ex) {
1812 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1818 case CLEAR_DNS_CACHE_MSG: {
1819 synchronized (ActivityManagerService.this) {
1820 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1821 ProcessRecord r = mLruProcesses.get(i);
1822 if (r.thread != null) {
1824 r.thread.clearDnsCache();
1825 } catch (RemoteException ex) {
1826 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1832 case UPDATE_HTTP_PROXY_MSG: {
1833 ProxyInfo proxy = (ProxyInfo)msg.obj;
1836 String exclList = "";
1837 Uri pacFileUrl = Uri.EMPTY;
1838 if (proxy != null) {
1839 host = proxy.getHost();
1840 port = Integer.toString(proxy.getPort());
1841 exclList = proxy.getExclusionListAsString();
1842 pacFileUrl = proxy.getPacFileUrl();
1844 synchronized (ActivityManagerService.this) {
1845 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1846 ProcessRecord r = mLruProcesses.get(i);
1847 if (r.thread != null) {
1849 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1850 } catch (RemoteException ex) {
1851 Slog.w(TAG, "Failed to update http proxy for: " +
1852 r.info.processName);
1858 case PROC_START_TIMEOUT_MSG: {
1861 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1863 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1866 ProcessRecord app = (ProcessRecord)msg.obj;
1867 synchronized (ActivityManagerService.this) {
1868 processStartTimedOutLocked(app);
1871 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1872 ProcessRecord app = (ProcessRecord)msg.obj;
1873 synchronized (ActivityManagerService.this) {
1874 processContentProviderPublishTimedOutLocked(app);
1877 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1878 synchronized (ActivityManagerService.this) {
1879 mActivityStarter.doPendingActivityLaunchesLocked(true);
1882 case KILL_APPLICATION_MSG: {
1883 synchronized (ActivityManagerService.this) {
1884 final int appId = msg.arg1;
1885 final int userId = msg.arg2;
1886 Bundle bundle = (Bundle)msg.obj;
1887 String pkg = bundle.getString("pkg");
1888 String reason = bundle.getString("reason");
1889 forceStopPackageLocked(pkg, appId, false, false, true, false,
1890 false, userId, reason);
1893 case FINALIZE_PENDING_INTENT_MSG: {
1894 ((PendingIntentRecord)msg.obj).completeFinalize();
1896 case POST_HEAVY_NOTIFICATION_MSG: {
1897 INotificationManager inm = NotificationManager.getService();
1902 ActivityRecord root = (ActivityRecord)msg.obj;
1903 ProcessRecord process = root.app;
1904 if (process == null) {
1909 Context context = mContext.createPackageContext(process.info.packageName, 0);
1910 String text = mContext.getString(R.string.heavy_weight_notification,
1911 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1912 Notification notification = new Notification.Builder(context)
1913 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1917 .setColor(mContext.getColor(
1918 com.android.internal.R.color.system_notification_accent_color))
1919 .setContentTitle(text)
1921 mContext.getText(R.string.heavy_weight_notification_detail))
1922 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1923 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1924 new UserHandle(root.userId)))
1927 int[] outId = new int[1];
1928 inm.enqueueNotificationWithTag("android", "android", null,
1929 R.string.heavy_weight_notification,
1930 notification, outId, root.userId);
1931 } catch (RuntimeException e) {
1932 Slog.w(ActivityManagerService.TAG,
1933 "Error showing notification for heavy-weight app", e);
1934 } catch (RemoteException e) {
1936 } catch (NameNotFoundException e) {
1937 Slog.w(TAG, "Unable to create context for heavy notification", e);
1940 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1941 INotificationManager inm = NotificationManager.getService();
1946 inm.cancelNotificationWithTag("android", null,
1947 R.string.heavy_weight_notification, msg.arg1);
1948 } catch (RuntimeException e) {
1949 Slog.w(ActivityManagerService.TAG,
1950 "Error canceling notification for service", e);
1951 } catch (RemoteException e) {
1954 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1955 synchronized (ActivityManagerService.this) {
1956 checkExcessivePowerUsageLocked(true);
1957 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1958 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1959 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1962 case REPORT_MEM_USAGE_MSG: {
1963 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1964 Thread thread = new Thread() {
1965 @Override public void run() {
1966 reportMemUsage(memInfos);
1972 case REPORT_USER_SWITCH_MSG: {
1973 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1976 case CONTINUE_USER_SWITCH_MSG: {
1977 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1980 case USER_SWITCH_TIMEOUT_MSG: {
1981 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1984 case IMMERSIVE_MODE_LOCK_MSG: {
1985 final boolean nextState = (msg.arg1 != 0);
1986 if (mUpdateLock.isHeld() != nextState) {
1987 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1988 "Applying new update lock state '" + nextState
1989 + "' for " + (ActivityRecord)msg.obj);
1991 mUpdateLock.acquire();
1993 mUpdateLock.release();
1998 case PERSIST_URI_GRANTS_MSG: {
1999 writeGrantedUriPermissions();
2002 case REQUEST_ALL_PSS_MSG: {
2003 synchronized (ActivityManagerService.this) {
2004 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
2008 case START_PROFILES_MSG: {
2009 synchronized (ActivityManagerService.this) {
2010 mUserController.startProfilesLocked();
2015 synchronized (ActivityManagerService.this) {
2016 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2017 ProcessRecord r = mLruProcesses.get(i);
2018 if (r.thread != null) {
2020 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2021 } catch (RemoteException ex) {
2022 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2029 case SYSTEM_USER_START_MSG: {
2030 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2031 Integer.toString(msg.arg1), msg.arg1);
2032 mSystemServiceManager.startUser(msg.arg1);
2035 case SYSTEM_USER_UNLOCK_MSG: {
2036 final int userId = msg.arg1;
2037 mSystemServiceManager.unlockUser(userId);
2038 synchronized (ActivityManagerService.this) {
2039 mRecentTasks.loadUserRecentsLocked(userId);
2041 if (userId == UserHandle.USER_SYSTEM) {
2042 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2044 installEncryptionUnawareProviders(userId);
2045 mUserController.finishUserUnlocked((UserState) msg.obj);
2048 case SYSTEM_USER_CURRENT_MSG: {
2049 mBatteryStatsService.noteEvent(
2050 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2051 Integer.toString(msg.arg2), msg.arg2);
2052 mBatteryStatsService.noteEvent(
2053 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2054 Integer.toString(msg.arg1), msg.arg1);
2055 mSystemServiceManager.switchUser(msg.arg1);
2058 case ENTER_ANIMATION_COMPLETE_MSG: {
2059 synchronized (ActivityManagerService.this) {
2060 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2061 if (r != null && r.app != null && r.app.thread != null) {
2063 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2064 } catch (RemoteException e) {
2070 case FINISH_BOOTING_MSG: {
2071 if (msg.arg1 != 0) {
2072 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2074 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2076 if (msg.arg2 != 0) {
2077 enableScreenAfterBoot();
2081 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2083 Locale l = (Locale) msg.obj;
2084 IBinder service = ServiceManager.getService("mount");
2085 IMountService mountService = IMountService.Stub.asInterface(service);
2086 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2087 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2088 } catch (RemoteException e) {
2089 Log.e(TAG, "Error storing locale for decryption UI", e);
2093 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2094 synchronized (ActivityManagerService.this) {
2095 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2097 // Make a one-way callback to the listener
2098 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2099 } catch (RemoteException e){
2100 // Handled by the RemoteCallbackList
2103 mTaskStackListeners.finishBroadcast();
2107 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2108 synchronized (ActivityManagerService.this) {
2109 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2111 // Make a one-way callback to the listener
2112 mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2113 } catch (RemoteException e){
2114 // Handled by the RemoteCallbackList
2117 mTaskStackListeners.finishBroadcast();
2121 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2122 synchronized (ActivityManagerService.this) {
2123 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2125 // Make a one-way callback to the listener
2126 mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2127 } catch (RemoteException e){
2128 // Handled by the RemoteCallbackList
2131 mTaskStackListeners.finishBroadcast();
2135 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2136 synchronized (ActivityManagerService.this) {
2137 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2139 // Make a one-way callback to the listener
2140 mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2141 } catch (RemoteException e){
2142 // Handled by the RemoteCallbackList
2145 mTaskStackListeners.finishBroadcast();
2149 case NOTIFY_FORCED_RESIZABLE_MSG: {
2150 synchronized (ActivityManagerService.this) {
2151 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2153 // Make a one-way callback to the listener
2154 mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2155 (String) msg.obj, msg.arg1);
2156 } catch (RemoteException e){
2157 // Handled by the RemoteCallbackList
2160 mTaskStackListeners.finishBroadcast();
2164 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2165 synchronized (ActivityManagerService.this) {
2166 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2168 // Make a one-way callback to the listener
2169 mTaskStackListeners.getBroadcastItem(i)
2170 .onActivityDismissingDockedStack();
2171 } catch (RemoteException e){
2172 // Handled by the RemoteCallbackList
2175 mTaskStackListeners.finishBroadcast();
2179 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2180 final int uid = msg.arg1;
2181 final byte[] firstPacket = (byte[]) msg.obj;
2183 synchronized (mPidsSelfLocked) {
2184 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2185 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2188 p.thread.notifyCleartextNetwork(firstPacket);
2189 } catch (RemoteException ignored) {
2196 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2197 final String procName;
2199 final long memLimit;
2200 final String reportPackage;
2201 synchronized (ActivityManagerService.this) {
2202 procName = mMemWatchDumpProcName;
2203 uid = mMemWatchDumpUid;
2204 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2206 val = mMemWatchProcesses.get(procName, 0);
2209 memLimit = val.first;
2210 reportPackage = val.second;
2213 reportPackage = null;
2216 if (procName == null) {
2220 if (DEBUG_PSS) Slog.d(TAG_PSS,
2221 "Showing dump heap notification from " + procName + "/" + uid);
2223 INotificationManager inm = NotificationManager.getService();
2228 String text = mContext.getString(R.string.dump_heap_notification, procName);
2231 Intent deleteIntent = new Intent();
2232 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2233 Intent intent = new Intent();
2234 intent.setClassName("android", DumpHeapActivity.class.getName());
2235 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2236 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2237 if (reportPackage != null) {
2238 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2240 int userId = UserHandle.getUserId(uid);
2241 Notification notification = new Notification.Builder(mContext)
2242 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2245 .setAutoCancel(true)
2247 .setColor(mContext.getColor(
2248 com.android.internal.R.color.system_notification_accent_color))
2249 .setContentTitle(text)
2251 mContext.getText(R.string.dump_heap_notification_detail))
2252 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2253 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2254 new UserHandle(userId)))
2255 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2256 deleteIntent, 0, UserHandle.SYSTEM))
2260 int[] outId = new int[1];
2261 inm.enqueueNotificationWithTag("android", "android", null,
2262 R.string.dump_heap_notification,
2263 notification, outId, userId);
2264 } catch (RuntimeException e) {
2265 Slog.w(ActivityManagerService.TAG,
2266 "Error showing notification for dump heap", e);
2267 } catch (RemoteException e) {
2270 case DELETE_DUMPHEAP_MSG: {
2271 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2272 DumpHeapActivity.JAVA_URI,
2273 Intent.FLAG_GRANT_READ_URI_PERMISSION
2274 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2275 UserHandle.myUserId());
2276 synchronized (ActivityManagerService.this) {
2277 mMemWatchDumpFile = null;
2278 mMemWatchDumpProcName = null;
2279 mMemWatchDumpPid = -1;
2280 mMemWatchDumpUid = -1;
2283 case FOREGROUND_PROFILE_CHANGED_MSG: {
2284 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2286 case REPORT_TIME_TRACKER_MSG: {
2287 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2288 tracker.deliverResult(mContext);
2290 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2291 mUserController.dispatchUserSwitchComplete(msg.arg1);
2293 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2294 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2296 connection.shutdown();
2297 } catch (RemoteException e) {
2298 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2300 // Only a UiAutomation can set this flag and now that
2301 // it is finished we make sure it is reset to its default.
2302 mUserIsMonkey = false;
2304 case APP_BOOST_DEACTIVATE_MSG: {
2305 synchronized(ActivityManagerService.this) {
2307 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2308 nativeMigrateFromBoost();
2310 mBoostStartTime = 0;
2312 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2313 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2318 case IDLE_UIDS_MSG: {
2321 case LOG_STACK_STATE: {
2322 synchronized (ActivityManagerService.this) {
2323 mStackSupervisor.logStackState();
2326 case VR_MODE_CHANGE_MSG: {
2327 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2328 if (vrService == null) {
2331 final ActivityRecord r = (ActivityRecord) msg.obj;
2333 ComponentName requestedPackage;
2334 ComponentName callingPackage;
2336 synchronized (ActivityManagerService.this) {
2337 vrMode = r.requestedVrComponent != null;
2338 requestedPackage = r.requestedVrComponent;
2340 callingPackage = r.info.getComponentName();
2341 if (mInVrMode != vrMode) {
2343 mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2344 if (r.app != null) {
2345 ProcessRecord proc = r.app;
2346 if (proc.vrThreadTid > 0) {
2347 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2349 if (mInVrMode == true) {
2350 Process.setThreadScheduler(proc.vrThreadTid,
2351 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2353 Process.setThreadScheduler(proc.vrThreadTid,
2354 Process.SCHED_OTHER, 0);
2356 } catch (IllegalArgumentException e) {
2357 Slog.w(TAG, "Failed to set scheduling policy, thread does"
2358 + " not exist:\n" + e);
2365 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2366 } case NOTIFY_VR_SLEEPING_MSG: {
2367 notifyVrManagerOfSleepState(msg.arg1 != 0);
2373 static final int COLLECT_PSS_BG_MSG = 1;
2375 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2377 public void handleMessage(Message msg) {
2379 case COLLECT_PSS_BG_MSG: {
2380 long start = SystemClock.uptimeMillis();
2381 MemInfoReader memInfo = null;
2382 synchronized (ActivityManagerService.this) {
2383 if (mFullPssPending) {
2384 mFullPssPending = false;
2385 memInfo = new MemInfoReader();
2388 if (memInfo != null) {
2389 updateCpuStatsNow();
2390 long nativeTotalPss = 0;
2391 final List<ProcessCpuTracker.Stats> stats;
2392 synchronized (mProcessCpuTracker) {
2393 stats = mProcessCpuTracker.getStats( (st)-> {
2394 return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2397 final int N = stats.size();
2398 for (int j = 0; j < N; j++) {
2399 synchronized (mPidsSelfLocked) {
2400 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2401 // This is one of our own processes; skip it.
2405 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2407 memInfo.readMemInfo();
2408 synchronized (ActivityManagerService.this) {
2409 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2410 + (SystemClock.uptimeMillis()-start) + "ms");
2411 final long cachedKb = memInfo.getCachedSizeKb();
2412 final long freeKb = memInfo.getFreeSizeKb();
2413 final long zramKb = memInfo.getZramTotalSizeKb();
2414 final long kernelKb = memInfo.getKernelUsedSizeKb();
2415 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2416 kernelKb*1024, nativeTotalPss*1024);
2417 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2423 long[] tmp = new long[2];
2429 synchronized (ActivityManagerService.this) {
2430 if (mPendingPssProcesses.size() <= 0) {
2431 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2432 "Collected PSS of " + num + " processes in "
2433 + (SystemClock.uptimeMillis() - start) + "ms");
2434 mPendingPssProcesses.clear();
2437 proc = mPendingPssProcesses.remove(0);
2438 procState = proc.pssProcState;
2439 lastPssTime = proc.lastPssTime;
2440 if (proc.thread != null && procState == proc.setProcState
2441 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2442 < SystemClock.uptimeMillis()) {
2450 long pss = Debug.getPss(pid, tmp, null);
2451 synchronized (ActivityManagerService.this) {
2452 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2453 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2455 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2456 SystemClock.uptimeMillis());
2466 public void setSystemProcess() {
2468 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2469 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2470 ServiceManager.addService("meminfo", new MemBinder(this));
2471 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2472 ServiceManager.addService("dbinfo", new DbBinder(this));
2473 if (MONITOR_CPU_USAGE) {
2474 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2476 ServiceManager.addService("permission", new PermissionController(this));
2477 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2479 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2480 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2481 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2483 synchronized (this) {
2484 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2485 app.persistent = true;
2487 app.maxAdj = ProcessList.SYSTEM_ADJ;
2488 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2489 synchronized (mPidsSelfLocked) {
2490 mPidsSelfLocked.put(app.pid, app);
2492 updateLruProcessLocked(app, false, null);
2493 updateOomAdjLocked();
2495 } catch (PackageManager.NameNotFoundException e) {
2496 throw new RuntimeException(
2497 "Unable to find android system package", e);
2501 public void setWindowManager(WindowManagerService wm) {
2502 mWindowManager = wm;
2503 mStackSupervisor.setWindowManager(wm);
2504 mActivityStarter.setWindowManager(wm);
2507 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2508 mUsageStatsService = usageStatsManager;
2511 public void startObservingNativeCrashes() {
2512 final NativeCrashListener ncl = new NativeCrashListener(this);
2516 public IAppOpsService getAppOpsService() {
2517 return mAppOpsService;
2520 static class MemBinder extends Binder {
2521 ActivityManagerService mActivityManagerService;
2522 MemBinder(ActivityManagerService activityManagerService) {
2523 mActivityManagerService = activityManagerService;
2527 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2528 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2529 != PackageManager.PERMISSION_GRANTED) {
2530 pw.println("Permission Denial: can't dump meminfo from from pid="
2531 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2532 + " without permission " + android.Manifest.permission.DUMP);
2536 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2540 static class GraphicsBinder extends Binder {
2541 ActivityManagerService mActivityManagerService;
2542 GraphicsBinder(ActivityManagerService activityManagerService) {
2543 mActivityManagerService = activityManagerService;
2547 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2548 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2549 != PackageManager.PERMISSION_GRANTED) {
2550 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2551 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2552 + " without permission " + android.Manifest.permission.DUMP);
2556 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2560 static class DbBinder extends Binder {
2561 ActivityManagerService mActivityManagerService;
2562 DbBinder(ActivityManagerService activityManagerService) {
2563 mActivityManagerService = activityManagerService;
2567 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2568 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2569 != PackageManager.PERMISSION_GRANTED) {
2570 pw.println("Permission Denial: can't dump dbinfo from from pid="
2571 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2572 + " without permission " + android.Manifest.permission.DUMP);
2576 mActivityManagerService.dumpDbInfo(fd, pw, args);
2580 static class CpuBinder extends Binder {
2581 ActivityManagerService mActivityManagerService;
2582 CpuBinder(ActivityManagerService activityManagerService) {
2583 mActivityManagerService = activityManagerService;
2587 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2588 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2589 != PackageManager.PERMISSION_GRANTED) {
2590 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2591 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2592 + " without permission " + android.Manifest.permission.DUMP);
2596 synchronized (mActivityManagerService.mProcessCpuTracker) {
2597 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2598 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2599 SystemClock.uptimeMillis()));
2604 public static final class Lifecycle extends SystemService {
2605 private final ActivityManagerService mService;
2607 public Lifecycle(Context context) {
2609 mService = new ActivityManagerService(context);
2613 public void onStart() {
2617 public ActivityManagerService getService() {
2622 // Note: This method is invoked on the main thread but may need to attach various
2623 // handlers to other threads. So take care to be explicit about the looper.
2624 public ActivityManagerService(Context systemContext) {
2625 mContext = systemContext;
2626 mFactoryTest = FactoryTest.getMode();
2627 mSystemThread = ActivityThread.currentActivityThread();
2629 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2631 mPermissionReviewRequired = mContext.getResources().getBoolean(
2632 com.android.internal.R.bool.config_permissionReviewRequired);
2634 mHandlerThread = new ServiceThread(TAG,
2635 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2636 mHandlerThread.start();
2637 mHandler = new MainHandler(mHandlerThread.getLooper());
2638 mUiHandler = new UiHandler();
2640 /* static; one-time init here */
2641 if (sKillHandler == null) {
2642 sKillThread = new ServiceThread(TAG + ":kill",
2643 android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2644 sKillThread.start();
2645 sKillHandler = new KillHandler(sKillThread.getLooper());
2648 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2649 "foreground", BROADCAST_FG_TIMEOUT, false);
2650 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2651 "background", BROADCAST_BG_TIMEOUT, true);
2652 mBroadcastQueues[0] = mFgBroadcastQueue;
2653 mBroadcastQueues[1] = mBgBroadcastQueue;
2655 mServices = new ActiveServices(this);
2656 mProviderMap = new ProviderMap(this);
2657 mAppErrors = new AppErrors(mContext, this);
2659 // TODO: Move creation of battery stats service outside of activity manager service.
2660 File dataDir = Environment.getDataDirectory();
2661 File systemDir = new File(dataDir, "system");
2663 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2664 mBatteryStatsService.getActiveStatistics().readLocked();
2665 mBatteryStatsService.scheduleWriteToDisk();
2666 mOnBattery = DEBUG_POWER ? true
2667 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2668 mBatteryStatsService.getActiveStatistics().setCallback(this);
2670 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2672 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2673 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2674 new IAppOpsCallback.Stub() {
2675 @Override public void opChanged(int op, int uid, String packageName) {
2676 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2677 if (mAppOpsService.checkOperation(op, uid, packageName)
2678 != AppOpsManager.MODE_ALLOWED) {
2679 runInBackgroundDisabled(uid);
2685 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2687 mUserController = new UserController(this);
2689 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2690 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2692 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2693 mUseFifoUiScheduling = true;
2696 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2698 mConfiguration.setToDefaults();
2699 mConfiguration.setLocales(LocaleList.getDefault());
2701 mConfigurationSeq = mConfiguration.seq = 1;
2702 mProcessCpuTracker.init();
2704 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2705 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2706 mStackSupervisor = new ActivityStackSupervisor(this);
2707 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2708 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2710 mProcessCpuThread = new Thread("CpuTracker") {
2716 synchronized(this) {
2717 final long now = SystemClock.uptimeMillis();
2718 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2719 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2720 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2721 // + ", write delay=" + nextWriteDelay);
2722 if (nextWriteDelay < nextCpuDelay) {
2723 nextCpuDelay = nextWriteDelay;
2725 if (nextCpuDelay > 0) {
2726 mProcessCpuMutexFree.set(true);
2727 this.wait(nextCpuDelay);
2730 } catch (InterruptedException e) {
2732 updateCpuStatsNow();
2733 } catch (Exception e) {
2734 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2740 Watchdog.getInstance().addMonitor(this);
2741 Watchdog.getInstance().addThread(mHandler);
2744 public void setSystemServiceManager(SystemServiceManager mgr) {
2745 mSystemServiceManager = mgr;
2748 public void setInstaller(Installer installer) {
2749 mInstaller = installer;
2752 private void start() {
2753 Process.removeAllProcessGroups();
2754 mProcessCpuThread.start();
2756 mBatteryStatsService.publish(mContext);
2757 mAppOpsService.publish(mContext);
2758 Slog.d("AppOps", "AppOpsService published");
2759 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2762 void onUserStoppedLocked(int userId) {
2763 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2766 public void initPowerManagement() {
2767 mStackSupervisor.initPowerManagement();
2768 mBatteryStatsService.initPowerManagement();
2769 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2770 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2771 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2772 mVoiceWakeLock.setReferenceCounted(false);
2776 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2777 throws RemoteException {
2778 if (code == SYSPROPS_TRANSACTION) {
2779 // We need to tell all apps about the system property change.
2780 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2781 synchronized(this) {
2782 final int NP = mProcessNames.getMap().size();
2783 for (int ip=0; ip<NP; ip++) {
2784 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2785 final int NA = apps.size();
2786 for (int ia=0; ia<NA; ia++) {
2787 ProcessRecord app = apps.valueAt(ia);
2788 if (app.thread != null) {
2789 procs.add(app.thread.asBinder());
2795 int N = procs.size();
2796 for (int i=0; i<N; i++) {
2797 Parcel data2 = Parcel.obtain();
2799 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2800 } catch (RemoteException e) {
2806 return super.onTransact(code, data, reply, flags);
2807 } catch (RuntimeException e) {
2808 // The activity manager only throws security exceptions, so let's
2810 if (!(e instanceof SecurityException)) {
2811 Slog.wtf(TAG, "Activity Manager Crash", e);
2817 void updateCpuStats() {
2818 final long now = SystemClock.uptimeMillis();
2819 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2822 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2823 synchronized (mProcessCpuThread) {
2824 mProcessCpuThread.notify();
2829 void updateCpuStatsNow() {
2830 synchronized (mProcessCpuTracker) {
2831 mProcessCpuMutexFree.set(false);
2832 final long now = SystemClock.uptimeMillis();
2833 boolean haveNewCpuStats = false;
2835 if (MONITOR_CPU_USAGE &&
2836 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2837 mLastCpuTime.set(now);
2838 mProcessCpuTracker.update();
2839 if (mProcessCpuTracker.hasGoodLastStats()) {
2840 haveNewCpuStats = true;
2841 //Slog.i(TAG, mProcessCpu.printCurrentState());
2842 //Slog.i(TAG, "Total CPU usage: "
2843 // + mProcessCpu.getTotalCpuPercent() + "%");
2845 // Slog the cpu usage if the property is set.
2846 if ("true".equals(SystemProperties.get("events.cpu"))) {
2847 int user = mProcessCpuTracker.getLastUserTime();
2848 int system = mProcessCpuTracker.getLastSystemTime();
2849 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2850 int irq = mProcessCpuTracker.getLastIrqTime();
2851 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2852 int idle = mProcessCpuTracker.getLastIdleTime();
2854 int total = user + system + iowait + irq + softIrq + idle;
2855 if (total == 0) total = 1;
2857 EventLog.writeEvent(EventLogTags.CPU,
2858 ((user+system+iowait+irq+softIrq) * 100) / total,
2859 (user * 100) / total,
2860 (system * 100) / total,
2861 (iowait * 100) / total,
2862 (irq * 100) / total,
2863 (softIrq * 100) / total);
2868 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2869 synchronized(bstats) {
2870 synchronized(mPidsSelfLocked) {
2871 if (haveNewCpuStats) {
2872 if (bstats.startAddingCpuLocked()) {
2875 final int N = mProcessCpuTracker.countStats();
2876 for (int i=0; i<N; i++) {
2877 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2881 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2882 totalUTime += st.rel_utime;
2883 totalSTime += st.rel_stime;
2885 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2886 if (ps == null || !ps.isActive()) {
2887 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2888 pr.info.uid, pr.processName);
2890 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2891 pr.curCpuTime += st.rel_utime + st.rel_stime;
2893 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2894 if (ps == null || !ps.isActive()) {
2895 st.batteryStats = ps = bstats.getProcessStatsLocked(
2896 bstats.mapUid(st.uid), st.name);
2898 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2901 final int userTime = mProcessCpuTracker.getLastUserTime();
2902 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2903 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2904 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2905 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2906 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2907 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2908 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2913 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2914 mLastWriteTime = now;
2915 mBatteryStatsService.scheduleWriteToDisk();
2922 public void batteryNeedsCpuUpdate() {
2923 updateCpuStatsNow();
2927 public void batteryPowerChanged(boolean onBattery) {
2928 // When plugging in, update the CPU stats first before changing
2930 updateCpuStatsNow();
2931 synchronized (this) {
2932 synchronized(mPidsSelfLocked) {
2933 mOnBattery = DEBUG_POWER ? true : onBattery;
2939 public void batterySendBroadcast(Intent intent) {
2940 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2941 AppOpsManager.OP_NONE, null, false, false,
2942 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2946 * Initialize the application bind args. These are passed to each
2947 * process when the bindApplication() IPC is sent to the process. They're
2948 * lazily setup to make sure the services are running when they're asked for.
2950 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2951 // Isolated processes won't get this optimization, so that we don't
2952 // violate the rules about which services they have access to.
2954 if (mIsolatedAppBindArgs == null) {
2955 mIsolatedAppBindArgs = new HashMap<>();
2956 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2958 return mIsolatedAppBindArgs;
2961 if (mAppBindArgs == null) {
2962 mAppBindArgs = new HashMap<>();
2964 // Setup the application init args
2965 mAppBindArgs.put("package", ServiceManager.getService("package"));
2966 mAppBindArgs.put("window", ServiceManager.getService("window"));
2967 mAppBindArgs.put(Context.ALARM_SERVICE,
2968 ServiceManager.getService(Context.ALARM_SERVICE));
2970 return mAppBindArgs;
2973 boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2974 if (r == null || mFocusedActivity == r) {
2978 if (!r.isFocusable()) {
2979 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2983 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2985 final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2986 if (wasDoingSetFocusedActivity) Slog.w(TAG,
2987 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2988 mDoingSetFocusedActivity = true;
2990 final ActivityRecord last = mFocusedActivity;
2991 mFocusedActivity = r;
2992 if (r.task.isApplicationTask()) {
2993 if (mCurAppTimeTracker != r.appTimeTracker) {
2994 // We are switching app tracking. Complete the current one.
2995 if (mCurAppTimeTracker != null) {
2996 mCurAppTimeTracker.stop();
2997 mHandler.obtainMessage(
2998 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2999 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
3000 mCurAppTimeTracker = null;
3002 if (r.appTimeTracker != null) {
3003 mCurAppTimeTracker = r.appTimeTracker;
3004 startTimeTrackingFocusedActivityLocked();
3007 startTimeTrackingFocusedActivityLocked();
3010 r.appTimeTracker = null;
3012 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3013 // TODO: Probably not, because we don't want to resume voice on switching
3014 // back to this activity
3015 if (r.task.voiceInteractor != null) {
3016 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3018 finishRunningVoiceLocked();
3019 IVoiceInteractionSession session;
3020 if (last != null && ((session = last.task.voiceSession) != null
3021 || (session = last.voiceSession) != null)) {
3022 // We had been in a voice interaction session, but now focused has
3023 // move to something different. Just finish the session, we can't
3024 // return to it and retain the proper state and synchronization with
3025 // the voice interaction service.
3026 finishVoiceTask(session);
3029 if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3030 mWindowManager.setFocusedApp(r.appToken, true);
3032 applyUpdateLockStateLocked(r);
3033 applyUpdateVrModeLocked(r);
3034 if (mFocusedActivity.userId != mLastFocusedUserId) {
3035 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3036 mHandler.obtainMessage(
3037 FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3038 mLastFocusedUserId = mFocusedActivity.userId;
3041 // Log a warning if the focused app is changed during the process. This could
3042 // indicate a problem of the focus setting logic!
3043 if (mFocusedActivity != r) Slog.w(TAG,
3044 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3045 mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3047 EventLogTags.writeAmFocusedActivity(
3048 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3049 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3054 final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3055 if (mFocusedActivity != goingAway) {
3059 final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3060 if (focusedStack != null) {
3061 final ActivityRecord top = focusedStack.topActivity();
3062 if (top != null && top.userId != mLastFocusedUserId) {
3063 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3064 mHandler.sendMessage(
3065 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3066 mLastFocusedUserId = top.userId;
3070 // Try to move focus to another activity if possible.
3071 if (setFocusedActivityLocked(
3072 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3076 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3077 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3078 mFocusedActivity = null;
3079 EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3083 public void setFocusedStack(int stackId) {
3084 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3085 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3086 final long callingId = Binder.clearCallingIdentity();
3088 synchronized (this) {
3089 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3090 if (stack == null) {
3093 final ActivityRecord r = stack.topRunningActivityLocked();
3094 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3095 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3099 Binder.restoreCallingIdentity(callingId);
3104 public void setFocusedTask(int taskId) {
3105 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3106 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3107 final long callingId = Binder.clearCallingIdentity();
3109 synchronized (this) {
3110 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3114 if (mUserController.shouldConfirmCredentials(task.userId)) {
3115 mActivityStarter.showConfirmDeviceCredential(task.userId);
3116 if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3117 mStackSupervisor.moveTaskToStackLocked(task.taskId,
3118 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3119 "setFocusedTask", ANIMATE);
3123 final ActivityRecord r = task.topRunningActivityLocked();
3124 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3125 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3129 Binder.restoreCallingIdentity(callingId);
3133 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3135 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3136 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3137 synchronized (this) {
3138 if (listener != null) {
3139 mTaskStackListeners.register(listener);
3145 public void notifyActivityDrawn(IBinder token) {
3146 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3147 synchronized (this) {
3148 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3150 r.task.stack.notifyActivityDrawnLocked(r);
3155 final void applyUpdateLockStateLocked(ActivityRecord r) {
3156 // Modifications to the UpdateLock state are done on our handler, outside
3157 // the activity manager's locks. The new state is determined based on the
3158 // state *now* of the relevant activity record. The object is passed to
3159 // the handler solely for logging detail, not to be consulted/modified.
3160 final boolean nextState = r != null && r.immersive;
3161 mHandler.sendMessage(
3162 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3165 final void applyUpdateVrModeLocked(ActivityRecord r) {
3166 mHandler.sendMessage(
3167 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3170 private void sendNotifyVrManagerOfSleepState(boolean isSleeping) {
3171 mHandler.sendMessage(
3172 mHandler.obtainMessage(NOTIFY_VR_SLEEPING_MSG, isSleeping ? 1 : 0, 0));
3175 private void notifyVrManagerOfSleepState(boolean isSleeping) {
3176 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
3177 if (vrService == null) {
3180 vrService.onSleepStateChanged(isSleeping);
3183 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3184 Message msg = Message.obtain();
3185 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3186 msg.obj = r.task.askedCompatMode ? null : r;
3187 mUiHandler.sendMessage(msg);
3190 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3191 if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3192 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3193 final Message msg = Message.obtain();
3194 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3196 mUiHandler.sendMessage(msg);
3200 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3201 String what, Object obj, ProcessRecord srcApp) {
3202 app.lastActivityTime = now;
3204 if (app.activities.size() > 0) {
3205 // Don't want to touch dependent processes that are hosting activities.
3209 int lrui = mLruProcesses.lastIndexOf(app);
3211 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3212 + what + " " + obj + " from " + srcApp);
3216 if (lrui >= index) {
3217 // Don't want to cause this to move dependent processes *back* in the
3218 // list as if they were less frequently used.
3222 if (lrui >= mLruProcessActivityStart) {
3223 // Don't want to touch dependent processes that are hosting activities.
3227 mLruProcesses.remove(lrui);
3231 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3232 + " in LRU list: " + app);
3233 mLruProcesses.add(index, app);
3237 static void killProcessGroup(int uid, int pid) {
3238 if (sKillHandler != null) {
3239 sKillHandler.sendMessage(
3240 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3242 Slog.w(TAG, "Asked to kill process group before system bringup!");
3243 Process.killProcessGroup(uid, pid);
3247 final void removeLruProcessLocked(ProcessRecord app) {
3248 int lrui = mLruProcesses.lastIndexOf(app);
3251 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3252 Process.killProcessQuiet(app.pid);
3253 killProcessGroup(app.uid, app.pid);
3255 if (lrui <= mLruProcessActivityStart) {
3256 mLruProcessActivityStart--;
3258 if (lrui <= mLruProcessServiceStart) {
3259 mLruProcessServiceStart--;
3261 mLruProcesses.remove(lrui);
3265 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3266 ProcessRecord client) {
3267 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3268 || app.treatLikeActivity;
3269 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3270 if (!activityChange && hasActivity) {
3271 // The process has activities, so we are only allowing activity-based adjustments
3272 // to move it. It should be kept in the front of the list with other
3273 // processes that have activities, and we don't want those to change their
3274 // order except due to activity operations.
3279 final long now = SystemClock.uptimeMillis();
3280 app.lastActivityTime = now;
3282 // First a quick reject: if the app is already at the position we will
3283 // put it, then there is nothing to do.
3285 final int N = mLruProcesses.size();
3286 if (N > 0 && mLruProcesses.get(N-1) == app) {
3287 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3291 if (mLruProcessServiceStart > 0
3292 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3293 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3298 int lrui = mLruProcesses.lastIndexOf(app);
3300 if (app.persistent && lrui >= 0) {
3301 // We don't care about the position of persistent processes, as long as
3302 // they are in the list.
3303 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3307 /* In progress: compute new position first, so we can avoid doing work
3308 if the process is not actually going to move. Not yet working.
3311 boolean inActivity = false, inService = false;
3313 // Process has activities, put it at the very tipsy-top.
3314 addIndex = mLruProcesses.size();
3315 nextIndex = mLruProcessServiceStart;
3317 } else if (hasService) {
3318 // Process has services, put it at the top of the service list.
3319 addIndex = mLruProcessActivityStart;
3320 nextIndex = mLruProcessServiceStart;
3324 // Process not otherwise of interest, it goes to the top of the non-service area.
3325 addIndex = mLruProcessServiceStart;
3326 if (client != null) {
3327 int clientIndex = mLruProcesses.lastIndexOf(client);
3328 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3330 if (clientIndex >= 0 && addIndex > clientIndex) {
3331 addIndex = clientIndex;
3334 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3337 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3338 + mLruProcessActivityStart + "): " + app);
3342 if (lrui < mLruProcessActivityStart) {
3343 mLruProcessActivityStart--;
3345 if (lrui < mLruProcessServiceStart) {
3346 mLruProcessServiceStart--;
3349 if (addIndex > lrui) {
3352 if (nextIndex > lrui) {
3356 mLruProcesses.remove(lrui);
3360 mLruProcesses.add(addIndex, app);
3362 mLruProcessActivityStart++;
3365 mLruProcessActivityStart++;
3371 final int N = mLruProcesses.size();
3372 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3373 // Process doesn't have activities, but has clients with
3374 // activities... move it up, but one below the top (the top
3375 // should always have a real activity).
3376 if (DEBUG_LRU) Slog.d(TAG_LRU,
3377 "Adding to second-top of LRU activity list: " + app);
3378 mLruProcesses.add(N - 1, app);
3379 // To keep it from spamming the LRU list (by making a bunch of clients),
3380 // we will push down any other entries owned by the app.
3381 final int uid = app.info.uid;
3382 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3383 ProcessRecord subProc = mLruProcesses.get(i);
3384 if (subProc.info.uid == uid) {
3385 // We want to push this one down the list. If the process after
3386 // it is for the same uid, however, don't do so, because we don't
3387 // want them internally to be re-ordered.
3388 if (mLruProcesses.get(i - 1).info.uid != uid) {
3389 if (DEBUG_LRU) Slog.d(TAG_LRU,
3390 "Pushing uid " + uid + " swapping at " + i + ": "
3391 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3392 ProcessRecord tmp = mLruProcesses.get(i);
3393 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3394 mLruProcesses.set(i - 1, tmp);
3398 // A gap, we can stop here.
3403 // Process has activities, put it at the very tipsy-top.
3404 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3405 mLruProcesses.add(app);
3407 nextIndex = mLruProcessServiceStart;
3408 } else if (hasService) {
3409 // Process has services, put it at the top of the service list.
3410 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3411 mLruProcesses.add(mLruProcessActivityStart, app);
3412 nextIndex = mLruProcessServiceStart;
3413 mLruProcessActivityStart++;
3415 // Process not otherwise of interest, it goes to the top of the non-service area.
3416 int index = mLruProcessServiceStart;
3417 if (client != null) {
3418 // If there is a client, don't allow the process to be moved up higher
3419 // in the list than that client.
3420 int clientIndex = mLruProcesses.lastIndexOf(client);
3421 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3422 + " when updating " + app);
3423 if (clientIndex <= lrui) {
3424 // Don't allow the client index restriction to push it down farther in the
3425 // list than it already is.
3428 if (clientIndex >= 0 && index > clientIndex) {
3429 index = clientIndex;
3432 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3433 mLruProcesses.add(index, app);
3434 nextIndex = index-1;
3435 mLruProcessActivityStart++;
3436 mLruProcessServiceStart++;
3439 // If the app is currently using a content provider or service,
3440 // bump those processes as well.
3441 for (int j=app.connections.size()-1; j>=0; j--) {
3442 ConnectionRecord cr = app.connections.valueAt(j);
3443 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3444 && cr.binding.service.app != null
3445 && cr.binding.service.app.lruSeq != mLruSeq
3446 && !cr.binding.service.app.persistent) {
3447 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3448 "service connection", cr, app);
3451 for (int j=app.conProviders.size()-1; j>=0; j--) {
3452 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3453 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3454 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3455 "provider reference", cpr, app);
3460 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3461 if (uid == Process.SYSTEM_UID) {
3462 // The system gets to run in any process. If there are multiple
3463 // processes with the same uid, just pick the first (this
3464 // should never happen).
3465 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3466 if (procs == null) return null;
3467 final int procCount = procs.size();
3468 for (int i = 0; i < procCount; i++) {
3469 final int procUid = procs.keyAt(i);
3470 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3471 // Don't use an app process or different user process for system component.
3474 return procs.valueAt(i);
3477 ProcessRecord proc = mProcessNames.get(processName, uid);
3478 if (false && proc != null && !keepIfLarge
3479 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3480 && proc.lastCachedPss >= 4000) {
3481 // Turn this condition on to cause killing to happen regularly, for testing.
3482 if (proc.baseProcessTracker != null) {
3483 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3485 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3486 } else if (proc != null && !keepIfLarge
3487 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3488 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3489 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3490 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3491 if (proc.baseProcessTracker != null) {
3492 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3494 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3500 void notifyPackageUse(String packageName, int reason) {
3501 IPackageManager pm = AppGlobals.getPackageManager();
3503 pm.notifyPackageUse(packageName, reason);
3504 } catch (RemoteException e) {
3508 boolean isNextTransitionForward() {
3509 int transit = mWindowManager.getPendingAppTransition();
3510 return transit == TRANSIT_ACTIVITY_OPEN
3511 || transit == TRANSIT_TASK_OPEN
3512 || transit == TRANSIT_TASK_TO_FRONT;
3515 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3516 String processName, String abiOverride, int uid, Runnable crashHandler) {
3517 synchronized(this) {
3518 ApplicationInfo info = new ApplicationInfo();
3519 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3520 // For isolated processes, the former contains the parent's uid and the latter the
3521 // actual uid of the isolated process.
3522 // In the special case introduced by this method (which is, starting an isolated
3523 // process directly from the SystemServer without an actual parent app process) the
3524 // closest thing to a parent's uid is SYSTEM_UID.
3525 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3526 // the |isolated| logic in the ProcessRecord constructor.
3527 info.uid = Process.SYSTEM_UID;
3528 info.processName = processName;
3529 info.className = entryPoint;
3530 info.packageName = "android";
3531 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3532 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3533 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3534 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3536 return proc != null ? proc.pid : 0;
3540 final ProcessRecord startProcessLocked(String processName,
3541 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3542 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3543 boolean isolated, boolean keepIfLarge) {
3544 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3545 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3546 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3547 null /* crashHandler */);
3550 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3551 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3552 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3553 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3554 long startTime = SystemClock.elapsedRealtime();
3557 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3558 checkTime(startTime, "startProcess: after getProcessRecord");
3560 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3561 // If we are in the background, then check to see if this process
3562 // is bad. If so, we will just silently fail.
3563 if (mAppErrors.isBadProcessLocked(info)) {
3564 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3565 + "/" + info.processName);
3569 // When the user is explicitly starting a process, then clear its
3570 // crash count so that we won't make it bad until they see at
3571 // least one crash dialog again, and make the process good again
3572 // if it had been bad.
3573 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3574 + "/" + info.processName);
3575 mAppErrors.resetProcessCrashTimeLocked(info);
3576 if (mAppErrors.isBadProcessLocked(info)) {
3577 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3578 UserHandle.getUserId(info.uid), info.uid,
3580 mAppErrors.clearBadProcessLocked(info);
3587 // If this is an isolated process, it can't re-use an existing process.
3591 // app launch boost for big.little configurations
3592 // use cpusets to migrate freshly launched tasks to big cores
3593 nativeMigrateToBoost();
3595 mBoostStartTime = SystemClock.uptimeMillis();
3596 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3597 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3599 // We don't have to do anything more if:
3600 // (1) There is an existing application record; and
3601 // (2) The caller doesn't think it is dead, OR there is no thread
3602 // object attached to it so we know it couldn't have crashed; and
3603 // (3) There is a pid assigned to it, so it is either starting or
3605 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3606 + " app=" + app + " knownToBeDead=" + knownToBeDead
3607 + " thread=" + (app != null ? app.thread : null)
3608 + " pid=" + (app != null ? app.pid : -1));
3609 if (app != null && app.pid > 0) {
3610 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3611 // We already have the app running, or are waiting for it to
3612 // come up (we have a pid but not yet its thread), so keep it.
3613 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3614 // If this is a new package in the process, add the package to the list
3615 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3616 checkTime(startTime, "startProcess: done, added package to proc");
3620 // An application record is attached to a previous process,
3622 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3623 checkTime(startTime, "startProcess: bad proc running, killing");
3624 killProcessGroup(app.uid, app.pid);
3625 handleAppDiedLocked(app, true, true);
3626 checkTime(startTime, "startProcess: done killing old proc");
3629 String hostingNameStr = hostingName != null
3630 ? hostingName.flattenToShortString() : null;
3633 checkTime(startTime, "startProcess: creating new process record");
3634 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3636 Slog.w(TAG, "Failed making new process record for "
3637 + processName + "/" + info.uid + " isolated=" + isolated);
3640 app.crashHandler = crashHandler;
3641 checkTime(startTime, "startProcess: done creating new process record");
3643 // If this is a new package in the process, add the package to the list
3644 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3645 checkTime(startTime, "startProcess: added package to existing proc");
3648 // If the system is not ready yet, then hold off on starting this
3649 // process until it is.
3650 if (!mProcessesReady
3651 && !isAllowedWhileBooting(info)
3652 && !allowWhileBooting) {
3653 if (!mProcessesOnHold.contains(app)) {
3654 mProcessesOnHold.add(app);
3656 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3657 "System not ready, putting on hold: " + app);
3658 checkTime(startTime, "startProcess: returning with proc on hold");
3662 checkTime(startTime, "startProcess: stepping in to startProcess");
3664 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3665 checkTime(startTime, "startProcess: done starting proc!");
3666 return (app.pid != 0) ? app : null;
3669 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3670 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3673 private final void startProcessLocked(ProcessRecord app,
3674 String hostingType, String hostingNameStr) {
3675 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3676 null /* entryPoint */, null /* entryPointArgs */);
3679 private final void startProcessLocked(ProcessRecord app, String hostingType,
3680 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3681 long startTime = SystemClock.elapsedRealtime();
3682 if (app.pid > 0 && app.pid != MY_PID) {
3683 checkTime(startTime, "startProcess: removing from pids map");
3684 synchronized (mPidsSelfLocked) {
3685 mPidsSelfLocked.remove(app.pid);
3686 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3688 checkTime(startTime, "startProcess: done removing from pids map");
3692 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3693 "startProcessLocked removing on hold: " + app);
3694 mProcessesOnHold.remove(app);
3696 checkTime(startTime, "startProcess: starting to update cpu stats");
3698 checkTime(startTime, "startProcess: done updating cpu stats");
3702 final int userId = UserHandle.getUserId(app.uid);
3703 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3704 } catch (RemoteException e) {
3705 throw e.rethrowAsRuntimeException();
3710 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3711 if (!app.isolated) {
3712 int[] permGids = null;
3714 checkTime(startTime, "startProcess: getting gids from package manager");
3715 final IPackageManager pm = AppGlobals.getPackageManager();
3716 permGids = pm.getPackageGids(app.info.packageName,
3717 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3718 MountServiceInternal mountServiceInternal = LocalServices.getService(
3719 MountServiceInternal.class);
3720 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3721 app.info.packageName);
3722 } catch (RemoteException e) {
3723 throw e.rethrowAsRuntimeException();
3727 * Add shared application and profile GIDs so applications can share some
3728 * resources like shared libraries and access user-wide resources
3730 if (ArrayUtils.isEmpty(permGids)) {
3733 gids = new int[permGids.length + 2];
3734 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3736 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3737 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3739 checkTime(startTime, "startProcess: building args");
3740 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3741 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3742 && mTopComponent != null
3743 && app.processName.equals(mTopComponent.getPackageName())) {
3746 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3747 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3752 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3753 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3754 // Also turn on CheckJNI for debuggable apps. It's quite
3755 // awkward to turn on otherwise.
3756 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3758 // Run the app in safe mode if its manifest requests so or the
3759 // system is booted in safe mode.
3760 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3761 mSafeMode == true) {
3762 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3764 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3765 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3767 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3768 if ("true".equals(genDebugInfoProperty)) {
3769 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3771 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3772 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3774 if ("1".equals(SystemProperties.get("debug.assert"))) {
3775 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3777 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3778 // Enable all debug flags required by the native debugger.
3779 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3780 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3781 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3782 mNativeDebuggingApp = null;
3785 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3786 if (requiredAbi == null) {
3787 requiredAbi = Build.SUPPORTED_ABIS[0];
3790 String instructionSet = null;
3791 if (app.info.primaryCpuAbi != null) {
3792 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3796 app.requiredAbi = requiredAbi;
3797 app.instructionSet = instructionSet;
3799 // Start the process. It will either succeed and return a result containing
3800 // the PID of the new process, or else throw a RuntimeException.
3801 boolean isActivityProcess = (entryPoint == null);
3802 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3803 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3805 checkTime(startTime, "startProcess: asking zygote to start proc");
3806 Process.ProcessStartResult startResult = Process.start(entryPoint,
3807 app.processName, uid, uid, gids, debugFlags, mountExternal,
3808 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3809 app.info.dataDir, entryPointArgs);
3810 checkTime(startTime, "startProcess: returned from zygote!");
3811 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3813 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3814 checkTime(startTime, "startProcess: done updating battery stats");
3816 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3817 UserHandle.getUserId(uid), startResult.pid, uid,
3818 app.processName, hostingType,
3819 hostingNameStr != null ? hostingNameStr : "");
3822 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3823 app.info.seinfo, app.info.sourceDir, startResult.pid);
3824 } catch (RemoteException ex) {
3828 if (app.persistent) {
3829 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3832 checkTime(startTime, "startProcess: building log message");
3833 StringBuilder buf = mStringBuilder;
3835 buf.append("Start proc ");
3836 buf.append(startResult.pid);
3838 buf.append(app.processName);
3840 UserHandle.formatUid(buf, uid);
3841 if (!isActivityProcess) {
3843 buf.append(entryPoint);
3846 buf.append(" for ");
3847 buf.append(hostingType);
3848 if (hostingNameStr != null) {
3850 buf.append(hostingNameStr);
3852 Slog.i(TAG, buf.toString());
3853 app.setPid(startResult.pid);
3854 app.usingWrapper = startResult.usingWrapper;
3855 app.removed = false;
3857 app.killedByAm = false;
3858 checkTime(startTime, "startProcess: starting to update pids map");
3859 ProcessRecord oldApp;
3860 synchronized (mPidsSelfLocked) {
3861 oldApp = mPidsSelfLocked.get(startResult.pid);
3863 // If there is already an app occupying that pid that hasn't been cleaned up
3864 if (oldApp != null && !app.isolated) {
3865 // Clean up anything relating to this pid first
3866 Slog.w(TAG, "Reusing pid " + startResult.pid
3867 + " while app is still mapped to it");
3868 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3869 true /*replacingPid*/);
3871 synchronized (mPidsSelfLocked) {
3872 this.mPidsSelfLocked.put(startResult.pid, app);
3873 if (isActivityProcess) {
3874 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3876 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3877 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3880 checkTime(startTime, "startProcess: done updating pids map");
3881 } catch (RuntimeException e) {
3882 Slog.e(TAG, "Failure starting process " + app.processName, e);
3884 // Something went very wrong while trying to start this process; one
3885 // common case is when the package is frozen due to an active
3886 // upgrade. To recover, clean up any active bookkeeping related to
3887 // starting this process. (We already invoked this method once when
3888 // the package was initially frozen through KILL_APPLICATION_MSG, so
3889 // it doesn't hurt to use it again.)
3890 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3891 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3895 void updateUsageStats(ActivityRecord component, boolean resumed) {
3896 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3897 "updateUsageStats: comp=" + component + "res=" + resumed);
3898 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3900 if (mUsageStatsService != null) {
3901 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3902 UsageEvents.Event.MOVE_TO_FOREGROUND);
3904 synchronized (stats) {
3905 stats.noteActivityResumedLocked(component.app.uid);
3908 if (mUsageStatsService != null) {
3909 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3910 UsageEvents.Event.MOVE_TO_BACKGROUND);
3912 synchronized (stats) {
3913 stats.noteActivityPausedLocked(component.app.uid);
3918 Intent getHomeIntent() {
3919 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3920 intent.setComponent(mTopComponent);
3921 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3922 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3923 intent.addCategory(Intent.CATEGORY_HOME);
3928 boolean startHomeActivityLocked(int userId, String reason) {
3929 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3930 && mTopAction == null) {
3931 // We are running in factory test mode, but unable to find
3932 // the factory test app, so just sit around displaying the
3933 // error message and don't try to start anything.
3936 Intent intent = getHomeIntent();
3937 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3938 if (aInfo != null) {
3939 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3940 // Don't do this if the home app is currently being
3942 aInfo = new ActivityInfo(aInfo);
3943 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3944 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3945 aInfo.applicationInfo.uid, true);
3946 if (app == null || app.instrumentationClass == null) {
3947 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3948 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3951 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3957 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3958 ActivityInfo ai = null;
3959 ComponentName comp = intent.getComponent();
3963 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3965 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3967 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3971 ai = info.activityInfo;
3974 } catch (RemoteException e) {
3982 * Starts the "new version setup screen" if appropriate.
3984 void startSetupActivityLocked() {
3985 // Only do this once per boot.
3986 if (mCheckedForSetup) {
3990 // We will show this screen if the current one is a different
3991 // version than the last one shown, and we are not running in
3992 // low-level factory test mode.
3993 final ContentResolver resolver = mContext.getContentResolver();
3994 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3995 Settings.Global.getInt(resolver,
3996 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3997 mCheckedForSetup = true;
3999 // See if we should be showing the platform update setup UI.
4000 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4001 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4002 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4003 if (!ris.isEmpty()) {
4004 final ResolveInfo ri = ris.get(0);
4005 String vers = ri.activityInfo.metaData != null
4006 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4008 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4009 vers = ri.activityInfo.applicationInfo.metaData.getString(
4010 Intent.METADATA_SETUP_VERSION);
4012 String lastVers = Settings.Secure.getString(
4013 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4014 if (vers != null && !vers.equals(lastVers)) {
4015 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4016 intent.setComponent(new ComponentName(
4017 ri.activityInfo.packageName, ri.activityInfo.name));
4018 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4019 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4020 null, 0, 0, 0, null, false, false, null, null, null);
4026 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4027 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4030 void enforceNotIsolatedCaller(String caller) {
4031 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4032 throw new SecurityException("Isolated process not allowed to call " + caller);
4036 void enforceShellRestriction(String restriction, int userHandle) {
4037 if (Binder.getCallingUid() == Process.SHELL_UID) {
4038 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4039 throw new SecurityException("Shell does not have permission to access user "
4046 public int getFrontActivityScreenCompatMode() {
4047 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4048 synchronized (this) {
4049 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4054 public void setFrontActivityScreenCompatMode(int mode) {
4055 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4056 "setFrontActivityScreenCompatMode");
4057 synchronized (this) {
4058 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4063 public int getPackageScreenCompatMode(String packageName) {
4064 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4065 synchronized (this) {
4066 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4071 public void setPackageScreenCompatMode(String packageName, int mode) {
4072 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4073 "setPackageScreenCompatMode");
4074 synchronized (this) {
4075 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4080 public boolean getPackageAskScreenCompat(String packageName) {
4081 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4082 synchronized (this) {
4083 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4088 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4089 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4090 "setPackageAskScreenCompat");
4091 synchronized (this) {
4092 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4096 private boolean hasUsageStatsPermission(String callingPackage) {
4097 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4098 Binder.getCallingUid(), callingPackage);
4099 if (mode == AppOpsManager.MODE_DEFAULT) {
4100 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4101 == PackageManager.PERMISSION_GRANTED;
4103 return mode == AppOpsManager.MODE_ALLOWED;
4107 public int getPackageProcessState(String packageName, String callingPackage) {
4108 if (!hasUsageStatsPermission(callingPackage)) {
4109 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4110 "getPackageProcessState");
4113 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4114 synchronized (this) {
4115 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4116 final ProcessRecord proc = mLruProcesses.get(i);
4117 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4118 || procState > proc.setProcState) {
4119 boolean found = false;
4120 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4121 if (proc.pkgList.keyAt(j).equals(packageName)) {
4122 procState = proc.setProcState;
4126 if (proc.pkgDeps != null && !found) {
4127 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4128 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4129 procState = proc.setProcState;
4141 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4142 synchronized (this) {
4143 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4147 if (app.trimMemoryLevel < level && app.thread != null &&
4148 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4149 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4151 app.thread.scheduleTrimMemory(level);
4152 app.trimMemoryLevel = level;
4154 } catch (RemoteException e) {
4155 // Fallthrough to failure case.
4162 private void dispatchProcessesChanged() {
4164 synchronized (this) {
4165 N = mPendingProcessChanges.size();
4166 if (mActiveProcessChanges.length < N) {
4167 mActiveProcessChanges = new ProcessChangeItem[N];
4169 mPendingProcessChanges.toArray(mActiveProcessChanges);
4170 mPendingProcessChanges.clear();
4171 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4172 "*** Delivering " + N + " process changes");
4175 int i = mProcessObservers.beginBroadcast();
4178 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4179 if (observer != null) {
4181 for (int j=0; j<N; j++) {
4182 ProcessChangeItem item = mActiveProcessChanges[j];
4183 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4184 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4185 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4186 + item.uid + ": " + item.foregroundActivities);
4187 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4188 item.foregroundActivities);
4190 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4191 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4192 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4193 + ": " + item.processState);
4194 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4197 } catch (RemoteException e) {
4201 mProcessObservers.finishBroadcast();
4203 synchronized (this) {
4204 for (int j=0; j<N; j++) {
4205 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4210 private void dispatchProcessDied(int pid, int uid) {
4211 int i = mProcessObservers.beginBroadcast();
4214 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4215 if (observer != null) {
4217 observer.onProcessDied(pid, uid);
4218 } catch (RemoteException e) {
4222 mProcessObservers.finishBroadcast();
4225 private void dispatchUidsChanged() {
4227 synchronized (this) {
4228 N = mPendingUidChanges.size();
4229 if (mActiveUidChanges.length < N) {
4230 mActiveUidChanges = new UidRecord.ChangeItem[N];
4232 for (int i=0; i<N; i++) {
4233 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4234 mActiveUidChanges[i] = change;
4235 if (change.uidRecord != null) {
4236 change.uidRecord.pendingChange = null;
4237 change.uidRecord = null;
4240 mPendingUidChanges.clear();
4241 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4242 "*** Delivering " + N + " uid changes");
4245 if (mLocalPowerManager != null) {
4246 for (int j=0; j<N; j++) {
4247 UidRecord.ChangeItem item = mActiveUidChanges[j];
4248 if (item.change == UidRecord.CHANGE_GONE
4249 || item.change == UidRecord.CHANGE_GONE_IDLE) {
4250 mLocalPowerManager.uidGone(item.uid);
4252 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4257 int i = mUidObservers.beginBroadcast();
4260 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4261 final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4262 if (observer != null) {
4264 for (int j=0; j<N; j++) {
4265 UidRecord.ChangeItem item = mActiveUidChanges[j];
4266 final int change = item.change;
4267 UidRecord validateUid = null;
4268 if (VALIDATE_UID_STATES && i == 0) {
4269 validateUid = mValidateUids.get(item.uid);
4270 if (validateUid == null && change != UidRecord.CHANGE_GONE
4271 && change != UidRecord.CHANGE_GONE_IDLE) {
4272 validateUid = new UidRecord(item.uid);
4273 mValidateUids.put(item.uid, validateUid);
4276 if (change == UidRecord.CHANGE_IDLE
4277 || change == UidRecord.CHANGE_GONE_IDLE) {
4278 if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4279 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4280 "UID idle uid=" + item.uid);
4281 observer.onUidIdle(item.uid);
4283 if (VALIDATE_UID_STATES && i == 0) {
4284 if (validateUid != null) {
4285 validateUid.idle = true;
4288 } else if (change == UidRecord.CHANGE_ACTIVE) {
4289 if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4290 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4291 "UID active uid=" + item.uid);
4292 observer.onUidActive(item.uid);
4294 if (VALIDATE_UID_STATES && i == 0) {
4295 validateUid.idle = false;
4298 if (change == UidRecord.CHANGE_GONE
4299 || change == UidRecord.CHANGE_GONE_IDLE) {
4300 if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4301 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4302 "UID gone uid=" + item.uid);
4303 observer.onUidGone(item.uid);
4305 if (VALIDATE_UID_STATES && i == 0) {
4306 if (validateUid != null) {
4307 mValidateUids.remove(item.uid);
4311 if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4312 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4313 "UID CHANGED uid=" + item.uid
4314 + ": " + item.processState);
4315 observer.onUidStateChanged(item.uid, item.processState);
4317 if (VALIDATE_UID_STATES && i == 0) {
4318 validateUid.curProcState = validateUid.setProcState
4319 = item.processState;
4323 } catch (RemoteException e) {
4327 mUidObservers.finishBroadcast();
4329 synchronized (this) {
4330 for (int j=0; j<N; j++) {
4331 mAvailUidChanges.add(mActiveUidChanges[j]);
4337 public final int startActivity(IApplicationThread caller, String callingPackage,
4338 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4339 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4340 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4341 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4342 UserHandle.getCallingUserId());
4345 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4346 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4347 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4348 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4349 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4351 // TODO: Switch to user app stacks here.
4352 String mimeType = intent.getType();
4353 final Uri data = intent.getData();
4354 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4355 mimeType = getProviderMimeType(data, userId);
4357 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4359 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4360 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4361 null, 0, 0, null, null, null, null, false, userId, container, null);
4365 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4366 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4367 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4368 enforceNotIsolatedCaller("startActivity");
4369 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4370 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4371 // TODO: Switch to user app stacks here.
4372 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4373 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4374 profilerInfo, null, null, bOptions, false, userId, null, null);
4378 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4379 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4380 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4383 // This is very dangerous -- it allows you to perform a start activity (including
4384 // permission grants) as any app that may launch one of your own activities. So
4385 // we will only allow this to be done from activities that are part of the core framework,
4386 // and then only when they are running as the system.
4387 final ActivityRecord sourceRecord;
4388 final int targetUid;
4389 final String targetPackage;
4390 synchronized (this) {
4391 if (resultTo == null) {
4392 throw new SecurityException("Must be called from an activity");
4394 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4395 if (sourceRecord == null) {
4396 throw new SecurityException("Called with bad activity token: " + resultTo);
4398 if (!sourceRecord.info.packageName.equals("android")) {
4399 throw new SecurityException(
4400 "Must be called from an activity that is declared in the android package");
4402 if (sourceRecord.app == null) {
4403 throw new SecurityException("Called without a process attached to activity");
4405 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4406 // This is still okay, as long as this activity is running under the
4407 // uid of the original calling activity.
4408 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4409 throw new SecurityException(
4410 "Calling activity in uid " + sourceRecord.app.uid
4411 + " must be system uid or original calling uid "
4412 + sourceRecord.launchedFromUid);
4415 if (ignoreTargetSecurity) {
4416 if (intent.getComponent() == null) {
4417 throw new SecurityException(
4418 "Component must be specified with ignoreTargetSecurity");
4420 if (intent.getSelector() != null) {
4421 throw new SecurityException(
4422 "Selector not allowed with ignoreTargetSecurity");
4425 targetUid = sourceRecord.launchedFromUid;
4426 targetPackage = sourceRecord.launchedFromPackage;
4429 if (userId == UserHandle.USER_NULL) {
4430 userId = UserHandle.getUserId(sourceRecord.app.uid);
4433 // TODO: Switch to user app stacks here.
4435 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4436 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4437 null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4439 } catch (SecurityException e) {
4440 // XXX need to figure out how to propagate to original app.
4441 // A SecurityException here is generally actually a fault of the original
4442 // calling activity (such as a fairly granting permissions), so propagate it
4445 StringBuilder msg = new StringBuilder();
4446 msg.append("While launching");
4447 msg.append(intent.toString());
4449 msg.append(e.getMessage());
4456 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4457 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4458 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4459 enforceNotIsolatedCaller("startActivityAndWait");
4460 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4461 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4462 WaitResult res = new WaitResult();
4463 // TODO: Switch to user app stacks here.
4464 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4465 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4466 bOptions, false, userId, null, null);
4471 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4472 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4473 int startFlags, Configuration config, Bundle bOptions, int userId) {
4474 enforceNotIsolatedCaller("startActivityWithConfig");
4475 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4476 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4477 // TODO: Switch to user app stacks here.
4478 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4479 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4480 null, null, config, bOptions, false, userId, null, null);
4485 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4486 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4487 int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4488 throws TransactionTooLargeException {
4489 enforceNotIsolatedCaller("startActivityIntentSender");
4490 // Refuse possible leaked file descriptors
4491 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4492 throw new IllegalArgumentException("File descriptors passed in Intent");
4495 IIntentSender sender = intent.getTarget();
4496 if (!(sender instanceof PendingIntentRecord)) {
4497 throw new IllegalArgumentException("Bad PendingIntent object");
4500 PendingIntentRecord pir = (PendingIntentRecord)sender;
4502 synchronized (this) {
4503 // If this is coming from the currently resumed activity, it is
4504 // effectively saying that app switches are allowed at this point.
4505 final ActivityStack stack = getFocusedStack();
4506 if (stack.mResumedActivity != null &&
4507 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4508 mAppSwitchesAllowedTime = 0;
4511 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4512 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4517 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4518 Intent intent, String resolvedType, IVoiceInteractionSession session,
4519 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4520 Bundle bOptions, int userId) {
4521 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4522 != PackageManager.PERMISSION_GRANTED) {
4523 String msg = "Permission Denial: startVoiceActivity() from pid="
4524 + Binder.getCallingPid()
4525 + ", uid=" + Binder.getCallingUid()
4526 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4528 throw new SecurityException(msg);
4530 if (session == null || interactor == null) {
4531 throw new NullPointerException("null session or interactor");
4533 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4534 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4535 // TODO: Switch to user app stacks here.
4536 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4537 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4538 null, bOptions, false, userId, null, null);
4542 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4543 throws RemoteException {
4544 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4545 synchronized (this) {
4546 ActivityRecord activity = getFocusedStack().topActivity();
4547 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4548 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4550 if (mRunningVoice != null || activity.task.voiceSession != null
4551 || activity.voiceSession != null) {
4552 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4555 if (activity.pendingVoiceInteractionStart) {
4556 Slog.w(TAG, "Pending start of voice interaction already.");
4559 activity.pendingVoiceInteractionStart = true;
4561 LocalServices.getService(VoiceInteractionManagerInternal.class)
4562 .startLocalVoiceInteraction(callingActivity, options);
4566 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4567 LocalServices.getService(VoiceInteractionManagerInternal.class)
4568 .stopLocalVoiceInteraction(callingActivity);
4572 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4573 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4574 .supportsLocalVoiceInteraction();
4577 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4578 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4579 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4580 if (activityToCallback == null) return;
4581 activityToCallback.setVoiceSessionLocked(voiceSession);
4583 // Inform the activity
4585 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4587 long token = Binder.clearCallingIdentity();
4589 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4591 Binder.restoreCallingIdentity(token);
4593 // TODO: VI Should we cache the activity so that it's easier to find later
4594 // rather than scan through all the stacks and activities?
4595 } catch (RemoteException re) {
4596 activityToCallback.clearVoiceSessionLocked();
4597 // TODO: VI Should this terminate the voice session?
4602 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4603 synchronized (this) {
4604 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4606 mVoiceWakeLock.acquire();
4608 mVoiceWakeLock.release();
4615 public boolean startNextMatchingActivity(IBinder callingActivity,
4616 Intent intent, Bundle bOptions) {
4617 // Refuse possible leaked file descriptors
4618 if (intent != null && intent.hasFileDescriptors() == true) {
4619 throw new IllegalArgumentException("File descriptors passed in Intent");
4621 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4623 synchronized (this) {
4624 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4626 ActivityOptions.abort(options);
4629 if (r.app == null || r.app.thread == null) {
4630 // The caller is not running... d'oh!
4631 ActivityOptions.abort(options);
4634 intent = new Intent(intent);
4635 // The caller is not allowed to change the data.
4636 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4637 // And we are resetting to find the next component...
4638 intent.setComponent(null);
4640 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4642 ActivityInfo aInfo = null;
4644 List<ResolveInfo> resolves =
4645 AppGlobals.getPackageManager().queryIntentActivities(
4646 intent, r.resolvedType,
4647 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4648 UserHandle.getCallingUserId()).getList();
4650 // Look for the original activity in the list...
4651 final int N = resolves != null ? resolves.size() : 0;
4652 for (int i=0; i<N; i++) {
4653 ResolveInfo rInfo = resolves.get(i);
4654 if (rInfo.activityInfo.packageName.equals(r.packageName)
4655 && rInfo.activityInfo.name.equals(r.info.name)) {
4656 // We found the current one... the next matching is
4660 aInfo = resolves.get(i).activityInfo;
4663 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4664 + "/" + r.info.name);
4665 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4666 ? "null" : aInfo.packageName + "/" + aInfo.name));
4671 } catch (RemoteException e) {
4674 if (aInfo == null) {
4675 // Nobody who is next!
4676 ActivityOptions.abort(options);
4677 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4681 intent.setComponent(new ComponentName(
4682 aInfo.applicationInfo.packageName, aInfo.name));
4683 intent.setFlags(intent.getFlags()&~(
4684 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4685 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4686 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4687 Intent.FLAG_ACTIVITY_NEW_TASK));
4689 // Okay now we need to start the new activity, replacing the
4690 // currently running activity. This is a little tricky because
4691 // we want to start the new one as if the current one is finished,
4692 // but not finish the current one first so that there is no flicker.
4694 final boolean wasFinishing = r.finishing;
4697 // Propagate reply information over to the new activity.
4698 final ActivityRecord resultTo = r.resultTo;
4699 final String resultWho = r.resultWho;
4700 final int requestCode = r.requestCode;
4702 if (resultTo != null) {
4703 resultTo.removeResultsLocked(r, resultWho, requestCode);
4706 final long origId = Binder.clearCallingIdentity();
4707 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4708 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4709 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4710 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4711 false, false, null, null, null);
4712 Binder.restoreCallingIdentity(origId);
4714 r.finishing = wasFinishing;
4715 if (res != ActivityManager.START_SUCCESS) {
4723 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4724 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4725 String msg = "Permission Denial: startActivityFromRecents called without " +
4726 START_TASKS_FROM_RECENTS;
4728 throw new SecurityException(msg);
4730 final long origId = Binder.clearCallingIdentity();
4732 synchronized (this) {
4733 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4736 Binder.restoreCallingIdentity(origId);
4740 final int startActivityInPackage(int uid, String callingPackage,
4741 Intent intent, String resolvedType, IBinder resultTo,
4742 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4743 IActivityContainer container, TaskRecord inTask) {
4745 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4746 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4748 // TODO: Switch to user app stacks here.
4749 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4750 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4751 null, null, null, bOptions, false, userId, container, inTask);
4756 public final int startActivities(IApplicationThread caller, String callingPackage,
4757 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4759 enforceNotIsolatedCaller("startActivities");
4760 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4761 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4762 // TODO: Switch to user app stacks here.
4763 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4764 resolvedTypes, resultTo, bOptions, userId);
4768 final int startActivitiesInPackage(int uid, String callingPackage,
4769 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4770 Bundle bOptions, int userId) {
4772 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4773 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4774 // TODO: Switch to user app stacks here.
4775 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4776 resultTo, bOptions, userId);
4781 public void reportActivityFullyDrawn(IBinder token) {
4782 synchronized (this) {
4783 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4787 r.reportFullyDrawnLocked();
4792 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4793 synchronized (this) {
4794 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4798 TaskRecord task = r.task;
4799 if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4800 // Fixed screen orientation isn't supported when activities aren't in full screen
4804 final long origId = Binder.clearCallingIdentity();
4805 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4806 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4807 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4808 if (config != null) {
4809 r.frozenBeforeDestroy = true;
4810 if (!updateConfigurationLocked(config, r, false)) {
4811 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4814 Binder.restoreCallingIdentity(origId);
4819 public int getRequestedOrientation(IBinder token) {
4820 synchronized (this) {
4821 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4823 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4825 return mWindowManager.getAppOrientation(r.appToken);
4830 * This is the internal entry point for handling Activity.finish().
4832 * @param token The Binder token referencing the Activity we want to finish.
4833 * @param resultCode Result code, if any, from this Activity.
4834 * @param resultData Result data (Intent), if any, from this Activity.
4835 * @param finishTask Whether to finish the task associated with this Activity.
4837 * @return Returns true if the activity successfully finished, or false if it is still running.
4840 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4842 // Refuse possible leaked file descriptors
4843 if (resultData != null && resultData.hasFileDescriptors() == true) {
4844 throw new IllegalArgumentException("File descriptors passed in Intent");
4847 synchronized(this) {
4848 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4852 // Keep track of the root activity of the task before we finish it
4853 TaskRecord tr = r.task;
4854 ActivityRecord rootR = tr.getRootActivity();
4855 if (rootR == null) {
4856 Slog.w(TAG, "Finishing task with all activities already finished");
4858 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4860 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4861 mStackSupervisor.isLastLockedTask(tr)) {
4862 Slog.i(TAG, "Not finishing task in lock task mode");
4863 mStackSupervisor.showLockTaskToast();
4866 if (mController != null) {
4867 // Find the first activity that is not finishing.
4868 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4870 // ask watcher if this is allowed
4871 boolean resumeOK = true;
4873 resumeOK = mController.activityResuming(next.packageName);
4874 } catch (RemoteException e) {
4876 Watchdog.getInstance().setActivityController(null);
4880 Slog.i(TAG, "Not finishing activity because controller resumed");
4885 final long origId = Binder.clearCallingIdentity();
4888 final boolean finishWithRootActivity =
4889 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4890 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4891 || (finishWithRootActivity && r == rootR)) {
4892 // If requested, remove the task that is associated to this activity only if it
4893 // was the root activity in the task. The result code and data is ignored
4894 // because we don't support returning them across task boundaries. Also, to
4895 // keep backwards compatibility we remove the task from recents when finishing
4896 // task with root activity.
4897 res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4899 Slog.i(TAG, "Removing task failed to finish activity");
4902 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4903 resultData, "app-request", true);
4905 Slog.i(TAG, "Failed to finish by app-request");
4910 Binder.restoreCallingIdentity(origId);
4916 public final void finishHeavyWeightApp() {
4917 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4918 != PackageManager.PERMISSION_GRANTED) {
4919 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4920 + Binder.getCallingPid()
4921 + ", uid=" + Binder.getCallingUid()
4922 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4924 throw new SecurityException(msg);
4927 synchronized(this) {
4928 if (mHeavyWeightProcess == null) {
4932 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4933 for (int i = 0; i < activities.size(); i++) {
4934 ActivityRecord r = activities.get(i);
4935 if (!r.finishing && r.isInStackLocked()) {
4936 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4937 null, "finish-heavy", true);
4941 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4942 mHeavyWeightProcess.userId, 0));
4943 mHeavyWeightProcess = null;
4948 public void crashApplication(int uid, int initialPid, String packageName,
4950 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4951 != PackageManager.PERMISSION_GRANTED) {
4952 String msg = "Permission Denial: crashApplication() from pid="
4953 + Binder.getCallingPid()
4954 + ", uid=" + Binder.getCallingUid()
4955 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4957 throw new SecurityException(msg);
4960 synchronized(this) {
4961 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4966 public final void finishSubActivity(IBinder token, String resultWho,
4968 synchronized(this) {
4969 final long origId = Binder.clearCallingIdentity();
4970 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4972 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4974 Binder.restoreCallingIdentity(origId);
4979 public boolean finishActivityAffinity(IBinder token) {
4980 synchronized(this) {
4981 final long origId = Binder.clearCallingIdentity();
4983 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4988 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4990 final TaskRecord task = r.task;
4991 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4992 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4993 mStackSupervisor.showLockTaskToast();
4996 return task.stack.finishActivityAffinityLocked(r);
4998 Binder.restoreCallingIdentity(origId);
5004 public void finishVoiceTask(IVoiceInteractionSession session) {
5005 synchronized (this) {
5006 final long origId = Binder.clearCallingIdentity();
5008 // TODO: VI Consider treating local voice interactions and voice tasks
5010 mStackSupervisor.finishVoiceTask(session);
5012 Binder.restoreCallingIdentity(origId);
5019 public boolean releaseActivityInstance(IBinder token) {
5020 synchronized(this) {
5021 final long origId = Binder.clearCallingIdentity();
5023 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5027 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5029 Binder.restoreCallingIdentity(origId);
5035 public void releaseSomeActivities(IApplicationThread appInt) {
5036 synchronized(this) {
5037 final long origId = Binder.clearCallingIdentity();
5039 ProcessRecord app = getRecordForAppLocked(appInt);
5040 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5042 Binder.restoreCallingIdentity(origId);
5048 public boolean willActivityBeVisible(IBinder token) {
5049 synchronized(this) {
5050 ActivityStack stack = ActivityRecord.getStackLocked(token);
5051 if (stack != null) {
5052 return stack.willActivityBeVisibleLocked(token);
5059 public void overridePendingTransition(IBinder token, String packageName,
5060 int enterAnim, int exitAnim) {
5061 synchronized(this) {
5062 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5067 final long origId = Binder.clearCallingIdentity();
5069 if (self.state == ActivityState.RESUMED
5070 || self.state == ActivityState.PAUSING) {
5071 mWindowManager.overridePendingAppTransition(packageName,
5072 enterAnim, exitAnim, null);
5075 Binder.restoreCallingIdentity(origId);
5080 * Main function for removing an existing process from the activity manager
5081 * as a result of that process going away. Clears out all connections
5084 private final void handleAppDiedLocked(ProcessRecord app,
5085 boolean restarting, boolean allowRestart) {
5087 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5088 false /*replacingPid*/);
5089 if (!kept && !restarting) {
5090 removeLruProcessLocked(app);
5092 ProcessList.remove(pid);
5096 if (mProfileProc == app) {
5097 clearProfilerLocked();
5100 // Remove this application's activities from active lists.
5101 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5103 app.activities.clear();
5105 if (app.instrumentationClass != null) {
5106 Slog.w(TAG, "Crash of app " + app.processName
5107 + " running instrumentation " + app.instrumentationClass);
5108 Bundle info = new Bundle();
5109 info.putString("shortMsg", "Process crashed.");
5110 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5113 if (!restarting && hasVisibleActivities
5114 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5115 // If there was nothing to resume, and we are not already restarting this process, but
5116 // there is a visible activity that is hosted by the process... then make sure all
5117 // visible activities are running, taking care of restarting this process.
5118 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5122 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5123 IBinder threadBinder = thread.asBinder();
5124 // Find the application record.
5125 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5126 ProcessRecord rec = mLruProcesses.get(i);
5127 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5134 final ProcessRecord getRecordForAppLocked(
5135 IApplicationThread thread) {
5136 if (thread == null) {
5140 int appIndex = getLRURecordIndexForAppLocked(thread);
5141 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5144 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5145 // If there are no longer any background processes running,
5146 // and the app that died was not running instrumentation,
5147 // then tell everyone we are now low on memory.
5148 boolean haveBg = false;
5149 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5150 ProcessRecord rec = mLruProcesses.get(i);
5151 if (rec.thread != null
5152 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5159 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5161 long now = SystemClock.uptimeMillis();
5162 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5165 mLastMemUsageReportTime = now;
5168 final ArrayList<ProcessMemInfo> memInfos
5169 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5170 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5171 long now = SystemClock.uptimeMillis();
5172 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5173 ProcessRecord rec = mLruProcesses.get(i);
5174 if (rec == dyingProc || rec.thread == null) {
5178 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5179 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5181 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5182 // The low memory report is overriding any current
5183 // state for a GC request. Make sure to do
5184 // heavy/important/visible/foreground processes first.
5185 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5186 rec.lastRequestedGc = 0;
5188 rec.lastRequestedGc = rec.lastLowMemory;
5190 rec.reportLowMemory = true;
5191 rec.lastLowMemory = now;
5192 mProcessesToGc.remove(rec);
5193 addProcessToGcListLocked(rec);
5197 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5198 mHandler.sendMessage(msg);
5200 scheduleAppGcsLocked();
5204 final void appDiedLocked(ProcessRecord app) {
5205 appDiedLocked(app, app.pid, app.thread, false);
5208 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5209 boolean fromBinderDied) {
5210 // First check if this ProcessRecord is actually active for the pid.
5211 synchronized (mPidsSelfLocked) {
5212 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5213 if (curProc != app) {
5214 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5219 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5220 synchronized (stats) {
5221 stats.noteProcessDiedLocked(app.info.uid, pid);
5225 if (!fromBinderDied) {
5226 Process.killProcessQuiet(pid);
5228 killProcessGroup(app.uid, pid);
5232 // Clean up already done if the process has been re-started.
5233 if (app.pid == pid && app.thread != null &&
5234 app.thread.asBinder() == thread.asBinder()) {
5235 boolean doLowMem = app.instrumentationClass == null;
5236 boolean doOomAdj = doLowMem;
5237 if (!app.killedByAm) {
5238 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5240 mAllowLowerMemLevel = true;
5242 // Note that we always want to do oom adj to update our state with the
5243 // new number of procs.
5244 mAllowLowerMemLevel = false;
5247 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5248 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5249 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5250 handleAppDiedLocked(app, false, true);
5253 updateOomAdjLocked();
5256 doLowMemReportIfNeededLocked(app);
5258 } else if (app.pid != pid) {
5259 // A new process has already been started.
5260 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5261 + ") has died and restarted (pid " + app.pid + ").");
5262 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5263 } else if (DEBUG_PROCESSES) {
5264 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5265 + thread.asBinder());
5270 * If a stack trace dump file is configured, dump process stack traces.
5271 * @param clearTraces causes the dump file to be erased prior to the new
5272 * traces being written, if true; when false, the new traces will be
5273 * appended to any existing file content.
5274 * @param firstPids of dalvik VM processes to dump stack traces for first
5275 * @param lastPids of dalvik VM processes to dump stack traces for last
5276 * @param nativeProcs optional list of native process names to dump stack crawls
5277 * @return file containing stack traces, or null if no dump file is configured
5279 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5280 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5281 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5282 if (tracesPath == null || tracesPath.length() == 0) {
5286 File tracesFile = new File(tracesPath);
5288 if (clearTraces && tracesFile.exists()) tracesFile.delete();
5289 tracesFile.createNewFile();
5290 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5291 } catch (IOException e) {
5292 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5296 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5300 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5301 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5302 // Use a FileObserver to detect when traces finish writing.
5303 // The order of traces is considered important to maintain for legibility.
5304 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5306 public synchronized void onEvent(int event, String path) { notify(); }
5310 observer.startWatching();
5312 // First collect all of the stacks of the most important pids.
5313 if (firstPids != null) {
5315 int num = firstPids.size();
5316 for (int i = 0; i < num; i++) {
5317 synchronized (observer) {
5318 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5319 + firstPids.get(i));
5320 final long sime = SystemClock.elapsedRealtime();
5321 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5322 observer.wait(1000); // Wait for write-close, give up after 1 sec
5323 if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5324 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5327 } catch (InterruptedException e) {
5332 // Next collect the stacks of the native pids
5333 if (nativeProcs != null) {
5334 int[] pids = Process.getPidsForCommands(nativeProcs);
5336 for (int pid : pids) {
5337 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5338 final long sime = SystemClock.elapsedRealtime();
5339 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5340 if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5341 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5346 // Lastly, measure CPU usage.
5347 if (processCpuTracker != null) {
5348 processCpuTracker.init();
5350 processCpuTracker.update();
5352 synchronized (processCpuTracker) {
5353 processCpuTracker.wait(500); // measure over 1/2 second.
5355 } catch (InterruptedException e) {
5357 processCpuTracker.update();
5359 // We'll take the stack crawls of just the top apps using CPU.
5360 final int N = processCpuTracker.countWorkingStats();
5362 for (int i=0; i<N && numProcs<5; i++) {
5363 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5364 if (lastPids.indexOfKey(stats.pid) >= 0) {
5367 synchronized (observer) {
5368 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5370 final long stime = SystemClock.elapsedRealtime();
5371 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5372 observer.wait(1000); // Wait for write-close, give up after 1 sec
5373 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5374 + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5376 } catch (InterruptedException e) {
5379 } else if (DEBUG_ANR) {
5380 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5386 observer.stopWatching();
5390 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5391 if (true || IS_USER_BUILD) {
5394 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5395 if (tracesPath == null || tracesPath.length() == 0) {
5399 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5400 StrictMode.allowThreadDiskWrites();
5402 final File tracesFile = new File(tracesPath);
5403 final File tracesDir = tracesFile.getParentFile();
5404 final File tracesTmp = new File(tracesDir, "__tmp__");
5406 if (tracesFile.exists()) {
5408 tracesFile.renameTo(tracesTmp);
5410 StringBuilder sb = new StringBuilder();
5411 Time tobj = new Time();
5412 tobj.set(System.currentTimeMillis());
5413 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5415 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5416 sb.append(" since ");
5418 FileOutputStream fos = new FileOutputStream(tracesFile);
5419 fos.write(sb.toString().getBytes());
5421 fos.write("\n*** No application process!".getBytes());
5424 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5425 } catch (IOException e) {
5426 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5431 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5432 firstPids.add(app.pid);
5433 dumpStackTraces(tracesPath, firstPids, null, null, null);
5436 File lastTracesFile = null;
5437 File curTracesFile = null;
5438 for (int i=9; i>=0; i--) {
5439 String name = String.format(Locale.US, "slow%02d.txt", i);
5440 curTracesFile = new File(tracesDir, name);
5441 if (curTracesFile.exists()) {
5442 if (lastTracesFile != null) {
5443 curTracesFile.renameTo(lastTracesFile);
5445 curTracesFile.delete();
5448 lastTracesFile = curTracesFile;
5450 tracesFile.renameTo(curTracesFile);
5451 if (tracesTmp.exists()) {
5452 tracesTmp.renameTo(tracesFile);
5455 StrictMode.setThreadPolicy(oldPolicy);
5459 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5460 if (!mLaunchWarningShown) {
5461 mLaunchWarningShown = true;
5462 mUiHandler.post(new Runnable() {
5465 synchronized (ActivityManagerService.this) {
5466 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5468 mUiHandler.postDelayed(new Runnable() {
5471 synchronized (ActivityManagerService.this) {
5473 mLaunchWarningShown = false;
5484 public boolean clearApplicationUserData(final String packageName,
5485 final IPackageDataObserver observer, int userId) {
5486 enforceNotIsolatedCaller("clearApplicationUserData");
5487 int uid = Binder.getCallingUid();
5488 int pid = Binder.getCallingPid();
5489 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5490 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5493 long callingId = Binder.clearCallingIdentity();
5495 IPackageManager pm = AppGlobals.getPackageManager();
5497 synchronized(this) {
5498 if (getPackageManagerInternalLocked().isPackageDataProtected(
5499 userId, packageName)) {
5500 throw new SecurityException(
5501 "Cannot clear data for a protected package: " + packageName);
5505 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5506 } catch (RemoteException e) {
5509 Slog.w(TAG, "Invalid packageName: " + packageName);
5510 if (observer != null) {
5512 observer.onRemoveCompleted(packageName, false);
5513 } catch (RemoteException e) {
5514 Slog.i(TAG, "Observer no longer exists.");
5519 if (uid == pkgUid || checkComponentPermission(
5520 android.Manifest.permission.CLEAR_APP_USER_DATA,
5522 == PackageManager.PERMISSION_GRANTED) {
5523 forceStopPackageLocked(packageName, pkgUid, "clear data");
5525 throw new SecurityException("PID " + pid + " does not have permission "
5526 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5527 + " of package " + packageName);
5530 // Remove all tasks match the cleared application package and user
5531 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5532 final TaskRecord tr = mRecentTasks.get(i);
5533 final String taskPackageName =
5534 tr.getBaseIntent().getComponent().getPackageName();
5535 if (tr.userId != userId) continue;
5536 if (!taskPackageName.equals(packageName)) continue;
5537 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5541 final int pkgUidF = pkgUid;
5542 final int userIdF = userId;
5543 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5545 public void onRemoveCompleted(String packageName, boolean succeeded)
5546 throws RemoteException {
5547 synchronized (ActivityManagerService.this) {
5548 finishForceStopPackageLocked(packageName, pkgUidF);
5551 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5552 Uri.fromParts("package", packageName, null));
5553 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5554 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5555 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5556 null, null, 0, null, null, null, null, false, false, userIdF);
5558 if (observer != null) {
5559 observer.onRemoveCompleted(packageName, succeeded);
5565 // Clear application user data
5566 pm.clearApplicationUserData(packageName, localObserver, userId);
5568 synchronized(this) {
5569 // Remove all permissions granted from/to this package
5570 removeUriPermissionsForPackageLocked(packageName, userId, true);
5573 // Remove all zen rules created by this package; revoke it's zen access.
5574 INotificationManager inm = NotificationManager.getService();
5575 inm.removeAutomaticZenRules(packageName);
5576 inm.setNotificationPolicyAccessGranted(packageName, false);
5578 } catch (RemoteException e) {
5581 Binder.restoreCallingIdentity(callingId);
5587 public void killBackgroundProcesses(final String packageName, int userId) {
5588 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5589 != PackageManager.PERMISSION_GRANTED &&
5590 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5591 != PackageManager.PERMISSION_GRANTED) {
5592 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5593 + Binder.getCallingPid()
5594 + ", uid=" + Binder.getCallingUid()
5595 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5597 throw new SecurityException(msg);
5600 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5601 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5602 long callingId = Binder.clearCallingIdentity();
5604 IPackageManager pm = AppGlobals.getPackageManager();
5605 synchronized(this) {
5608 appId = UserHandle.getAppId(
5609 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5610 } catch (RemoteException e) {
5613 Slog.w(TAG, "Invalid packageName: " + packageName);
5616 killPackageProcessesLocked(packageName, appId, userId,
5617 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5620 Binder.restoreCallingIdentity(callingId);
5625 public void killAllBackgroundProcesses() {
5626 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5627 != PackageManager.PERMISSION_GRANTED) {
5628 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5629 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5630 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5632 throw new SecurityException(msg);
5635 final long callingId = Binder.clearCallingIdentity();
5637 synchronized (this) {
5638 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5639 final int NP = mProcessNames.getMap().size();
5640 for (int ip = 0; ip < NP; ip++) {
5641 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5642 final int NA = apps.size();
5643 for (int ia = 0; ia < NA; ia++) {
5644 final ProcessRecord app = apps.valueAt(ia);
5645 if (app.persistent) {
5646 // We don't kill persistent processes.
5651 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5658 final int N = procs.size();
5659 for (int i = 0; i < N; i++) {
5660 removeProcessLocked(procs.get(i), false, true, "kill all background");
5663 mAllowLowerMemLevel = true;
5665 updateOomAdjLocked();
5666 doLowMemReportIfNeededLocked(null);
5669 Binder.restoreCallingIdentity(callingId);
5674 * Kills all background processes, except those matching any of the
5675 * specified properties.
5677 * @param minTargetSdk the target SDK version at or above which to preserve
5678 * processes, or {@code -1} to ignore the target SDK
5679 * @param maxProcState the process state at or below which to preserve
5680 * processes, or {@code -1} to ignore the process state
5682 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5683 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5684 != PackageManager.PERMISSION_GRANTED) {
5685 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5686 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5687 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5689 throw new SecurityException(msg);
5692 final long callingId = Binder.clearCallingIdentity();
5694 synchronized (this) {
5695 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5696 final int NP = mProcessNames.getMap().size();
5697 for (int ip = 0; ip < NP; ip++) {
5698 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5699 final int NA = apps.size();
5700 for (int ia = 0; ia < NA; ia++) {
5701 final ProcessRecord app = apps.valueAt(ia);
5704 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5705 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5712 final int N = procs.size();
5713 for (int i = 0; i < N; i++) {
5714 removeProcessLocked(procs.get(i), false, true, "kill all background except");
5718 Binder.restoreCallingIdentity(callingId);
5723 public void forceStopPackage(final String packageName, int userId) {
5724 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5725 != PackageManager.PERMISSION_GRANTED) {
5726 String msg = "Permission Denial: forceStopPackage() from pid="
5727 + Binder.getCallingPid()
5728 + ", uid=" + Binder.getCallingUid()
5729 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5731 throw new SecurityException(msg);
5733 final int callingPid = Binder.getCallingPid();
5734 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5735 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5736 long callingId = Binder.clearCallingIdentity();
5738 IPackageManager pm = AppGlobals.getPackageManager();
5739 synchronized(this) {
5740 int[] users = userId == UserHandle.USER_ALL
5741 ? mUserController.getUsers() : new int[] { userId };
5742 for (int user : users) {
5745 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5747 } catch (RemoteException e) {
5750 Slog.w(TAG, "Invalid packageName: " + packageName);
5754 pm.setPackageStoppedState(packageName, true, user);
5755 } catch (RemoteException e) {
5756 } catch (IllegalArgumentException e) {
5757 Slog.w(TAG, "Failed trying to unstop package "
5758 + packageName + ": " + e);
5760 if (mUserController.isUserRunningLocked(user, 0)) {
5761 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5762 finishForceStopPackageLocked(packageName, pkgUid);
5767 Binder.restoreCallingIdentity(callingId);
5772 public void addPackageDependency(String packageName) {
5773 synchronized (this) {
5774 int callingPid = Binder.getCallingPid();
5775 if (callingPid == Process.myPid()) {
5780 synchronized (mPidsSelfLocked) {
5781 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5784 if (proc.pkgDeps == null) {
5785 proc.pkgDeps = new ArraySet<String>(1);
5787 proc.pkgDeps.add(packageName);
5793 * The pkg name and app id have to be specified.
5796 public void killApplication(String pkg, int appId, int userId, String reason) {
5800 // Make sure the uid is valid.
5802 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5805 int callerUid = Binder.getCallingUid();
5806 // Only the system server can kill an application
5807 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5808 // Post an aysnc message to kill the application
5809 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5812 Bundle bundle = new Bundle();
5813 bundle.putString("pkg", pkg);
5814 bundle.putString("reason", reason);
5816 mHandler.sendMessage(msg);
5818 throw new SecurityException(callerUid + " cannot kill pkg: " +
5824 public void closeSystemDialogs(String reason) {
5825 enforceNotIsolatedCaller("closeSystemDialogs");
5827 final int pid = Binder.getCallingPid();
5828 final int uid = Binder.getCallingUid();
5829 final long origId = Binder.clearCallingIdentity();
5831 synchronized (this) {
5832 // Only allow this from foreground processes, so that background
5833 // applications can't abuse it to prevent system UI from being shown.
5834 if (uid >= Process.FIRST_APPLICATION_UID) {
5836 synchronized (mPidsSelfLocked) {
5837 proc = mPidsSelfLocked.get(pid);
5839 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5840 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5841 + " from background process " + proc);
5845 closeSystemDialogsLocked(reason);
5848 Binder.restoreCallingIdentity(origId);
5852 void closeSystemDialogsLocked(String reason) {
5853 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5854 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5855 | Intent.FLAG_RECEIVER_FOREGROUND);
5856 if (reason != null) {
5857 intent.putExtra("reason", reason);
5859 mWindowManager.closeSystemDialogs(reason);
5861 mStackSupervisor.closeSystemDialogsLocked();
5863 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5864 AppOpsManager.OP_NONE, null, false, false,
5865 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5869 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5870 enforceNotIsolatedCaller("getProcessMemoryInfo");
5871 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5872 for (int i=pids.length-1; i>=0; i--) {
5875 synchronized (this) {
5876 synchronized (mPidsSelfLocked) {
5877 proc = mPidsSelfLocked.get(pids[i]);
5878 oomAdj = proc != null ? proc.setAdj : 0;
5881 infos[i] = new Debug.MemoryInfo();
5882 Debug.getMemoryInfo(pids[i], infos[i]);
5884 synchronized (this) {
5885 if (proc.thread != null && proc.setAdj == oomAdj) {
5886 // Record this for posterity if the process has been stable.
5887 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5888 infos[i].getTotalUss(), false, proc.pkgList);
5897 public long[] getProcessPss(int[] pids) {
5898 enforceNotIsolatedCaller("getProcessPss");
5899 long[] pss = new long[pids.length];
5900 for (int i=pids.length-1; i>=0; i--) {
5903 synchronized (this) {
5904 synchronized (mPidsSelfLocked) {
5905 proc = mPidsSelfLocked.get(pids[i]);
5906 oomAdj = proc != null ? proc.setAdj : 0;
5909 long[] tmpUss = new long[1];
5910 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5912 synchronized (this) {
5913 if (proc.thread != null && proc.setAdj == oomAdj) {
5914 // Record this for posterity if the process has been stable.
5915 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5924 public void killApplicationProcess(String processName, int uid) {
5925 if (processName == null) {
5929 int callerUid = Binder.getCallingUid();
5930 // Only the system server can kill an application
5931 if (callerUid == Process.SYSTEM_UID) {
5932 synchronized (this) {
5933 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5934 if (app != null && app.thread != null) {
5936 app.thread.scheduleSuicide();
5937 } catch (RemoteException e) {
5938 // If the other end already died, then our work here is done.
5941 Slog.w(TAG, "Process/uid not found attempting kill of "
5942 + processName + " / " + uid);
5946 throw new SecurityException(callerUid + " cannot kill app process: " +
5951 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5952 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5953 false, true, false, false, UserHandle.getUserId(uid), reason);
5956 private void finishForceStopPackageLocked(final String packageName, int uid) {
5957 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5958 Uri.fromParts("package", packageName, null));
5959 if (!mProcessesReady) {
5960 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5961 | Intent.FLAG_RECEIVER_FOREGROUND);
5963 intent.putExtra(Intent.EXTRA_UID, uid);
5964 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5965 broadcastIntentLocked(null, null, intent,
5966 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5967 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5971 private final boolean killPackageProcessesLocked(String packageName, int appId,
5972 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5973 boolean doit, boolean evenPersistent, String reason) {
5974 ArrayList<ProcessRecord> procs = new ArrayList<>();
5976 // Remove all processes this package may have touched: all with the
5977 // same UID (except for the system or root user), and all whose name
5978 // matches the package name.
5979 final int NP = mProcessNames.getMap().size();
5980 for (int ip=0; ip<NP; ip++) {
5981 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5982 final int NA = apps.size();
5983 for (int ia=0; ia<NA; ia++) {
5984 ProcessRecord app = apps.valueAt(ia);
5985 if (app.persistent && !evenPersistent) {
5986 // we don't kill persistent processes
5996 // Skip process if it doesn't meet our oom adj requirement.
5997 if (app.setAdj < minOomAdj) {
6001 // If no package is specified, we call all processes under the
6003 if (packageName == null) {
6004 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6007 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6010 // Package has been specified, we want to hit all processes
6011 // that match it. We need to qualify this by the processes
6012 // that are running under the specified app and user ID.
6014 final boolean isDep = app.pkgDeps != null
6015 && app.pkgDeps.contains(packageName);
6016 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6019 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6022 if (!app.pkgList.containsKey(packageName) && !isDep) {
6027 // Process has passed all conditions, kill it!
6036 int N = procs.size();
6037 for (int i=0; i<N; i++) {
6038 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6040 updateOomAdjLocked();
6044 private void cleanupDisabledPackageComponentsLocked(
6045 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6047 Set<String> disabledClasses = null;
6048 boolean packageDisabled = false;
6049 IPackageManager pm = AppGlobals.getPackageManager();
6051 if (changedClasses == null) {
6052 // Nothing changed...
6056 // Determine enable/disable state of the package and its components.
6057 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6058 for (int i = changedClasses.length - 1; i >= 0; i--) {
6059 final String changedClass = changedClasses[i];
6061 if (changedClass.equals(packageName)) {
6063 // Entire package setting changed
6064 enabled = pm.getApplicationEnabledSetting(packageName,
6065 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6066 } catch (Exception e) {
6067 // No such package/component; probably racing with uninstall. In any
6068 // event it means we have nothing further to do here.
6071 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6072 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6073 if (packageDisabled) {
6074 // Entire package is disabled.
6075 // No need to continue to check component states.
6076 disabledClasses = null;
6081 enabled = pm.getComponentEnabledSetting(
6082 new ComponentName(packageName, changedClass),
6083 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6084 } catch (Exception e) {
6085 // As above, probably racing with uninstall.
6088 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6089 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6090 if (disabledClasses == null) {
6091 disabledClasses = new ArraySet<>(changedClasses.length);
6093 disabledClasses.add(changedClass);
6098 if (!packageDisabled && disabledClasses == null) {
6099 // Nothing to do here...
6103 // Clean-up disabled activities.
6104 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6105 packageName, disabledClasses, true, false, userId) && mBooted) {
6106 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6107 mStackSupervisor.scheduleIdleLocked();
6110 // Clean-up disabled tasks
6111 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6113 // Clean-up disabled services.
6114 mServices.bringDownDisabledPackageServicesLocked(
6115 packageName, disabledClasses, userId, false, killProcess, true);
6117 // Clean-up disabled providers.
6118 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6119 mProviderMap.collectPackageProvidersLocked(
6120 packageName, disabledClasses, true, false, userId, providers);
6121 for (int i = providers.size() - 1; i >= 0; i--) {
6122 removeDyingProviderLocked(null, providers.get(i), true);
6125 // Clean-up disabled broadcast receivers.
6126 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6127 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6128 packageName, disabledClasses, userId, true);
6133 final boolean clearBroadcastQueueForUserLocked(int userId) {
6134 boolean didSomething = false;
6135 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6136 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6137 null, null, userId, true);
6139 return didSomething;
6142 final boolean forceStopPackageLocked(String packageName, int appId,
6143 boolean callerWillRestart, boolean purgeCache, boolean doit,
6144 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6147 if (userId == UserHandle.USER_ALL && packageName == null) {
6148 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6151 if (appId < 0 && packageName != null) {
6153 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6154 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6155 } catch (RemoteException e) {
6160 if (packageName != null) {
6161 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6162 + " user=" + userId + ": " + reason);
6164 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6167 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6170 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6171 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6172 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6174 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6175 packageName, null, doit, evenPersistent, userId)) {
6179 didSomething = true;
6182 if (mServices.bringDownDisabledPackageServicesLocked(
6183 packageName, null, userId, evenPersistent, true, doit)) {
6187 didSomething = true;
6190 if (packageName == null) {
6191 // Remove all sticky broadcasts from this user.
6192 mStickyBroadcasts.remove(userId);
6195 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6196 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6197 userId, providers)) {
6201 didSomething = true;
6203 for (i = providers.size() - 1; i >= 0; i--) {
6204 removeDyingProviderLocked(null, providers.get(i), true);
6207 // Remove transient permissions granted from/to this package/user
6208 removeUriPermissionsForPackageLocked(packageName, userId, false);
6211 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6212 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6213 packageName, null, userId, doit);
6217 if (packageName == null || uninstalling) {
6218 // Remove pending intents. For now we only do this when force
6219 // stopping users, because we have some problems when doing this
6220 // for packages -- app widgets are not currently cleaned up for
6221 // such packages, so they can be left with bad pending intents.
6222 if (mIntentSenderRecords.size() > 0) {
6223 Iterator<WeakReference<PendingIntentRecord>> it
6224 = mIntentSenderRecords.values().iterator();
6225 while (it.hasNext()) {
6226 WeakReference<PendingIntentRecord> wpir = it.next();
6231 PendingIntentRecord pir = wpir.get();
6236 if (packageName == null) {
6237 // Stopping user, remove all objects for the user.
6238 if (pir.key.userId != userId) {
6239 // Not the same user, skip it.
6243 if (UserHandle.getAppId(pir.uid) != appId) {
6244 // Different app id, skip it.
6247 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6248 // Different user, skip it.
6251 if (!pir.key.packageName.equals(packageName)) {
6252 // Different package, skip it.
6259 didSomething = true;
6261 pir.canceled = true;
6262 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6263 pir.key.activity.pendingResults.remove(pir.ref);
6270 if (purgeCache && packageName != null) {
6271 AttributeCache ac = AttributeCache.instance();
6273 ac.removePackage(packageName);
6277 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6278 mStackSupervisor.scheduleIdleLocked();
6282 return didSomething;
6285 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6286 return removeProcessNameLocked(name, uid, null);
6289 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6290 final ProcessRecord expecting) {
6291 ProcessRecord old = mProcessNames.get(name, uid);
6292 // Only actually remove when the currently recorded value matches the
6293 // record that we expected; if it doesn't match then we raced with a
6294 // newly created process and we don't want to destroy the new one.
6295 if ((expecting == null) || (old == expecting)) {
6296 mProcessNames.remove(name, uid);
6298 if (old != null && old.uidRecord != null) {
6299 old.uidRecord.numProcs--;
6300 if (old.uidRecord.numProcs == 0) {
6301 // No more processes using this uid, tell clients it is gone.
6302 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6303 "No more processes in " + old.uidRecord);
6304 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6305 mActiveUids.remove(uid);
6306 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6308 old.uidRecord = null;
6310 mIsolatedProcesses.remove(uid);
6314 private final void addProcessNameLocked(ProcessRecord proc) {
6315 // We shouldn't already have a process under this name, but just in case we
6316 // need to clean up whatever may be there now.
6317 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6318 if (old == proc && proc.persistent) {
6319 // We are re-adding a persistent process. Whatevs! Just leave it there.
6320 Slog.w(TAG, "Re-adding persistent process " + proc);
6321 } else if (old != null) {
6322 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6324 UidRecord uidRec = mActiveUids.get(proc.uid);
6325 if (uidRec == null) {
6326 uidRec = new UidRecord(proc.uid);
6327 // This is the first appearance of the uid, report it now!
6328 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6329 "Creating new process uid: " + uidRec);
6330 mActiveUids.put(proc.uid, uidRec);
6331 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6332 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6334 proc.uidRecord = uidRec;
6336 // Reset render thread tid if it was already set, so new process can set it again.
6337 proc.renderThreadTid = 0;
6339 mProcessNames.put(proc.processName, proc.uid, proc);
6340 if (proc.isolated) {
6341 mIsolatedProcesses.put(proc.uid, proc);
6345 boolean removeProcessLocked(ProcessRecord app,
6346 boolean callerWillRestart, boolean allowRestart, String reason) {
6347 final String name = app.processName;
6348 final int uid = app.uid;
6349 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6350 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6352 ProcessRecord old = mProcessNames.get(name, uid);
6354 // This process is no longer active, so nothing to do.
6355 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6358 removeProcessNameLocked(name, uid);
6359 if (mHeavyWeightProcess == app) {
6360 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6361 mHeavyWeightProcess.userId, 0));
6362 mHeavyWeightProcess = null;
6364 boolean needRestart = false;
6365 if (app.pid > 0 && app.pid != MY_PID) {
6367 synchronized (mPidsSelfLocked) {
6368 mPidsSelfLocked.remove(pid);
6369 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6371 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6373 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6375 boolean willRestart = false;
6376 if (app.persistent && !app.isolated) {
6377 if (!callerWillRestart) {
6383 app.kill(reason, true);
6384 handleAppDiedLocked(app, willRestart, allowRestart);
6386 removeLruProcessLocked(app);
6387 addAppLocked(app.info, false, null /* ABI override */);
6390 mRemovedProcesses.add(app);
6396 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6397 cleanupAppInLaunchingProvidersLocked(app, true);
6398 removeProcessLocked(app, false, true, "timeout publishing content providers");
6401 private final void processStartTimedOutLocked(ProcessRecord app) {
6402 final int pid = app.pid;
6403 boolean gone = false;
6404 synchronized (mPidsSelfLocked) {
6405 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6406 if (knownApp != null && knownApp.thread == null) {
6407 mPidsSelfLocked.remove(pid);
6413 Slog.w(TAG, "Process " + app + " failed to attach");
6414 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6415 pid, app.uid, app.processName);
6416 removeProcessNameLocked(app.processName, app.uid);
6417 if (mHeavyWeightProcess == app) {
6418 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6419 mHeavyWeightProcess.userId, 0));
6420 mHeavyWeightProcess = null;
6422 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6424 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6426 // Take care of any launching providers waiting for this process.
6427 cleanupAppInLaunchingProvidersLocked(app, true);
6428 // Take care of any services that are waiting for the process.
6429 mServices.processStartTimedOutLocked(app);
6430 app.kill("start timeout", true);
6431 removeLruProcessLocked(app);
6432 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6433 Slog.w(TAG, "Unattached app died before backup, skipping");
6435 IBackupManager bm = IBackupManager.Stub.asInterface(
6436 ServiceManager.getService(Context.BACKUP_SERVICE));
6437 bm.agentDisconnected(app.info.packageName);
6438 } catch (RemoteException e) {
6439 // Can't happen; the backup manager is local
6442 if (isPendingBroadcastProcessLocked(pid)) {
6443 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6444 skipPendingBroadcastLocked(pid);
6447 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6451 private final boolean attachApplicationLocked(IApplicationThread thread,
6454 // Find the application record that is being attached... either via
6455 // the pid if we are running in multiple processes, or just pull the
6456 // next app record if we are emulating process with anonymous threads.
6458 long startTime = SystemClock.uptimeMillis();
6459 if (pid != MY_PID && pid >= 0) {
6460 synchronized (mPidsSelfLocked) {
6461 app = mPidsSelfLocked.get(pid);
6468 Slog.w(TAG, "No pending application record for pid " + pid
6469 + " (IApplicationThread " + thread + "); dropping process");
6470 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6471 if (pid > 0 && pid != MY_PID) {
6472 Process.killProcessQuiet(pid);
6473 //TODO: killProcessGroup(app.info.uid, pid);
6476 thread.scheduleExit();
6477 } catch (Exception e) {
6478 // Ignore exceptions.
6484 // If this application record is still attached to a previous
6485 // process, clean it up now.
6486 if (app.thread != null) {
6487 handleAppDiedLocked(app, true, true);
6490 // Tell the process all about itself.
6492 if (DEBUG_ALL) Slog.v(
6493 TAG, "Binding process pid " + pid + " to record " + app);
6495 final String processName = app.processName;
6497 AppDeathRecipient adr = new AppDeathRecipient(
6499 thread.asBinder().linkToDeath(adr, 0);
6500 app.deathRecipient = adr;
6501 } catch (RemoteException e) {
6502 app.resetPackageList(mProcessStats);
6503 startProcessLocked(app, "link fail", processName);
6507 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6509 app.makeActive(thread, mProcessStats);
6510 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6511 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6512 app.forcingToForeground = null;
6513 updateProcessForegroundLocked(app, false, false);
6514 app.hasShownUi = false;
6515 app.debugging = false;
6517 app.killedByAm = false;
6519 // We carefully use the same state that PackageManager uses for
6520 // filtering, since we use this flag to decide if we need to install
6521 // providers when user is unlocked later
6522 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6524 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6526 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6527 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6529 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6530 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6532 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6535 checkTime(startTime, "attachApplicationLocked: before bindApplication");
6538 Slog.i(TAG, "Launching preboot mode app: " + app);
6541 if (DEBUG_ALL) Slog.v(
6542 TAG, "New app record " + app
6543 + " thread=" + thread.asBinder() + " pid=" + pid);
6545 int testMode = IApplicationThread.DEBUG_OFF;
6546 if (mDebugApp != null && mDebugApp.equals(processName)) {
6547 testMode = mWaitForDebugger
6548 ? IApplicationThread.DEBUG_WAIT
6549 : IApplicationThread.DEBUG_ON;
6550 app.debugging = true;
6551 if (mDebugTransient) {
6552 mDebugApp = mOrigDebugApp;
6553 mWaitForDebugger = mOrigWaitForDebugger;
6556 String profileFile = app.instrumentationProfileFile;
6557 ParcelFileDescriptor profileFd = null;
6558 int samplingInterval = 0;
6559 boolean profileAutoStop = false;
6560 if (mProfileApp != null && mProfileApp.equals(processName)) {
6562 profileFile = mProfileFile;
6563 profileFd = mProfileFd;
6564 samplingInterval = mSamplingInterval;
6565 profileAutoStop = mAutoStopProfiler;
6567 boolean enableTrackAllocation = false;
6568 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6569 enableTrackAllocation = true;
6570 mTrackAllocationApp = null;
6573 // If the app is being launched for restore or full backup, set it up specially
6574 boolean isRestrictedBackupMode = false;
6575 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6576 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6577 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6578 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6579 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6582 if (app.instrumentationClass != null) {
6583 notifyPackageUse(app.instrumentationClass.getPackageName(),
6584 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6586 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6587 + processName + " with config " + mConfiguration);
6588 ApplicationInfo appInfo = app.instrumentationInfo != null
6589 ? app.instrumentationInfo : app.info;
6590 app.compat = compatibilityInfoForPackageLocked(appInfo);
6591 if (profileFd != null) {
6592 profileFd = profileFd.dup();
6594 ProfilerInfo profilerInfo = profileFile == null ? null
6595 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6596 checkTime(startTime, "attachApplicationLocked: immediately before bindApplication");
6597 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6598 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6599 app.instrumentationUiAutomationConnection, testMode,
6600 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6601 isRestrictedBackupMode || !normalMode, app.persistent,
6602 new Configuration(mConfiguration), app.compat,
6603 getCommonServicesLocked(app.isolated),
6604 mCoreSettingsObserver.getCoreSettingsLocked());
6605 checkTime(startTime, "attachApplicationLocked: immediately after bindApplication");
6606 updateLruProcessLocked(app, false, null);
6607 checkTime(startTime, "attachApplicationLocked: after updateLruProcessLocked");
6608 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6609 } catch (Exception e) {
6610 // todo: Yikes! What should we do? For now we will try to
6611 // start another process, but that could easily get us in
6612 // an infinite loop of restarting processes...
6613 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6615 app.resetPackageList(mProcessStats);
6616 app.unlinkDeathRecipient();
6617 startProcessLocked(app, "bind fail", processName);
6621 // Remove this record from the list of starting applications.
6622 mPersistentStartingProcesses.remove(app);
6623 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6624 "Attach application locked removing on hold: " + app);
6625 mProcessesOnHold.remove(app);
6627 boolean badApp = false;
6628 boolean didSomething = false;
6630 // See if the top visible activity is waiting to run in this process...
6633 if (mStackSupervisor.attachApplicationLocked(app)) {
6634 didSomething = true;
6636 } catch (Exception e) {
6637 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6642 // Find any services that should be running in this process...
6645 didSomething |= mServices.attachApplicationLocked(app, processName);
6646 checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
6647 } catch (Exception e) {
6648 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6653 // Check if a next-broadcast receiver is in this process...
6654 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6656 didSomething |= sendPendingBroadcastsLocked(app);
6657 checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
6658 } catch (Exception e) {
6659 // If the app died trying to launch the receiver we declare it 'bad'
6660 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6665 // Check whether the next backup agent is in this process...
6666 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6667 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6668 "New app is backup target, launching agent for " + app);
6669 notifyPackageUse(mBackupTarget.appInfo.packageName,
6670 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6672 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6673 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6674 mBackupTarget.backupMode);
6675 } catch (Exception e) {
6676 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6682 app.kill("error during init", true);
6683 handleAppDiedLocked(app, false, true);
6687 if (!didSomething) {
6688 updateOomAdjLocked();
6689 checkTime(startTime, "attachApplicationLocked: after updateOomAdjLocked");
6696 public final void attachApplication(IApplicationThread thread) {
6697 synchronized (this) {
6698 int callingPid = Binder.getCallingPid();
6699 final long origId = Binder.clearCallingIdentity();
6700 attachApplicationLocked(thread, callingPid);
6701 Binder.restoreCallingIdentity(origId);
6706 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6707 final long origId = Binder.clearCallingIdentity();
6708 synchronized (this) {
6709 ActivityStack stack = ActivityRecord.getStackLocked(token);
6710 if (stack != null) {
6712 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6713 if (stopProfiling) {
6714 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6717 } catch (IOException e) {
6719 clearProfilerLocked();
6724 Binder.restoreCallingIdentity(origId);
6727 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6728 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6729 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6732 void enableScreenAfterBoot() {
6733 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6734 SystemClock.uptimeMillis());
6735 mWindowManager.enableScreenAfterBoot();
6737 synchronized (this) {
6738 updateEventDispatchingLocked();
6743 public void showBootMessage(final CharSequence msg, final boolean always) {
6744 if (Binder.getCallingUid() != Process.myUid()) {
6745 throw new SecurityException();
6747 mWindowManager.showBootMessage(msg, always);
6751 public void keyguardWaitingForActivityDrawn() {
6752 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6753 final long token = Binder.clearCallingIdentity();
6755 synchronized (this) {
6756 if (DEBUG_LOCKSCREEN) logLockScreen("");
6757 mWindowManager.keyguardWaitingForActivityDrawn();
6758 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6759 mLockScreenShown = LOCK_SCREEN_LEAVING;
6760 updateSleepIfNeededLocked();
6764 Binder.restoreCallingIdentity(token);
6769 public void keyguardGoingAway(int flags) {
6770 enforceNotIsolatedCaller("keyguardGoingAway");
6771 final long token = Binder.clearCallingIdentity();
6773 synchronized (this) {
6774 if (DEBUG_LOCKSCREEN) logLockScreen("");
6775 mWindowManager.keyguardGoingAway(flags);
6776 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6777 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6778 updateSleepIfNeededLocked();
6780 // Some stack visibility might change (e.g. docked stack)
6781 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6785 Binder.restoreCallingIdentity(token);
6789 final void finishBooting() {
6790 synchronized (this) {
6791 if (!mBootAnimationComplete) {
6792 mCallFinishBooting = true;
6795 mCallFinishBooting = false;
6798 ArraySet<String> completedIsas = new ArraySet<String>();
6799 for (String abi : Build.SUPPORTED_ABIS) {
6800 Process.establishZygoteConnectionForAbi(abi);
6801 final String instructionSet = VMRuntime.getInstructionSet(abi);
6802 if (!completedIsas.contains(instructionSet)) {
6804 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6805 } catch (InstallerException e) {
6806 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6807 e.getMessage() +")");
6809 completedIsas.add(instructionSet);
6813 IntentFilter pkgFilter = new IntentFilter();
6814 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6815 pkgFilter.addDataScheme("package");
6816 mContext.registerReceiver(new BroadcastReceiver() {
6818 public void onReceive(Context context, Intent intent) {
6819 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6821 for (String pkg : pkgs) {
6822 synchronized (ActivityManagerService.this) {
6823 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6824 0, "query restart")) {
6825 setResultCode(Activity.RESULT_OK);
6834 IntentFilter dumpheapFilter = new IntentFilter();
6835 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6836 mContext.registerReceiver(new BroadcastReceiver() {
6838 public void onReceive(Context context, Intent intent) {
6839 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6840 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6842 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6847 // Let system services know.
6848 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6850 synchronized (this) {
6851 // Ensure that any processes we had put on hold are now started
6853 final int NP = mProcessesOnHold.size();
6855 ArrayList<ProcessRecord> procs =
6856 new ArrayList<ProcessRecord>(mProcessesOnHold);
6857 for (int ip=0; ip<NP; ip++) {
6858 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6860 startProcessLocked(procs.get(ip), "on-hold", null);
6864 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6865 // Start looking for apps that are abusing wake locks.
6866 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6867 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6868 // Tell anyone interested that we are done booting!
6869 SystemProperties.set("sys.boot_completed", "1");
6871 // And trigger dev.bootcomplete if we are not showing encryption progress
6872 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6873 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6874 SystemProperties.set("dev.bootcomplete", "1");
6876 mUserController.sendBootCompletedLocked(
6877 new IIntentReceiver.Stub() {
6879 public void performReceive(Intent intent, int resultCode,
6880 String data, Bundle extras, boolean ordered,
6881 boolean sticky, int sendingUser) {
6882 synchronized (ActivityManagerService.this) {
6883 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6888 scheduleStartProfilesLocked();
6894 public void bootAnimationComplete() {
6895 final boolean callFinishBooting;
6896 synchronized (this) {
6897 callFinishBooting = mCallFinishBooting;
6898 mBootAnimationComplete = true;
6900 if (callFinishBooting) {
6901 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6903 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6907 final void ensureBootCompleted() {
6909 boolean enableScreen;
6910 synchronized (this) {
6913 enableScreen = !mBooted;
6918 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6920 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6924 enableScreenAfterBoot();
6929 public final void activityResumed(IBinder token) {
6930 final long origId = Binder.clearCallingIdentity();
6931 synchronized(this) {
6932 ActivityStack stack = ActivityRecord.getStackLocked(token);
6933 if (stack != null) {
6934 stack.activityResumedLocked(token);
6937 Binder.restoreCallingIdentity(origId);
6941 public final void activityPaused(IBinder token) {
6942 final long origId = Binder.clearCallingIdentity();
6943 synchronized(this) {
6944 ActivityStack stack = ActivityRecord.getStackLocked(token);
6945 if (stack != null) {
6946 stack.activityPausedLocked(token, false);
6949 Binder.restoreCallingIdentity(origId);
6953 public final void activityStopped(IBinder token, Bundle icicle,
6954 PersistableBundle persistentState, CharSequence description) {
6955 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6957 // Refuse possible leaked file descriptors
6958 if (icicle != null && icicle.hasFileDescriptors()) {
6959 throw new IllegalArgumentException("File descriptors passed in Bundle");
6962 final long origId = Binder.clearCallingIdentity();
6964 synchronized (this) {
6965 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6967 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6973 Binder.restoreCallingIdentity(origId);
6977 public final void activityDestroyed(IBinder token) {
6978 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6979 synchronized (this) {
6980 ActivityStack stack = ActivityRecord.getStackLocked(token);
6981 if (stack != null) {
6982 stack.activityDestroyedLocked(token, "activityDestroyed");
6988 public final void activityRelaunched(IBinder token) {
6989 final long origId = Binder.clearCallingIdentity();
6990 synchronized (this) {
6991 mStackSupervisor.activityRelaunchedLocked(token);
6993 Binder.restoreCallingIdentity(origId);
6997 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6998 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6999 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
7000 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
7001 synchronized (this) {
7002 ActivityRecord record = ActivityRecord.isInStackLocked(token);
7003 if (record == null) {
7004 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
7005 + "found for: " + token);
7007 record.setSizeConfigurations(horizontalSizeConfiguration,
7008 verticalSizeConfigurations, smallestSizeConfigurations);
7013 public final void backgroundResourcesReleased(IBinder token) {
7014 final long origId = Binder.clearCallingIdentity();
7016 synchronized (this) {
7017 ActivityStack stack = ActivityRecord.getStackLocked(token);
7018 if (stack != null) {
7019 stack.backgroundResourcesReleased();
7023 Binder.restoreCallingIdentity(origId);
7028 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7029 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7033 public final void notifyEnterAnimationComplete(IBinder token) {
7034 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7038 public String getCallingPackage(IBinder token) {
7039 synchronized (this) {
7040 ActivityRecord r = getCallingRecordLocked(token);
7041 return r != null ? r.info.packageName : null;
7046 public ComponentName getCallingActivity(IBinder token) {
7047 synchronized (this) {
7048 ActivityRecord r = getCallingRecordLocked(token);
7049 return r != null ? r.intent.getComponent() : null;
7053 private ActivityRecord getCallingRecordLocked(IBinder token) {
7054 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7062 public ComponentName getActivityClassForToken(IBinder token) {
7063 synchronized(this) {
7064 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7068 return r.intent.getComponent();
7073 public String getPackageForToken(IBinder token) {
7074 synchronized(this) {
7075 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7079 return r.packageName;
7084 public boolean isRootVoiceInteraction(IBinder token) {
7085 synchronized(this) {
7086 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7090 return r.rootVoiceInteraction;
7095 public IIntentSender getIntentSender(int type,
7096 String packageName, IBinder token, String resultWho,
7097 int requestCode, Intent[] intents, String[] resolvedTypes,
7098 int flags, Bundle bOptions, int userId) {
7099 enforceNotIsolatedCaller("getIntentSender");
7100 // Refuse possible leaked file descriptors
7101 if (intents != null) {
7102 if (intents.length < 1) {
7103 throw new IllegalArgumentException("Intents array length must be >= 1");
7105 for (int i=0; i<intents.length; i++) {
7106 Intent intent = intents[i];
7107 if (intent != null) {
7108 if (intent.hasFileDescriptors()) {
7109 throw new IllegalArgumentException("File descriptors passed in Intent");
7111 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7112 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7113 throw new IllegalArgumentException(
7114 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7116 intents[i] = new Intent(intent);
7119 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7120 throw new IllegalArgumentException(
7121 "Intent array length does not match resolvedTypes length");
7124 if (bOptions != null) {
7125 if (bOptions.hasFileDescriptors()) {
7126 throw new IllegalArgumentException("File descriptors passed in options");
7130 synchronized(this) {
7131 int callingUid = Binder.getCallingUid();
7132 int origUserId = userId;
7133 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7134 type == ActivityManager.INTENT_SENDER_BROADCAST,
7135 ALLOW_NON_FULL, "getIntentSender", null);
7136 if (origUserId == UserHandle.USER_CURRENT) {
7137 // We don't want to evaluate this until the pending intent is
7138 // actually executed. However, we do want to always do the
7139 // security checking for it above.
7140 userId = UserHandle.USER_CURRENT;
7143 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7144 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7145 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7146 if (!UserHandle.isSameApp(callingUid, uid)) {
7147 String msg = "Permission Denial: getIntentSender() from pid="
7148 + Binder.getCallingPid()
7149 + ", uid=" + Binder.getCallingUid()
7150 + ", (need uid=" + uid + ")"
7151 + " is not allowed to send as package " + packageName;
7153 throw new SecurityException(msg);
7157 return getIntentSenderLocked(type, packageName, callingUid, userId,
7158 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7160 } catch (RemoteException e) {
7161 throw new SecurityException(e);
7166 IIntentSender getIntentSenderLocked(int type, String packageName,
7167 int callingUid, int userId, IBinder token, String resultWho,
7168 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7170 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7171 ActivityRecord activity = null;
7172 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7173 activity = ActivityRecord.isInStackLocked(token);
7174 if (activity == null) {
7175 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7178 if (activity.finishing) {
7179 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7184 // We're going to be splicing together extras before sending, so we're
7185 // okay poking into any contained extras.
7186 if (intents != null) {
7187 for (int i = 0; i < intents.length; i++) {
7188 intents[i].setDefusable(true);
7191 Bundle.setDefusable(bOptions, true);
7193 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7194 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7195 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7196 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7197 |PendingIntent.FLAG_UPDATE_CURRENT);
7199 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7200 type, packageName, activity, resultWho,
7201 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7202 WeakReference<PendingIntentRecord> ref;
7203 ref = mIntentSenderRecords.get(key);
7204 PendingIntentRecord rec = ref != null ? ref.get() : null;
7206 if (!cancelCurrent) {
7207 if (updateCurrent) {
7208 if (rec.key.requestIntent != null) {
7209 rec.key.requestIntent.replaceExtras(intents != null ?
7210 intents[intents.length - 1] : null);
7212 if (intents != null) {
7213 intents[intents.length-1] = rec.key.requestIntent;
7214 rec.key.allIntents = intents;
7215 rec.key.allResolvedTypes = resolvedTypes;
7217 rec.key.allIntents = null;
7218 rec.key.allResolvedTypes = null;
7223 rec.canceled = true;
7224 mIntentSenderRecords.remove(key);
7229 rec = new PendingIntentRecord(this, key, callingUid);
7230 mIntentSenderRecords.put(key, rec.ref);
7231 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7232 if (activity.pendingResults == null) {
7233 activity.pendingResults
7234 = new HashSet<WeakReference<PendingIntentRecord>>();
7236 activity.pendingResults.add(rec.ref);
7242 public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7243 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7244 if (target instanceof PendingIntentRecord) {
7245 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7246 finishedReceiver, requiredPermission, options);
7248 if (intent == null) {
7249 // Weird case: someone has given us their own custom IIntentSender, and now
7250 // they have someone else trying to send to it but of course this isn't
7251 // really a PendingIntent, so there is no base Intent, and the caller isn't
7252 // supplying an Intent... but we never want to dispatch a null Intent to
7253 // a receiver, so um... let's make something up.
7254 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7255 intent = new Intent(Intent.ACTION_MAIN);
7258 target.send(code, intent, resolvedType, null, requiredPermission, options);
7259 } catch (RemoteException e) {
7261 // Platform code can rely on getting a result back when the send is done, but if
7262 // this intent sender is from outside of the system we can't rely on it doing that.
7263 // So instead we don't give it the result receiver, and instead just directly
7264 // report the finish immediately.
7265 if (finishedReceiver != null) {
7267 finishedReceiver.performReceive(intent, 0,
7268 null, null, false, false, UserHandle.getCallingUserId());
7269 } catch (RemoteException e) {
7277 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7279 * <p>{@code callerUid} must be allowed to request such whitelist by calling
7280 * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7282 void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7283 if (DEBUG_WHITELISTS) {
7284 Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7285 + targetUid + ", " + duration + ")");
7287 synchronized (mPidsSelfLocked) {
7288 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7290 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7293 if (!pr.whitelistManager) {
7294 if (DEBUG_WHITELISTS) {
7295 Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7296 + callerPid + " is not allowed");
7302 final long token = Binder.clearCallingIdentity();
7304 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7305 true, "pe from uid:" + callerUid);
7307 Binder.restoreCallingIdentity(token);
7312 public void cancelIntentSender(IIntentSender sender) {
7313 if (!(sender instanceof PendingIntentRecord)) {
7316 synchronized(this) {
7317 PendingIntentRecord rec = (PendingIntentRecord)sender;
7319 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7320 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7321 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7322 String msg = "Permission Denial: cancelIntentSender() from pid="
7323 + Binder.getCallingPid()
7324 + ", uid=" + Binder.getCallingUid()
7325 + " is not allowed to cancel packges "
7326 + rec.key.packageName;
7328 throw new SecurityException(msg);
7330 } catch (RemoteException e) {
7331 throw new SecurityException(e);
7333 cancelIntentSenderLocked(rec, true);
7337 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7338 rec.canceled = true;
7339 mIntentSenderRecords.remove(rec.key);
7340 if (cleanActivity && rec.key.activity != null) {
7341 rec.key.activity.pendingResults.remove(rec.ref);
7346 public String getPackageForIntentSender(IIntentSender pendingResult) {
7347 if (!(pendingResult instanceof PendingIntentRecord)) {
7351 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7352 return res.key.packageName;
7353 } catch (ClassCastException e) {
7359 public int getUidForIntentSender(IIntentSender sender) {
7360 if (sender instanceof PendingIntentRecord) {
7362 PendingIntentRecord res = (PendingIntentRecord)sender;
7364 } catch (ClassCastException e) {
7371 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7372 if (!(pendingResult instanceof PendingIntentRecord)) {
7376 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7377 if (res.key.allIntents == null) {
7380 for (int i=0; i<res.key.allIntents.length; i++) {
7381 Intent intent = res.key.allIntents[i];
7382 if (intent.getPackage() != null && intent.getComponent() != null) {
7387 } catch (ClassCastException e) {
7393 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7394 if (!(pendingResult instanceof PendingIntentRecord)) {
7398 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7399 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7403 } catch (ClassCastException e) {
7409 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7410 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7411 "getIntentForIntentSender()");
7412 if (!(pendingResult instanceof PendingIntentRecord)) {
7416 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7417 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7418 } catch (ClassCastException e) {
7424 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7425 if (!(pendingResult instanceof PendingIntentRecord)) {
7429 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7430 synchronized (this) {
7431 return getTagForIntentSenderLocked(res, prefix);
7433 } catch (ClassCastException e) {
7438 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7439 final Intent intent = res.key.requestIntent;
7440 if (intent != null) {
7441 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7442 || res.lastTagPrefix.equals(prefix))) {
7445 res.lastTagPrefix = prefix;
7446 final StringBuilder sb = new StringBuilder(128);
7447 if (prefix != null) {
7450 if (intent.getAction() != null) {
7451 sb.append(intent.getAction());
7452 } else if (intent.getComponent() != null) {
7453 intent.getComponent().appendShortString(sb);
7457 return res.lastTag = sb.toString();
7463 public void setProcessLimit(int max) {
7464 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7465 "setProcessLimit()");
7466 synchronized (this) {
7467 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7468 mProcessLimitOverride = max;
7474 public int getProcessLimit() {
7475 synchronized (this) {
7476 return mProcessLimitOverride;
7480 void foregroundTokenDied(ForegroundToken token) {
7481 synchronized (ActivityManagerService.this) {
7482 synchronized (mPidsSelfLocked) {
7484 = mForegroundProcesses.get(token.pid);
7488 mForegroundProcesses.remove(token.pid);
7489 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7493 pr.forcingToForeground = null;
7494 updateProcessForegroundLocked(pr, false, false);
7496 updateOomAdjLocked();
7501 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7502 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7503 "setProcessForeground()");
7504 synchronized(this) {
7505 boolean changed = false;
7507 synchronized (mPidsSelfLocked) {
7508 ProcessRecord pr = mPidsSelfLocked.get(pid);
7509 if (pr == null && isForeground) {
7510 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7513 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7514 if (oldToken != null) {
7515 oldToken.token.unlinkToDeath(oldToken, 0);
7516 mForegroundProcesses.remove(pid);
7518 pr.forcingToForeground = null;
7522 if (isForeground && token != null) {
7523 ForegroundToken newToken = new ForegroundToken() {
7525 public void binderDied() {
7526 foregroundTokenDied(this);
7530 newToken.token = token;
7532 token.linkToDeath(newToken, 0);
7533 mForegroundProcesses.put(pid, newToken);
7534 pr.forcingToForeground = token;
7536 } catch (RemoteException e) {
7537 // If the process died while doing this, we will later
7538 // do the cleanup with the process death link.
7544 updateOomAdjLocked();
7550 public boolean isAppForeground(int uid) throws RemoteException {
7551 synchronized (this) {
7552 UidRecord uidRec = mActiveUids.get(uid);
7553 if (uidRec == null || uidRec.idle) {
7556 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7560 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7561 // be guarded by permission checking.
7562 int getUidState(int uid) {
7563 synchronized (this) {
7564 UidRecord uidRec = mActiveUids.get(uid);
7565 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7570 public boolean isInMultiWindowMode(IBinder token) {
7571 final long origId = Binder.clearCallingIdentity();
7573 synchronized(this) {
7574 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7578 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7579 return !r.task.mFullscreen;
7582 Binder.restoreCallingIdentity(origId);
7587 public boolean isInPictureInPictureMode(IBinder token) {
7588 final long origId = Binder.clearCallingIdentity();
7590 synchronized(this) {
7591 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7592 if (stack == null) {
7595 return stack.mStackId == PINNED_STACK_ID;
7598 Binder.restoreCallingIdentity(origId);
7603 public void enterPictureInPictureMode(IBinder token) {
7604 final long origId = Binder.clearCallingIdentity();
7606 synchronized(this) {
7607 if (!mSupportsPictureInPicture) {
7608 throw new IllegalStateException("enterPictureInPictureMode: "
7609 + "Device doesn't support picture-in-picture mode.");
7612 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7615 throw new IllegalStateException("enterPictureInPictureMode: "
7616 + "Can't find activity for token=" + token);
7619 if (!r.supportsPictureInPicture()) {
7620 throw new IllegalArgumentException("enterPictureInPictureMode: "
7621 + "Picture-In-Picture not supported for r=" + r);
7624 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7626 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7627 final Rect bounds = (pinnedStack != null)
7628 ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7630 mStackSupervisor.moveActivityToPinnedStackLocked(
7631 r, "enterPictureInPictureMode", bounds);
7634 Binder.restoreCallingIdentity(origId);
7638 // =========================================================
7640 // =========================================================
7642 static class ProcessInfoService extends IProcessInfoService.Stub {
7643 final ActivityManagerService mActivityManagerService;
7644 ProcessInfoService(ActivityManagerService activityManagerService) {
7645 mActivityManagerService = activityManagerService;
7649 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7650 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7651 /*in*/ pids, /*out*/ states, null);
7655 public void getProcessStatesAndOomScoresFromPids(
7656 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7657 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7658 /*in*/ pids, /*out*/ states, /*out*/ scores);
7663 * For each PID in the given input array, write the current process state
7664 * for that process into the states array, or -1 to indicate that no
7665 * process with the given PID exists. If scores array is provided, write
7666 * the oom score for the process into the scores array, with INVALID_ADJ
7667 * indicating the PID doesn't exist.
7669 public void getProcessStatesAndOomScoresForPIDs(
7670 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7671 if (scores != null) {
7672 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7673 "getProcessStatesAndOomScoresForPIDs()");
7677 throw new NullPointerException("pids");
7678 } else if (states == null) {
7679 throw new NullPointerException("states");
7680 } else if (pids.length != states.length) {
7681 throw new IllegalArgumentException("pids and states arrays have different lengths!");
7682 } else if (scores != null && pids.length != scores.length) {
7683 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7686 synchronized (mPidsSelfLocked) {
7687 for (int i = 0; i < pids.length; i++) {
7688 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7689 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7691 if (scores != null) {
7692 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7698 // =========================================================
7700 // =========================================================
7702 static class PermissionController extends IPermissionController.Stub {
7703 ActivityManagerService mActivityManagerService;
7704 PermissionController(ActivityManagerService activityManagerService) {
7705 mActivityManagerService = activityManagerService;
7709 public boolean checkPermission(String permission, int pid, int uid) {
7710 return mActivityManagerService.checkPermission(permission, pid,
7711 uid) == PackageManager.PERMISSION_GRANTED;
7715 public String[] getPackagesForUid(int uid) {
7716 return mActivityManagerService.mContext.getPackageManager()
7717 .getPackagesForUid(uid);
7721 public boolean isRuntimePermission(String permission) {
7723 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7724 .getPermissionInfo(permission, 0);
7725 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7726 } catch (NameNotFoundException nnfe) {
7727 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7733 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7735 public int checkComponentPermission(String permission, int pid, int uid,
7736 int owningUid, boolean exported) {
7737 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7738 owningUid, exported);
7742 public Object getAMSLock() {
7743 return ActivityManagerService.this;
7748 * This can be called with or without the global lock held.
7750 int checkComponentPermission(String permission, int pid, int uid,
7751 int owningUid, boolean exported) {
7752 if (pid == MY_PID) {
7753 return PackageManager.PERMISSION_GRANTED;
7755 return ActivityManager.checkComponentPermission(permission, uid,
7756 owningUid, exported);
7760 * As the only public entry point for permissions checking, this method
7761 * can enforce the semantic that requesting a check on a null global
7762 * permission is automatically denied. (Internally a null permission
7763 * string is used when calling {@link #checkComponentPermission} in cases
7764 * when only uid-based security is needed.)
7766 * This can be called with or without the global lock held.
7769 public int checkPermission(String permission, int pid, int uid) {
7770 if (permission == null) {
7771 return PackageManager.PERMISSION_DENIED;
7773 return checkComponentPermission(permission, pid, uid, -1, true);
7777 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7778 if (permission == null) {
7779 return PackageManager.PERMISSION_DENIED;
7782 // We might be performing an operation on behalf of an indirect binder
7783 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7784 // client identity accordingly before proceeding.
7785 Identity tlsIdentity = sCallerIdentity.get();
7786 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7787 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7788 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7789 uid = tlsIdentity.uid;
7790 pid = tlsIdentity.pid;
7793 return checkComponentPermission(permission, pid, uid, -1, true);
7797 * Binder IPC calls go through the public entry point.
7798 * This can be called with or without the global lock held.
7800 int checkCallingPermission(String permission) {
7801 return checkPermission(permission,
7802 Binder.getCallingPid(),
7803 UserHandle.getAppId(Binder.getCallingUid()));
7807 * This can be called with or without the global lock held.
7809 void enforceCallingPermission(String permission, String func) {
7810 if (checkCallingPermission(permission)
7811 == PackageManager.PERMISSION_GRANTED) {
7815 String msg = "Permission Denial: " + func + " from pid="
7816 + Binder.getCallingPid()
7817 + ", uid=" + Binder.getCallingUid()
7818 + " requires " + permission;
7820 throw new SecurityException(msg);
7824 * Determine if UID is holding permissions required to access {@link Uri} in
7825 * the given {@link ProviderInfo}. Final permission checking is always done
7826 * in {@link ContentProvider}.
7828 private final boolean checkHoldingPermissionsLocked(
7829 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7830 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7831 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7832 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7833 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7834 != PERMISSION_GRANTED) {
7838 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7841 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7842 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7843 if (pi.applicationInfo.uid == uid) {
7845 } else if (!pi.exported) {
7849 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7850 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7852 // check if target holds top-level <provider> permissions
7853 if (!readMet && pi.readPermission != null && considerUidPermissions
7854 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7857 if (!writeMet && pi.writePermission != null && considerUidPermissions
7858 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7862 // track if unprotected read/write is allowed; any denied
7863 // <path-permission> below removes this ability
7864 boolean allowDefaultRead = pi.readPermission == null;
7865 boolean allowDefaultWrite = pi.writePermission == null;
7867 // check if target holds any <path-permission> that match uri
7868 final PathPermission[] pps = pi.pathPermissions;
7870 final String path = grantUri.uri.getPath();
7872 while (i > 0 && (!readMet || !writeMet)) {
7874 PathPermission pp = pps[i];
7875 if (pp.match(path)) {
7877 final String pprperm = pp.getReadPermission();
7878 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7879 "Checking read perm for " + pprperm + " for " + pp.getPath()
7880 + ": match=" + pp.match(path)
7881 + " check=" + pm.checkUidPermission(pprperm, uid));
7882 if (pprperm != null) {
7883 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7884 == PERMISSION_GRANTED) {
7887 allowDefaultRead = false;
7892 final String ppwperm = pp.getWritePermission();
7893 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7894 "Checking write perm " + ppwperm + " for " + pp.getPath()
7895 + ": match=" + pp.match(path)
7896 + " check=" + pm.checkUidPermission(ppwperm, uid));
7897 if (ppwperm != null) {
7898 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7899 == PERMISSION_GRANTED) {
7902 allowDefaultWrite = false;
7910 // grant unprotected <provider> read/write, if not blocked by
7911 // <path-permission> above
7912 if (allowDefaultRead) readMet = true;
7913 if (allowDefaultWrite) writeMet = true;
7915 } catch (RemoteException e) {
7919 return readMet && writeMet;
7922 public int getAppStartMode(int uid, String packageName) {
7923 synchronized (this) {
7924 return checkAllowBackgroundLocked(uid, packageName, -1, true);
7928 int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7929 boolean allowWhenForeground) {
7930 UidRecord uidRec = mActiveUids.get(uid);
7931 if (!mLenientBackgroundCheck) {
7932 if (!allowWhenForeground || uidRec == null
7933 || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7934 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7935 packageName) != AppOpsManager.MODE_ALLOWED) {
7936 return ActivityManager.APP_START_MODE_DELAYED;
7940 } else if (uidRec == null || uidRec.idle) {
7941 if (callingPid >= 0) {
7943 synchronized (mPidsSelfLocked) {
7944 proc = mPidsSelfLocked.get(callingPid);
7946 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7947 // Whoever is instigating this is in the foreground, so we will allow it
7949 return ActivityManager.APP_START_MODE_NORMAL;
7952 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7953 != AppOpsManager.MODE_ALLOWED) {
7954 return ActivityManager.APP_START_MODE_DELAYED;
7957 return ActivityManager.APP_START_MODE_NORMAL;
7960 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7961 ProviderInfo pi = null;
7962 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7967 pi = AppGlobals.getPackageManager().resolveContentProvider(
7968 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7970 } catch (RemoteException ex) {
7976 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7977 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7978 if (targetUris != null) {
7979 return targetUris.get(grantUri);
7984 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7985 String targetPkg, int targetUid, GrantUri grantUri) {
7986 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7987 if (targetUris == null) {
7988 targetUris = Maps.newArrayMap();
7989 mGrantedUriPermissions.put(targetUid, targetUris);
7992 UriPermission perm = targetUris.get(grantUri);
7994 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7995 targetUris.put(grantUri, perm);
8001 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
8002 final int modeFlags) {
8003 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
8004 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
8005 : UriPermission.STRENGTH_OWNED;
8007 // Root gets to do everything.
8012 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8013 if (perms == null) return false;
8015 // First look for exact match
8016 final UriPermission exactPerm = perms.get(grantUri);
8017 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8021 // No exact match, look for prefixes
8022 final int N = perms.size();
8023 for (int i = 0; i < N; i++) {
8024 final UriPermission perm = perms.valueAt(i);
8025 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8026 && perm.getStrength(modeFlags) >= minStrength) {
8035 * @param uri This uri must NOT contain an embedded userId.
8036 * @param userId The userId in which the uri is to be resolved.
8039 public int checkUriPermission(Uri uri, int pid, int uid,
8040 final int modeFlags, int userId, IBinder callerToken) {
8041 enforceNotIsolatedCaller("checkUriPermission");
8043 // Another redirected-binder-call permissions check as in
8044 // {@link checkPermissionWithToken}.
8045 Identity tlsIdentity = sCallerIdentity.get();
8046 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8047 uid = tlsIdentity.uid;
8048 pid = tlsIdentity.pid;
8051 // Our own process gets to do everything.
8052 if (pid == MY_PID) {
8053 return PackageManager.PERMISSION_GRANTED;
8055 synchronized (this) {
8056 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8057 ? PackageManager.PERMISSION_GRANTED
8058 : PackageManager.PERMISSION_DENIED;
8063 * Check if the targetPkg can be granted permission to access uri by
8064 * the callingUid using the given modeFlags. Throws a security exception
8065 * if callingUid is not allowed to do this. Returns the uid of the target
8066 * if the URI permission grant should be performed; returns -1 if it is not
8067 * needed (for example targetPkg already has permission to access the URI).
8068 * If you already know the uid of the target, you can supply it in
8069 * lastTargetUid else set that to -1.
8071 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8072 final int modeFlags, int lastTargetUid) {
8073 if (!Intent.isAccessUriMode(modeFlags)) {
8077 if (targetPkg != null) {
8078 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079 "Checking grant " + targetPkg + " permission to " + grantUri);
8082 final IPackageManager pm = AppGlobals.getPackageManager();
8084 // If this is not a content: uri, we can't do anything with it.
8085 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8086 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8087 "Can't grant URI permission for non-content URI: " + grantUri);
8091 final String authority = grantUri.uri.getAuthority();
8092 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8093 MATCH_DEBUG_TRIAGED_MISSING);
8095 Slog.w(TAG, "No content provider found for permission check: " +
8096 grantUri.uri.toSafeString());
8100 int targetUid = lastTargetUid;
8101 if (targetUid < 0 && targetPkg != null) {
8103 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8104 UserHandle.getUserId(callingUid));
8105 if (targetUid < 0) {
8106 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8107 "Can't grant URI permission no uid for: " + targetPkg);
8110 } catch (RemoteException ex) {
8115 if (targetUid >= 0) {
8116 // First... does the target actually need this permission?
8117 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8118 // No need to grant the target this permission.
8119 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8120 "Target " + targetPkg + " already has full permission to " + grantUri);
8124 // First... there is no target package, so can anyone access it?
8125 boolean allowed = pi.exported;
8126 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8127 if (pi.readPermission != null) {
8131 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8132 if (pi.writePermission != null) {
8141 /* There is a special cross user grant if:
8142 * - The target is on another user.
8143 * - Apps on the current user can access the uri without any uid permissions.
8144 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8145 * grant uri permissions.
8147 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8148 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8149 modeFlags, false /*without considering the uid permissions*/);
8151 // Second... is the provider allowing granting of URI permissions?
8152 if (!specialCrossUserGrant) {
8153 if (!pi.grantUriPermissions) {
8154 throw new SecurityException("Provider " + pi.packageName
8156 + " does not allow granting of Uri permissions (uri "
8159 if (pi.uriPermissionPatterns != null) {
8160 final int N = pi.uriPermissionPatterns.length;
8161 boolean allowed = false;
8162 for (int i=0; i<N; i++) {
8163 if (pi.uriPermissionPatterns[i] != null
8164 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8170 throw new SecurityException("Provider " + pi.packageName
8172 + " does not allow granting of permission to path of Uri "
8178 // Third... does the caller itself have permission to access
8180 final int callingAppId = UserHandle.getAppId(callingUid);
8181 if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8182 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8183 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8186 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8187 // Require they hold a strong enough Uri permission
8188 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8189 throw new SecurityException("Uid " + callingUid
8190 + " does not have permission to uri " + grantUri);
8198 * @param uri This uri must NOT contain an embedded userId.
8199 * @param userId The userId in which the uri is to be resolved.
8202 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8203 final int modeFlags, int userId) {
8204 enforceNotIsolatedCaller("checkGrantUriPermission");
8205 synchronized(this) {
8206 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8207 new GrantUri(userId, uri, false), modeFlags, -1);
8211 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8212 final int modeFlags, UriPermissionOwner owner) {
8213 if (!Intent.isAccessUriMode(modeFlags)) {
8217 // So here we are: the caller has the assumed permission
8218 // to the uri, and the target doesn't. Let's now give this to
8221 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8222 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8224 final String authority = grantUri.uri.getAuthority();
8225 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8226 MATCH_DEBUG_TRIAGED_MISSING);
8228 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8232 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8233 grantUri.prefix = true;
8235 final UriPermission perm = findOrCreateUriPermissionLocked(
8236 pi.packageName, targetPkg, targetUid, grantUri);
8237 perm.grantModes(modeFlags, owner);
8240 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8241 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8242 if (targetPkg == null) {
8243 throw new NullPointerException("targetPkg");
8246 final IPackageManager pm = AppGlobals.getPackageManager();
8248 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8249 } catch (RemoteException ex) {
8253 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8255 if (targetUid < 0) {
8259 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8263 static class NeededUriGrants extends ArrayList<GrantUri> {
8264 final String targetPkg;
8265 final int targetUid;
8268 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8269 this.targetPkg = targetPkg;
8270 this.targetUid = targetUid;
8276 * Like checkGrantUriPermissionLocked, but takes an Intent.
8278 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8279 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8280 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8281 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8282 + " clip=" + (intent != null ? intent.getClipData() : null)
8283 + " from " + intent + "; flags=0x"
8284 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8286 if (targetPkg == null) {
8287 throw new NullPointerException("targetPkg");
8290 if (intent == null) {
8293 Uri data = intent.getData();
8294 ClipData clip = intent.getClipData();
8295 if (data == null && clip == null) {
8298 // Default userId for uris in the intent (if they don't specify it themselves)
8299 int contentUserHint = intent.getContentUserHint();
8300 if (contentUserHint == UserHandle.USER_CURRENT) {
8301 contentUserHint = UserHandle.getUserId(callingUid);
8303 final IPackageManager pm = AppGlobals.getPackageManager();
8305 if (needed != null) {
8306 targetUid = needed.targetUid;
8309 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8311 } catch (RemoteException ex) {
8314 if (targetUid < 0) {
8315 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8316 "Can't grant URI permission no uid for: " + targetPkg
8317 + " on user " + targetUserId);
8322 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8323 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8325 if (targetUid > 0) {
8326 if (needed == null) {
8327 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8329 needed.add(grantUri);
8333 for (int i=0; i<clip.getItemCount(); i++) {
8334 Uri uri = clip.getItemAt(i).getUri();
8336 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8337 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8339 if (targetUid > 0) {
8340 if (needed == null) {
8341 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8343 needed.add(grantUri);
8346 Intent clipIntent = clip.getItemAt(i).getIntent();
8347 if (clipIntent != null) {
8348 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8349 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8350 if (newNeeded != null) {
8362 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8364 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8365 UriPermissionOwner owner) {
8366 if (needed != null) {
8367 for (int i=0; i<needed.size(); i++) {
8368 GrantUri grantUri = needed.get(i);
8369 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8370 grantUri, needed.flags, owner);
8375 void grantUriPermissionFromIntentLocked(int callingUid,
8376 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8377 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8378 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8379 if (needed == null) {
8383 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8387 * @param uri This uri must NOT contain an embedded userId.
8388 * @param userId The userId in which the uri is to be resolved.
8391 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8392 final int modeFlags, int userId) {
8393 enforceNotIsolatedCaller("grantUriPermission");
8394 GrantUri grantUri = new GrantUri(userId, uri, false);
8395 synchronized(this) {
8396 final ProcessRecord r = getRecordForAppLocked(caller);
8398 throw new SecurityException("Unable to find app for caller "
8400 + " when granting permission to uri " + grantUri);
8402 if (targetPkg == null) {
8403 throw new IllegalArgumentException("null target");
8405 if (grantUri == null) {
8406 throw new IllegalArgumentException("null uri");
8409 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8410 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8411 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8412 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8414 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8415 UserHandle.getUserId(r.uid));
8419 void removeUriPermissionIfNeededLocked(UriPermission perm) {
8420 if (perm.modeFlags == 0) {
8421 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8423 if (perms != null) {
8424 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8425 "Removing " + perm.targetUid + " permission to " + perm.uri);
8427 perms.remove(perm.uri);
8428 if (perms.isEmpty()) {
8429 mGrantedUriPermissions.remove(perm.targetUid);
8435 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8436 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8437 "Revoking all granted permissions to " + grantUri);
8439 final IPackageManager pm = AppGlobals.getPackageManager();
8440 final String authority = grantUri.uri.getAuthority();
8441 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8442 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8444 Slog.w(TAG, "No content provider found for permission revoke: "
8445 + grantUri.toSafeString());
8449 // Does the caller have this permission on the URI?
8450 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8451 // If they don't have direct access to the URI, then revoke any
8452 // ownerless URI permissions that have been granted to them.
8453 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8454 if (perms != null) {
8455 boolean persistChanged = false;
8456 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8457 final UriPermission perm = it.next();
8458 if (perm.uri.sourceUserId == grantUri.sourceUserId
8459 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8460 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8461 "Revoking non-owned " + perm.targetUid
8462 + " permission to " + perm.uri);
8463 persistChanged |= perm.revokeModes(
8464 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8465 if (perm.modeFlags == 0) {
8470 if (perms.isEmpty()) {
8471 mGrantedUriPermissions.remove(callingUid);
8473 if (persistChanged) {
8474 schedulePersistUriGrants();
8480 boolean persistChanged = false;
8482 // Go through all of the permissions and remove any that match.
8483 int N = mGrantedUriPermissions.size();
8484 for (int i = 0; i < N; i++) {
8485 final int targetUid = mGrantedUriPermissions.keyAt(i);
8486 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8488 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8489 final UriPermission perm = it.next();
8490 if (perm.uri.sourceUserId == grantUri.sourceUserId
8491 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8492 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8493 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8494 persistChanged |= perm.revokeModes(
8495 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8496 if (perm.modeFlags == 0) {
8502 if (perms.isEmpty()) {
8503 mGrantedUriPermissions.remove(targetUid);
8509 if (persistChanged) {
8510 schedulePersistUriGrants();
8515 * @param uri This uri must NOT contain an embedded userId.
8516 * @param userId The userId in which the uri is to be resolved.
8519 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8521 enforceNotIsolatedCaller("revokeUriPermission");
8522 synchronized(this) {
8523 final ProcessRecord r = getRecordForAppLocked(caller);
8525 throw new SecurityException("Unable to find app for caller "
8527 + " when revoking permission to uri " + uri);
8530 Slog.w(TAG, "revokeUriPermission: null uri");
8534 if (!Intent.isAccessUriMode(modeFlags)) {
8538 final String authority = uri.getAuthority();
8539 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8540 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8542 Slog.w(TAG, "No content provider found for permission revoke: "
8543 + uri.toSafeString());
8547 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8552 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8555 * @param packageName Package name to match, or {@code null} to apply to all
8557 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8559 * @param persistable If persistable grants should be removed.
8561 private void removeUriPermissionsForPackageLocked(
8562 String packageName, int userHandle, boolean persistable) {
8563 if (userHandle == UserHandle.USER_ALL && packageName == null) {
8564 throw new IllegalArgumentException("Must narrow by either package or user");
8567 boolean persistChanged = false;
8569 int N = mGrantedUriPermissions.size();
8570 for (int i = 0; i < N; i++) {
8571 final int targetUid = mGrantedUriPermissions.keyAt(i);
8572 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8574 // Only inspect grants matching user
8575 if (userHandle == UserHandle.USER_ALL
8576 || userHandle == UserHandle.getUserId(targetUid)) {
8577 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8578 final UriPermission perm = it.next();
8580 // Only inspect grants matching package
8581 if (packageName == null || perm.sourcePkg.equals(packageName)
8582 || perm.targetPkg.equals(packageName)) {
8583 // Hacky solution as part of fixing a security bug; ignore
8584 // grants associated with DownloadManager so we don't have
8585 // to immediately launch it to regrant the permissions
8586 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8587 && !persistable) continue;
8589 persistChanged |= perm.revokeModes(persistable
8590 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8592 // Only remove when no modes remain; any persisted grants
8593 // will keep this alive.
8594 if (perm.modeFlags == 0) {
8600 if (perms.isEmpty()) {
8601 mGrantedUriPermissions.remove(targetUid);
8608 if (persistChanged) {
8609 schedulePersistUriGrants();
8614 public IBinder newUriPermissionOwner(String name) {
8615 enforceNotIsolatedCaller("newUriPermissionOwner");
8616 synchronized(this) {
8617 UriPermissionOwner owner = new UriPermissionOwner(this, name);
8618 return owner.getExternalTokenLocked();
8623 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8624 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8625 synchronized(this) {
8626 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8628 throw new IllegalArgumentException("Activity does not exist; token="
8631 return r.getUriPermissionsLocked().getExternalTokenLocked();
8635 * @param uri This uri must NOT contain an embedded userId.
8636 * @param sourceUserId The userId in which the uri is to be resolved.
8637 * @param targetUserId The userId of the app that receives the grant.
8640 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8641 final int modeFlags, int sourceUserId, int targetUserId) {
8642 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8643 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8644 "grantUriPermissionFromOwner", null);
8645 synchronized(this) {
8646 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8647 if (owner == null) {
8648 throw new IllegalArgumentException("Unknown owner: " + token);
8650 if (fromUid != Binder.getCallingUid()) {
8651 if (Binder.getCallingUid() != Process.myUid()) {
8652 // Only system code can grant URI permissions on behalf
8654 throw new SecurityException("nice try");
8657 if (targetPkg == null) {
8658 throw new IllegalArgumentException("null target");
8661 throw new IllegalArgumentException("null uri");
8664 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8665 modeFlags, owner, targetUserId);
8670 * @param uri This uri must NOT contain an embedded userId.
8671 * @param userId The userId in which the uri is to be resolved.
8674 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8675 synchronized(this) {
8676 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8677 if (owner == null) {
8678 throw new IllegalArgumentException("Unknown owner: " + token);
8682 owner.removeUriPermissionsLocked(mode);
8684 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8685 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8690 private void schedulePersistUriGrants() {
8691 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8692 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8693 10 * DateUtils.SECOND_IN_MILLIS);
8697 private void writeGrantedUriPermissions() {
8698 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8700 // Snapshot permissions so we can persist without lock
8701 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8702 synchronized (this) {
8703 final int size = mGrantedUriPermissions.size();
8704 for (int i = 0; i < size; i++) {
8705 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8706 for (UriPermission perm : perms.values()) {
8707 if (perm.persistedModeFlags != 0) {
8708 persist.add(perm.snapshot());
8714 FileOutputStream fos = null;
8716 fos = mGrantFile.startWrite();
8718 XmlSerializer out = new FastXmlSerializer();
8719 out.setOutput(fos, StandardCharsets.UTF_8.name());
8720 out.startDocument(null, true);
8721 out.startTag(null, TAG_URI_GRANTS);
8722 for (UriPermission.Snapshot perm : persist) {
8723 out.startTag(null, TAG_URI_GRANT);
8724 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8725 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8726 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8727 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8728 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8729 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8730 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8731 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8732 out.endTag(null, TAG_URI_GRANT);
8734 out.endTag(null, TAG_URI_GRANTS);
8737 mGrantFile.finishWrite(fos);
8738 } catch (IOException e) {
8740 mGrantFile.failWrite(fos);
8745 private void readGrantedUriPermissionsLocked() {
8746 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8748 final long now = System.currentTimeMillis();
8750 FileInputStream fis = null;
8752 fis = mGrantFile.openRead();
8753 final XmlPullParser in = Xml.newPullParser();
8754 in.setInput(fis, StandardCharsets.UTF_8.name());
8757 while ((type = in.next()) != END_DOCUMENT) {
8758 final String tag = in.getName();
8759 if (type == START_TAG) {
8760 if (TAG_URI_GRANT.equals(tag)) {
8761 final int sourceUserId;
8762 final int targetUserId;
8763 final int userHandle = readIntAttribute(in,
8764 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8765 if (userHandle != UserHandle.USER_NULL) {
8766 // For backwards compatibility.
8767 sourceUserId = userHandle;
8768 targetUserId = userHandle;
8770 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8771 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8773 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8774 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8775 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8776 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8777 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8778 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8780 // Sanity check that provider still belongs to source package
8781 // Both direct boot aware and unaware packages are fine as we
8782 // will do filtering at query time to avoid multiple parsing.
8783 final ProviderInfo pi = getProviderInfoLocked(
8784 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8785 | MATCH_DIRECT_BOOT_UNAWARE);
8786 if (pi != null && sourcePkg.equals(pi.packageName)) {
8789 targetUid = AppGlobals.getPackageManager().getPackageUid(
8790 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8791 } catch (RemoteException e) {
8793 if (targetUid != -1) {
8794 final UriPermission perm = findOrCreateUriPermissionLocked(
8795 sourcePkg, targetPkg, targetUid,
8796 new GrantUri(sourceUserId, uri, prefix));
8797 perm.initPersistedModes(modeFlags, createdTime);
8800 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8801 + " but instead found " + pi);
8806 } catch (FileNotFoundException e) {
8807 // Missing grants is okay
8808 } catch (IOException e) {
8809 Slog.wtf(TAG, "Failed reading Uri grants", e);
8810 } catch (XmlPullParserException e) {
8811 Slog.wtf(TAG, "Failed reading Uri grants", e);
8813 IoUtils.closeQuietly(fis);
8818 * @param uri This uri must NOT contain an embedded userId.
8819 * @param userId The userId in which the uri is to be resolved.
8822 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8823 enforceNotIsolatedCaller("takePersistableUriPermission");
8825 Preconditions.checkFlagsArgument(modeFlags,
8826 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8828 synchronized (this) {
8829 final int callingUid = Binder.getCallingUid();
8830 boolean persistChanged = false;
8831 GrantUri grantUri = new GrantUri(userId, uri, false);
8833 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8834 new GrantUri(userId, uri, false));
8835 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8836 new GrantUri(userId, uri, true));
8838 final boolean exactValid = (exactPerm != null)
8839 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8840 final boolean prefixValid = (prefixPerm != null)
8841 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8843 if (!(exactValid || prefixValid)) {
8844 throw new SecurityException("No persistable permission grants found for UID "
8845 + callingUid + " and Uri " + grantUri.toSafeString());
8849 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8852 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8855 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8857 if (persistChanged) {
8858 schedulePersistUriGrants();
8864 * @param uri This uri must NOT contain an embedded userId.
8865 * @param userId The userId in which the uri is to be resolved.
8868 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8869 enforceNotIsolatedCaller("releasePersistableUriPermission");
8871 Preconditions.checkFlagsArgument(modeFlags,
8872 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8874 synchronized (this) {
8875 final int callingUid = Binder.getCallingUid();
8876 boolean persistChanged = false;
8878 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8879 new GrantUri(userId, uri, false));
8880 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8881 new GrantUri(userId, uri, true));
8882 if (exactPerm == null && prefixPerm == null) {
8883 throw new SecurityException("No permission grants found for UID " + callingUid
8884 + " and Uri " + uri.toSafeString());
8887 if (exactPerm != null) {
8888 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8889 removeUriPermissionIfNeededLocked(exactPerm);
8891 if (prefixPerm != null) {
8892 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8893 removeUriPermissionIfNeededLocked(prefixPerm);
8896 if (persistChanged) {
8897 schedulePersistUriGrants();
8903 * Prune any older {@link UriPermission} for the given UID until outstanding
8904 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8906 * @return if any mutations occured that require persisting.
8908 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8909 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8910 if (perms == null) return false;
8911 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8913 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8914 for (UriPermission perm : perms.values()) {
8915 if (perm.persistedModeFlags != 0) {
8916 persisted.add(perm);
8920 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8921 if (trimCount <= 0) return false;
8923 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8924 for (int i = 0; i < trimCount; i++) {
8925 final UriPermission perm = persisted.get(i);
8927 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8928 "Trimming grant created at " + perm.persistedCreateTime);
8930 perm.releasePersistableModes(~0);
8931 removeUriPermissionIfNeededLocked(perm);
8938 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8939 String packageName, boolean incoming) {
8940 enforceNotIsolatedCaller("getPersistedUriPermissions");
8941 Preconditions.checkNotNull(packageName, "packageName");
8943 final int callingUid = Binder.getCallingUid();
8944 final int callingUserId = UserHandle.getUserId(callingUid);
8945 final IPackageManager pm = AppGlobals.getPackageManager();
8947 final int packageUid = pm.getPackageUid(packageName,
8948 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8949 if (packageUid != callingUid) {
8950 throw new SecurityException(
8951 "Package " + packageName + " does not belong to calling UID " + callingUid);
8953 } catch (RemoteException e) {
8954 throw new SecurityException("Failed to verify package name ownership");
8957 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8958 synchronized (this) {
8960 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8962 if (perms == null) {
8963 Slog.w(TAG, "No permission grants found for " + packageName);
8965 for (UriPermission perm : perms.values()) {
8966 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8967 result.add(perm.buildPersistedPublicApiObject());
8972 final int size = mGrantedUriPermissions.size();
8973 for (int i = 0; i < size; i++) {
8974 final ArrayMap<GrantUri, UriPermission> perms =
8975 mGrantedUriPermissions.valueAt(i);
8976 for (UriPermission perm : perms.values()) {
8977 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8978 result.add(perm.buildPersistedPublicApiObject());
8984 return new ParceledListSlice<android.content.UriPermission>(result);
8988 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8989 String packageName, int userId) {
8990 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8991 "getGrantedUriPermissions");
8993 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8994 synchronized (this) {
8995 final int size = mGrantedUriPermissions.size();
8996 for (int i = 0; i < size; i++) {
8997 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8998 for (UriPermission perm : perms.values()) {
8999 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
9000 && perm.persistedModeFlags != 0) {
9001 result.add(perm.buildPersistedPublicApiObject());
9006 return new ParceledListSlice<android.content.UriPermission>(result);
9010 public void clearGrantedUriPermissions(String packageName, int userId) {
9011 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
9012 "clearGrantedUriPermissions");
9013 removeUriPermissionsForPackageLocked(packageName, userId, true);
9017 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9018 synchronized (this) {
9020 who != null ? getRecordForAppLocked(who) : null;
9021 if (app == null) return;
9023 Message msg = Message.obtain();
9024 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9026 msg.arg1 = waiting ? 1 : 0;
9027 mUiHandler.sendMessage(msg);
9032 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9033 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9034 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9035 outInfo.availMem = Process.getFreeMemory();
9036 outInfo.totalMem = Process.getTotalMemory();
9037 outInfo.threshold = homeAppMem;
9038 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9039 outInfo.hiddenAppThreshold = cachedAppMem;
9040 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9041 ProcessList.SERVICE_ADJ);
9042 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9043 ProcessList.VISIBLE_APP_ADJ);
9044 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9045 ProcessList.FOREGROUND_APP_ADJ);
9048 // =========================================================
9050 // =========================================================
9053 public List<IAppTask> getAppTasks(String callingPackage) {
9054 int callingUid = Binder.getCallingUid();
9055 long ident = Binder.clearCallingIdentity();
9057 synchronized(this) {
9058 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9060 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9062 final int N = mRecentTasks.size();
9063 for (int i = 0; i < N; i++) {
9064 TaskRecord tr = mRecentTasks.get(i);
9065 // Skip tasks that do not match the caller. We don't need to verify
9066 // callingPackage, because we are also limiting to callingUid and know
9067 // that will limit to the correct security sandbox.
9068 if (tr.effectiveUid != callingUid) {
9071 Intent intent = tr.getBaseIntent();
9072 if (intent == null ||
9073 !callingPackage.equals(intent.getComponent().getPackageName())) {
9076 ActivityManager.RecentTaskInfo taskInfo =
9077 createRecentTaskInfoFromTaskRecord(tr);
9078 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9082 Binder.restoreCallingIdentity(ident);
9089 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9090 final int callingUid = Binder.getCallingUid();
9091 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9093 synchronized(this) {
9094 if (DEBUG_ALL) Slog.v(
9095 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9097 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9100 // TODO: Improve with MRU list from all ActivityStacks.
9101 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9108 * Creates a new RecentTaskInfo from a TaskRecord.
9110 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9111 // Update the task description to reflect any changes in the task stack
9112 tr.updateTaskDescription();
9114 // Compose the recent task info
9115 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9116 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9117 rti.persistentId = tr.taskId;
9118 rti.baseIntent = new Intent(tr.getBaseIntent());
9119 rti.origActivity = tr.origActivity;
9120 rti.realActivity = tr.realActivity;
9121 rti.description = tr.lastDescription;
9122 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9123 rti.userId = tr.userId;
9124 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9125 rti.firstActiveTime = tr.firstActiveTime;
9126 rti.lastActiveTime = tr.lastActiveTime;
9127 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9128 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9129 rti.numActivities = 0;
9130 if (tr.mBounds != null) {
9131 rti.bounds = new Rect(tr.mBounds);
9133 rti.isDockable = tr.canGoInDockedStack();
9134 rti.resizeMode = tr.mResizeMode;
9136 ActivityRecord base = null;
9137 ActivityRecord top = null;
9140 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9141 tmp = tr.mActivities.get(i);
9142 if (tmp.finishing) {
9146 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9149 rti.numActivities++;
9152 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9153 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9158 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9159 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9160 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9162 if (checkPermission(android.Manifest.permission.GET_TASKS,
9163 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9164 // Temporary compatibility: some existing apps on the system image may
9165 // still be requesting the old permission and not switched to the new
9166 // one; if so, we'll still allow them full access. This means we need
9167 // to see if they are holding the old permission and are a system app.
9169 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9171 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9172 + " is using old GET_TASKS but privileged; allowing");
9174 } catch (RemoteException e) {
9179 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9180 + " does not hold REAL_GET_TASKS; limiting output");
9186 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9188 final int callingUid = Binder.getCallingUid();
9189 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9190 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9192 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9193 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9194 synchronized (this) {
9195 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9197 final boolean detailed = checkCallingPermission(
9198 android.Manifest.permission.GET_DETAILED_TASKS)
9199 == PackageManager.PERMISSION_GRANTED;
9201 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9202 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9203 return ParceledListSlice.emptyList();
9205 mRecentTasks.loadUserRecentsLocked(userId);
9207 final int recentsCount = mRecentTasks.size();
9208 ArrayList<ActivityManager.RecentTaskInfo> res =
9209 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9211 final Set<Integer> includedUsers;
9212 if (includeProfiles) {
9213 includedUsers = mUserController.getProfileIds(userId);
9215 includedUsers = new HashSet<>();
9217 includedUsers.add(Integer.valueOf(userId));
9219 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9220 TaskRecord tr = mRecentTasks.get(i);
9221 // Only add calling user or related users recent tasks
9222 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9223 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9227 if (tr.realActivitySuspended) {
9228 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9232 // Return the entry if desired by the caller. We always return
9233 // the first entry, because callers always expect this to be the
9234 // foreground app. We may filter others if the caller has
9235 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9236 // we should exclude the entry.
9240 || (tr.intent == null)
9241 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9244 // If the caller doesn't have the GET_TASKS permission, then only
9245 // allow them to see a small subset of tasks -- their own and home.
9246 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9247 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9251 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9252 if (tr.stack != null && tr.stack.isHomeStack()) {
9253 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9254 "Skipping, home stack task: " + tr);
9258 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9259 final ActivityStack stack = tr.stack;
9260 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9261 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9262 "Skipping, top task in docked stack: " + tr);
9266 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9267 if (tr.stack != null && tr.stack.isPinnedStack()) {
9268 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9269 "Skipping, pinned stack task: " + tr);
9273 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9274 // Don't include auto remove tasks that are finished or finishing.
9275 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9276 "Skipping, auto-remove without activity: " + tr);
9279 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9280 && !tr.isAvailable) {
9281 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9282 "Skipping, unavail real act: " + tr);
9286 if (!tr.mUserSetupComplete) {
9287 // Don't include task launched while user is not done setting-up.
9288 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9289 "Skipping, user setup not complete: " + tr);
9293 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9295 rti.baseIntent.replaceExtras((Bundle)null);
9302 return new ParceledListSlice<>(res);
9307 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9308 synchronized (this) {
9309 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9310 "getTaskThumbnail()");
9311 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9312 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9314 return tr.getTaskThumbnailLocked();
9321 public int addAppTask(IBinder activityToken, Intent intent,
9322 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9323 final int callingUid = Binder.getCallingUid();
9324 final long callingIdent = Binder.clearCallingIdentity();
9327 synchronized (this) {
9328 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9330 throw new IllegalArgumentException("Activity does not exist; token="
9333 ComponentName comp = intent.getComponent();
9335 throw new IllegalArgumentException("Intent " + intent
9336 + " must specify explicit component");
9338 if (thumbnail.getWidth() != mThumbnailWidth
9339 || thumbnail.getHeight() != mThumbnailHeight) {
9340 throw new IllegalArgumentException("Bad thumbnail size: got "
9341 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9342 + mThumbnailWidth + "x" + mThumbnailHeight);
9344 if (intent.getSelector() != null) {
9345 intent.setSelector(null);
9347 if (intent.getSourceBounds() != null) {
9348 intent.setSourceBounds(null);
9350 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9351 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9352 // The caller has added this as an auto-remove task... that makes no
9353 // sense, so turn off auto-remove.
9354 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9357 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9358 mLastAddedTaskActivity = null;
9360 ActivityInfo ainfo = mLastAddedTaskActivity;
9361 if (ainfo == null) {
9362 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9363 comp, 0, UserHandle.getUserId(callingUid));
9364 if (ainfo.applicationInfo.uid != callingUid) {
9365 throw new SecurityException(
9366 "Can't add task for another application: target uid="
9367 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9371 // Use the full screen as the context for the task thumbnail
9372 final Point displaySize = new Point();
9373 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9374 r.task.stack.getDisplaySize(displaySize);
9375 thumbnailInfo.taskWidth = displaySize.x;
9376 thumbnailInfo.taskHeight = displaySize.y;
9377 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9379 TaskRecord task = new TaskRecord(this,
9380 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9381 ainfo, intent, description, thumbnailInfo);
9383 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9385 // If this would have caused a trim, then we'll abort because that
9386 // means it would be added at the end of the list but then just removed.
9387 return INVALID_TASK_ID;
9390 final int N = mRecentTasks.size();
9391 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9392 final TaskRecord tr = mRecentTasks.remove(N - 1);
9393 tr.removedFromRecents();
9396 task.inRecents = true;
9397 mRecentTasks.add(task);
9398 r.task.stack.addTask(task, false, "addAppTask");
9400 task.setLastThumbnailLocked(thumbnail);
9401 task.freeLastThumbnail();
9406 Binder.restoreCallingIdentity(callingIdent);
9411 public Point getAppTaskThumbnailSize() {
9412 synchronized (this) {
9413 return new Point(mThumbnailWidth, mThumbnailHeight);
9418 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9419 synchronized (this) {
9420 ActivityRecord r = ActivityRecord.isInStackLocked(token);
9422 r.setTaskDescription(td);
9423 r.task.updateTaskDescription();
9429 public void setTaskResizeable(int taskId, int resizeableMode) {
9430 synchronized (this) {
9431 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9432 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9434 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9437 if (task.mResizeMode != resizeableMode) {
9438 task.mResizeMode = resizeableMode;
9439 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9440 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9441 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9447 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9448 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9449 long ident = Binder.clearCallingIdentity();
9451 synchronized (this) {
9452 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9454 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9457 int stackId = task.stack.mStackId;
9458 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9459 // in crop windows resize mode or if the task size is affected by the docked stack
9460 // changing size. No need to update configuration.
9461 if (bounds != null && task.inCropWindowsResizeMode()
9462 && mStackSupervisor.isStackDockedInEffect(stackId)) {
9463 mWindowManager.scrollTask(task.taskId, bounds);
9467 // Place the task in the right stack if it isn't there already based on
9468 // the requested bounds.
9469 // The stack transition logic is:
9470 // - a null bounds on a freeform task moves that task to fullscreen
9471 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9472 // that task to freeform
9473 // - otherwise the task is not moved
9474 if (!StackId.isTaskResizeAllowed(stackId)) {
9475 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9477 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9478 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9479 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9480 stackId = FREEFORM_WORKSPACE_STACK_ID;
9482 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9483 if (stackId != task.stack.mStackId) {
9484 mStackSupervisor.moveTaskToStackUncheckedLocked(
9485 task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9486 preserveWindow = false;
9489 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9490 false /* deferResume */);
9493 Binder.restoreCallingIdentity(ident);
9498 public Rect getTaskBounds(int taskId) {
9499 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9500 long ident = Binder.clearCallingIdentity();
9501 Rect rect = new Rect();
9503 synchronized (this) {
9504 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9505 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9507 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9510 if (task.stack != null) {
9511 // Return the bounds from window manager since it will be adjusted for various
9512 // things like the presense of a docked stack for tasks that aren't resizeable.
9513 mWindowManager.getTaskBounds(task.taskId, rect);
9515 // Task isn't in window manager yet since it isn't associated with a stack.
9516 // Return the persist value from activity manager
9517 if (task.mBounds != null) {
9518 rect.set(task.mBounds);
9519 } else if (task.mLastNonFullscreenBounds != null) {
9520 rect.set(task.mLastNonFullscreenBounds);
9525 Binder.restoreCallingIdentity(ident);
9531 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9532 if (userId != UserHandle.getCallingUserId()) {
9533 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9534 "getTaskDescriptionIcon");
9536 final File passedIconFile = new File(filePath);
9537 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9538 passedIconFile.getName());
9539 if (!legitIconFile.getPath().equals(filePath)
9540 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9541 throw new IllegalArgumentException("Bad file path: " + filePath
9542 + " passed for userId " + userId);
9544 return mRecentTasks.getTaskDescriptionIcon(filePath);
9548 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9549 throws RemoteException {
9550 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9551 opts.getCustomInPlaceResId() == 0) {
9552 throw new IllegalArgumentException("Expected in-place ActivityOption " +
9553 "with valid animation");
9555 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9556 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9557 opts.getCustomInPlaceResId());
9558 mWindowManager.executeAppTransition();
9561 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9562 boolean removeFromRecents) {
9563 if (removeFromRecents) {
9564 mRecentTasks.remove(tr);
9565 tr.removedFromRecents();
9567 ComponentName component = tr.getBaseIntent().getComponent();
9568 if (component == null) {
9569 Slog.w(TAG, "No component for base intent of task: " + tr);
9573 // Find any running services associated with this app and stop if needed.
9574 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9580 // Determine if the process(es) for this task should be killed.
9581 final String pkg = component.getPackageName();
9582 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9583 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9584 for (int i = 0; i < pmap.size(); i++) {
9586 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9587 for (int j = 0; j < uids.size(); j++) {
9588 ProcessRecord proc = uids.valueAt(j);
9589 if (proc.userId != tr.userId) {
9590 // Don't kill process for a different user.
9593 if (proc == mHomeProcess) {
9594 // Don't kill the home process along with tasks from the same package.
9597 if (!proc.pkgList.containsKey(pkg)) {
9598 // Don't kill process that is not associated with this task.
9602 for (int k = 0; k < proc.activities.size(); k++) {
9603 TaskRecord otherTask = proc.activities.get(k).task;
9604 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9605 // Don't kill process(es) that has an activity in a different task that is
9611 if (proc.foregroundServices) {
9612 // Don't kill process(es) with foreground service.
9616 // Add process to kill list.
9617 procsToKill.add(proc);
9621 // Kill the running processes.
9622 for (int i = 0; i < procsToKill.size(); i++) {
9623 ProcessRecord pr = procsToKill.get(i);
9624 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9625 && pr.curReceiver == null) {
9626 pr.kill("remove task", true);
9628 // We delay killing processes that are not in the background or running a receiver.
9629 pr.waitingToKill = "remove task";
9634 private void removeTasksByPackageNameLocked(String packageName, int userId) {
9635 // Remove all tasks with activities in the specified package from the list of recent tasks
9636 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9637 TaskRecord tr = mRecentTasks.get(i);
9638 if (tr.userId != userId) continue;
9640 ComponentName cn = tr.intent.getComponent();
9641 if (cn != null && cn.getPackageName().equals(packageName)) {
9642 // If the package name matches, remove the task.
9643 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9648 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9651 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9652 TaskRecord tr = mRecentTasks.get(i);
9653 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9657 ComponentName cn = tr.intent.getComponent();
9658 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9659 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9660 if (sameComponent) {
9661 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9667 * Removes the task with the specified task id.
9669 * @param taskId Identifier of the task to be removed.
9670 * @param killProcess Kill any process associated with the task if possible.
9671 * @param removeFromRecents Whether to also remove the task from recents.
9672 * @return Returns true if the given task was found and removed.
9674 private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9675 boolean removeFromRecents) {
9676 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9677 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9679 tr.removeTaskActivitiesLocked();
9680 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9681 if (tr.isPersistable) {
9682 notifyTaskPersisterLocked(null, true);
9686 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9691 public void removeStack(int stackId) {
9692 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9693 if (stackId == HOME_STACK_ID) {
9694 throw new IllegalArgumentException("Removing home stack is not allowed.");
9697 synchronized (this) {
9698 final long ident = Binder.clearCallingIdentity();
9700 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9701 if (stack == null) {
9704 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9705 for (int i = tasks.size() - 1; i >= 0; i--) {
9706 removeTaskByIdLocked(
9707 tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9710 Binder.restoreCallingIdentity(ident);
9716 public boolean removeTask(int taskId) {
9717 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9718 synchronized (this) {
9719 final long ident = Binder.clearCallingIdentity();
9721 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9723 Binder.restoreCallingIdentity(ident);
9729 * TODO: Add mController hook
9732 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9733 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9735 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9736 synchronized(this) {
9737 moveTaskToFrontLocked(taskId, flags, bOptions);
9741 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9742 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9744 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9745 Binder.getCallingUid(), -1, -1, "Task to front")) {
9746 ActivityOptions.abort(options);
9749 final long origId = Binder.clearCallingIdentity();
9751 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9753 Slog.d(TAG, "Could not find task for id: "+ taskId);
9756 if (mStackSupervisor.isLockTaskModeViolation(task)) {
9757 mStackSupervisor.showLockTaskToast();
9758 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9761 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9762 if (prev != null && prev.isRecentsActivity()) {
9763 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9765 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9766 false /* forceNonResizable */);
9768 Binder.restoreCallingIdentity(origId);
9770 ActivityOptions.abort(options);
9774 * Moves an activity, and all of the other activities within the same task, to the bottom
9775 * of the history stack. The activity's order within the task is unchanged.
9777 * @param token A reference to the activity we wish to move
9778 * @param nonRoot If false then this only works if the activity is the root
9779 * of a task; if true it will work for any activity in a task.
9780 * @return Returns true if the move completed, false if not.
9783 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9784 enforceNotIsolatedCaller("moveActivityTaskToBack");
9785 synchronized(this) {
9786 final long origId = Binder.clearCallingIdentity();
9788 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9789 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9791 if (mStackSupervisor.isLockedTask(task)) {
9792 mStackSupervisor.showLockTaskToast();
9795 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9798 Binder.restoreCallingIdentity(origId);
9805 public void moveTaskBackwards(int task) {
9806 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9807 "moveTaskBackwards()");
9809 synchronized(this) {
9810 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9811 Binder.getCallingUid(), -1, -1, "Task backwards")) {
9814 final long origId = Binder.clearCallingIdentity();
9815 moveTaskBackwardsLocked(task);
9816 Binder.restoreCallingIdentity(origId);
9820 private final void moveTaskBackwardsLocked(int task) {
9821 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9825 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9826 IActivityContainerCallback callback) throws RemoteException {
9827 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9828 synchronized (this) {
9829 if (parentActivityToken == null) {
9830 throw new IllegalArgumentException("parent token must not be null");
9832 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9836 if (callback == null) {
9837 throw new IllegalArgumentException("callback must not be null");
9839 return mStackSupervisor.createVirtualActivityContainer(r, callback);
9844 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9845 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9846 synchronized (this) {
9847 mStackSupervisor.deleteActivityContainer(container);
9852 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9853 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9854 synchronized (this) {
9855 final int stackId = mStackSupervisor.getNextStackId();
9856 final ActivityStack stack =
9857 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9858 if (stack == null) {
9861 return stack.mActivityContainer;
9866 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9867 synchronized (this) {
9868 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9869 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9870 return stack.mActivityContainer.getDisplayId();
9872 return Display.DEFAULT_DISPLAY;
9877 public int getActivityStackId(IBinder token) throws RemoteException {
9878 synchronized (this) {
9879 ActivityStack stack = ActivityRecord.getStackLocked(token);
9880 if (stack == null) {
9881 return INVALID_STACK_ID;
9883 return stack.mStackId;
9888 public void exitFreeformMode(IBinder token) throws RemoteException {
9889 synchronized (this) {
9890 long ident = Binder.clearCallingIdentity();
9892 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9894 throw new IllegalArgumentException(
9895 "exitFreeformMode: No activity record matching token=" + token);
9897 final ActivityStack stack = r.getStackLocked(token);
9898 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9899 throw new IllegalStateException(
9900 "exitFreeformMode: You can only go fullscreen from freeform.");
9902 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9903 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9904 ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9906 Binder.restoreCallingIdentity(ident);
9912 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9913 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9914 if (stackId == HOME_STACK_ID) {
9915 throw new IllegalArgumentException(
9916 "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9918 synchronized (this) {
9919 long ident = Binder.clearCallingIdentity();
9921 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9922 + " to stackId=" + stackId + " toTop=" + toTop);
9923 if (stackId == DOCKED_STACK_ID) {
9924 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9925 null /* initialBounds */);
9927 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9928 !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9929 if (result && stackId == DOCKED_STACK_ID) {
9930 // If task moved to docked stack - show recents if needed.
9931 mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9932 "moveTaskToDockedStack");
9935 Binder.restoreCallingIdentity(ident);
9941 public void swapDockedAndFullscreenStack() throws RemoteException {
9942 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9943 synchronized (this) {
9944 long ident = Binder.clearCallingIdentity();
9946 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9947 FULLSCREEN_WORKSPACE_STACK_ID);
9948 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9950 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9951 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9953 if (topTask == null || tasks == null || tasks.size() == 0) {
9955 "Unable to swap tasks, either docked or fullscreen stack is empty.");
9959 // TODO: App transition
9960 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9962 // Defer the resume so resume/pausing while moving stacks is dangerous.
9963 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9964 false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9965 ANIMATE, true /* deferResume */);
9966 final int size = tasks.size();
9967 for (int i = 0; i < size; i++) {
9968 final int id = tasks.get(i).taskId;
9969 if (id == topTask.taskId) {
9972 mStackSupervisor.moveTaskToStackLocked(id,
9973 FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9974 "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9977 // Because we deferred the resume, to avoid conflicts with stack switches while
9978 // resuming, we need to do it after all the tasks are moved.
9979 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9980 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9982 mWindowManager.executeAppTransition();
9984 Binder.restoreCallingIdentity(ident);
9990 * Moves the input task to the docked stack.
9992 * @param taskId Id of task to move.
9993 * @param createMode The mode the docked stack should be created in if it doesn't exist
9995 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9997 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9998 * @param toTop If the task and stack should be moved to the top.
9999 * @param animate Whether we should play an animation for the moving the task
10000 * @param initialBounds If the docked stack gets created, it will use these bounds for the
10001 * docked stack. Pass {@code null} to use default bounds.
10004 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
10005 Rect initialBounds, boolean moveHomeStackFront) {
10006 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
10007 synchronized (this) {
10008 long ident = Binder.clearCallingIdentity();
10010 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
10011 + " to createMode=" + createMode + " toTop=" + toTop);
10012 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10013 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10014 taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10015 animate, DEFER_RESUME);
10017 if (moveHomeStackFront) {
10018 mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10020 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10024 Binder.restoreCallingIdentity(ident);
10030 * Moves the top activity in the input stackId to the pinned stack.
10032 * @param stackId Id of stack to move the top activity to pinned stack.
10033 * @param bounds Bounds to use for pinned stack.
10035 * @return True if the top activity of the input stack was successfully moved to the pinned
10039 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10040 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10041 synchronized (this) {
10042 if (!mSupportsPictureInPicture) {
10043 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10044 + "Device doesn't support picture-in-pciture mode");
10047 long ident = Binder.clearCallingIdentity();
10049 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10051 Binder.restoreCallingIdentity(ident);
10057 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10058 boolean preserveWindows, boolean animate, int animationDuration) {
10059 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10060 long ident = Binder.clearCallingIdentity();
10062 synchronized (this) {
10064 if (stackId == PINNED_STACK_ID) {
10065 mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10067 throw new IllegalArgumentException("Stack: " + stackId
10068 + " doesn't support animated resize.");
10071 mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10072 null /* tempTaskInsetBounds */, preserveWindows,
10073 allowResizeInDockedMode, !DEFER_RESUME);
10077 Binder.restoreCallingIdentity(ident);
10082 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10083 Rect tempDockedTaskInsetBounds,
10084 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10085 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10086 "resizeDockedStack()");
10087 long ident = Binder.clearCallingIdentity();
10089 synchronized (this) {
10090 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10091 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10095 Binder.restoreCallingIdentity(ident);
10100 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10101 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10102 "resizePinnedStack()");
10103 final long ident = Binder.clearCallingIdentity();
10105 synchronized (this) {
10106 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10109 Binder.restoreCallingIdentity(ident);
10114 public void positionTaskInStack(int taskId, int stackId, int position) {
10115 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10116 if (stackId == HOME_STACK_ID) {
10117 throw new IllegalArgumentException(
10118 "positionTaskInStack: Attempt to change the position of task "
10119 + taskId + " in/to home stack");
10121 synchronized (this) {
10122 long ident = Binder.clearCallingIdentity();
10124 if (DEBUG_STACK) Slog.d(TAG_STACK,
10125 "positionTaskInStack: positioning task=" + taskId
10126 + " in stackId=" + stackId + " at position=" + position);
10127 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10129 Binder.restoreCallingIdentity(ident);
10135 public List<StackInfo> getAllStackInfos() {
10136 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10137 long ident = Binder.clearCallingIdentity();
10139 synchronized (this) {
10140 return mStackSupervisor.getAllStackInfosLocked();
10143 Binder.restoreCallingIdentity(ident);
10148 public StackInfo getStackInfo(int stackId) {
10149 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10150 long ident = Binder.clearCallingIdentity();
10152 synchronized (this) {
10153 return mStackSupervisor.getStackInfoLocked(stackId);
10156 Binder.restoreCallingIdentity(ident);
10161 public boolean isInHomeStack(int taskId) {
10162 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10163 long ident = Binder.clearCallingIdentity();
10165 synchronized (this) {
10166 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10167 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10168 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10171 Binder.restoreCallingIdentity(ident);
10176 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10177 synchronized(this) {
10178 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10183 public void updateDeviceOwner(String packageName) {
10184 final int callingUid = Binder.getCallingUid();
10185 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10186 throw new SecurityException("updateDeviceOwner called from non-system process");
10188 synchronized (this) {
10189 mDeviceOwnerName = packageName;
10194 public void updateLockTaskPackages(int userId, String[] packages) {
10195 final int callingUid = Binder.getCallingUid();
10196 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10197 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10198 "updateLockTaskPackages()");
10200 synchronized (this) {
10201 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10202 Arrays.toString(packages));
10203 mLockTaskPackages.put(userId, packages);
10204 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10209 void startLockTaskModeLocked(TaskRecord task) {
10210 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10211 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10215 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10216 // is initiated by system after the pinning request was shown and locked mode is initiated
10217 // by an authorized app directly
10218 final int callingUid = Binder.getCallingUid();
10219 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10220 long ident = Binder.clearCallingIdentity();
10222 if (!isSystemInitiated) {
10223 task.mLockTaskUid = callingUid;
10224 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10225 // startLockTask() called by app and task mode is lockTaskModeDefault.
10226 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10227 StatusBarManagerInternal statusBarManager =
10228 LocalServices.getService(StatusBarManagerInternal.class);
10229 if (statusBarManager != null) {
10230 statusBarManager.showScreenPinningRequest(task.taskId);
10235 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10236 if (stack == null || task != stack.topTask()) {
10237 throw new IllegalArgumentException("Invalid task, not in foreground");
10240 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10242 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10243 ActivityManager.LOCK_TASK_MODE_PINNED :
10244 ActivityManager.LOCK_TASK_MODE_LOCKED,
10245 "startLockTask", true);
10247 Binder.restoreCallingIdentity(ident);
10252 public void startLockTaskMode(int taskId) {
10253 synchronized (this) {
10254 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10255 if (task != null) {
10256 startLockTaskModeLocked(task);
10262 public void startLockTaskMode(IBinder token) {
10263 synchronized (this) {
10264 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10268 final TaskRecord task = r.task;
10269 if (task != null) {
10270 startLockTaskModeLocked(task);
10276 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10277 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10278 // This makes inner call to look as if it was initiated by system.
10279 long ident = Binder.clearCallingIdentity();
10281 synchronized (this) {
10282 startLockTaskMode(taskId);
10285 Binder.restoreCallingIdentity(ident);
10290 public void stopLockTaskMode() {
10291 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10292 if (lockTask == null) {
10293 // Our work here is done.
10297 final int callingUid = Binder.getCallingUid();
10298 final int lockTaskUid = lockTask.mLockTaskUid;
10299 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10300 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10304 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10305 // It is possible lockTaskMode was started by the system process because
10306 // android:lockTaskMode is set to a locking value in the application manifest
10307 // instead of the app calling startLockTaskMode. In this case
10308 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10309 // {@link TaskRecord.effectiveUid} instead. Also caller with
10310 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10311 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10312 && callingUid != lockTaskUid
10313 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10314 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10315 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10318 long ident = Binder.clearCallingIdentity();
10320 Log.d(TAG, "stopLockTaskMode");
10322 synchronized (this) {
10323 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10324 "stopLockTask", true);
10326 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10328 tm.showInCallScreen(false);
10331 Binder.restoreCallingIdentity(ident);
10336 * This API should be called by SystemUI only when user perform certain action to dismiss
10337 * lock task mode. We should only dismiss pinned lock task mode in this case.
10340 public void stopSystemLockTaskMode() throws RemoteException {
10341 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10342 stopLockTaskMode();
10344 mStackSupervisor.showLockTaskToast();
10349 public boolean isInLockTaskMode() {
10350 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10354 public int getLockTaskModeState() {
10355 synchronized (this) {
10356 return mStackSupervisor.getLockTaskModeState();
10361 public void showLockTaskEscapeMessage(IBinder token) {
10362 synchronized (this) {
10363 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10367 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10371 // =========================================================
10372 // CONTENT PROVIDERS
10373 // =========================================================
10375 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10376 List<ProviderInfo> providers = null;
10378 providers = AppGlobals.getPackageManager()
10379 .queryContentProviders(app.processName, app.uid,
10380 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10381 | MATCH_DEBUG_TRIAGED_MISSING)
10383 } catch (RemoteException ex) {
10385 if (DEBUG_MU) Slog.v(TAG_MU,
10386 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10387 int userId = app.userId;
10388 if (providers != null) {
10389 int N = providers.size();
10390 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10391 for (int i=0; i<N; i++) {
10392 // TODO: keep logic in sync with installEncryptionUnawareProviders
10394 (ProviderInfo)providers.get(i);
10395 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10396 cpi.name, cpi.flags);
10397 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10398 // This is a singleton provider, but a user besides the
10399 // default user is asking to initialize a process it runs
10400 // in... well, no, it doesn't actually run in this process,
10401 // it runs in the process of the default user. Get rid of it.
10402 providers.remove(i);
10408 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10409 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10411 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10412 mProviderMap.putProviderByClass(comp, cpr);
10414 if (DEBUG_MU) Slog.v(TAG_MU,
10415 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10416 app.pubProviders.put(cpi.name, cpr);
10417 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10418 // Don't add this if it is a platform component that is marked
10419 // to run in multiple processes, because this is actually
10420 // part of the framework so doesn't make sense to track as a
10421 // separate apk in the process.
10422 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10425 notifyPackageUse(cpi.applicationInfo.packageName,
10426 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10433 * Check if the calling UID has a possible chance at accessing the provider
10434 * at the given authority and user.
10436 public String checkContentProviderAccess(String authority, int userId) {
10437 if (userId == UserHandle.USER_ALL) {
10438 mContext.enforceCallingOrSelfPermission(
10439 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10440 userId = UserHandle.getCallingUserId();
10443 ProviderInfo cpi = null;
10445 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10446 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10447 | PackageManager.MATCH_DIRECT_BOOT_AWARE
10448 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10450 } catch (RemoteException ignored) {
10453 // TODO: make this an outright failure in a future platform release;
10454 // until then anonymous content notifications are unprotected
10455 //return "Failed to find provider " + authority + " for user " + userId;
10459 ProcessRecord r = null;
10460 synchronized (mPidsSelfLocked) {
10461 r = mPidsSelfLocked.get(Binder.getCallingPid());
10464 return "Failed to find PID " + Binder.getCallingPid();
10467 synchronized (this) {
10468 return checkContentProviderPermissionLocked(cpi, r, userId, true);
10473 * Check if {@link ProcessRecord} has a possible chance at accessing the
10474 * given {@link ProviderInfo}. Final permission checking is always done
10475 * in {@link ContentProvider}.
10477 private final String checkContentProviderPermissionLocked(
10478 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10479 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10480 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10481 boolean checkedGrants = false;
10483 // Looking for cross-user grants before enforcing the typical cross-users permissions
10484 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10485 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10486 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10489 checkedGrants = true;
10491 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10492 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10493 if (userId != tmpTargetUserId) {
10494 // When we actually went to determine the final targer user ID, this ended
10495 // up different than our initial check for the authority. This is because
10496 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10497 // SELF. So we need to re-check the grants again.
10498 checkedGrants = false;
10501 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10502 cpi.applicationInfo.uid, cpi.exported)
10503 == PackageManager.PERMISSION_GRANTED) {
10506 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10507 cpi.applicationInfo.uid, cpi.exported)
10508 == PackageManager.PERMISSION_GRANTED) {
10512 PathPermission[] pps = cpi.pathPermissions;
10514 int i = pps.length;
10517 PathPermission pp = pps[i];
10518 String pprperm = pp.getReadPermission();
10519 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10520 cpi.applicationInfo.uid, cpi.exported)
10521 == PackageManager.PERMISSION_GRANTED) {
10524 String ppwperm = pp.getWritePermission();
10525 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10526 cpi.applicationInfo.uid, cpi.exported)
10527 == PackageManager.PERMISSION_GRANTED) {
10532 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10537 if (!cpi.exported) {
10538 msg = "Permission Denial: opening provider " + cpi.name
10539 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10540 + ", uid=" + callingUid + ") that is not exported from uid "
10541 + cpi.applicationInfo.uid;
10543 msg = "Permission Denial: opening provider " + cpi.name
10544 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10545 + ", uid=" + callingUid + ") requires "
10546 + cpi.readPermission + " or " + cpi.writePermission;
10553 * Returns if the ContentProvider has granted a uri to callingUid
10555 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10556 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10557 if (perms != null) {
10558 for (int i=perms.size()-1; i>=0; i--) {
10559 GrantUri grantUri = perms.keyAt(i);
10560 if (grantUri.sourceUserId == userId || !checkUser) {
10561 if (matchesProvider(grantUri.uri, cpi)) {
10571 * Returns true if the uri authority is one of the authorities specified in the provider.
10573 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10574 String uriAuth = uri.getAuthority();
10575 String cpiAuth = cpi.authority;
10576 if (cpiAuth.indexOf(';') == -1) {
10577 return cpiAuth.equals(uriAuth);
10579 String[] cpiAuths = cpiAuth.split(";");
10580 int length = cpiAuths.length;
10581 for (int i = 0; i < length; i++) {
10582 if (cpiAuths[i].equals(uriAuth)) return true;
10587 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10588 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10590 for (int i=0; i<r.conProviders.size(); i++) {
10591 ContentProviderConnection conn = r.conProviders.get(i);
10592 if (conn.provider == cpr) {
10593 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10594 "Adding provider requested by "
10595 + r.processName + " from process "
10596 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10597 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10599 conn.stableCount++;
10600 conn.numStableIncs++;
10602 conn.unstableCount++;
10603 conn.numUnstableIncs++;
10608 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10610 conn.stableCount = 1;
10611 conn.numStableIncs = 1;
10613 conn.unstableCount = 1;
10614 conn.numUnstableIncs = 1;
10616 cpr.connections.add(conn);
10617 r.conProviders.add(conn);
10618 startAssociationLocked(r.uid, r.processName, r.curProcState,
10619 cpr.uid, cpr.name, cpr.info.processName);
10622 cpr.addExternalProcessHandleLocked(externalProcessToken);
10626 boolean decProviderCountLocked(ContentProviderConnection conn,
10627 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10628 if (conn != null) {
10629 cpr = conn.provider;
10630 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10631 "Removing provider requested by "
10632 + conn.client.processName + " from process "
10633 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10634 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10636 conn.stableCount--;
10638 conn.unstableCount--;
10640 if (conn.stableCount == 0 && conn.unstableCount == 0) {
10641 cpr.connections.remove(conn);
10642 conn.client.conProviders.remove(conn);
10643 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10644 // The client is more important than last activity -- note the time this
10645 // is happening, so we keep the old provider process around a bit as last
10646 // activity to avoid thrashing it.
10647 if (cpr.proc != null) {
10648 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10651 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10656 cpr.removeExternalProcessHandleLocked(externalProcessToken);
10660 private void checkTime(long startTime, String where) {
10661 long now = SystemClock.uptimeMillis();
10662 if ((now-startTime) > 50) {
10663 // If we are taking more than 50ms, log about it.
10664 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10668 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10670 PROC_SPACE_TERM|PROC_PARENS,
10671 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
10674 private final long[] mProcessStateStatsLongs = new long[1];
10676 boolean isProcessAliveLocked(ProcessRecord proc) {
10677 if (proc.procStatFile == null) {
10678 proc.procStatFile = "/proc/" + proc.pid + "/stat";
10680 mProcessStateStatsLongs[0] = 0;
10681 if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10682 mProcessStateStatsLongs, null)) {
10683 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10686 final long state = mProcessStateStatsLongs[0];
10687 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10689 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10692 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10693 String name, IBinder token, boolean stable, int userId) {
10694 ContentProviderRecord cpr;
10695 ContentProviderConnection conn = null;
10696 ProviderInfo cpi = null;
10698 synchronized(this) {
10699 long startTime = SystemClock.uptimeMillis();
10701 ProcessRecord r = null;
10702 if (caller != null) {
10703 r = getRecordForAppLocked(caller);
10705 throw new SecurityException(
10706 "Unable to find app for caller " + caller
10707 + " (pid=" + Binder.getCallingPid()
10708 + ") when getting content provider " + name);
10712 boolean checkCrossUser = true;
10714 checkTime(startTime, "getContentProviderImpl: getProviderByName");
10716 // First check if this content provider has been published...
10717 cpr = mProviderMap.getProviderByName(name, userId);
10718 // If that didn't work, check if it exists for user 0 and then
10719 // verify that it's a singleton provider before using it.
10720 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10721 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10724 if (isSingleton(cpi.processName, cpi.applicationInfo,
10725 cpi.name, cpi.flags)
10726 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10727 userId = UserHandle.USER_SYSTEM;
10728 checkCrossUser = false;
10736 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10737 if (providerRunning) {
10740 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10741 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10743 throw new SecurityException(msg);
10745 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10747 if (r != null && cpr.canRunHere(r)) {
10748 // This provider has been published or is in the process
10749 // of being published... but it is also allowed to run
10750 // in the caller's process, so don't make a connection
10751 // and just let the caller instantiate its own instance.
10752 ContentProviderHolder holder = cpr.newHolder(null);
10753 // don't give caller the provider object, it needs
10754 // to make its own.
10755 holder.provider = null;
10759 final long origId = Binder.clearCallingIdentity();
10761 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10763 // In this case the provider instance already exists, so we can
10764 // return it right away.
10765 conn = incProviderCountLocked(r, cpr, token, stable);
10766 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10767 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10768 // If this is a perceptible app accessing the provider,
10769 // make sure to count it as being accessed and thus
10770 // back up on the LRU list. This is good because
10771 // content providers are often expensive to start.
10772 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10773 updateLruProcessLocked(cpr.proc, false, null);
10774 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10778 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10779 final int verifiedAdj = cpr.proc.verifiedAdj;
10780 boolean success = updateOomAdjLocked(cpr.proc);
10781 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10782 // if the process has been successfully adjusted. So to reduce races with
10783 // it, we will check whether the process still exists. Note that this doesn't
10784 // completely get rid of races with LMK killing the process, but should make
10785 // them much smaller.
10786 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10789 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10790 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10791 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10792 // NOTE: there is still a race here where a signal could be
10793 // pending on the process even though we managed to update its
10794 // adj level. Not sure what to do about this, but at least
10795 // the race is now smaller.
10797 // Uh oh... it looks like the provider's process
10798 // has been killed on us. We need to wait for a new
10799 // process to be started, and make sure its death
10800 // doesn't kill our process.
10801 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10802 + " is crashing; detaching " + r);
10803 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10804 checkTime(startTime, "getContentProviderImpl: before appDied");
10805 appDiedLocked(cpr.proc);
10806 checkTime(startTime, "getContentProviderImpl: after appDied");
10808 // This wasn't the last ref our process had on
10809 // the provider... we have now been killed, bail.
10812 providerRunning = false;
10815 cpr.proc.verifiedAdj = cpr.proc.setAdj;
10818 Binder.restoreCallingIdentity(origId);
10821 if (!providerRunning) {
10823 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10824 cpi = AppGlobals.getPackageManager().
10825 resolveContentProvider(name,
10826 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10827 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10828 } catch (RemoteException ex) {
10833 // If the provider is a singleton AND
10834 // (it's a call within the same user || the provider is a
10836 // Then allow connecting to the singleton provider
10837 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10838 cpi.name, cpi.flags)
10839 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10841 userId = UserHandle.USER_SYSTEM;
10843 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10844 checkTime(startTime, "getContentProviderImpl: got app info for user");
10847 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10848 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10850 throw new SecurityException(msg);
10852 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10854 if (!mProcessesReady
10855 && !cpi.processName.equals("system")) {
10856 // If this content provider does not run in the system
10857 // process, and the system is not yet ready to run other
10858 // processes, then fail fast instead of hanging.
10859 throw new IllegalArgumentException(
10860 "Attempt to launch content provider before system ready");
10863 // Make sure that the user who owns this provider is running. If not,
10864 // we don't want to allow it to run.
10865 if (!mUserController.isUserRunningLocked(userId, 0)) {
10866 Slog.w(TAG, "Unable to launch app "
10867 + cpi.applicationInfo.packageName + "/"
10868 + cpi.applicationInfo.uid + " for provider "
10869 + name + ": user " + userId + " is stopped");
10873 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10874 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10875 cpr = mProviderMap.getProviderByClass(comp, userId);
10876 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10877 final boolean firstClass = cpr == null;
10879 final long ident = Binder.clearCallingIdentity();
10881 // If permissions need a review before any of the app components can run,
10882 // we return no provider and launch a review activity if the calling app
10883 // is in the foreground.
10884 if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10885 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10891 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10892 ApplicationInfo ai =
10893 AppGlobals.getPackageManager().
10894 getApplicationInfo(
10895 cpi.applicationInfo.packageName,
10896 STOCK_PM_FLAGS, userId);
10897 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10899 Slog.w(TAG, "No package info for content provider "
10903 ai = getAppInfoForUser(ai, userId);
10904 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10905 } catch (RemoteException ex) {
10906 // pm is in same process, this will never happen.
10908 Binder.restoreCallingIdentity(ident);
10912 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10914 if (r != null && cpr.canRunHere(r)) {
10915 // If this is a multiprocess provider, then just return its
10916 // info and allow the caller to instantiate it. Only do
10917 // this if the provider is the same user as the caller's
10918 // process, or can run as root (so can be in any process).
10919 return cpr.newHolder(null);
10922 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10923 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10924 + cpr.info.name + " callers=" + Debug.getCallers(6));
10926 // This is single process, and our app is now connecting to it.
10927 // See if we are already in the process of launching this
10929 final int N = mLaunchingProviders.size();
10931 for (i = 0; i < N; i++) {
10932 if (mLaunchingProviders.get(i) == cpr) {
10937 // If the provider is not already being launched, then get it
10940 final long origId = Binder.clearCallingIdentity();
10943 // Content provider is now in use, its package can't be stopped.
10945 checkTime(startTime, "getContentProviderImpl: before set stopped state");
10946 AppGlobals.getPackageManager().setPackageStoppedState(
10947 cpr.appInfo.packageName, false, userId);
10948 checkTime(startTime, "getContentProviderImpl: after set stopped state");
10949 } catch (RemoteException e) {
10950 } catch (IllegalArgumentException e) {
10951 Slog.w(TAG, "Failed trying to unstop package "
10952 + cpr.appInfo.packageName + ": " + e);
10955 // Use existing process if already started
10956 checkTime(startTime, "getContentProviderImpl: looking for process record");
10957 ProcessRecord proc = getProcessRecordLocked(
10958 cpi.processName, cpr.appInfo.uid, false);
10959 if (proc != null && proc.thread != null && !proc.killed) {
10960 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10961 "Installing in existing process " + proc);
10962 if (!proc.pubProviders.containsKey(cpi.name)) {
10963 checkTime(startTime, "getContentProviderImpl: scheduling install");
10964 proc.pubProviders.put(cpi.name, cpr);
10966 proc.thread.scheduleInstallProvider(cpi);
10967 } catch (RemoteException e) {
10971 checkTime(startTime, "getContentProviderImpl: before start process");
10972 proc = startProcessLocked(cpi.processName,
10973 cpr.appInfo, false, 0, "content provider",
10974 new ComponentName(cpi.applicationInfo.packageName,
10975 cpi.name), false, false, false);
10976 checkTime(startTime, "getContentProviderImpl: after start process");
10977 if (proc == null) {
10978 Slog.w(TAG, "Unable to launch app "
10979 + cpi.applicationInfo.packageName + "/"
10980 + cpi.applicationInfo.uid + " for provider "
10981 + name + ": process is bad");
10985 cpr.launchingApp = proc;
10986 mLaunchingProviders.add(cpr);
10988 Binder.restoreCallingIdentity(origId);
10992 checkTime(startTime, "getContentProviderImpl: updating data structures");
10994 // Make sure the provider is published (the same provider class
10995 // may be published under multiple names).
10997 mProviderMap.putProviderByClass(comp, cpr);
11000 mProviderMap.putProviderByName(name, cpr);
11001 conn = incProviderCountLocked(r, cpr, token, stable);
11002 if (conn != null) {
11003 conn.waiting = true;
11006 checkTime(startTime, "getContentProviderImpl: done!");
11009 // Wait for the provider to be published...
11010 synchronized (cpr) {
11011 while (cpr.provider == null) {
11012 if (cpr.launchingApp == null) {
11013 Slog.w(TAG, "Unable to launch app "
11014 + cpi.applicationInfo.packageName + "/"
11015 + cpi.applicationInfo.uid + " for provider "
11016 + name + ": launching app became null");
11017 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11018 UserHandle.getUserId(cpi.applicationInfo.uid),
11019 cpi.applicationInfo.packageName,
11020 cpi.applicationInfo.uid, name);
11024 if (DEBUG_MU) Slog.v(TAG_MU,
11025 "Waiting to start provider " + cpr
11026 + " launchingApp=" + cpr.launchingApp);
11027 if (conn != null) {
11028 conn.waiting = true;
11031 } catch (InterruptedException ex) {
11033 if (conn != null) {
11034 conn.waiting = false;
11039 return cpr != null ? cpr.newHolder(conn) : null;
11042 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11043 ProcessRecord r, final int userId) {
11044 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11045 cpi.packageName, userId)) {
11047 final boolean callerForeground = r == null || r.setSchedGroup
11048 != ProcessList.SCHED_GROUP_BACKGROUND;
11050 // Show a permission review UI only for starting from a foreground app
11051 if (!callerForeground) {
11052 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11053 + cpi.packageName + " requires a permissions review");
11057 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11058 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11059 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11060 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11062 if (DEBUG_PERMISSIONS_REVIEW) {
11063 Slog.i(TAG, "u" + userId + " Launching permission review "
11064 + "for package " + cpi.packageName);
11067 final UserHandle userHandle = new UserHandle(userId);
11068 mHandler.post(new Runnable() {
11070 public void run() {
11071 mContext.startActivityAsUser(intent, userHandle);
11081 PackageManagerInternal getPackageManagerInternalLocked() {
11082 if (mPackageManagerInt == null) {
11083 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11085 return mPackageManagerInt;
11089 public final ContentProviderHolder getContentProvider(
11090 IApplicationThread caller, String name, int userId, boolean stable) {
11091 enforceNotIsolatedCaller("getContentProvider");
11092 if (caller == null) {
11093 String msg = "null IApplicationThread when getting content provider "
11096 throw new SecurityException(msg);
11098 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11099 // with cross-user grant.
11100 return getContentProviderImpl(caller, name, null, stable, userId);
11103 public ContentProviderHolder getContentProviderExternal(
11104 String name, int userId, IBinder token) {
11105 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11106 "Do not have permission in call getContentProviderExternal()");
11107 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11108 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11109 return getContentProviderExternalUnchecked(name, token, userId);
11112 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11113 IBinder token, int userId) {
11114 return getContentProviderImpl(null, name, token, true, userId);
11118 * Drop a content provider from a ProcessRecord's bookkeeping
11120 public void removeContentProvider(IBinder connection, boolean stable) {
11121 enforceNotIsolatedCaller("removeContentProvider");
11122 long ident = Binder.clearCallingIdentity();
11124 synchronized (this) {
11125 ContentProviderConnection conn;
11127 conn = (ContentProviderConnection)connection;
11128 } catch (ClassCastException e) {
11129 String msg ="removeContentProvider: " + connection
11130 + " not a ContentProviderConnection";
11132 throw new IllegalArgumentException(msg);
11134 if (conn == null) {
11135 throw new NullPointerException("connection is null");
11137 if (decProviderCountLocked(conn, null, null, stable)) {
11138 updateOomAdjLocked();
11142 Binder.restoreCallingIdentity(ident);
11146 public void removeContentProviderExternal(String name, IBinder token) {
11147 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11148 "Do not have permission in call removeContentProviderExternal()");
11149 int userId = UserHandle.getCallingUserId();
11150 long ident = Binder.clearCallingIdentity();
11152 removeContentProviderExternalUnchecked(name, token, userId);
11154 Binder.restoreCallingIdentity(ident);
11158 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11159 synchronized (this) {
11160 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11162 //remove from mProvidersByClass
11163 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11167 //update content provider record entry info
11168 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11169 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11170 if (localCpr.hasExternalProcessHandles()) {
11171 if (localCpr.removeExternalProcessHandleLocked(token)) {
11172 updateOomAdjLocked();
11174 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11175 + " with no external reference for token: "
11179 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11180 + " with no external references.");
11185 public final void publishContentProviders(IApplicationThread caller,
11186 List<ContentProviderHolder> providers) {
11187 if (providers == null) {
11191 enforceNotIsolatedCaller("publishContentProviders");
11192 synchronized (this) {
11193 final ProcessRecord r = getRecordForAppLocked(caller);
11194 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11196 throw new SecurityException(
11197 "Unable to find app for caller " + caller
11198 + " (pid=" + Binder.getCallingPid()
11199 + ") when publishing content providers");
11202 final long origId = Binder.clearCallingIdentity();
11204 final int N = providers.size();
11205 for (int i = 0; i < N; i++) {
11206 ContentProviderHolder src = providers.get(i);
11207 if (src == null || src.info == null || src.provider == null) {
11210 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11211 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11213 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11214 mProviderMap.putProviderByClass(comp, dst);
11215 String names[] = dst.info.authority.split(";");
11216 for (int j = 0; j < names.length; j++) {
11217 mProviderMap.putProviderByName(names[j], dst);
11220 int launchingCount = mLaunchingProviders.size();
11222 boolean wasInLaunchingProviders = false;
11223 for (j = 0; j < launchingCount; j++) {
11224 if (mLaunchingProviders.get(j) == dst) {
11225 mLaunchingProviders.remove(j);
11226 wasInLaunchingProviders = true;
11231 if (wasInLaunchingProviders) {
11232 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11234 synchronized (dst) {
11235 dst.provider = src.provider;
11239 updateOomAdjLocked(r);
11240 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11241 src.info.authority);
11245 Binder.restoreCallingIdentity(origId);
11249 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11250 ContentProviderConnection conn;
11252 conn = (ContentProviderConnection)connection;
11253 } catch (ClassCastException e) {
11254 String msg ="refContentProvider: " + connection
11255 + " not a ContentProviderConnection";
11257 throw new IllegalArgumentException(msg);
11259 if (conn == null) {
11260 throw new NullPointerException("connection is null");
11263 synchronized (this) {
11265 conn.numStableIncs += stable;
11267 stable = conn.stableCount + stable;
11269 throw new IllegalStateException("stableCount < 0: " + stable);
11272 if (unstable > 0) {
11273 conn.numUnstableIncs += unstable;
11275 unstable = conn.unstableCount + unstable;
11276 if (unstable < 0) {
11277 throw new IllegalStateException("unstableCount < 0: " + unstable);
11280 if ((stable+unstable) <= 0) {
11281 throw new IllegalStateException("ref counts can't go to zero here: stable="
11282 + stable + " unstable=" + unstable);
11284 conn.stableCount = stable;
11285 conn.unstableCount = unstable;
11290 public void unstableProviderDied(IBinder connection) {
11291 ContentProviderConnection conn;
11293 conn = (ContentProviderConnection)connection;
11294 } catch (ClassCastException e) {
11295 String msg ="refContentProvider: " + connection
11296 + " not a ContentProviderConnection";
11298 throw new IllegalArgumentException(msg);
11300 if (conn == null) {
11301 throw new NullPointerException("connection is null");
11304 // Safely retrieve the content provider associated with the connection.
11305 IContentProvider provider;
11306 synchronized (this) {
11307 provider = conn.provider.provider;
11310 if (provider == null) {
11311 // Um, yeah, we're way ahead of you.
11315 // Make sure the caller is being honest with us.
11316 if (provider.asBinder().pingBinder()) {
11317 // Er, no, still looks good to us.
11318 synchronized (this) {
11319 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11320 + " says " + conn + " died, but we don't agree");
11325 // Well look at that! It's dead!
11326 synchronized (this) {
11327 if (conn.provider.provider != provider) {
11328 // But something changed... good enough.
11332 ProcessRecord proc = conn.provider.proc;
11333 if (proc == null || proc.thread == null) {
11334 // Seems like the process is already cleaned up.
11338 // As far as we're concerned, this is just like receiving a
11339 // death notification... just a bit prematurely.
11340 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11341 + ") early provider death");
11342 final long ident = Binder.clearCallingIdentity();
11344 appDiedLocked(proc);
11346 Binder.restoreCallingIdentity(ident);
11352 public void appNotRespondingViaProvider(IBinder connection) {
11353 enforceCallingPermission(
11354 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11356 final ContentProviderConnection conn = (ContentProviderConnection) connection;
11357 if (conn == null) {
11358 Slog.w(TAG, "ContentProviderConnection is null");
11362 final ProcessRecord host = conn.provider.proc;
11363 if (host == null) {
11364 Slog.w(TAG, "Failed to find hosting ProcessRecord");
11368 mHandler.post(new Runnable() {
11370 public void run() {
11371 mAppErrors.appNotResponding(host, null, null, false,
11372 "ContentProvider not responding");
11377 public final void installSystemProviders() {
11378 List<ProviderInfo> providers;
11379 synchronized (this) {
11380 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11381 providers = generateApplicationProvidersLocked(app);
11382 if (providers != null) {
11383 for (int i=providers.size()-1; i>=0; i--) {
11384 ProviderInfo pi = (ProviderInfo)providers.get(i);
11385 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11386 Slog.w(TAG, "Not installing system proc provider " + pi.name
11387 + ": not system .apk");
11388 providers.remove(i);
11393 if (providers != null) {
11394 mSystemThread.installSystemProviders(providers);
11397 mCoreSettingsObserver = new CoreSettingsObserver(this);
11398 mFontScaleSettingObserver = new FontScaleSettingObserver();
11400 //mUsageStatsService.monitorPackages();
11403 private void startPersistentApps(int matchFlags) {
11404 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11406 synchronized (this) {
11408 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11409 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11410 for (ApplicationInfo app : apps) {
11411 if (!"android".equals(app.packageName)) {
11412 addAppLocked(app, false, null /* ABI override */);
11415 } catch (RemoteException ex) {
11421 * When a user is unlocked, we need to install encryption-unaware providers
11422 * belonging to any running apps.
11424 private void installEncryptionUnawareProviders(int userId) {
11425 // We're only interested in providers that are encryption unaware, and
11426 // we don't care about uninstalled apps, since there's no way they're
11427 // running at this point.
11428 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11430 synchronized (this) {
11431 final int NP = mProcessNames.getMap().size();
11432 for (int ip = 0; ip < NP; ip++) {
11433 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11434 final int NA = apps.size();
11435 for (int ia = 0; ia < NA; ia++) {
11436 final ProcessRecord app = apps.valueAt(ia);
11437 if (app.userId != userId || app.thread == null || app.unlocked) continue;
11439 final int NG = app.pkgList.size();
11440 for (int ig = 0; ig < NG; ig++) {
11442 final String pkgName = app.pkgList.keyAt(ig);
11443 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11444 .getPackageInfo(pkgName, matchFlags, userId);
11445 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11446 for (ProviderInfo pi : pkgInfo.providers) {
11447 // TODO: keep in sync with generateApplicationProvidersLocked
11448 final boolean processMatch = Objects.equals(pi.processName,
11449 app.processName) || pi.multiprocess;
11450 final boolean userMatch = isSingleton(pi.processName,
11451 pi.applicationInfo, pi.name, pi.flags)
11452 ? (app.userId == UserHandle.USER_SYSTEM) : true;
11453 if (processMatch && userMatch) {
11454 Log.v(TAG, "Installing " + pi);
11455 app.thread.scheduleInstallProvider(pi);
11457 Log.v(TAG, "Skipping " + pi);
11461 } catch (RemoteException ignored) {
11470 * Allows apps to retrieve the MIME type of a URI.
11471 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11472 * users, then it does not need permission to access the ContentProvider.
11473 * Either, it needs cross-user uri grants.
11475 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11477 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11478 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11480 public String getProviderMimeType(Uri uri, int userId) {
11481 enforceNotIsolatedCaller("getProviderMimeType");
11482 final String name = uri.getAuthority();
11483 int callingUid = Binder.getCallingUid();
11484 int callingPid = Binder.getCallingPid();
11486 boolean clearedIdentity = false;
11487 synchronized (this) {
11488 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11490 if (canClearIdentity(callingPid, callingUid, userId)) {
11491 clearedIdentity = true;
11492 ident = Binder.clearCallingIdentity();
11494 ContentProviderHolder holder = null;
11496 holder = getContentProviderExternalUnchecked(name, null, userId);
11497 if (holder != null) {
11498 return holder.provider.getType(uri);
11500 } catch (RemoteException e) {
11501 Log.w(TAG, "Content provider dead retrieving " + uri, e);
11503 } catch (Exception e) {
11504 Log.w(TAG, "Exception while determining type of " + uri, e);
11507 // We need to clear the identity to call removeContentProviderExternalUnchecked
11508 if (!clearedIdentity) {
11509 ident = Binder.clearCallingIdentity();
11512 if (holder != null) {
11513 removeContentProviderExternalUnchecked(name, null, userId);
11516 Binder.restoreCallingIdentity(ident);
11523 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11524 if (UserHandle.getUserId(callingUid) == userId) {
11527 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11528 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11529 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11530 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11536 // =========================================================
11537 // GLOBAL MANAGEMENT
11538 // =========================================================
11540 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11541 boolean isolated, int isolatedUid) {
11542 String proc = customProcess != null ? customProcess : info.processName;
11543 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11544 final int userId = UserHandle.getUserId(info.uid);
11545 int uid = info.uid;
11547 if (isolatedUid == 0) {
11548 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11550 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11551 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11552 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11554 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11555 mNextIsolatedProcessUid++;
11556 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11557 // No process for this uid, use it.
11561 if (stepsLeft <= 0) {
11566 // Special case for startIsolatedProcess (internal only), where
11567 // the uid of the isolated process is specified by the caller.
11571 // Register the isolated UID with this application so BatteryStats knows to
11572 // attribute resource usage to the application.
11574 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11575 // about the process state of the isolated UID *before* it is registered with the
11576 // owning application.
11577 mBatteryStatsService.addIsolatedUid(uid, info.uid);
11579 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11580 if (!mBooted && !mBooting
11581 && userId == UserHandle.USER_SYSTEM
11582 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11583 r.persistent = true;
11585 addProcessNameLocked(r);
11589 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11590 String abiOverride) {
11593 app = getProcessRecordLocked(info.processName, info.uid, true);
11599 app = newProcessRecordLocked(info, null, isolated, 0);
11600 updateLruProcessLocked(app, false, null);
11601 updateOomAdjLocked();
11604 // This package really, really can not be stopped.
11606 AppGlobals.getPackageManager().setPackageStoppedState(
11607 info.packageName, false, UserHandle.getUserId(app.uid));
11608 } catch (RemoteException e) {
11609 } catch (IllegalArgumentException e) {
11610 Slog.w(TAG, "Failed trying to unstop package "
11611 + info.packageName + ": " + e);
11614 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11615 app.persistent = true;
11616 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11618 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11619 mPersistentStartingProcesses.add(app);
11620 startProcessLocked(app, "added application", app.processName, abiOverride,
11621 null /* entryPoint */, null /* entryPointArgs */);
11627 public void unhandledBack() {
11628 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11629 "unhandledBack()");
11631 synchronized(this) {
11632 final long origId = Binder.clearCallingIdentity();
11634 getFocusedStack().unhandledBackLocked();
11636 Binder.restoreCallingIdentity(origId);
11641 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11642 enforceNotIsolatedCaller("openContentUri");
11643 final int userId = UserHandle.getCallingUserId();
11644 String name = uri.getAuthority();
11645 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11646 ParcelFileDescriptor pfd = null;
11648 // We record the binder invoker's uid in thread-local storage before
11649 // going to the content provider to open the file. Later, in the code
11650 // that handles all permissions checks, we look for this uid and use
11651 // that rather than the Activity Manager's own uid. The effect is that
11652 // we do the check against the caller's permissions even though it looks
11653 // to the content provider like the Activity Manager itself is making
11655 Binder token = new Binder();
11656 sCallerIdentity.set(new Identity(
11657 token, Binder.getCallingPid(), Binder.getCallingUid()));
11659 pfd = cph.provider.openFile(null, uri, "r", null, token);
11660 } catch (FileNotFoundException e) {
11661 // do nothing; pfd will be returned null
11663 // Ensure that whatever happens, we clean up the identity state
11664 sCallerIdentity.remove();
11665 // Ensure we're done with the provider.
11666 removeContentProviderExternalUnchecked(name, null, userId);
11669 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11674 // Actually is sleeping or shutting down or whatever else in the future
11675 // is an inactive state.
11676 boolean isSleepingOrShuttingDownLocked() {
11677 return isSleepingLocked() || mShuttingDown;
11680 boolean isShuttingDownLocked() {
11681 return mShuttingDown;
11684 boolean isSleepingLocked() {
11688 void onWakefulnessChanged(int wakefulness) {
11689 synchronized(this) {
11690 mWakefulness = wakefulness;
11691 updateSleepIfNeededLocked();
11695 void finishRunningVoiceLocked() {
11696 if (mRunningVoice != null) {
11697 mRunningVoice = null;
11698 mVoiceWakeLock.release();
11699 updateSleepIfNeededLocked();
11703 void startTimeTrackingFocusedActivityLocked() {
11704 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11705 mCurAppTimeTracker.start(mFocusedActivity.packageName);
11709 void updateSleepIfNeededLocked() {
11710 if (mSleeping && !shouldSleepLocked()) {
11712 startTimeTrackingFocusedActivityLocked();
11713 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11714 mStackSupervisor.comeOutOfSleepIfNeededLocked();
11715 sendNotifyVrManagerOfSleepState(false);
11716 updateOomAdjLocked();
11717 } else if (!mSleeping && shouldSleepLocked()) {
11719 if (mCurAppTimeTracker != null) {
11720 mCurAppTimeTracker.stop();
11722 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11723 mStackSupervisor.goingToSleepLocked();
11724 sendNotifyVrManagerOfSleepState(true);
11725 updateOomAdjLocked();
11727 // Initialize the wake times of all processes.
11728 checkExcessivePowerUsageLocked(false);
11729 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11730 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11731 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11735 private boolean shouldSleepLocked() {
11736 // Resume applications while running a voice interactor.
11737 if (mRunningVoice != null) {
11741 // TODO: Transform the lock screen state into a sleep token instead.
11742 switch (mWakefulness) {
11743 case PowerManagerInternal.WAKEFULNESS_AWAKE:
11744 case PowerManagerInternal.WAKEFULNESS_DREAMING:
11745 case PowerManagerInternal.WAKEFULNESS_DOZING:
11746 // Pause applications whenever the lock screen is shown or any sleep
11747 // tokens have been acquired.
11748 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11749 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11751 // If we're asleep then pause applications unconditionally.
11756 /** Pokes the task persister. */
11757 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11758 mRecentTasks.notifyTaskPersisterLocked(task, flush);
11761 /** Notifies all listeners when the task stack has changed. */
11762 void notifyTaskStackChangedLocked() {
11763 mHandler.sendEmptyMessage(LOG_STACK_STATE);
11764 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11765 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11766 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11769 /** Notifies all listeners when an Activity is pinned. */
11770 void notifyActivityPinnedLocked() {
11771 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11772 mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11776 * Notifies all listeners when an attempt was made to start an an activity that is already
11777 * running in the pinned stack and the activity was not actually started, but the task is
11778 * either brought to the front or a new Intent is delivered to it.
11780 void notifyPinnedActivityRestartAttemptLocked() {
11781 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11782 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11785 /** Notifies all listeners when the pinned stack animation ends. */
11787 public void notifyPinnedStackAnimationEnded() {
11788 synchronized (this) {
11789 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11790 mHandler.obtainMessage(
11791 NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11796 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11797 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11801 public boolean shutdown(int timeout) {
11802 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11803 != PackageManager.PERMISSION_GRANTED) {
11804 throw new SecurityException("Requires permission "
11805 + android.Manifest.permission.SHUTDOWN);
11808 boolean timedout = false;
11810 synchronized(this) {
11811 mShuttingDown = true;
11812 updateEventDispatchingLocked();
11813 timedout = mStackSupervisor.shutdownLocked(timeout);
11816 mAppOpsService.shutdown();
11817 if (mUsageStatsService != null) {
11818 mUsageStatsService.prepareShutdown();
11820 mBatteryStatsService.shutdown();
11821 synchronized (this) {
11822 mProcessStats.shutdownLocked();
11823 notifyTaskPersisterLocked(null, true);
11829 public final void activitySlept(IBinder token) {
11830 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11832 final long origId = Binder.clearCallingIdentity();
11834 synchronized (this) {
11835 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11837 mStackSupervisor.activitySleptLocked(r);
11841 Binder.restoreCallingIdentity(origId);
11844 private String lockScreenShownToString() {
11845 switch (mLockScreenShown) {
11846 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11847 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11848 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11849 default: return "Unknown=" + mLockScreenShown;
11853 void logLockScreen(String msg) {
11854 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11855 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11856 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11857 + " mSleeping=" + mSleeping);
11860 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11861 Slog.d(TAG, "<<< startRunningVoiceLocked()");
11862 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11863 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11864 boolean wasRunningVoice = mRunningVoice != null;
11865 mRunningVoice = session;
11866 if (!wasRunningVoice) {
11867 mVoiceWakeLock.acquire();
11868 updateSleepIfNeededLocked();
11873 private void updateEventDispatchingLocked() {
11874 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11877 public void setLockScreenShown(boolean showing, boolean occluded) {
11878 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11879 != PackageManager.PERMISSION_GRANTED) {
11880 throw new SecurityException("Requires permission "
11881 + android.Manifest.permission.DEVICE_POWER);
11884 synchronized(this) {
11885 long ident = Binder.clearCallingIdentity();
11887 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11888 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11889 if (showing && occluded) {
11890 // The lock screen is currently showing, but is occluded by a window that can
11891 // show on top of the lock screen. In this can we want to dismiss the docked
11892 // stack since it will be complicated/risky to try to put the activity on top
11893 // of the lock screen in the right fullscreen configuration.
11894 mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11895 mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11898 updateSleepIfNeededLocked();
11900 Binder.restoreCallingIdentity(ident);
11906 public void notifyLockedProfile(@UserIdInt int userId) {
11908 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11909 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11911 } catch (RemoteException ex) {
11912 throw new SecurityException("Fail to check is caller a privileged app", ex);
11915 synchronized (this) {
11916 if (mStackSupervisor.isUserLockedProfile(userId)) {
11917 final long ident = Binder.clearCallingIdentity();
11919 final int currentUserId = mUserController.getCurrentUserIdLocked();
11921 // Drop locked freeform tasks out into the fullscreen stack.
11922 // TODO: Redact the tasks in place. It's much better to keep them on the screen
11923 // where they were before, but in an obscured state.
11924 mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11926 if (mUserController.isLockScreenDisabled(currentUserId)) {
11927 // If there is no device lock, we will show the profile's credential page.
11928 mActivityStarter.showConfirmDeviceCredential(userId);
11930 // Showing launcher to avoid user entering credential twice.
11931 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11934 Binder.restoreCallingIdentity(ident);
11941 public void startConfirmDeviceCredentialIntent(Intent intent) {
11942 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11943 synchronized (this) {
11944 final long ident = Binder.clearCallingIdentity();
11946 mActivityStarter.startConfirmCredentialIntent(intent);
11948 Binder.restoreCallingIdentity(ident);
11954 public void stopAppSwitches() {
11955 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11956 != PackageManager.PERMISSION_GRANTED) {
11957 throw new SecurityException("viewquires permission "
11958 + android.Manifest.permission.STOP_APP_SWITCHES);
11961 synchronized(this) {
11962 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11963 + APP_SWITCH_DELAY_TIME;
11964 mDidAppSwitch = false;
11965 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11966 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11967 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11971 public void resumeAppSwitches() {
11972 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11973 != PackageManager.PERMISSION_GRANTED) {
11974 throw new SecurityException("Requires permission "
11975 + android.Manifest.permission.STOP_APP_SWITCHES);
11978 synchronized(this) {
11979 // Note that we don't execute any pending app switches... we will
11980 // let those wait until either the timeout, or the next start
11981 // activity request.
11982 mAppSwitchesAllowedTime = 0;
11986 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11987 int callingPid, int callingUid, String name) {
11988 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11992 int perm = checkComponentPermission(
11993 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11994 sourceUid, -1, true);
11995 if (perm == PackageManager.PERMISSION_GRANTED) {
11999 // If the actual IPC caller is different from the logical source, then
12000 // also see if they are allowed to control app switches.
12001 if (callingUid != -1 && callingUid != sourceUid) {
12002 perm = checkComponentPermission(
12003 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
12004 callingUid, -1, true);
12005 if (perm == PackageManager.PERMISSION_GRANTED) {
12010 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
12014 public void setDebugApp(String packageName, boolean waitForDebugger,
12015 boolean persistent) {
12016 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12019 long ident = Binder.clearCallingIdentity();
12021 // Note that this is not really thread safe if there are multiple
12022 // callers into it at the same time, but that's not a situation we
12025 final ContentResolver resolver = mContext.getContentResolver();
12026 Settings.Global.putString(
12027 resolver, Settings.Global.DEBUG_APP,
12029 Settings.Global.putInt(
12030 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12031 waitForDebugger ? 1 : 0);
12034 synchronized (this) {
12036 mOrigDebugApp = mDebugApp;
12037 mOrigWaitForDebugger = mWaitForDebugger;
12039 mDebugApp = packageName;
12040 mWaitForDebugger = waitForDebugger;
12041 mDebugTransient = !persistent;
12042 if (packageName != null) {
12043 forceStopPackageLocked(packageName, -1, false, false, true, true,
12044 false, UserHandle.USER_ALL, "set debug app");
12048 Binder.restoreCallingIdentity(ident);
12052 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12053 synchronized (this) {
12054 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12055 if (!isDebuggable) {
12056 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12057 throw new SecurityException("Process not debuggable: " + app.packageName);
12061 mTrackAllocationApp = processName;
12065 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12066 synchronized (this) {
12067 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12068 if (!isDebuggable) {
12069 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12070 throw new SecurityException("Process not debuggable: " + app.packageName);
12073 mProfileApp = processName;
12074 mProfileFile = profilerInfo.profileFile;
12075 if (mProfileFd != null) {
12077 mProfileFd.close();
12078 } catch (IOException e) {
12082 mProfileFd = profilerInfo.profileFd;
12083 mSamplingInterval = profilerInfo.samplingInterval;
12084 mAutoStopProfiler = profilerInfo.autoStopProfiler;
12089 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12090 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12091 if (!isDebuggable) {
12092 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12093 throw new SecurityException("Process not debuggable: " + app.packageName);
12096 mNativeDebuggingApp = processName;
12100 public void setAlwaysFinish(boolean enabled) {
12101 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12102 "setAlwaysFinish()");
12104 long ident = Binder.clearCallingIdentity();
12106 Settings.Global.putInt(
12107 mContext.getContentResolver(),
12108 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12110 synchronized (this) {
12111 mAlwaysFinishActivities = enabled;
12114 Binder.restoreCallingIdentity(ident);
12119 public void setLenientBackgroundCheck(boolean enabled) {
12120 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12121 "setLenientBackgroundCheck()");
12123 long ident = Binder.clearCallingIdentity();
12125 Settings.Global.putInt(
12126 mContext.getContentResolver(),
12127 Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12129 synchronized (this) {
12130 mLenientBackgroundCheck = enabled;
12133 Binder.restoreCallingIdentity(ident);
12138 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12139 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12140 "setActivityController()");
12141 synchronized (this) {
12142 mController = controller;
12143 mControllerIsAMonkey = imAMonkey;
12144 Watchdog.getInstance().setActivityController(controller);
12149 public void setUserIsMonkey(boolean userIsMonkey) {
12150 synchronized (this) {
12151 synchronized (mPidsSelfLocked) {
12152 final int callingPid = Binder.getCallingPid();
12153 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12154 if (precessRecord == null) {
12155 throw new SecurityException("Unknown process: " + callingPid);
12157 if (precessRecord.instrumentationUiAutomationConnection == null) {
12158 throw new SecurityException("Only an instrumentation process "
12159 + "with a UiAutomation can call setUserIsMonkey");
12162 mUserIsMonkey = userIsMonkey;
12167 public boolean isUserAMonkey() {
12168 synchronized (this) {
12169 // If there is a controller also implies the user is a monkey.
12170 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12174 public void requestBugReport(int bugreportType) {
12175 String service = null;
12176 switch (bugreportType) {
12177 case ActivityManager.BUGREPORT_OPTION_FULL:
12178 service = "bugreport";
12180 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12181 service = "bugreportplus";
12183 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12184 service = "bugreportremote";
12186 case ActivityManager.BUGREPORT_OPTION_WEAR:
12187 service = "bugreportwear";
12189 case ActivityManager.BUGREPORT_OPTION_TELEPHONY:
12190 service = "bugreportelefony";
12193 if (service == null) {
12194 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12197 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12198 SystemProperties.set("ctl.start", service);
12201 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12202 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12205 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12206 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12207 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12209 return KEY_DISPATCHING_TIMEOUT;
12213 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12214 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12215 != PackageManager.PERMISSION_GRANTED) {
12216 throw new SecurityException("Requires permission "
12217 + android.Manifest.permission.FILTER_EVENTS);
12219 ProcessRecord proc;
12221 synchronized (this) {
12222 synchronized (mPidsSelfLocked) {
12223 proc = mPidsSelfLocked.get(pid);
12225 timeout = getInputDispatchingTimeoutLocked(proc);
12228 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12236 * Handle input dispatching timeouts.
12237 * Returns whether input dispatching should be aborted or not.
12239 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12240 final ActivityRecord activity, final ActivityRecord parent,
12241 final boolean aboveSystem, String reason) {
12242 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12243 != PackageManager.PERMISSION_GRANTED) {
12244 throw new SecurityException("Requires permission "
12245 + android.Manifest.permission.FILTER_EVENTS);
12248 final String annotation;
12249 if (reason == null) {
12250 annotation = "Input dispatching timed out";
12252 annotation = "Input dispatching timed out (" + reason + ")";
12255 if (proc != null) {
12256 synchronized (this) {
12257 if (proc.debugging) {
12262 // Give more time since we were dexopting.
12263 mDidDexOpt = false;
12267 if (proc.instrumentationClass != null) {
12268 Bundle info = new Bundle();
12269 info.putString("shortMsg", "keyDispatchingTimedOut");
12270 info.putString("longMsg", annotation);
12271 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12275 mHandler.post(new Runnable() {
12277 public void run() {
12278 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12287 public Bundle getAssistContextExtras(int requestType) {
12288 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12289 null, null, true /* focused */, true /* newSessionId */,
12290 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12294 synchronized (pae) {
12295 while (!pae.haveResult) {
12298 } catch (InterruptedException e) {
12302 synchronized (this) {
12303 buildAssistBundleLocked(pae, pae.result);
12304 mPendingAssistExtras.remove(pae);
12305 mUiHandler.removeCallbacks(pae);
12311 public boolean isAssistDataAllowedOnCurrentActivity() {
12313 synchronized (this) {
12314 userId = mUserController.getCurrentUserIdLocked();
12315 ActivityRecord activity = getFocusedStack().topActivity();
12316 if (activity == null) {
12319 userId = activity.userId;
12321 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12322 Context.DEVICE_POLICY_SERVICE);
12323 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12327 public boolean showAssistFromActivity(IBinder token, Bundle args) {
12328 long ident = Binder.clearCallingIdentity();
12330 synchronized (this) {
12331 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12332 ActivityRecord top = getFocusedStack().topActivity();
12333 if (top != caller) {
12334 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12335 + " is not current top " + top);
12338 if (!top.nowVisible) {
12339 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12340 + " is not visible");
12344 AssistUtils utils = new AssistUtils(mContext);
12345 return utils.showSessionForActiveService(args,
12346 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12348 Binder.restoreCallingIdentity(ident);
12353 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12354 Bundle receiverExtras,
12355 IBinder activityToken, boolean focused, boolean newSessionId) {
12356 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12357 activityToken, focused, newSessionId,
12358 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12362 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12363 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12364 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12365 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12366 "enqueueAssistContext()");
12367 synchronized (this) {
12368 ActivityRecord activity = getFocusedStack().topActivity();
12369 if (activity == null) {
12370 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12373 if (activity.app == null || activity.app.thread == null) {
12374 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12378 if (activityToken != null) {
12379 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12380 if (activity != caller) {
12381 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12382 + " is not current top " + activity);
12387 activity = ActivityRecord.forTokenLocked(activityToken);
12388 if (activity == null) {
12389 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12390 + " couldn't be found");
12395 PendingAssistExtras pae;
12396 Bundle extras = new Bundle();
12397 if (args != null) {
12398 extras.putAll(args);
12400 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12401 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12402 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12404 // Increment the sessionId if necessary
12405 if (newSessionId) {
12409 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12410 requestType, mViSessionId);
12411 mPendingAssistExtras.add(pae);
12412 mUiHandler.postDelayed(pae, timeout);
12413 } catch (RemoteException e) {
12414 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12421 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12422 IResultReceiver receiver;
12423 synchronized (this) {
12424 mPendingAssistExtras.remove(pae);
12425 receiver = pae.receiver;
12427 if (receiver != null) {
12428 // Caller wants result sent back to them.
12429 Bundle sendBundle = new Bundle();
12430 // At least return the receiver extras
12431 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12432 pae.receiverExtras);
12434 pae.receiver.send(0, sendBundle);
12435 } catch (RemoteException e) {
12440 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12441 if (result != null) {
12442 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12444 if (pae.hint != null) {
12445 pae.extras.putBoolean(pae.hint, true);
12449 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12450 AssistContent content, Uri referrer) {
12451 PendingAssistExtras pae = (PendingAssistExtras)token;
12452 synchronized (pae) {
12453 pae.result = extras;
12454 pae.structure = structure;
12455 pae.content = content;
12456 if (referrer != null) {
12457 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12459 pae.haveResult = true;
12461 if (pae.intent == null && pae.receiver == null) {
12462 // Caller is just waiting for the result.
12467 // We are now ready to launch the assist activity.
12468 IResultReceiver sendReceiver = null;
12469 Bundle sendBundle = null;
12470 synchronized (this) {
12471 buildAssistBundleLocked(pae, extras);
12472 boolean exists = mPendingAssistExtras.remove(pae);
12473 mUiHandler.removeCallbacks(pae);
12478 if ((sendReceiver=pae.receiver) != null) {
12479 // Caller wants result sent back to them.
12480 sendBundle = new Bundle();
12481 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12482 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12483 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12484 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12485 pae.receiverExtras);
12488 if (sendReceiver != null) {
12490 sendReceiver.send(0, sendBundle);
12491 } catch (RemoteException e) {
12496 long ident = Binder.clearCallingIdentity();
12498 pae.intent.replaceExtras(pae.extras);
12499 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12500 | Intent.FLAG_ACTIVITY_SINGLE_TOP
12501 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12502 closeSystemDialogs("assist");
12504 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12505 } catch (ActivityNotFoundException e) {
12506 Slog.w(TAG, "No activity to handle assist action.", e);
12509 Binder.restoreCallingIdentity(ident);
12513 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12515 return enqueueAssistContext(requestType, intent, hint, null, null, null,
12516 true /* focused */, true /* newSessionId */,
12517 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12520 public void registerProcessObserver(IProcessObserver observer) {
12521 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12522 "registerProcessObserver()");
12523 synchronized (this) {
12524 mProcessObservers.register(observer);
12529 public void unregisterProcessObserver(IProcessObserver observer) {
12530 synchronized (this) {
12531 mProcessObservers.unregister(observer);
12536 public void registerUidObserver(IUidObserver observer, int which) {
12537 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12538 "registerUidObserver()");
12539 synchronized (this) {
12540 mUidObservers.register(observer, which);
12545 public void unregisterUidObserver(IUidObserver observer) {
12546 synchronized (this) {
12547 mUidObservers.unregister(observer);
12552 public boolean convertFromTranslucent(IBinder token) {
12553 final long origId = Binder.clearCallingIdentity();
12555 synchronized (this) {
12556 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12560 final boolean translucentChanged = r.changeWindowTranslucency(true);
12561 if (translucentChanged) {
12562 r.task.stack.releaseBackgroundResources(r);
12563 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12565 mWindowManager.setAppFullscreen(token, true);
12566 return translucentChanged;
12569 Binder.restoreCallingIdentity(origId);
12574 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12575 final long origId = Binder.clearCallingIdentity();
12577 synchronized (this) {
12578 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12582 int index = r.task.mActivities.lastIndexOf(r);
12584 ActivityRecord under = r.task.mActivities.get(index - 1);
12585 under.returningOptions = options;
12587 final boolean translucentChanged = r.changeWindowTranslucency(false);
12588 if (translucentChanged) {
12589 r.task.stack.convertActivityToTranslucent(r);
12591 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12592 mWindowManager.setAppFullscreen(token, false);
12593 return translucentChanged;
12596 Binder.restoreCallingIdentity(origId);
12601 public boolean requestVisibleBehind(IBinder token, boolean visible) {
12602 final long origId = Binder.clearCallingIdentity();
12604 synchronized (this) {
12605 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12607 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12612 Binder.restoreCallingIdentity(origId);
12617 public boolean isBackgroundVisibleBehind(IBinder token) {
12618 final long origId = Binder.clearCallingIdentity();
12620 synchronized (this) {
12621 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12622 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12623 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12624 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12628 Binder.restoreCallingIdentity(origId);
12633 public ActivityOptions getActivityOptions(IBinder token) {
12634 final long origId = Binder.clearCallingIdentity();
12636 synchronized (this) {
12637 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12639 final ActivityOptions activityOptions = r.pendingOptions;
12640 r.pendingOptions = null;
12641 return activityOptions;
12646 Binder.restoreCallingIdentity(origId);
12651 public void setImmersive(IBinder token, boolean immersive) {
12652 synchronized(this) {
12653 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12655 throw new IllegalArgumentException();
12657 r.immersive = immersive;
12659 // update associated state if we're frontmost
12660 if (r == mFocusedActivity) {
12661 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12662 applyUpdateLockStateLocked(r);
12668 public boolean isImmersive(IBinder token) {
12669 synchronized (this) {
12670 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12672 throw new IllegalArgumentException();
12674 return r.immersive;
12678 public void setVrThread(int tid) {
12679 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12680 throw new UnsupportedOperationException("VR mode not supported on this device!");
12683 synchronized (this) {
12684 ProcessRecord proc;
12685 synchronized (mPidsSelfLocked) {
12686 final int pid = Binder.getCallingPid();
12687 proc = mPidsSelfLocked.get(pid);
12689 if (proc != null && mInVrMode && tid >= 0) {
12690 // ensure the tid belongs to the process
12691 if (!Process.isThreadInProcess(pid, tid)) {
12692 throw new IllegalArgumentException("VR thread does not belong to process");
12695 // reset existing VR thread to CFS if this thread still exists and belongs to
12696 // the calling process
12697 if (proc.vrThreadTid != 0
12698 && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12700 Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12701 } catch (IllegalArgumentException e) {
12702 // Ignore this. Only occurs in race condition where previous VR thread
12703 // was destroyed during this method call.
12707 proc.vrThreadTid = tid;
12709 // promote to FIFO now if the tid is non-zero
12711 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12712 proc.vrThreadTid > 0) {
12713 Process.setThreadScheduler(proc.vrThreadTid,
12714 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12716 } catch (IllegalArgumentException e) {
12717 Slog.e(TAG, "Failed to set scheduling policy, thread does"
12718 + " not exist:\n" + e);
12726 public void setRenderThread(int tid) {
12727 synchronized (this) {
12728 ProcessRecord proc;
12729 synchronized (mPidsSelfLocked) {
12730 int pid = Binder.getCallingPid();
12731 proc = mPidsSelfLocked.get(pid);
12732 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12733 // ensure the tid belongs to the process
12734 if (!Process.isThreadInProcess(pid, tid)) {
12735 throw new IllegalArgumentException(
12736 "Render thread does not belong to process");
12738 proc.renderThreadTid = tid;
12739 if (DEBUG_OOM_ADJ) {
12740 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12742 // promote to FIFO now
12743 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12744 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12745 if (mUseFifoUiScheduling) {
12746 Process.setThreadScheduler(proc.renderThreadTid,
12747 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12749 Process.setThreadPriority(proc.renderThreadTid, -10);
12753 if (DEBUG_OOM_ADJ) {
12754 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12755 "PID: " + pid + ", TID: " + tid + " FIFO: " +
12756 mUseFifoUiScheduling);
12764 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12765 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12766 throw new UnsupportedOperationException("VR mode not supported on this device!");
12769 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12772 synchronized (this) {
12773 r = ActivityRecord.isInStackLocked(token);
12777 throw new IllegalArgumentException();
12781 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12782 VrManagerInternal.NO_ERROR) {
12786 synchronized(this) {
12787 r.requestedVrComponent = (enabled) ? packageName : null;
12789 // Update associated state if this activity is currently focused
12790 if (r == mFocusedActivity) {
12791 applyUpdateVrModeLocked(r);
12798 public boolean isVrModePackageEnabled(ComponentName packageName) {
12799 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12800 throw new UnsupportedOperationException("VR mode not supported on this device!");
12803 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12805 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12806 VrManagerInternal.NO_ERROR;
12809 public boolean isTopActivityImmersive() {
12810 enforceNotIsolatedCaller("startActivity");
12811 synchronized (this) {
12812 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12813 return (r != null) ? r.immersive : false;
12818 public boolean isTopOfTask(IBinder token) {
12819 synchronized (this) {
12820 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12822 throw new IllegalArgumentException();
12824 return r.task.getTopActivity() == r;
12829 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12830 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12831 String msg = "Permission Denial: setHasTopUi() from pid="
12832 + Binder.getCallingPid()
12833 + ", uid=" + Binder.getCallingUid()
12834 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12836 throw new SecurityException(msg);
12838 final int pid = Binder.getCallingPid();
12839 final long origId = Binder.clearCallingIdentity();
12841 synchronized (this) {
12842 boolean changed = false;
12844 synchronized (mPidsSelfLocked) {
12845 pr = mPidsSelfLocked.get(pid);
12847 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12850 if (pr.hasTopUi != hasTopUi) {
12851 Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12852 pr.hasTopUi = hasTopUi;
12857 updateOomAdjLocked(pr);
12861 Binder.restoreCallingIdentity(origId);
12865 public final void enterSafeMode() {
12866 synchronized(this) {
12867 // It only makes sense to do this before the system is ready
12868 // and started launching other packages.
12869 if (!mSystemReady) {
12871 AppGlobals.getPackageManager().enterSafeMode();
12872 } catch (RemoteException e) {
12880 public final void showSafeModeOverlay() {
12881 View v = LayoutInflater.from(mContext).inflate(
12882 com.android.internal.R.layout.safe_mode, null);
12883 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12884 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12885 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12886 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12887 lp.gravity = Gravity.BOTTOM | Gravity.START;
12888 lp.format = v.getBackground().getOpacity();
12889 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12890 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12891 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12892 ((WindowManager)mContext.getSystemService(
12893 Context.WINDOW_SERVICE)).addView(v, lp);
12896 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12897 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12900 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12901 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12902 synchronized (stats) {
12903 if (mBatteryStatsService.isOnBattery()) {
12904 mBatteryStatsService.enforceCallingPermission();
12905 int MY_UID = Binder.getCallingUid();
12907 if (sender == null) {
12910 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12912 BatteryStatsImpl.Uid.Pkg pkg =
12913 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12914 sourcePkg != null ? sourcePkg : rec.key.packageName);
12915 pkg.noteWakeupAlarmLocked(tag);
12920 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12921 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12924 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12925 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12926 synchronized (stats) {
12927 mBatteryStatsService.enforceCallingPermission();
12928 int MY_UID = Binder.getCallingUid();
12930 if (sender == null) {
12933 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12935 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12939 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12940 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12943 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12944 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12945 synchronized (stats) {
12946 mBatteryStatsService.enforceCallingPermission();
12947 int MY_UID = Binder.getCallingUid();
12949 if (sender == null) {
12952 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12954 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12958 public boolean killPids(int[] pids, String pReason, boolean secure) {
12959 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12960 throw new SecurityException("killPids only available to the system");
12962 String reason = (pReason == null) ? "Unknown" : pReason;
12963 // XXX Note: don't acquire main activity lock here, because the window
12964 // manager calls in with its locks held.
12966 boolean killed = false;
12967 synchronized (mPidsSelfLocked) {
12969 for (int i=0; i<pids.length; i++) {
12970 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12971 if (proc != null) {
12972 int type = proc.setAdj;
12973 if (type > worstType) {
12979 // If the worst oom_adj is somewhere in the cached proc LRU range,
12980 // then constrain it so we will kill all cached procs.
12981 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12982 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12983 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12986 // If this is not a secure call, don't let it kill processes that
12988 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12989 worstType = ProcessList.SERVICE_ADJ;
12992 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12993 for (int i=0; i<pids.length; i++) {
12994 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12995 if (proc == null) {
12998 int adj = proc.setAdj;
12999 if (adj >= worstType && !proc.killedByAm) {
13000 proc.kill(reason, true);
13009 public void killUid(int appId, int userId, String reason) {
13010 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
13011 synchronized (this) {
13012 final long identity = Binder.clearCallingIdentity();
13014 killPackageProcessesLocked(null, appId, userId,
13015 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
13016 reason != null ? reason : "kill uid");
13018 Binder.restoreCallingIdentity(identity);
13024 public boolean killProcessesBelowForeground(String reason) {
13025 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13026 throw new SecurityException("killProcessesBelowForeground() only available to system");
13029 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13032 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13033 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13034 throw new SecurityException("killProcessesBelowAdj() only available to system");
13037 boolean killed = false;
13038 synchronized (mPidsSelfLocked) {
13039 final int size = mPidsSelfLocked.size();
13040 for (int i = 0; i < size; i++) {
13041 final int pid = mPidsSelfLocked.keyAt(i);
13042 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13043 if (proc == null) continue;
13045 final int adj = proc.setAdj;
13046 if (adj > belowAdj && !proc.killedByAm) {
13047 proc.kill(reason, true);
13056 public void hang(final IBinder who, boolean allowRestart) {
13057 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13058 != PackageManager.PERMISSION_GRANTED) {
13059 throw new SecurityException("Requires permission "
13060 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13063 final IBinder.DeathRecipient death = new DeathRecipient() {
13065 public void binderDied() {
13066 synchronized (this) {
13073 who.linkToDeath(death, 0);
13074 } catch (RemoteException e) {
13075 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13079 synchronized (this) {
13080 Watchdog.getInstance().setAllowRestart(allowRestart);
13081 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13082 synchronized (death) {
13083 while (who.isBinderAlive()) {
13086 } catch (InterruptedException e) {
13090 Watchdog.getInstance().setAllowRestart(true);
13095 public void restart() {
13096 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13097 != PackageManager.PERMISSION_GRANTED) {
13098 throw new SecurityException("Requires permission "
13099 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13102 Log.i(TAG, "Sending shutdown broadcast...");
13104 BroadcastReceiver br = new BroadcastReceiver() {
13105 @Override public void onReceive(Context context, Intent intent) {
13106 // Now the broadcast is done, finish up the low-level shutdown.
13107 Log.i(TAG, "Shutting down activity manager...");
13109 Log.i(TAG, "Shutdown complete, restarting!");
13110 Process.killProcess(Process.myPid());
13115 // First send the high-level shut down broadcast.
13116 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13117 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13118 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13119 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13120 mContext.sendOrderedBroadcastAsUser(intent,
13121 UserHandle.ALL, null, br, mHandler, 0, null, null);
13123 br.onReceive(mContext, intent);
13126 private long getLowRamTimeSinceIdle(long now) {
13127 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13131 public void performIdleMaintenance() {
13132 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13133 != PackageManager.PERMISSION_GRANTED) {
13134 throw new SecurityException("Requires permission "
13135 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13138 synchronized (this) {
13139 final long now = SystemClock.uptimeMillis();
13140 final long timeSinceLastIdle = now - mLastIdleTime;
13141 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13142 mLastIdleTime = now;
13143 mLowRamTimeSinceLastIdle = 0;
13144 if (mLowRamStartTime != 0) {
13145 mLowRamStartTime = now;
13148 StringBuilder sb = new StringBuilder(128);
13149 sb.append("Idle maintenance over ");
13150 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13151 sb.append(" low RAM for ");
13152 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13153 Slog.i(TAG, sb.toString());
13155 // If at least 1/3 of our time since the last idle period has been spent
13156 // with RAM low, then we want to kill processes.
13157 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13159 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13160 ProcessRecord proc = mLruProcesses.get(i);
13161 if (proc.notCachedSinceIdle) {
13162 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13163 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13164 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13165 if (doKilling && proc.initialIdlePss != 0
13166 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13167 sb = new StringBuilder(128);
13169 sb.append(proc.processName);
13170 sb.append(" in idle maint: pss=");
13171 sb.append(proc.lastPss);
13172 sb.append(", swapPss=");
13173 sb.append(proc.lastSwapPss);
13174 sb.append(", initialPss=");
13175 sb.append(proc.initialIdlePss);
13176 sb.append(", period=");
13177 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13178 sb.append(", lowRamPeriod=");
13179 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13180 Slog.wtfQuiet(TAG, sb.toString());
13181 proc.kill("idle maint (pss " + proc.lastPss
13182 + " from " + proc.initialIdlePss + ")", true);
13185 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13186 && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13187 proc.notCachedSinceIdle = true;
13188 proc.initialIdlePss = 0;
13189 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13190 mTestPssMode, isSleepingLocked(), now);
13194 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13195 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13200 public void sendIdleJobTrigger() {
13201 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13202 != PackageManager.PERMISSION_GRANTED) {
13203 throw new SecurityException("Requires permission "
13204 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13207 final long ident = Binder.clearCallingIdentity();
13209 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13210 .setPackage("android")
13211 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13212 broadcastIntent(null, intent, null, null, 0, null, null, null,
13213 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13215 Binder.restoreCallingIdentity(ident);
13219 private void retrieveSettings() {
13220 final ContentResolver resolver = mContext.getContentResolver();
13221 final boolean freeformWindowManagement =
13222 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13223 || Settings.Global.getInt(
13224 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13225 final boolean supportsPictureInPicture =
13226 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13228 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13229 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13230 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13231 final boolean alwaysFinishActivities =
13232 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13233 final boolean lenientBackgroundCheck =
13234 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13235 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13236 final boolean forceResizable = Settings.Global.getInt(
13237 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13238 final boolean supportsLeanbackOnly =
13239 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13241 // Transfer any global setting for forcing RTL layout, into a System Property
13242 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13244 final Configuration configuration = new Configuration();
13245 Settings.System.getConfiguration(resolver, configuration);
13247 // This will take care of setting the correct layout direction flags
13248 configuration.setLayoutDirection(configuration.locale);
13251 synchronized (this) {
13252 mDebugApp = mOrigDebugApp = debugApp;
13253 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13254 mAlwaysFinishActivities = alwaysFinishActivities;
13255 mLenientBackgroundCheck = lenientBackgroundCheck;
13256 mSupportsLeanbackOnly = supportsLeanbackOnly;
13257 mForceResizableActivities = forceResizable;
13258 mWindowManager.setForceResizableTasks(mForceResizableActivities);
13259 if (supportsMultiWindow || forceResizable) {
13260 mSupportsMultiWindow = true;
13261 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13262 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13264 mSupportsMultiWindow = false;
13265 mSupportsFreeformWindowManagement = false;
13266 mSupportsPictureInPicture = false;
13268 // This happens before any activities are started, so we can
13269 // change mConfiguration in-place.
13270 updateConfigurationLocked(configuration, null, true);
13271 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13272 "Initial config: " + mConfiguration);
13274 // Load resources only after the current configuration has been set.
13275 final Resources res = mContext.getResources();
13276 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13277 mThumbnailWidth = res.getDimensionPixelSize(
13278 com.android.internal.R.dimen.thumbnail_width);
13279 mThumbnailHeight = res.getDimensionPixelSize(
13280 com.android.internal.R.dimen.thumbnail_height);
13281 mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13282 com.android.internal.R.string.config_defaultPictureInPictureBounds));
13283 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13284 com.android.internal.R.string.config_appsNotReportingCrashes));
13285 if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13286 mFullscreenThumbnailScale = (float) res
13287 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13288 (float) mConfiguration.screenWidthDp;
13290 mFullscreenThumbnailScale = res.getFraction(
13291 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13296 public boolean testIsSystemReady() {
13297 // no need to synchronize(this) just to read & return the value
13298 return mSystemReady;
13301 public void systemReady(final Runnable goingCallback) {
13302 synchronized(this) {
13303 if (mSystemReady) {
13304 // If we're done calling all the receivers, run the next "boot phase" passed in
13305 // by the SystemServer
13306 if (goingCallback != null) {
13307 goingCallback.run();
13312 mLocalDeviceIdleController
13313 = LocalServices.getService(DeviceIdleController.LocalService.class);
13315 // Make sure we have the current profile info, since it is needed for security checks.
13316 mUserController.onSystemReady();
13317 mRecentTasks.onSystemReadyLocked();
13318 mAppOpsService.systemReady();
13319 mSystemReady = true;
13322 ArrayList<ProcessRecord> procsToKill = null;
13323 synchronized(mPidsSelfLocked) {
13324 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13325 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13326 if (!isAllowedWhileBooting(proc.info)){
13327 if (procsToKill == null) {
13328 procsToKill = new ArrayList<ProcessRecord>();
13330 procsToKill.add(proc);
13335 synchronized(this) {
13336 if (procsToKill != null) {
13337 for (int i=procsToKill.size()-1; i>=0; i--) {
13338 ProcessRecord proc = procsToKill.get(i);
13339 Slog.i(TAG, "Removing system update proc: " + proc);
13340 removeProcessLocked(proc, true, false, "system update done");
13344 // Now that we have cleaned up any update processes, we
13345 // are ready to start launching real processes and know that
13346 // we won't trample on them any more.
13347 mProcessesReady = true;
13350 Slog.i(TAG, "System now ready");
13351 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13352 SystemClock.uptimeMillis());
13354 synchronized(this) {
13355 // Make sure we have no pre-ready processes sitting around.
13357 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13358 ResolveInfo ri = mContext.getPackageManager()
13359 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13361 CharSequence errorMsg = null;
13363 ActivityInfo ai = ri.activityInfo;
13364 ApplicationInfo app = ai.applicationInfo;
13365 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13366 mTopAction = Intent.ACTION_FACTORY_TEST;
13368 mTopComponent = new ComponentName(app.packageName,
13371 errorMsg = mContext.getResources().getText(
13372 com.android.internal.R.string.factorytest_not_system);
13375 errorMsg = mContext.getResources().getText(
13376 com.android.internal.R.string.factorytest_no_action);
13378 if (errorMsg != null) {
13381 mTopComponent = null;
13382 Message msg = Message.obtain();
13383 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13384 msg.getData().putCharSequence("msg", errorMsg);
13385 mUiHandler.sendMessage(msg);
13390 retrieveSettings();
13391 final int currentUserId;
13392 synchronized (this) {
13393 currentUserId = mUserController.getCurrentUserIdLocked();
13394 readGrantedUriPermissionsLocked();
13397 if (goingCallback != null) goingCallback.run();
13399 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13400 Integer.toString(currentUserId), currentUserId);
13401 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13402 Integer.toString(currentUserId), currentUserId);
13403 mSystemServiceManager.startUser(currentUserId);
13405 synchronized (this) {
13406 // Only start up encryption-aware persistent apps; once user is
13407 // unlocked we'll come back around and start unaware apps
13408 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13410 // Start up initial activity.
13412 // Enable home activity for system user, so that the system can always boot
13413 if (UserManager.isSplitSystemUser()) {
13414 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13416 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13417 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13418 UserHandle.USER_SYSTEM);
13419 } catch (RemoteException e) {
13420 throw e.rethrowAsRuntimeException();
13423 startHomeActivityLocked(currentUserId, "systemReady");
13426 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13427 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13428 + " data partition or your device will be unstable.");
13429 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13431 } catch (RemoteException e) {
13434 if (!Build.isBuildConsistent()) {
13435 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13436 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13439 long ident = Binder.clearCallingIdentity();
13441 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13442 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13443 | Intent.FLAG_RECEIVER_FOREGROUND);
13444 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13445 broadcastIntentLocked(null, null, intent,
13446 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13447 null, false, false, MY_PID, Process.SYSTEM_UID,
13449 intent = new Intent(Intent.ACTION_USER_STARTING);
13450 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13451 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13452 broadcastIntentLocked(null, null, intent,
13453 null, new IIntentReceiver.Stub() {
13455 public void performReceive(Intent intent, int resultCode, String data,
13456 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13457 throws RemoteException {
13460 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13461 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13462 } catch (Throwable t) {
13463 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13465 Binder.restoreCallingIdentity(ident);
13467 mStackSupervisor.resumeFocusedStackTopActivityLocked();
13468 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13472 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13473 synchronized (this) {
13474 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13478 void skipCurrentReceiverLocked(ProcessRecord app) {
13479 for (BroadcastQueue queue : mBroadcastQueues) {
13480 queue.skipCurrentReceiverLocked(app);
13485 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13486 * The application process will exit immediately after this call returns.
13487 * @param app object of the crashing app, null for the system server
13488 * @param crashInfo describing the exception
13490 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13491 ProcessRecord r = findAppProcess(app, "Crash");
13492 final String processName = app == null ? "system_server"
13493 : (r == null ? "unknown" : r.processName);
13495 handleApplicationCrashInner("crash", r, processName, crashInfo);
13498 /* Native crash reporting uses this inner version because it needs to be somewhat
13499 * decoupled from the AM-managed cleanup lifecycle
13501 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13502 ApplicationErrorReport.CrashInfo crashInfo) {
13503 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13504 UserHandle.getUserId(Binder.getCallingUid()), processName,
13505 r == null ? -1 : r.info.flags,
13506 crashInfo.exceptionClassName,
13507 crashInfo.exceptionMessage,
13508 crashInfo.throwFileName,
13509 crashInfo.throwLineNumber);
13511 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13513 mAppErrors.crashApplication(r, crashInfo);
13516 public void handleApplicationStrictModeViolation(
13519 StrictMode.ViolationInfo info) {
13520 ProcessRecord r = findAppProcess(app, "StrictMode");
13525 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13526 Integer stackFingerprint = info.hashCode();
13527 boolean logIt = true;
13528 synchronized (mAlreadyLoggedViolatedStacks) {
13529 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13531 // TODO: sub-sample into EventLog for these, with
13532 // the info.durationMillis? Then we'd get
13533 // the relative pain numbers, without logging all
13534 // the stack traces repeatedly. We'd want to do
13535 // likewise in the client code, which also does
13536 // dup suppression, before the Binder call.
13538 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13539 mAlreadyLoggedViolatedStacks.clear();
13541 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13545 logStrictModeViolationToDropBox(r, info);
13549 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13550 AppErrorResult result = new AppErrorResult();
13551 synchronized (this) {
13552 final long origId = Binder.clearCallingIdentity();
13554 Message msg = Message.obtain();
13555 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13556 HashMap<String, Object> data = new HashMap<String, Object>();
13557 data.put("result", result);
13558 data.put("app", r);
13559 data.put("violationMask", violationMask);
13560 data.put("info", info);
13562 mUiHandler.sendMessage(msg);
13564 Binder.restoreCallingIdentity(origId);
13566 int res = result.get();
13567 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13571 // Depending on the policy in effect, there could be a bunch of
13572 // these in quick succession so we try to batch these together to
13573 // minimize disk writes, number of dropbox entries, and maximize
13574 // compression, by having more fewer, larger records.
13575 private void logStrictModeViolationToDropBox(
13576 ProcessRecord process,
13577 StrictMode.ViolationInfo info) {
13578 if (info == null) {
13581 final boolean isSystemApp = process == null ||
13582 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13583 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13584 final String processName = process == null ? "unknown" : process.processName;
13585 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13586 final DropBoxManager dbox = (DropBoxManager)
13587 mContext.getSystemService(Context.DROPBOX_SERVICE);
13589 // Exit early if the dropbox isn't configured to accept this report type.
13590 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13592 boolean bufferWasEmpty;
13593 boolean needsFlush;
13594 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13595 synchronized (sb) {
13596 bufferWasEmpty = sb.length() == 0;
13597 appendDropBoxProcessHeaders(process, processName, sb);
13598 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13599 sb.append("System-App: ").append(isSystemApp).append("\n");
13600 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13601 if (info.violationNumThisLoop != 0) {
13602 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13604 if (info.numAnimationsRunning != 0) {
13605 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13607 if (info.broadcastIntentAction != null) {
13608 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13610 if (info.durationMillis != -1) {
13611 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13613 if (info.numInstances != -1) {
13614 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13616 if (info.tags != null) {
13617 for (String tag : info.tags) {
13618 sb.append("Span-Tag: ").append(tag).append("\n");
13622 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13623 sb.append(info.crashInfo.stackTrace);
13626 if (info.message != null) {
13627 sb.append(info.message);
13631 // Only buffer up to ~64k. Various logging bits truncate
13633 needsFlush = (sb.length() > 64 * 1024);
13636 // Flush immediately if the buffer's grown too large, or this
13637 // is a non-system app. Non-system apps are isolated with a
13638 // different tag & policy and not batched.
13640 // Batching is useful during internal testing with
13641 // StrictMode settings turned up high. Without batching,
13642 // thousands of separate files could be created on boot.
13643 if (!isSystemApp || needsFlush) {
13644 new Thread("Error dump: " + dropboxTag) {
13646 public void run() {
13648 synchronized (sb) {
13649 report = sb.toString();
13650 sb.delete(0, sb.length());
13653 if (report.length() != 0) {
13654 dbox.addText(dropboxTag, report);
13661 // System app batching:
13662 if (!bufferWasEmpty) {
13663 // An existing dropbox-writing thread is outstanding, so
13664 // we don't need to start it up. The existing thread will
13665 // catch the buffer appends we just did.
13669 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13670 // (After this point, we shouldn't access AMS internal data structures.)
13671 new Thread("Error dump: " + dropboxTag) {
13673 public void run() {
13674 // 5 second sleep to let stacks arrive and be batched together
13676 Thread.sleep(5000); // 5 seconds
13677 } catch (InterruptedException e) {}
13679 String errorReport;
13680 synchronized (mStrictModeBuffer) {
13681 errorReport = mStrictModeBuffer.toString();
13682 if (errorReport.length() == 0) {
13685 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13686 mStrictModeBuffer.trimToSize();
13688 dbox.addText(dropboxTag, errorReport);
13694 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13695 * @param app object of the crashing app, null for the system server
13696 * @param tag reported by the caller
13697 * @param system whether this wtf is coming from the system
13698 * @param crashInfo describing the context of the error
13699 * @return true if the process should exit immediately (WTF is fatal)
13701 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13702 final ApplicationErrorReport.CrashInfo crashInfo) {
13703 final int callingUid = Binder.getCallingUid();
13704 final int callingPid = Binder.getCallingPid();
13707 // If this is coming from the system, we could very well have low-level
13708 // system locks held, so we want to do this all asynchronously. And we
13709 // never want this to become fatal, so there is that too.
13710 mHandler.post(new Runnable() {
13711 @Override public void run() {
13712 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13718 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13721 if (r != null && r.pid != Process.myPid() &&
13722 Settings.Global.getInt(mContext.getContentResolver(),
13723 Settings.Global.WTF_IS_FATAL, 0) != 0) {
13724 mAppErrors.crashApplication(r, crashInfo);
13731 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13732 final ApplicationErrorReport.CrashInfo crashInfo) {
13733 final ProcessRecord r = findAppProcess(app, "WTF");
13734 final String processName = app == null ? "system_server"
13735 : (r == null ? "unknown" : r.processName);
13737 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13738 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13740 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13746 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13747 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13749 private ProcessRecord findAppProcess(IBinder app, String reason) {
13754 synchronized (this) {
13755 final int NP = mProcessNames.getMap().size();
13756 for (int ip=0; ip<NP; ip++) {
13757 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13758 final int NA = apps.size();
13759 for (int ia=0; ia<NA; ia++) {
13760 ProcessRecord p = apps.valueAt(ia);
13761 if (p.thread != null && p.thread.asBinder() == app) {
13767 Slog.w(TAG, "Can't find mystery application for " + reason
13768 + " from pid=" + Binder.getCallingPid()
13769 + " uid=" + Binder.getCallingUid() + ": " + app);
13775 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13776 * to append various headers to the dropbox log text.
13778 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13779 StringBuilder sb) {
13780 // Watchdog thread ends up invoking this function (with
13781 // a null ProcessRecord) to add the stack file to dropbox.
13782 // Do not acquire a lock on this (am) in such cases, as it
13783 // could cause a potential deadlock, if and when watchdog
13784 // is invoked due to unavailability of lock on am and it
13785 // would prevent watchdog from killing system_server.
13786 if (process == null) {
13787 sb.append("Process: ").append(processName).append("\n");
13790 // Note: ProcessRecord 'process' is guarded by the service
13791 // instance. (notably process.pkgList, which could otherwise change
13792 // concurrently during execution of this method)
13793 synchronized (this) {
13794 sb.append("Process: ").append(processName).append("\n");
13795 int flags = process.info.flags;
13796 IPackageManager pm = AppGlobals.getPackageManager();
13797 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13798 for (int ip=0; ip<process.pkgList.size(); ip++) {
13799 String pkg = process.pkgList.keyAt(ip);
13800 sb.append("Package: ").append(pkg);
13802 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13804 sb.append(" v").append(pi.versionCode);
13805 if (pi.versionName != null) {
13806 sb.append(" (").append(pi.versionName).append(")");
13809 } catch (RemoteException e) {
13810 Slog.e(TAG, "Error getting package info: " + pkg, e);
13817 private static String processClass(ProcessRecord process) {
13818 if (process == null || process.pid == MY_PID) {
13819 return "system_server";
13820 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13821 return "system_app";
13827 private volatile long mWtfClusterStart;
13828 private volatile int mWtfClusterCount;
13831 * Write a description of an error (crash, WTF, ANR) to the drop box.
13832 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13833 * @param process which caused the error, null means the system server
13834 * @param activity which triggered the error, null if unknown
13835 * @param parent activity related to the error, null if unknown
13836 * @param subject line related to the error, null if absent
13837 * @param report in long form describing the error, null if absent
13838 * @param dataFile text file to include in the report, null if none
13839 * @param crashInfo giving an application stack trace, null if absent
13841 public void addErrorToDropBox(String eventType,
13842 ProcessRecord process, String processName, ActivityRecord activity,
13843 ActivityRecord parent, String subject,
13844 final String report, final File dataFile,
13845 final ApplicationErrorReport.CrashInfo crashInfo) {
13846 // NOTE -- this must never acquire the ActivityManagerService lock,
13847 // otherwise the watchdog may be prevented from resetting the system.
13849 final String dropboxTag = processClass(process) + "_" + eventType;
13850 final DropBoxManager dbox = (DropBoxManager)
13851 mContext.getSystemService(Context.DROPBOX_SERVICE);
13853 // Exit early if the dropbox isn't configured to accept this report type.
13854 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13856 // Rate-limit how often we're willing to do the heavy lifting below to
13857 // collect and record logs; currently 5 logs per 10 second period.
13858 final long now = SystemClock.elapsedRealtime();
13859 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13860 mWtfClusterStart = now;
13861 mWtfClusterCount = 1;
13863 if (mWtfClusterCount++ >= 5) return;
13866 final StringBuilder sb = new StringBuilder(1024);
13867 appendDropBoxProcessHeaders(process, processName, sb);
13868 if (process != null) {
13869 sb.append("Foreground: ")
13870 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13873 if (activity != null) {
13874 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13876 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13877 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13879 if (parent != null && parent != activity) {
13880 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13882 if (subject != null) {
13883 sb.append("Subject: ").append(subject).append("\n");
13885 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13886 if (Debug.isDebuggerConnected()) {
13887 sb.append("Debugger: Connected\n");
13891 // Do the rest in a worker thread to avoid blocking the caller on I/O
13892 // (After this point, we shouldn't access AMS internal data structures.)
13893 Thread worker = new Thread("Error dump: " + dropboxTag) {
13895 public void run() {
13896 if (report != null) {
13900 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13901 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13902 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13903 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13905 if (dataFile != null && maxDataFileSize > 0) {
13907 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13908 "\n\n[[TRUNCATED]]"));
13909 } catch (IOException e) {
13910 Slog.e(TAG, "Error reading " + dataFile, e);
13913 if (crashInfo != null && crashInfo.stackTrace != null) {
13914 sb.append(crashInfo.stackTrace);
13920 // Merge several logcat streams, and take the last N lines
13921 InputStreamReader input = null;
13923 java.lang.Process logcat = new ProcessBuilder(
13924 "/system/bin/timeout", "-k", "15s", "10s",
13925 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13926 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13927 .redirectErrorStream(true).start();
13929 try { logcat.getOutputStream().close(); } catch (IOException e) {}
13930 try { logcat.getErrorStream().close(); } catch (IOException e) {}
13931 input = new InputStreamReader(logcat.getInputStream());
13934 char[] buf = new char[8192];
13935 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13936 } catch (IOException e) {
13937 Slog.e(TAG, "Error running logcat", e);
13939 if (input != null) try { input.close(); } catch (IOException e) {}
13943 dbox.addText(dropboxTag, sb.toString());
13947 if (process == null) {
13948 // If process is null, we are being called from some internal code
13949 // and may be about to die -- run this synchronously.
13957 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13958 enforceNotIsolatedCaller("getProcessesInErrorState");
13959 // assume our apps are happy - lazy create the list
13960 List<ActivityManager.ProcessErrorStateInfo> errList = null;
13962 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13963 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13964 int userId = UserHandle.getUserId(Binder.getCallingUid());
13966 synchronized (this) {
13968 // iterate across all processes
13969 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13970 ProcessRecord app = mLruProcesses.get(i);
13971 if (!allUsers && app.userId != userId) {
13974 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13975 // This one's in trouble, so we'll generate a report for it
13976 // crashes are higher priority (in case there's a crash *and* an anr)
13977 ActivityManager.ProcessErrorStateInfo report = null;
13978 if (app.crashing) {
13979 report = app.crashingReport;
13980 } else if (app.notResponding) {
13981 report = app.notRespondingReport;
13984 if (report != null) {
13985 if (errList == null) {
13986 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13988 errList.add(report);
13990 Slog.w(TAG, "Missing app error report, app = " + app.processName +
13991 " crashing = " + app.crashing +
13992 " notResponding = " + app.notResponding);
14001 static int procStateToImportance(int procState, int memAdj,
14002 ActivityManager.RunningAppProcessInfo currApp) {
14003 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
14004 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
14005 currApp.lru = memAdj;
14012 private void fillInProcMemInfo(ProcessRecord app,
14013 ActivityManager.RunningAppProcessInfo outInfo) {
14014 outInfo.pid = app.pid;
14015 outInfo.uid = app.info.uid;
14016 if (mHeavyWeightProcess == app) {
14017 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14019 if (app.persistent) {
14020 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14022 if (app.activities.size() > 0) {
14023 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14025 outInfo.lastTrimLevel = app.trimMemoryLevel;
14026 int adj = app.curAdj;
14027 int procState = app.curProcState;
14028 outInfo.importance = procStateToImportance(procState, adj, outInfo);
14029 outInfo.importanceReasonCode = app.adjTypeCode;
14030 outInfo.processState = app.curProcState;
14034 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14035 enforceNotIsolatedCaller("getRunningAppProcesses");
14037 final int callingUid = Binder.getCallingUid();
14039 // Lazy instantiation of list
14040 List<ActivityManager.RunningAppProcessInfo> runList = null;
14041 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14042 callingUid) == PackageManager.PERMISSION_GRANTED;
14043 final int userId = UserHandle.getUserId(callingUid);
14044 final boolean allUids = isGetTasksAllowed(
14045 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14047 synchronized (this) {
14048 // Iterate across all processes
14049 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14050 ProcessRecord app = mLruProcesses.get(i);
14051 if ((!allUsers && app.userId != userId)
14052 || (!allUids && app.uid != callingUid)) {
14055 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14056 // Generate process state info for running application
14057 ActivityManager.RunningAppProcessInfo currApp =
14058 new ActivityManager.RunningAppProcessInfo(app.processName,
14059 app.pid, app.getPackageList());
14060 fillInProcMemInfo(app, currApp);
14061 if (app.adjSource instanceof ProcessRecord) {
14062 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14063 currApp.importanceReasonImportance =
14064 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14065 app.adjSourceProcState);
14066 } else if (app.adjSource instanceof ActivityRecord) {
14067 ActivityRecord r = (ActivityRecord)app.adjSource;
14068 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14070 if (app.adjTarget instanceof ComponentName) {
14071 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14073 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14074 // + " lru=" + currApp.lru);
14075 if (runList == null) {
14076 runList = new ArrayList<>();
14078 runList.add(currApp);
14086 public List<ApplicationInfo> getRunningExternalApplications() {
14087 enforceNotIsolatedCaller("getRunningExternalApplications");
14088 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14089 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14090 if (runningApps != null && runningApps.size() > 0) {
14091 Set<String> extList = new HashSet<String>();
14092 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14093 if (app.pkgList != null) {
14094 for (String pkg : app.pkgList) {
14099 IPackageManager pm = AppGlobals.getPackageManager();
14100 for (String pkg : extList) {
14102 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14103 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14106 } catch (RemoteException e) {
14114 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14115 enforceNotIsolatedCaller("getMyMemoryState");
14116 synchronized (this) {
14117 ProcessRecord proc;
14118 synchronized (mPidsSelfLocked) {
14119 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14121 fillInProcMemInfo(proc, outInfo);
14126 public int getMemoryTrimLevel() {
14127 enforceNotIsolatedCaller("getMyMemoryState");
14128 synchronized (this) {
14129 return mLastMemoryLevel;
14134 public void onShellCommand(FileDescriptor in, FileDescriptor out,
14135 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14136 (new ActivityManagerShellCommand(this, false)).exec(
14137 this, in, out, err, args, resultReceiver);
14141 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14142 if (checkCallingPermission(android.Manifest.permission.DUMP)
14143 != PackageManager.PERMISSION_GRANTED) {
14144 pw.println("Permission Denial: can't dump ActivityManager from from pid="
14145 + Binder.getCallingPid()
14146 + ", uid=" + Binder.getCallingUid()
14147 + " without permission "
14148 + android.Manifest.permission.DUMP);
14152 boolean dumpAll = false;
14153 boolean dumpClient = false;
14154 boolean dumpCheckin = false;
14155 boolean dumpCheckinFormat = false;
14156 String dumpPackage = null;
14159 while (opti < args.length) {
14160 String opt = args[opti];
14161 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14165 if ("-a".equals(opt)) {
14167 } else if ("-c".equals(opt)) {
14169 } else if ("-p".equals(opt)) {
14170 if (opti < args.length) {
14171 dumpPackage = args[opti];
14174 pw.println("Error: -p option requires package argument");
14178 } else if ("--checkin".equals(opt)) {
14179 dumpCheckin = dumpCheckinFormat = true;
14180 } else if ("-C".equals(opt)) {
14181 dumpCheckinFormat = true;
14182 } else if ("-h".equals(opt)) {
14183 ActivityManagerShellCommand.dumpHelp(pw, true);
14186 pw.println("Unknown argument: " + opt + "; use -h for help");
14190 long origId = Binder.clearCallingIdentity();
14191 boolean more = false;
14192 // Is the caller requesting to dump a particular piece of data?
14193 if (opti < args.length) {
14194 String cmd = args[opti];
14196 if ("activities".equals(cmd) || "a".equals(cmd)) {
14197 synchronized (this) {
14198 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14200 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14201 synchronized (this) {
14202 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14204 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14207 if (opti >= args.length) {
14209 newArgs = EMPTY_STRING_ARRAY;
14211 dumpPackage = args[opti];
14213 newArgs = new String[args.length - opti];
14214 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14215 args.length - opti);
14217 synchronized (this) {
14218 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14220 } else if ("broadcast-stats".equals(cmd)) {
14223 if (opti >= args.length) {
14225 newArgs = EMPTY_STRING_ARRAY;
14227 dumpPackage = args[opti];
14229 newArgs = new String[args.length - opti];
14230 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14231 args.length - opti);
14233 synchronized (this) {
14234 if (dumpCheckinFormat) {
14235 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14238 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14241 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14244 if (opti >= args.length) {
14246 newArgs = EMPTY_STRING_ARRAY;
14248 dumpPackage = args[opti];
14250 newArgs = new String[args.length - opti];
14251 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14252 args.length - opti);
14254 synchronized (this) {
14255 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14257 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14260 if (opti >= args.length) {
14262 newArgs = EMPTY_STRING_ARRAY;
14264 dumpPackage = args[opti];
14266 newArgs = new String[args.length - opti];
14267 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14268 args.length - opti);
14270 synchronized (this) {
14271 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14273 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14274 synchronized (this) {
14275 dumpOomLocked(fd, pw, args, opti, true);
14277 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14278 synchronized (this) {
14279 dumpPermissionsLocked(fd, pw, args, opti, true, null);
14281 } else if ("provider".equals(cmd)) {
14284 if (opti >= args.length) {
14286 newArgs = EMPTY_STRING_ARRAY;
14290 newArgs = new String[args.length - opti];
14291 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14293 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14294 pw.println("No providers match: " + name);
14295 pw.println("Use -h for help.");
14297 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14298 synchronized (this) {
14299 dumpProvidersLocked(fd, pw, args, opti, true, null);
14301 } else if ("service".equals(cmd)) {
14304 if (opti >= args.length) {
14306 newArgs = EMPTY_STRING_ARRAY;
14310 newArgs = new String[args.length - opti];
14311 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14312 args.length - opti);
14314 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14315 pw.println("No services match: " + name);
14316 pw.println("Use -h for help.");
14318 } else if ("package".equals(cmd)) {
14320 if (opti >= args.length) {
14321 pw.println("package: no package name specified");
14322 pw.println("Use -h for help.");
14324 dumpPackage = args[opti];
14326 newArgs = new String[args.length - opti];
14327 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14328 args.length - opti);
14333 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14334 synchronized (this) {
14335 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14337 } else if ("services".equals(cmd) || "s".equals(cmd)) {
14339 ActiveServices.ServiceDumper dumper;
14340 synchronized (this) {
14341 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14344 dumper.dumpWithClient();
14346 synchronized (this) {
14347 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14348 dumpPackage).dumpLocked();
14351 } else if ("locks".equals(cmd)) {
14352 LockGuard.dump(fd, pw, args);
14354 // Dumping a single activity?
14355 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14356 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14357 int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14359 pw.println("Bad activity command, or no activities match: " + cmd);
14360 pw.println("Use -h for help.");
14365 Binder.restoreCallingIdentity(origId);
14370 // No piece of data specified, dump everything.
14371 if (dumpCheckinFormat) {
14372 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14373 } else if (dumpClient) {
14374 ActiveServices.ServiceDumper sdumper;
14375 synchronized (this) {
14376 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14379 pw.println("-------------------------------------------------------------------------------");
14381 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14384 pw.println("-------------------------------------------------------------------------------");
14386 if (dumpAll || dumpPackage != null) {
14387 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14390 pw.println("-------------------------------------------------------------------------------");
14393 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14396 pw.println("-------------------------------------------------------------------------------");
14398 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14401 pw.println("-------------------------------------------------------------------------------");
14403 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14406 sdumper.dumpWithClient();
14408 synchronized (this) {
14410 pw.println("-------------------------------------------------------------------------------");
14412 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14415 pw.println("-------------------------------------------------------------------------------");
14417 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14418 if (mAssociations.size() > 0) {
14421 pw.println("-------------------------------------------------------------------------------");
14423 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14427 pw.println("-------------------------------------------------------------------------------");
14429 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14433 synchronized (this) {
14434 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14437 pw.println("-------------------------------------------------------------------------------");
14439 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14442 pw.println("-------------------------------------------------------------------------------");
14444 if (dumpAll || dumpPackage != null) {
14445 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14448 pw.println("-------------------------------------------------------------------------------");
14451 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14454 pw.println("-------------------------------------------------------------------------------");
14456 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14459 pw.println("-------------------------------------------------------------------------------");
14461 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14465 pw.println("-------------------------------------------------------------------------------");
14467 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14470 pw.println("-------------------------------------------------------------------------------");
14472 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14473 if (mAssociations.size() > 0) {
14476 pw.println("-------------------------------------------------------------------------------");
14478 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14482 pw.println("-------------------------------------------------------------------------------");
14484 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14487 Binder.restoreCallingIdentity(origId);
14490 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14491 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14492 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14494 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14496 boolean needSep = printedAnything;
14498 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14499 dumpPackage, needSep, " mFocusedActivity: ");
14501 printedAnything = true;
14505 if (dumpPackage == null) {
14510 printedAnything = true;
14511 mStackSupervisor.dump(pw, " ");
14514 if (!printedAnything) {
14515 pw.println(" (nothing)");
14519 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14520 int opti, boolean dumpAll, String dumpPackage) {
14521 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14523 boolean printedAnything = false;
14525 if (mRecentTasks != null && mRecentTasks.size() > 0) {
14526 boolean printedHeader = false;
14528 final int N = mRecentTasks.size();
14529 for (int i=0; i<N; i++) {
14530 TaskRecord tr = mRecentTasks.get(i);
14531 if (dumpPackage != null) {
14532 if (tr.realActivity == null ||
14533 !dumpPackage.equals(tr.realActivity)) {
14537 if (!printedHeader) {
14538 pw.println(" Recent tasks:");
14539 printedHeader = true;
14540 printedAnything = true;
14542 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
14545 mRecentTasks.get(i).dump(pw, " ");
14550 if (!printedAnything) {
14551 pw.println(" (nothing)");
14555 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14556 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14557 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14560 if (dumpPackage != null) {
14561 IPackageManager pm = AppGlobals.getPackageManager();
14563 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14564 } catch (RemoteException e) {
14568 boolean printedAnything = false;
14570 final long now = SystemClock.uptimeMillis();
14572 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14573 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14574 = mAssociations.valueAt(i1);
14575 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14576 SparseArray<ArrayMap<String, Association>> sourceUids
14577 = targetComponents.valueAt(i2);
14578 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14579 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14580 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14581 Association ass = sourceProcesses.valueAt(i4);
14582 if (dumpPackage != null) {
14583 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14584 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14588 printedAnything = true;
14590 pw.print(ass.mTargetProcess);
14592 UserHandle.formatUid(pw, ass.mTargetUid);
14594 pw.print(ass.mSourceProcess);
14596 UserHandle.formatUid(pw, ass.mSourceUid);
14599 pw.print(ass.mTargetComponent.flattenToShortString());
14602 long dur = ass.mTime;
14603 if (ass.mNesting > 0) {
14604 dur += now - ass.mStartTime;
14606 TimeUtils.formatDuration(dur, pw);
14608 pw.print(ass.mCount);
14609 pw.print(" times)");
14611 for (int i=0; i<ass.mStateTimes.length; i++) {
14612 long amt = ass.mStateTimes[i];
14613 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14614 amt += now - ass.mLastStateUptime;
14618 pw.print(ProcessList.makeProcStateString(
14619 i + ActivityManager.MIN_PROCESS_STATE));
14621 TimeUtils.formatDuration(amt, pw);
14622 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14628 if (ass.mNesting > 0) {
14629 pw.print(" Currently active: ");
14630 TimeUtils.formatDuration(now - ass.mStartTime, pw);
14639 if (!printedAnything) {
14640 pw.println(" (nothing)");
14644 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14645 String header, boolean needSep) {
14646 boolean printed = false;
14647 int whichAppId = -1;
14648 if (dumpPackage != null) {
14650 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14652 whichAppId = UserHandle.getAppId(info.uid);
14653 } catch (NameNotFoundException e) {
14654 e.printStackTrace();
14657 for (int i=0; i<uids.size(); i++) {
14658 UidRecord uidRec = uids.valueAt(i);
14659 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14668 pw.println(header);
14671 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
14672 pw.print(": "); pw.println(uidRec);
14677 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14678 int opti, boolean dumpAll, String dumpPackage) {
14679 boolean needSep = false;
14680 boolean printedAnything = false;
14683 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14686 final int NP = mProcessNames.getMap().size();
14687 for (int ip=0; ip<NP; ip++) {
14688 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14689 final int NA = procs.size();
14690 for (int ia=0; ia<NA; ia++) {
14691 ProcessRecord r = procs.valueAt(ia);
14692 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14696 pw.println(" All known processes:");
14698 printedAnything = true;
14700 pw.print(r.persistent ? " *PERS*" : " *APP*");
14701 pw.print(" UID "); pw.print(procs.keyAt(ia));
14702 pw.print(" "); pw.println(r);
14704 if (r.persistent) {
14711 if (mIsolatedProcesses.size() > 0) {
14712 boolean printed = false;
14713 for (int i=0; i<mIsolatedProcesses.size(); i++) {
14714 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14715 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14722 pw.println(" Isolated process list (sorted by uid):");
14723 printedAnything = true;
14727 pw.println(String.format("%sIsolated #%2d: %s",
14728 " ", i, r.toString()));
14732 if (mActiveUids.size() > 0) {
14733 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14734 printedAnything = needSep = true;
14737 if (mValidateUids.size() > 0) {
14738 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14739 printedAnything = needSep = true;
14743 if (mLruProcesses.size() > 0) {
14747 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14748 pw.print(" total, non-act at ");
14749 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14750 pw.print(", non-svc at ");
14751 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14753 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
14755 printedAnything = true;
14758 if (dumpAll || dumpPackage != null) {
14759 synchronized (mPidsSelfLocked) {
14760 boolean printed = false;
14761 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14762 ProcessRecord r = mPidsSelfLocked.valueAt(i);
14763 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14767 if (needSep) pw.println();
14769 pw.println(" PID mappings:");
14771 printedAnything = true;
14773 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14774 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14779 if (mForegroundProcesses.size() > 0) {
14780 synchronized (mPidsSelfLocked) {
14781 boolean printed = false;
14782 for (int i=0; i<mForegroundProcesses.size(); i++) {
14783 ProcessRecord r = mPidsSelfLocked.get(
14784 mForegroundProcesses.valueAt(i).pid);
14785 if (dumpPackage != null && (r == null
14786 || !r.pkgList.containsKey(dumpPackage))) {
14790 if (needSep) pw.println();
14792 pw.println(" Foreground Processes:");
14794 printedAnything = true;
14796 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
14797 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14802 if (mPersistentStartingProcesses.size() > 0) {
14803 if (needSep) pw.println();
14805 printedAnything = true;
14806 pw.println(" Persisent processes that are starting:");
14807 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
14808 "Starting Norm", "Restarting PERS", dumpPackage);
14811 if (mRemovedProcesses.size() > 0) {
14812 if (needSep) pw.println();
14814 printedAnything = true;
14815 pw.println(" Processes that are being removed:");
14816 dumpProcessList(pw, this, mRemovedProcesses, " ",
14817 "Removed Norm", "Removed PERS", dumpPackage);
14820 if (mProcessesOnHold.size() > 0) {
14821 if (needSep) pw.println();
14823 printedAnything = true;
14824 pw.println(" Processes that are on old until the system is ready:");
14825 dumpProcessList(pw, this, mProcessesOnHold, " ",
14826 "OnHold Norm", "OnHold PERS", dumpPackage);
14829 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14831 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14833 printedAnything = true;
14836 if (dumpPackage == null) {
14839 mUserController.dump(pw, dumpAll);
14841 if (mHomeProcess != null && (dumpPackage == null
14842 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14847 pw.println(" mHomeProcess: " + mHomeProcess);
14849 if (mPreviousProcess != null && (dumpPackage == null
14850 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14855 pw.println(" mPreviousProcess: " + mPreviousProcess);
14858 StringBuilder sb = new StringBuilder(128);
14859 sb.append(" mPreviousProcessVisibleTime: ");
14860 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14863 if (mHeavyWeightProcess != null && (dumpPackage == null
14864 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14869 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14871 if (dumpPackage == null) {
14872 pw.println(" mConfiguration: " + mConfiguration);
14875 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14876 if (mCompatModePackages.getPackages().size() > 0) {
14877 boolean printed = false;
14878 for (Map.Entry<String, Integer> entry
14879 : mCompatModePackages.getPackages().entrySet()) {
14880 String pkg = entry.getKey();
14881 int mode = entry.getValue();
14882 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14886 pw.println(" mScreenCompatPackages:");
14889 pw.print(" "); pw.print(pkg); pw.print(": ");
14890 pw.print(mode); pw.println();
14894 if (dumpPackage == null) {
14895 pw.println(" mWakefulness="
14896 + PowerManagerInternal.wakefulnessToString(mWakefulness));
14897 pw.println(" mSleepTokens=" + mSleepTokens);
14898 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
14899 + lockScreenShownToString());
14900 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14901 if (mRunningVoice != null) {
14902 pw.println(" mRunningVoice=" + mRunningVoice);
14903 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
14906 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14907 || mOrigWaitForDebugger) {
14908 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14909 || dumpPackage.equals(mOrigDebugApp)) {
14914 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14915 + " mDebugTransient=" + mDebugTransient
14916 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14919 if (mCurAppTimeTracker != null) {
14920 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
14922 if (mMemWatchProcesses.getMap().size() > 0) {
14923 pw.println(" Mem watch processes:");
14924 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14925 = mMemWatchProcesses.getMap();
14926 for (int i=0; i<procs.size(); i++) {
14927 final String proc = procs.keyAt(i);
14928 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14929 for (int j=0; j<uids.size(); j++) {
14934 StringBuilder sb = new StringBuilder();
14935 sb.append(" ").append(proc).append('/');
14936 UserHandle.formatUid(sb, uids.keyAt(j));
14937 Pair<Long, String> val = uids.valueAt(j);
14938 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14939 if (val.second != null) {
14940 sb.append(", report to ").append(val.second);
14942 pw.println(sb.toString());
14945 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14946 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14947 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14948 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14950 if (mTrackAllocationApp != null) {
14951 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14956 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
14959 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14960 || mProfileFd != null) {
14961 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14966 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14967 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14968 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14969 + mAutoStopProfiler);
14970 pw.println(" mProfileType=" + mProfileType);
14973 if (mNativeDebuggingApp != null) {
14974 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14979 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
14982 if (dumpPackage == null) {
14983 if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14984 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
14985 + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14987 if (mController != null) {
14988 pw.println(" mController=" + mController
14989 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14992 pw.println(" Total persistent processes: " + numPers);
14993 pw.println(" mProcessesReady=" + mProcessesReady
14994 + " mSystemReady=" + mSystemReady
14995 + " mBooted=" + mBooted
14996 + " mFactoryTest=" + mFactoryTest);
14997 pw.println(" mBooting=" + mBooting
14998 + " mCallFinishBooting=" + mCallFinishBooting
14999 + " mBootAnimationComplete=" + mBootAnimationComplete);
15000 pw.print(" mLastPowerCheckRealtime=");
15001 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
15003 pw.print(" mLastPowerCheckUptime=");
15004 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
15006 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
15007 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
15008 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
15009 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
15010 + " (" + mLruProcesses.size() + " total)"
15011 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
15012 + " mNumServiceProcs=" + mNumServiceProcs
15013 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
15014 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
15015 + " mLastMemoryLevel=" + mLastMemoryLevel
15016 + " mLastNumProcesses=" + mLastNumProcesses);
15017 long now = SystemClock.uptimeMillis();
15018 pw.print(" mLastIdleTime=");
15019 TimeUtils.formatDuration(now, mLastIdleTime, pw);
15020 pw.print(" mLowRamSinceLastIdle=");
15021 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15026 if (!printedAnything) {
15027 pw.println(" (nothing)");
15031 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15032 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15033 if (mProcessesToGc.size() > 0) {
15034 boolean printed = false;
15035 long now = SystemClock.uptimeMillis();
15036 for (int i=0; i<mProcessesToGc.size(); i++) {
15037 ProcessRecord proc = mProcessesToGc.get(i);
15038 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15042 if (needSep) pw.println();
15044 pw.println(" Processes that are waiting to GC:");
15047 pw.print(" Process "); pw.println(proc);
15048 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
15049 pw.print(", last gced=");
15050 pw.print(now-proc.lastRequestedGc);
15051 pw.print(" ms ago, last lowMem=");
15052 pw.print(now-proc.lastLowMemory);
15053 pw.println(" ms ago");
15060 void printOomLevel(PrintWriter pw, String name, int adj) {
15064 if (adj < 10) pw.print(' ');
15066 if (adj > -10) pw.print(' ');
15072 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15076 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15077 int opti, boolean dumpAll) {
15078 boolean needSep = false;
15080 if (mLruProcesses.size() > 0) {
15081 if (needSep) pw.println();
15083 pw.println(" OOM levels:");
15084 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15085 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15086 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15087 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15088 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15089 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15090 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15091 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15092 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15093 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15094 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15095 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15096 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15097 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15099 if (needSep) pw.println();
15100 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
15101 pw.print(" total, non-act at ");
15102 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15103 pw.print(", non-svc at ");
15104 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15106 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
15110 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15113 pw.println(" mHomeProcess: " + mHomeProcess);
15114 pw.println(" mPreviousProcess: " + mPreviousProcess);
15115 if (mHeavyWeightProcess != null) {
15116 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15123 * There are three ways to call this:
15124 * - no provider specified: dump all the providers
15125 * - a flattened component name that matched an existing provider was specified as the
15126 * first arg: dump that one provider
15127 * - the first arg isn't the flattened component name of an existing provider:
15128 * dump all providers whose component contains the first arg as a substring
15130 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15131 int opti, boolean dumpAll) {
15132 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15135 static class ItemMatcher {
15136 ArrayList<ComponentName> components;
15137 ArrayList<String> strings;
15138 ArrayList<Integer> objects;
15145 void build(String name) {
15146 ComponentName componentName = ComponentName.unflattenFromString(name);
15147 if (componentName != null) {
15148 if (components == null) {
15149 components = new ArrayList<ComponentName>();
15151 components.add(componentName);
15155 // Not a '/' separated full component name; maybe an object ID?
15157 objectId = Integer.parseInt(name, 16);
15158 if (objects == null) {
15159 objects = new ArrayList<Integer>();
15161 objects.add(objectId);
15163 } catch (RuntimeException e) {
15164 // Not an integer; just do string match.
15165 if (strings == null) {
15166 strings = new ArrayList<String>();
15174 int build(String[] args, int opti) {
15175 for (; opti<args.length; opti++) {
15176 String name = args[opti];
15177 if ("--".equals(name)) {
15185 boolean match(Object object, ComponentName comp) {
15189 if (components != null) {
15190 for (int i=0; i<components.size(); i++) {
15191 if (components.get(i).equals(comp)) {
15196 if (objects != null) {
15197 for (int i=0; i<objects.size(); i++) {
15198 if (System.identityHashCode(object) == objects.get(i)) {
15203 if (strings != null) {
15204 String flat = comp.flattenToString();
15205 for (int i=0; i<strings.size(); i++) {
15206 if (flat.contains(strings.get(i))) {
15216 * There are three things that cmd can be:
15217 * - a flattened component name that matches an existing activity
15218 * - the cmd arg isn't the flattened component name of an existing activity:
15219 * dump all activity whose component contains the cmd as a substring
15220 * - A hex number of the ActivityRecord object instance.
15222 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15223 int opti, boolean dumpAll) {
15224 ArrayList<ActivityRecord> activities;
15226 synchronized (this) {
15227 activities = mStackSupervisor.getDumpActivitiesLocked(name);
15230 if (activities.size() <= 0) {
15234 String[] newArgs = new String[args.length - opti];
15235 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15237 TaskRecord lastTask = null;
15238 boolean needSep = false;
15239 for (int i=activities.size()-1; i>=0; i--) {
15240 ActivityRecord r = activities.get(i);
15245 synchronized (this) {
15246 if (lastTask != r.task) {
15248 pw.print("TASK "); pw.print(lastTask.affinity);
15249 pw.print(" id="); pw.println(lastTask.taskId);
15251 lastTask.dump(pw, " ");
15255 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
15261 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15262 * there is a thread associated with the activity.
15264 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15265 final ActivityRecord r, String[] args, boolean dumpAll) {
15266 String innerPrefix = prefix + " ";
15267 synchronized (this) {
15268 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15269 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15271 if (r.app != null) pw.println(r.app.pid);
15272 else pw.println("(not running)");
15274 r.dump(pw, innerPrefix);
15277 if (r.app != null && r.app.thread != null) {
15278 // flush anything that is already in the PrintWriter since the thread is going
15279 // to write to the file descriptor directly
15282 TransferPipe tp = new TransferPipe();
15284 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15285 r.appToken, innerPrefix, args);
15290 } catch (IOException e) {
15291 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15292 } catch (RemoteException e) {
15293 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15298 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15299 int opti, boolean dumpAll, String dumpPackage) {
15300 boolean needSep = false;
15301 boolean onlyHistory = false;
15302 boolean printedAnything = false;
15304 if ("history".equals(dumpPackage)) {
15305 if (opti < args.length && "-s".equals(args[opti])) {
15308 onlyHistory = true;
15309 dumpPackage = null;
15312 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15313 if (!onlyHistory && dumpAll) {
15314 if (mRegisteredReceivers.size() > 0) {
15315 boolean printed = false;
15316 Iterator it = mRegisteredReceivers.values().iterator();
15317 while (it.hasNext()) {
15318 ReceiverList r = (ReceiverList)it.next();
15319 if (dumpPackage != null && (r.app == null ||
15320 !dumpPackage.equals(r.app.info.packageName))) {
15324 pw.println(" Registered Receivers:");
15327 printedAnything = true;
15329 pw.print(" * "); pw.println(r);
15334 if (mReceiverResolver.dump(pw, needSep ?
15335 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
15336 " ", dumpPackage, false, false)) {
15338 printedAnything = true;
15342 for (BroadcastQueue q : mBroadcastQueues) {
15343 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15344 printedAnything |= needSep;
15349 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15350 for (int user=0; user<mStickyBroadcasts.size(); user++) {
15355 printedAnything = true;
15356 pw.print(" Sticky broadcasts for user ");
15357 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15358 StringBuilder sb = new StringBuilder(128);
15359 for (Map.Entry<String, ArrayList<Intent>> ent
15360 : mStickyBroadcasts.valueAt(user).entrySet()) {
15361 pw.print(" * Sticky action "); pw.print(ent.getKey());
15364 ArrayList<Intent> intents = ent.getValue();
15365 final int N = intents.size();
15366 for (int i=0; i<N; i++) {
15368 sb.append(" Intent: ");
15369 intents.get(i).toShortString(sb, false, true, false, false);
15370 pw.println(sb.toString());
15371 Bundle bundle = intents.get(i).getExtras();
15372 if (bundle != null) {
15374 pw.println(bundle.toString());
15384 if (!onlyHistory && dumpAll) {
15386 for (BroadcastQueue queue : mBroadcastQueues) {
15387 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
15388 + queue.mBroadcastsScheduled);
15390 pw.println(" mHandler:");
15391 mHandler.dump(new PrintWriterPrinter(pw), " ");
15393 printedAnything = true;
15396 if (!printedAnything) {
15397 pw.println(" (nothing)");
15401 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15402 int opti, boolean dumpAll, String dumpPackage) {
15403 if (mCurBroadcastStats == null) {
15407 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15408 final long now = SystemClock.elapsedRealtime();
15409 if (mLastBroadcastStats != null) {
15410 pw.print(" Last stats (from ");
15411 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15413 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15415 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15416 - mLastBroadcastStats.mStartUptime, pw);
15417 pw.println(" uptime):");
15418 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15419 pw.println(" (nothing)");
15423 pw.print(" Current stats (from ");
15424 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15425 pw.print(" to now, ");
15426 TimeUtils.formatDuration(SystemClock.uptimeMillis()
15427 - mCurBroadcastStats.mStartUptime, pw);
15428 pw.println(" uptime):");
15429 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15430 pw.println(" (nothing)");
15434 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15435 int opti, boolean fullCheckin, String dumpPackage) {
15436 if (mCurBroadcastStats == null) {
15440 if (mLastBroadcastStats != null) {
15441 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15443 mLastBroadcastStats = null;
15447 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15449 mCurBroadcastStats = null;
15453 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15454 int opti, boolean dumpAll, String dumpPackage) {
15456 boolean printedAnything = false;
15458 ItemMatcher matcher = new ItemMatcher();
15459 matcher.build(args, opti);
15461 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15463 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15464 printedAnything |= needSep;
15466 if (mLaunchingProviders.size() > 0) {
15467 boolean printed = false;
15468 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15469 ContentProviderRecord r = mLaunchingProviders.get(i);
15470 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15474 if (needSep) pw.println();
15476 pw.println(" Launching content providers:");
15478 printedAnything = true;
15480 pw.print(" Launching #"); pw.print(i); pw.print(": ");
15485 if (!printedAnything) {
15486 pw.println(" (nothing)");
15490 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15491 int opti, boolean dumpAll, String dumpPackage) {
15492 boolean needSep = false;
15493 boolean printedAnything = false;
15495 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15497 if (mGrantedUriPermissions.size() > 0) {
15498 boolean printed = false;
15500 if (dumpPackage != null) {
15502 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15503 MATCH_UNINSTALLED_PACKAGES, 0);
15504 } catch (NameNotFoundException e) {
15508 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15509 int uid = mGrantedUriPermissions.keyAt(i);
15510 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15513 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15515 if (needSep) pw.println();
15517 pw.println(" Granted Uri Permissions:");
15519 printedAnything = true;
15521 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
15522 for (UriPermission perm : perms.values()) {
15523 pw.print(" "); pw.println(perm);
15525 perm.dump(pw, " ");
15531 if (!printedAnything) {
15532 pw.println(" (nothing)");
15536 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15537 int opti, boolean dumpAll, String dumpPackage) {
15538 boolean printed = false;
15540 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15542 if (mIntentSenderRecords.size() > 0) {
15543 Iterator<WeakReference<PendingIntentRecord>> it
15544 = mIntentSenderRecords.values().iterator();
15545 while (it.hasNext()) {
15546 WeakReference<PendingIntentRecord> ref = it.next();
15547 PendingIntentRecord rec = ref != null ? ref.get(): null;
15548 if (dumpPackage != null && (rec == null
15549 || !dumpPackage.equals(rec.key.packageName))) {
15554 pw.print(" * "); pw.println(rec);
15559 pw.print(" * "); pw.println(ref);
15565 pw.println(" (nothing)");
15569 private static final int dumpProcessList(PrintWriter pw,
15570 ActivityManagerService service, List list,
15571 String prefix, String normalLabel, String persistentLabel,
15572 String dumpPackage) {
15574 final int N = list.size()-1;
15575 for (int i=N; i>=0; i--) {
15576 ProcessRecord r = (ProcessRecord)list.get(i);
15577 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15580 pw.println(String.format("%s%s #%2d: %s",
15581 prefix, (r.persistent ? persistentLabel : normalLabel),
15583 if (r.persistent) {
15590 private static final boolean dumpProcessOomList(PrintWriter pw,
15591 ActivityManagerService service, List<ProcessRecord> origList,
15592 String prefix, String normalLabel, String persistentLabel,
15593 boolean inclDetails, String dumpPackage) {
15595 ArrayList<Pair<ProcessRecord, Integer>> list
15596 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15597 for (int i=0; i<origList.size(); i++) {
15598 ProcessRecord r = origList.get(i);
15599 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15602 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15605 if (list.size() <= 0) {
15609 Comparator<Pair<ProcessRecord, Integer>> comparator
15610 = new Comparator<Pair<ProcessRecord, Integer>>() {
15612 public int compare(Pair<ProcessRecord, Integer> object1,
15613 Pair<ProcessRecord, Integer> object2) {
15614 if (object1.first.setAdj != object2.first.setAdj) {
15615 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15617 if (object1.first.setProcState != object2.first.setProcState) {
15618 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15620 if (object1.second.intValue() != object2.second.intValue()) {
15621 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15627 Collections.sort(list, comparator);
15629 final long curRealtime = SystemClock.elapsedRealtime();
15630 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15631 final long curUptime = SystemClock.uptimeMillis();
15632 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15634 for (int i=list.size()-1; i>=0; i--) {
15635 ProcessRecord r = list.get(i).first;
15636 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15638 switch (r.setSchedGroup) {
15639 case ProcessList.SCHED_GROUP_BACKGROUND:
15642 case ProcessList.SCHED_GROUP_DEFAULT:
15645 case ProcessList.SCHED_GROUP_TOP_APP:
15653 if (r.foregroundActivities) {
15655 } else if (r.foregroundServices) {
15660 String procState = ProcessList.makeProcStateString(r.curProcState);
15662 pw.print(r.persistent ? persistentLabel : normalLabel);
15664 int num = (origList.size()-1)-list.get(i).second;
15665 if (num < 10) pw.print(' ');
15670 pw.print(schedGroup);
15672 pw.print(foreground);
15674 pw.print(procState);
15676 if (r.trimMemoryLevel < 10) pw.print(' ');
15677 pw.print(r.trimMemoryLevel);
15679 pw.print(r.toShortString());
15681 pw.print(r.adjType);
15683 if (r.adjSource != null || r.adjTarget != null) {
15686 if (r.adjTarget instanceof ComponentName) {
15687 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15688 } else if (r.adjTarget != null) {
15689 pw.print(r.adjTarget.toString());
15691 pw.print("{null}");
15694 if (r.adjSource instanceof ProcessRecord) {
15696 pw.print(((ProcessRecord)r.adjSource).toShortString());
15698 } else if (r.adjSource != null) {
15699 pw.println(r.adjSource.toString());
15701 pw.println("{null}");
15707 pw.print("oom: max="); pw.print(r.maxAdj);
15708 pw.print(" curRaw="); pw.print(r.curRawAdj);
15709 pw.print(" setRaw="); pw.print(r.setRawAdj);
15710 pw.print(" cur="); pw.print(r.curAdj);
15711 pw.print(" set="); pw.println(r.setAdj);
15714 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15715 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15716 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15717 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15718 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15722 pw.print("cached="); pw.print(r.cached);
15723 pw.print(" empty="); pw.print(r.empty);
15724 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15726 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15727 if (r.lastWakeTime != 0) {
15729 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15730 synchronized (stats) {
15731 wtime = stats.getProcessWakeTime(r.info.uid,
15732 r.pid, curRealtime);
15734 long timeUsed = wtime - r.lastWakeTime;
15737 pw.print("keep awake over ");
15738 TimeUtils.formatDuration(realtimeSince, pw);
15739 pw.print(" used ");
15740 TimeUtils.formatDuration(timeUsed, pw);
15742 pw.print((timeUsed*100)/realtimeSince);
15745 if (r.lastCpuTime != 0) {
15746 long timeUsed = r.curCpuTime - r.lastCpuTime;
15749 pw.print("run cpu over ");
15750 TimeUtils.formatDuration(uptimeSince, pw);
15751 pw.print(" used ");
15752 TimeUtils.formatDuration(timeUsed, pw);
15754 pw.print((timeUsed*100)/uptimeSince);
15763 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15765 ArrayList<ProcessRecord> procs;
15766 synchronized (this) {
15767 if (args != null && args.length > start
15768 && args[start].charAt(0) != '-') {
15769 procs = new ArrayList<ProcessRecord>();
15772 pid = Integer.parseInt(args[start]);
15773 } catch (NumberFormatException e) {
15775 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15776 ProcessRecord proc = mLruProcesses.get(i);
15777 if (proc.pid == pid) {
15779 } else if (allPkgs && proc.pkgList != null
15780 && proc.pkgList.containsKey(args[start])) {
15782 } else if (proc.processName.equals(args[start])) {
15786 if (procs.size() <= 0) {
15790 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15796 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15797 PrintWriter pw, String[] args) {
15798 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15799 if (procs == null) {
15800 pw.println("No process found for: " + args[0]);
15804 long uptime = SystemClock.uptimeMillis();
15805 long realtime = SystemClock.elapsedRealtime();
15806 pw.println("Applications Graphics Acceleration Info:");
15807 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15809 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15810 ProcessRecord r = procs.get(i);
15811 if (r.thread != null) {
15812 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15815 TransferPipe tp = new TransferPipe();
15817 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15822 } catch (IOException e) {
15823 pw.println("Failure while dumping the app: " + r);
15825 } catch (RemoteException e) {
15826 pw.println("Got a RemoteException while dumping the app " + r);
15833 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15834 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15835 if (procs == null) {
15836 pw.println("No process found for: " + args[0]);
15840 pw.println("Applications Database Info:");
15842 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15843 ProcessRecord r = procs.get(i);
15844 if (r.thread != null) {
15845 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15848 TransferPipe tp = new TransferPipe();
15850 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15855 } catch (IOException e) {
15856 pw.println("Failure while dumping the app: " + r);
15858 } catch (RemoteException e) {
15859 pw.println("Got a RemoteException while dumping the app " + r);
15866 final static class MemItem {
15867 final boolean isProc;
15868 final String label;
15869 final String shortLabel;
15871 final long swapPss;
15873 final boolean hasActivities;
15874 ArrayList<MemItem> subitems;
15876 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15877 boolean _hasActivities) {
15880 shortLabel = _shortLabel;
15882 swapPss = _swapPss;
15884 hasActivities = _hasActivities;
15887 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15890 shortLabel = _shortLabel;
15892 swapPss = _swapPss;
15894 hasActivities = false;
15898 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15899 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15900 if (sort && !isCompact) {
15901 Collections.sort(items, new Comparator<MemItem>() {
15903 public int compare(MemItem lhs, MemItem rhs) {
15904 if (lhs.pss < rhs.pss) {
15906 } else if (lhs.pss > rhs.pss) {
15914 for (int i=0; i<items.size(); i++) {
15915 MemItem mi = items.get(i);
15918 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15919 mi.label, stringifyKBSize(mi.swapPss));
15921 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15923 } else if (mi.isProc) {
15924 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15925 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15926 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15927 pw.println(mi.hasActivities ? ",a" : ",e");
15929 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15930 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15932 if (mi.subitems != null) {
15933 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
15934 true, isCompact, dumpSwapPss);
15939 // These are in KB.
15940 static final long[] DUMP_MEM_BUCKETS = new long[] {
15941 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15942 120*1024, 160*1024, 200*1024,
15943 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15944 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15947 static final void appendMemBucket(StringBuilder out, long memKB, String label,
15948 boolean stackLike) {
15949 int start = label.lastIndexOf('.');
15950 if (start >= 0) start++;
15952 int end = label.length();
15953 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15954 if (DUMP_MEM_BUCKETS[i] >= memKB) {
15955 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15956 out.append(bucket);
15957 out.append(stackLike ? "MB." : "MB ");
15958 out.append(label, start, end);
15962 out.append(memKB/1024);
15963 out.append(stackLike ? "MB." : "MB ");
15964 out.append(label, start, end);
15967 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15968 ProcessList.NATIVE_ADJ,
15969 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15970 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15971 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15972 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15973 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15974 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15976 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15978 "System", "Persistent", "Persistent Service", "Foreground",
15979 "Visible", "Perceptible",
15980 "Heavy Weight", "Backup",
15981 "A Services", "Home",
15982 "Previous", "B Services", "Cached"
15984 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15986 "sys", "pers", "persvc", "fore",
15989 "servicea", "home",
15990 "prev", "serviceb", "cached"
15993 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15994 long realtime, boolean isCheckinRequest, boolean isCompact) {
15996 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15998 if (isCheckinRequest || isCompact) {
15999 // short checkin version
16000 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
16002 pw.println("Applications Memory Usage (in Kilobytes):");
16003 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
16007 private static final int KSM_SHARED = 0;
16008 private static final int KSM_SHARING = 1;
16009 private static final int KSM_UNSHARED = 2;
16010 private static final int KSM_VOLATILE = 3;
16012 private final long[] getKsmInfo() {
16013 long[] longOut = new long[4];
16014 final int[] SINGLE_LONG_FORMAT = new int[] {
16015 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
16017 long[] longTmp = new long[1];
16018 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16019 SINGLE_LONG_FORMAT, null, longTmp, null);
16020 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16022 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16023 SINGLE_LONG_FORMAT, null, longTmp, null);
16024 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16026 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16027 SINGLE_LONG_FORMAT, null, longTmp, null);
16028 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16030 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16031 SINGLE_LONG_FORMAT, null, longTmp, null);
16032 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16036 private static String stringifySize(long size, int order) {
16037 Locale locale = Locale.US;
16040 return String.format(locale, "%,13d", size);
16042 return String.format(locale, "%,9dK", size / 1024);
16044 return String.format(locale, "%,5dM", size / 1024 / 1024);
16045 case 1024 * 1024 * 1024:
16046 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16048 throw new IllegalArgumentException("Invalid size order");
16052 private static String stringifyKBSize(long size) {
16053 return stringifySize(size * 1024, 1024);
16056 // Update this version number in case you change the 'compact' format
16057 private static final int MEMINFO_COMPACT_VERSION = 1;
16059 final void dumpApplicationMemoryUsage(FileDescriptor fd,
16060 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16061 boolean dumpDetails = false;
16062 boolean dumpFullDetails = false;
16063 boolean dumpDalvik = false;
16064 boolean dumpSummaryOnly = false;
16065 boolean dumpUnreachable = false;
16066 boolean oomOnly = false;
16067 boolean isCompact = false;
16068 boolean localOnly = false;
16069 boolean packages = false;
16070 boolean isCheckinRequest = false;
16071 boolean dumpSwapPss = false;
16074 while (opti < args.length) {
16075 String opt = args[opti];
16076 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16080 if ("-a".equals(opt)) {
16081 dumpDetails = true;
16082 dumpFullDetails = true;
16084 dumpSwapPss = true;
16085 } else if ("-d".equals(opt)) {
16087 } else if ("-c".equals(opt)) {
16089 } else if ("-s".equals(opt)) {
16090 dumpDetails = true;
16091 dumpSummaryOnly = true;
16092 } else if ("-S".equals(opt)) {
16093 dumpSwapPss = true;
16094 } else if ("--unreachable".equals(opt)) {
16095 dumpUnreachable = true;
16096 } else if ("--oom".equals(opt)) {
16098 } else if ("--local".equals(opt)) {
16100 } else if ("--package".equals(opt)) {
16102 } else if ("--checkin".equals(opt)) {
16103 isCheckinRequest = true;
16105 } else if ("-h".equals(opt)) {
16106 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16107 pw.println(" -a: include all available information for each process.");
16108 pw.println(" -d: include dalvik details.");
16109 pw.println(" -c: dump in a compact machine-parseable representation.");
16110 pw.println(" -s: dump only summary of application memory usage.");
16111 pw.println(" -S: dump also SwapPss.");
16112 pw.println(" --oom: only show processes organized by oom adj.");
16113 pw.println(" --local: only collect details locally, don't call process.");
16114 pw.println(" --package: interpret process arg as package, dumping all");
16115 pw.println(" processes that have loaded that package.");
16116 pw.println(" --checkin: dump data for a checkin");
16117 pw.println("If [process] is specified it can be the name or ");
16118 pw.println("pid of a specific process to dump.");
16121 pw.println("Unknown argument: " + opt + "; use -h for help");
16125 long uptime = SystemClock.uptimeMillis();
16126 long realtime = SystemClock.elapsedRealtime();
16127 final long[] tmpLong = new long[1];
16129 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16130 if (procs == null) {
16131 // No Java processes. Maybe they want to print a native process.
16132 if (args != null && args.length > opti
16133 && args[opti].charAt(0) != '-') {
16134 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16135 = new ArrayList<ProcessCpuTracker.Stats>();
16136 updateCpuStatsNow();
16139 findPid = Integer.parseInt(args[opti]);
16140 } catch (NumberFormatException e) {
16142 synchronized (mProcessCpuTracker) {
16143 final int N = mProcessCpuTracker.countStats();
16144 for (int i=0; i<N; i++) {
16145 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16146 if (st.pid == findPid || (st.baseName != null
16147 && st.baseName.equals(args[opti]))) {
16148 nativeProcs.add(st);
16152 if (nativeProcs.size() > 0) {
16153 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16155 Debug.MemoryInfo mi = null;
16156 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16157 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16158 final int pid = r.pid;
16159 if (!isCheckinRequest && dumpDetails) {
16160 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16163 mi = new Debug.MemoryInfo();
16165 if (dumpDetails || (!brief && !oomOnly)) {
16166 Debug.getMemoryInfo(pid, mi);
16168 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16169 mi.dalvikPrivateDirty = (int)tmpLong[0];
16171 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16172 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16173 if (isCheckinRequest) {
16180 pw.println("No process found for: " + args[opti]);
16184 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16185 dumpDetails = true;
16188 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16190 String[] innerArgs = new String[args.length-opti];
16191 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16193 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16194 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16195 long nativePss = 0;
16196 long nativeSwapPss = 0;
16197 long dalvikPss = 0;
16198 long dalvikSwapPss = 0;
16199 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16201 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16204 long otherSwapPss = 0;
16205 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16206 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16208 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16209 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16210 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16211 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16214 long totalSwapPss = 0;
16215 long cachedPss = 0;
16216 long cachedSwapPss = 0;
16217 boolean hasSwapPss = false;
16219 Debug.MemoryInfo mi = null;
16220 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16221 final ProcessRecord r = procs.get(i);
16222 final IApplicationThread thread;
16225 final boolean hasActivities;
16226 synchronized (this) {
16229 oomAdj = r.getSetAdjWithServices();
16230 hasActivities = r.activities.size() > 0;
16232 if (thread != null) {
16233 if (!isCheckinRequest && dumpDetails) {
16234 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16237 mi = new Debug.MemoryInfo();
16239 if (dumpDetails || (!brief && !oomOnly)) {
16240 Debug.getMemoryInfo(pid, mi);
16241 hasSwapPss = mi.hasSwappedOutPss;
16243 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16244 mi.dalvikPrivateDirty = (int)tmpLong[0];
16248 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16249 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16250 if (isCheckinRequest) {
16256 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16257 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16258 } catch (RemoteException e) {
16259 if (!isCheckinRequest) {
16260 pw.println("Got RemoteException!");
16267 final long myTotalPss = mi.getTotalPss();
16268 final long myTotalUss = mi.getTotalUss();
16269 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16271 synchronized (this) {
16272 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16273 // Record this for posterity if the process has been stable.
16274 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16278 if (!isCheckinRequest && mi != null) {
16279 totalPss += myTotalPss;
16280 totalSwapPss += myTotalSwapPss;
16281 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16282 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16283 myTotalSwapPss, pid, hasActivities);
16284 procMems.add(pssItem);
16285 procMemsMap.put(pid, pssItem);
16287 nativePss += mi.nativePss;
16288 nativeSwapPss += mi.nativeSwappedOutPss;
16289 dalvikPss += mi.dalvikPss;
16290 dalvikSwapPss += mi.dalvikSwappedOutPss;
16291 for (int j=0; j<dalvikSubitemPss.length; j++) {
16292 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16293 dalvikSubitemSwapPss[j] +=
16294 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16296 otherPss += mi.otherPss;
16297 otherSwapPss += mi.otherSwappedOutPss;
16298 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16299 long mem = mi.getOtherPss(j);
16302 mem = mi.getOtherSwappedOutPss(j);
16303 miscSwapPss[j] += mem;
16304 otherSwapPss -= mem;
16307 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16308 cachedPss += myTotalPss;
16309 cachedSwapPss += myTotalSwapPss;
16312 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16313 if (oomIndex == (oomPss.length - 1)
16314 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16315 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16316 oomPss[oomIndex] += myTotalPss;
16317 oomSwapPss[oomIndex] += myTotalSwapPss;
16318 if (oomProcs[oomIndex] == null) {
16319 oomProcs[oomIndex] = new ArrayList<MemItem>();
16321 oomProcs[oomIndex].add(pssItem);
16329 long nativeProcTotalPss = 0;
16331 if (!isCheckinRequest && procs.size() > 1 && !packages) {
16332 // If we are showing aggregations, also look for native processes to
16333 // include so that our aggregations are more accurate.
16334 updateCpuStatsNow();
16336 synchronized (mProcessCpuTracker) {
16337 final int N = mProcessCpuTracker.countStats();
16338 for (int i=0; i<N; i++) {
16339 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16340 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16342 mi = new Debug.MemoryInfo();
16344 if (!brief && !oomOnly) {
16345 Debug.getMemoryInfo(st.pid, mi);
16347 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16348 mi.nativePrivateDirty = (int)tmpLong[0];
16351 final long myTotalPss = mi.getTotalPss();
16352 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16353 totalPss += myTotalPss;
16354 nativeProcTotalPss += myTotalPss;
16356 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16357 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16358 procMems.add(pssItem);
16360 nativePss += mi.nativePss;
16361 nativeSwapPss += mi.nativeSwappedOutPss;
16362 dalvikPss += mi.dalvikPss;
16363 dalvikSwapPss += mi.dalvikSwappedOutPss;
16364 for (int j=0; j<dalvikSubitemPss.length; j++) {
16365 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16366 dalvikSubitemSwapPss[j] +=
16367 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16369 otherPss += mi.otherPss;
16370 otherSwapPss += mi.otherSwappedOutPss;
16371 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16372 long mem = mi.getOtherPss(j);
16375 mem = mi.getOtherSwappedOutPss(j);
16376 miscSwapPss[j] += mem;
16377 otherSwapPss -= mem;
16379 oomPss[0] += myTotalPss;
16380 oomSwapPss[0] += myTotalSwapPss;
16381 if (oomProcs[0] == null) {
16382 oomProcs[0] = new ArrayList<MemItem>();
16384 oomProcs[0].add(pssItem);
16389 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16391 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16392 final MemItem dalvikItem =
16393 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16394 if (dalvikSubitemPss.length > 0) {
16395 dalvikItem.subitems = new ArrayList<MemItem>();
16396 for (int j=0; j<dalvikSubitemPss.length; j++) {
16397 final String name = Debug.MemoryInfo.getOtherLabel(
16398 Debug.MemoryInfo.NUM_OTHER_STATS + j);
16399 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16400 dalvikSubitemSwapPss[j], j));
16403 catMems.add(dalvikItem);
16404 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16405 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16406 String label = Debug.MemoryInfo.getOtherLabel(j);
16407 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16410 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16411 for (int j=0; j<oomPss.length; j++) {
16412 if (oomPss[j] != 0) {
16413 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16414 : DUMP_MEM_OOM_LABEL[j];
16415 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16416 DUMP_MEM_OOM_ADJ[j]);
16417 item.subitems = oomProcs[j];
16422 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16423 if (!brief && !oomOnly && !isCompact) {
16425 pw.println("Total PSS by process:");
16426 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
16430 pw.println("Total PSS by OOM adjustment:");
16432 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
16433 if (!brief && !oomOnly) {
16434 PrintWriter out = categoryPw != null ? categoryPw : pw;
16437 out.println("Total PSS by category:");
16439 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
16444 MemInfoReader memInfo = new MemInfoReader();
16445 memInfo.readMemInfo();
16446 if (nativeProcTotalPss > 0) {
16447 synchronized (this) {
16448 final long cachedKb = memInfo.getCachedSizeKb();
16449 final long freeKb = memInfo.getFreeSizeKb();
16450 final long zramKb = memInfo.getZramTotalSizeKb();
16451 final long kernelKb = memInfo.getKernelUsedSizeKb();
16452 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16453 kernelKb*1024, nativeProcTotalPss*1024);
16454 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16455 nativeProcTotalPss);
16460 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16461 pw.print(" (status ");
16462 switch (mLastMemoryLevel) {
16463 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16464 pw.println("normal)");
16466 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16467 pw.println("moderate)");
16469 case ProcessStats.ADJ_MEM_FACTOR_LOW:
16470 pw.println("low)");
16472 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16473 pw.println("critical)");
16476 pw.print(mLastMemoryLevel);
16480 pw.print(" Free RAM: ");
16481 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16482 + memInfo.getFreeSizeKb()));
16484 pw.print(stringifyKBSize(cachedPss));
16485 pw.print(" cached pss + ");
16486 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16487 pw.print(" cached kernel + ");
16488 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16489 pw.println(" free)");
16491 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16492 pw.print(cachedPss + memInfo.getCachedSizeKb()
16493 + memInfo.getFreeSizeKb()); pw.print(",");
16494 pw.println(totalPss - cachedPss);
16497 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16498 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16499 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16501 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16502 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16503 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16504 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16505 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16507 pw.print("lostram,"); pw.println(lostRAM);
16510 if (memInfo.getZramTotalSizeKb() != 0) {
16512 pw.print(" ZRAM: ");
16513 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16514 pw.print(" physical used for ");
16515 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16516 - memInfo.getSwapFreeSizeKb()));
16517 pw.print(" in swap (");
16518 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16519 pw.println(" total swap)");
16521 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16522 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16523 pw.println(memInfo.getSwapFreeSizeKb());
16526 final long[] ksm = getKsmInfo();
16528 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16529 || ksm[KSM_VOLATILE] != 0) {
16530 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16531 pw.print(" saved from shared ");
16532 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16533 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16534 pw.print(" unshared; ");
16535 pw.print(stringifyKBSize(
16536 ksm[KSM_VOLATILE])); pw.println(" volatile");
16538 pw.print(" Tuning: ");
16539 pw.print(ActivityManager.staticGetMemoryClass());
16540 pw.print(" (large ");
16541 pw.print(ActivityManager.staticGetLargeMemoryClass());
16542 pw.print("), oom ");
16543 pw.print(stringifySize(
16544 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16545 pw.print(", restore limit ");
16546 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16547 if (ActivityManager.isLowRamDeviceStatic()) {
16548 pw.print(" (low-ram)");
16550 if (ActivityManager.isHighEndGfx()) {
16551 pw.print(" (high-end-gfx)");
16555 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16556 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16557 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16558 pw.print("tuning,");
16559 pw.print(ActivityManager.staticGetMemoryClass());
16561 pw.print(ActivityManager.staticGetLargeMemoryClass());
16563 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16564 if (ActivityManager.isLowRamDeviceStatic()) {
16565 pw.print(",low-ram");
16567 if (ActivityManager.isHighEndGfx()) {
16568 pw.print(",high-end-gfx");
16576 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16577 long memtrack, String name) {
16579 sb.append(ProcessList.makeOomAdjString(oomAdj));
16581 sb.append(ProcessList.makeProcStateString(procState));
16583 ProcessList.appendRamKb(sb, pss);
16586 if (memtrack > 0) {
16588 sb.append(stringifyKBSize(memtrack));
16589 sb.append(" memtrack)");
16593 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16594 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16595 sb.append(" (pid ");
16598 sb.append(mi.adjType);
16600 if (mi.adjReason != null) {
16602 sb.append(mi.adjReason);
16607 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16608 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16609 for (int i=0, N=memInfos.size(); i<N; i++) {
16610 ProcessMemInfo mi = memInfos.get(i);
16611 infoMap.put(mi.pid, mi);
16613 updateCpuStatsNow();
16614 long[] memtrackTmp = new long[1];
16615 final List<ProcessCpuTracker.Stats> stats;
16616 // Get a list of Stats that have vsize > 0
16617 synchronized (mProcessCpuTracker) {
16618 stats = mProcessCpuTracker.getStats((st) -> {
16619 return st.vsize > 0;
16622 final int statsCount = stats.size();
16623 for (int i = 0; i < statsCount; i++) {
16624 ProcessCpuTracker.Stats st = stats.get(i);
16625 long pss = Debug.getPss(st.pid, null, memtrackTmp);
16627 if (infoMap.indexOfKey(st.pid) < 0) {
16628 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16629 ProcessList.NATIVE_ADJ, -1, "native", null);
16631 mi.memtrack = memtrackTmp[0];
16638 long totalMemtrack = 0;
16639 for (int i=0, N=memInfos.size(); i<N; i++) {
16640 ProcessMemInfo mi = memInfos.get(i);
16642 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16643 mi.memtrack = memtrackTmp[0];
16645 totalPss += mi.pss;
16646 totalMemtrack += mi.memtrack;
16648 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16649 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16650 if (lhs.oomAdj != rhs.oomAdj) {
16651 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16653 if (lhs.pss != rhs.pss) {
16654 return lhs.pss < rhs.pss ? 1 : -1;
16660 StringBuilder tag = new StringBuilder(128);
16661 StringBuilder stack = new StringBuilder(128);
16662 tag.append("Low on memory -- ");
16663 appendMemBucket(tag, totalPss, "total", false);
16664 appendMemBucket(stack, totalPss, "total", true);
16666 StringBuilder fullNativeBuilder = new StringBuilder(1024);
16667 StringBuilder shortNativeBuilder = new StringBuilder(1024);
16668 StringBuilder fullJavaBuilder = new StringBuilder(1024);
16670 boolean firstLine = true;
16671 int lastOomAdj = Integer.MIN_VALUE;
16672 long extraNativeRam = 0;
16673 long extraNativeMemtrack = 0;
16674 long cachedPss = 0;
16675 for (int i=0, N=memInfos.size(); i<N; i++) {
16676 ProcessMemInfo mi = memInfos.get(i);
16678 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16679 cachedPss += mi.pss;
16682 if (mi.oomAdj != ProcessList.NATIVE_ADJ
16683 && (mi.oomAdj < ProcessList.SERVICE_ADJ
16684 || mi.oomAdj == ProcessList.HOME_APP_ADJ
16685 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16686 if (lastOomAdj != mi.oomAdj) {
16687 lastOomAdj = mi.oomAdj;
16688 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16691 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16696 stack.append("\n\t at ");
16704 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16705 appendMemBucket(tag, mi.pss, mi.name, false);
16707 appendMemBucket(stack, mi.pss, mi.name, true);
16708 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16709 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16711 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16712 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16713 stack.append(DUMP_MEM_OOM_LABEL[k]);
16715 stack.append(DUMP_MEM_OOM_ADJ[k]);
16722 appendMemInfo(fullNativeBuilder, mi);
16723 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16724 // The short form only has native processes that are >= 512K.
16725 if (mi.pss >= 512) {
16726 appendMemInfo(shortNativeBuilder, mi);
16728 extraNativeRam += mi.pss;
16729 extraNativeMemtrack += mi.memtrack;
16732 // Short form has all other details, but if we have collected RAM
16733 // from smaller native processes let's dump a summary of that.
16734 if (extraNativeRam > 0) {
16735 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16736 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16737 shortNativeBuilder.append('\n');
16738 extraNativeRam = 0;
16740 appendMemInfo(fullJavaBuilder, mi);
16744 fullJavaBuilder.append(" ");
16745 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16746 fullJavaBuilder.append(": TOTAL");
16747 if (totalMemtrack > 0) {
16748 fullJavaBuilder.append(" (");
16749 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16750 fullJavaBuilder.append(" memtrack)");
16753 fullJavaBuilder.append("\n");
16755 MemInfoReader memInfo = new MemInfoReader();
16756 memInfo.readMemInfo();
16757 final long[] infos = memInfo.getRawInfo();
16759 StringBuilder memInfoBuilder = new StringBuilder(1024);
16760 Debug.getMemInfo(infos);
16761 memInfoBuilder.append(" MemInfo: ");
16762 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16763 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16764 memInfoBuilder.append(stringifyKBSize(
16765 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16766 memInfoBuilder.append(stringifyKBSize(
16767 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16768 memInfoBuilder.append(stringifyKBSize(
16769 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16770 memInfoBuilder.append(" ");
16771 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16772 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16773 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16774 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16775 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16776 memInfoBuilder.append(" ZRAM: ");
16777 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16778 memInfoBuilder.append(" RAM, ");
16779 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16780 memInfoBuilder.append(" swap total, ");
16781 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16782 memInfoBuilder.append(" swap free\n");
16784 final long[] ksm = getKsmInfo();
16785 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16786 || ksm[KSM_VOLATILE] != 0) {
16787 memInfoBuilder.append(" KSM: ");
16788 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16789 memInfoBuilder.append(" saved from shared ");
16790 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16791 memInfoBuilder.append("\n ");
16792 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16793 memInfoBuilder.append(" unshared; ");
16794 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16795 memInfoBuilder.append(" volatile\n");
16797 memInfoBuilder.append(" Free RAM: ");
16798 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16799 + memInfo.getFreeSizeKb()));
16800 memInfoBuilder.append("\n");
16801 memInfoBuilder.append(" Used RAM: ");
16802 memInfoBuilder.append(stringifyKBSize(
16803 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16804 memInfoBuilder.append("\n");
16805 memInfoBuilder.append(" Lost RAM: ");
16806 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16807 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16808 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16809 memInfoBuilder.append("\n");
16810 Slog.i(TAG, "Low on memory:");
16811 Slog.i(TAG, shortNativeBuilder.toString());
16812 Slog.i(TAG, fullJavaBuilder.toString());
16813 Slog.i(TAG, memInfoBuilder.toString());
16815 StringBuilder dropBuilder = new StringBuilder(1024);
16817 StringWriter oomSw = new StringWriter();
16818 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16819 StringWriter catSw = new StringWriter();
16820 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16821 String[] emptyArgs = new String[] { };
16822 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
16824 String oomString = oomSw.toString();
16826 dropBuilder.append("Low on memory:");
16827 dropBuilder.append(stack);
16828 dropBuilder.append('\n');
16829 dropBuilder.append(fullNativeBuilder);
16830 dropBuilder.append(fullJavaBuilder);
16831 dropBuilder.append('\n');
16832 dropBuilder.append(memInfoBuilder);
16833 dropBuilder.append('\n');
16835 dropBuilder.append(oomString);
16836 dropBuilder.append('\n');
16838 StringWriter catSw = new StringWriter();
16839 synchronized (ActivityManagerService.this) {
16840 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16841 String[] emptyArgs = new String[] { };
16843 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16845 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16846 false, null).dumpLocked();
16848 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16851 dropBuilder.append(catSw.toString());
16852 addErrorToDropBox("lowmem", null, "system_server", null,
16853 null, tag.toString(), dropBuilder.toString(), null, null);
16854 //Slog.i(TAG, "Sent to dropbox:");
16855 //Slog.i(TAG, dropBuilder.toString());
16856 synchronized (ActivityManagerService.this) {
16857 long now = SystemClock.uptimeMillis();
16858 if (mLastMemUsageReportTime < now) {
16859 mLastMemUsageReportTime = now;
16865 * Searches array of arguments for the specified string
16866 * @param args array of argument strings
16867 * @param value value to search for
16868 * @return true if the value is contained in the array
16870 private static boolean scanArgs(String[] args, String value) {
16871 if (args != null) {
16872 for (String arg : args) {
16873 if (value.equals(arg)) {
16881 private final boolean removeDyingProviderLocked(ProcessRecord proc,
16882 ContentProviderRecord cpr, boolean always) {
16883 final boolean inLaunching = mLaunchingProviders.contains(cpr);
16885 if (!inLaunching || always) {
16886 synchronized (cpr) {
16887 cpr.launchingApp = null;
16890 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16891 String names[] = cpr.info.authority.split(";");
16892 for (int j = 0; j < names.length; j++) {
16893 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16897 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16898 ContentProviderConnection conn = cpr.connections.get(i);
16899 if (conn.waiting) {
16900 // If this connection is waiting for the provider, then we don't
16901 // need to mess with its process unless we are always removing
16902 // or for some reason the provider is not currently launching.
16903 if (inLaunching && !always) {
16907 ProcessRecord capp = conn.client;
16909 if (conn.stableCount > 0) {
16910 if (!capp.persistent && capp.thread != null
16912 && capp.pid != MY_PID) {
16913 capp.kill("depends on provider "
16914 + cpr.name.flattenToShortString()
16915 + " in dying proc " + (proc != null ? proc.processName : "??")
16916 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16918 } else if (capp.thread != null && conn.provider.provider != null) {
16920 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16921 } catch (RemoteException e) {
16923 // In the protocol here, we don't expect the client to correctly
16924 // clean up this connection, we'll just remove it.
16925 cpr.connections.remove(i);
16926 if (conn.client.conProviders.remove(conn)) {
16927 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16932 if (inLaunching && always) {
16933 mLaunchingProviders.remove(cpr);
16935 return inLaunching;
16939 * Main code for cleaning up a process when it has gone away. This is
16940 * called both as a result of the process dying, or directly when stopping
16941 * a process when running in single process mode.
16943 * @return Returns true if the given process has been restarted, so the
16944 * app that was passed in must remain on the process lists.
16946 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16947 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16948 Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16950 removeLruProcessLocked(app);
16951 ProcessList.remove(app.pid);
16954 mProcessesToGc.remove(app);
16955 mPendingPssProcesses.remove(app);
16957 // Dismiss any open dialogs.
16958 if (app.crashDialog != null && !app.forceCrashReport) {
16959 app.crashDialog.dismiss();
16960 app.crashDialog = null;
16962 if (app.anrDialog != null) {
16963 app.anrDialog.dismiss();
16964 app.anrDialog = null;
16966 if (app.waitDialog != null) {
16967 app.waitDialog.dismiss();
16968 app.waitDialog = null;
16971 app.crashing = false;
16972 app.notResponding = false;
16974 app.resetPackageList(mProcessStats);
16975 app.unlinkDeathRecipient();
16976 app.makeInactive(mProcessStats);
16977 app.waitingToKill = null;
16978 app.forcingToForeground = null;
16979 updateProcessForegroundLocked(app, false, false);
16980 app.foregroundActivities = false;
16981 app.hasShownUi = false;
16982 app.treatLikeActivity = false;
16983 app.hasAboveClient = false;
16984 app.hasClientActivities = false;
16986 mServices.killServicesLocked(app, allowRestart);
16988 boolean restart = false;
16990 // Remove published content providers.
16991 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16992 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16993 final boolean always = app.bad || !allowRestart;
16994 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16995 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16996 // We left the provider in the launching list, need to
17001 cpr.provider = null;
17004 app.pubProviders.clear();
17006 // Take care of any launching providers waiting for this process.
17007 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
17011 // Unregister from connected content providers.
17012 if (!app.conProviders.isEmpty()) {
17013 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
17014 ContentProviderConnection conn = app.conProviders.get(i);
17015 conn.provider.connections.remove(conn);
17016 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
17017 conn.provider.name);
17019 app.conProviders.clear();
17022 // At this point there may be remaining entries in mLaunchingProviders
17023 // where we were the only one waiting, so they are no longer of use.
17024 // Look for these and clean up if found.
17025 // XXX Commented out for now. Trying to figure out a way to reproduce
17026 // the actual situation to identify what is actually going on.
17028 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17029 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17030 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17031 synchronized (cpr) {
17032 cpr.launchingApp = null;
17039 skipCurrentReceiverLocked(app);
17041 // Unregister any receivers.
17042 for (int i = app.receivers.size() - 1; i >= 0; i--) {
17043 removeReceiverLocked(app.receivers.valueAt(i));
17045 app.receivers.clear();
17047 // If the app is undergoing backup, tell the backup manager about it
17048 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17049 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17050 + mBackupTarget.appInfo + " died during backup");
17052 IBackupManager bm = IBackupManager.Stub.asInterface(
17053 ServiceManager.getService(Context.BACKUP_SERVICE));
17054 bm.agentDisconnected(app.info.packageName);
17055 } catch (RemoteException e) {
17056 // can't happen; backup manager is local
17060 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17061 ProcessChangeItem item = mPendingProcessChanges.get(i);
17062 if (item.pid == app.pid) {
17063 mPendingProcessChanges.remove(i);
17064 mAvailProcessChanges.add(item);
17067 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17068 null).sendToTarget();
17070 // If the caller is restarting this app, then leave it in its
17071 // current lists and let the caller take care of it.
17076 if (!app.persistent || app.isolated) {
17077 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17078 "Removing non-persistent process during cleanup: " + app);
17079 if (!replacingPid) {
17080 removeProcessNameLocked(app.processName, app.uid, app);
17082 if (mHeavyWeightProcess == app) {
17083 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17084 mHeavyWeightProcess.userId, 0));
17085 mHeavyWeightProcess = null;
17087 } else if (!app.removed) {
17088 // This app is persistent, so we need to keep its record around.
17089 // If it is not already on the pending app list, add it there
17090 // and start a new process for it.
17091 if (mPersistentStartingProcesses.indexOf(app) < 0) {
17092 mPersistentStartingProcesses.add(app);
17096 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17097 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17098 mProcessesOnHold.remove(app);
17100 if (app == mHomeProcess) {
17101 mHomeProcess = null;
17103 if (app == mPreviousProcess) {
17104 mPreviousProcess = null;
17107 if (restart && !app.isolated) {
17108 // We have components that still need to be running in the
17109 // process, so re-launch it.
17111 ProcessList.remove(app.pid);
17113 addProcessNameLocked(app);
17114 startProcessLocked(app, "restart", app.processName);
17116 } else if (app.pid > 0 && app.pid != MY_PID) {
17119 synchronized (mPidsSelfLocked) {
17120 mPidsSelfLocked.remove(app.pid);
17121 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17123 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17124 if (app.isolated) {
17125 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17132 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17133 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17134 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17135 if (cpr.launchingApp == app) {
17142 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17143 // Look through the content providers we are waiting to have launched,
17144 // and if any run in this process then either schedule a restart of
17145 // the process or kill the client waiting for it if this process has
17147 boolean restart = false;
17148 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17149 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17150 if (cpr.launchingApp == app) {
17151 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17154 removeDyingProviderLocked(app, cpr, true);
17161 // =========================================================
17163 // =========================================================
17166 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17168 enforceNotIsolatedCaller("getServices");
17169 synchronized (this) {
17170 return mServices.getRunningServiceInfoLocked(maxNum, flags);
17175 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17176 enforceNotIsolatedCaller("getRunningServiceControlPanel");
17177 synchronized (this) {
17178 return mServices.getRunningServiceControlPanelLocked(name);
17183 public ComponentName startService(IApplicationThread caller, Intent service,
17184 String resolvedType, String callingPackage, int userId)
17185 throws TransactionTooLargeException {
17186 enforceNotIsolatedCaller("startService");
17187 // Refuse possible leaked file descriptors
17188 if (service != null && service.hasFileDescriptors() == true) {
17189 throw new IllegalArgumentException("File descriptors passed in Intent");
17192 if (callingPackage == null) {
17193 throw new IllegalArgumentException("callingPackage cannot be null");
17196 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17197 "startService: " + service + " type=" + resolvedType);
17198 synchronized(this) {
17199 final int callingPid = Binder.getCallingPid();
17200 final int callingUid = Binder.getCallingUid();
17201 final long origId = Binder.clearCallingIdentity();
17202 ComponentName res = mServices.startServiceLocked(caller, service,
17203 resolvedType, callingPid, callingUid, callingPackage, userId);
17204 Binder.restoreCallingIdentity(origId);
17209 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17210 String callingPackage, int userId)
17211 throws TransactionTooLargeException {
17212 synchronized(this) {
17213 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17214 "startServiceInPackage: " + service + " type=" + resolvedType);
17215 final long origId = Binder.clearCallingIdentity();
17216 ComponentName res = mServices.startServiceLocked(null, service,
17217 resolvedType, -1, uid, callingPackage, userId);
17218 Binder.restoreCallingIdentity(origId);
17224 public int stopService(IApplicationThread caller, Intent service,
17225 String resolvedType, int userId) {
17226 enforceNotIsolatedCaller("stopService");
17227 // Refuse possible leaked file descriptors
17228 if (service != null && service.hasFileDescriptors() == true) {
17229 throw new IllegalArgumentException("File descriptors passed in Intent");
17232 synchronized(this) {
17233 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17238 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17239 enforceNotIsolatedCaller("peekService");
17240 // Refuse possible leaked file descriptors
17241 if (service != null && service.hasFileDescriptors() == true) {
17242 throw new IllegalArgumentException("File descriptors passed in Intent");
17245 if (callingPackage == null) {
17246 throw new IllegalArgumentException("callingPackage cannot be null");
17249 synchronized(this) {
17250 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17255 public boolean stopServiceToken(ComponentName className, IBinder token,
17257 synchronized(this) {
17258 return mServices.stopServiceTokenLocked(className, token, startId);
17263 public void setServiceForeground(ComponentName className, IBinder token,
17264 int id, Notification notification, int flags) {
17265 synchronized(this) {
17266 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17271 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17272 boolean requireFull, String name, String callerPackage) {
17273 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17274 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17277 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17278 String className, int flags) {
17279 boolean result = false;
17280 // For apps that don't have pre-defined UIDs, check for permission
17281 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17282 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17283 if (ActivityManager.checkUidPermission(
17284 INTERACT_ACROSS_USERS,
17285 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17286 ComponentName comp = new ComponentName(aInfo.packageName, className);
17287 String msg = "Permission Denial: Component " + comp.flattenToShortString()
17288 + " requests FLAG_SINGLE_USER, but app does not hold "
17289 + INTERACT_ACROSS_USERS;
17291 throw new SecurityException(msg);
17293 // Permission passed
17296 } else if ("system".equals(componentProcessName)) {
17298 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17299 // Phone app and persistent apps are allowed to export singleuser providers.
17300 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17301 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17303 if (DEBUG_MU) Slog.v(TAG_MU,
17304 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17305 + Integer.toHexString(flags) + ") = " + result);
17310 * Checks to see if the caller is in the same app as the singleton
17311 * component, or the component is in a special app. It allows special apps
17312 * to export singleton components but prevents exporting singleton
17313 * components for regular apps.
17315 boolean isValidSingletonCall(int callingUid, int componentUid) {
17316 int componentAppId = UserHandle.getAppId(componentUid);
17317 return UserHandle.isSameApp(callingUid, componentUid)
17318 || componentAppId == Process.SYSTEM_UID
17319 || componentAppId == Process.PHONE_UID
17320 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17321 == PackageManager.PERMISSION_GRANTED;
17324 public int bindService(IApplicationThread caller, IBinder token, Intent service,
17325 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17326 int userId) throws TransactionTooLargeException {
17327 enforceNotIsolatedCaller("bindService");
17329 // Refuse possible leaked file descriptors
17330 if (service != null && service.hasFileDescriptors() == true) {
17331 throw new IllegalArgumentException("File descriptors passed in Intent");
17334 if (callingPackage == null) {
17335 throw new IllegalArgumentException("callingPackage cannot be null");
17338 synchronized(this) {
17339 return mServices.bindServiceLocked(caller, token, service,
17340 resolvedType, connection, flags, callingPackage, userId);
17344 public boolean unbindService(IServiceConnection connection) {
17345 synchronized (this) {
17346 return mServices.unbindServiceLocked(connection);
17350 public void publishService(IBinder token, Intent intent, IBinder service) {
17351 // Refuse possible leaked file descriptors
17352 if (intent != null && intent.hasFileDescriptors() == true) {
17353 throw new IllegalArgumentException("File descriptors passed in Intent");
17356 synchronized(this) {
17357 if (!(token instanceof ServiceRecord)) {
17358 throw new IllegalArgumentException("Invalid service token");
17360 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17364 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17365 // Refuse possible leaked file descriptors
17366 if (intent != null && intent.hasFileDescriptors() == true) {
17367 throw new IllegalArgumentException("File descriptors passed in Intent");
17370 synchronized(this) {
17371 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17375 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17376 synchronized(this) {
17377 if (!(token instanceof ServiceRecord)) {
17378 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17379 throw new IllegalArgumentException("Invalid service token");
17381 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17385 // =========================================================
17386 // BACKUP AND RESTORE
17387 // =========================================================
17389 // Cause the target app to be launched if necessary and its backup agent
17390 // instantiated. The backup agent will invoke backupAgentCreated() on the
17391 // activity manager to announce its creation.
17392 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17393 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17394 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17396 IPackageManager pm = AppGlobals.getPackageManager();
17397 ApplicationInfo app = null;
17399 app = pm.getApplicationInfo(packageName, 0, userId);
17400 } catch (RemoteException e) {
17401 // can't happen; package manager is process-local
17404 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17408 synchronized(this) {
17409 // !!! TODO: currently no check here that we're already bound
17410 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17411 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17412 synchronized (stats) {
17413 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17416 // Backup agent is now in use, its package can't be stopped.
17418 AppGlobals.getPackageManager().setPackageStoppedState(
17419 app.packageName, false, UserHandle.getUserId(app.uid));
17420 } catch (RemoteException e) {
17421 } catch (IllegalArgumentException e) {
17422 Slog.w(TAG, "Failed trying to unstop package "
17423 + app.packageName + ": " + e);
17426 BackupRecord r = new BackupRecord(ss, app, backupMode);
17427 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17428 ? new ComponentName(app.packageName, app.backupAgentName)
17429 : new ComponentName("android", "FullBackupAgent");
17430 // startProcessLocked() returns existing proc's record if it's already running
17431 ProcessRecord proc = startProcessLocked(app.processName, app,
17432 false, 0, "backup", hostingName, false, false, false);
17433 if (proc == null) {
17434 Slog.e(TAG, "Unable to start backup agent process " + r);
17438 // If the app is a regular app (uid >= 10000) and not the system server or phone
17439 // process, etc, then mark it as being in full backup so that certain calls to the
17440 // process can be blocked. This is not reset to false anywhere because we kill the
17441 // process after the full backup is done and the ProcessRecord will vaporize anyway.
17442 if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17443 proc.inFullBackup = true;
17447 mBackupAppName = app.packageName;
17449 // Try not to kill the process during backup
17450 updateOomAdjLocked(proc);
17452 // If the process is already attached, schedule the creation of the backup agent now.
17453 // If it is not yet live, this will be done when it attaches to the framework.
17454 if (proc.thread != null) {
17455 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17457 proc.thread.scheduleCreateBackupAgent(app,
17458 compatibilityInfoForPackageLocked(app), backupMode);
17459 } catch (RemoteException e) {
17460 // Will time out on the backup manager side
17463 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17465 // Invariants: at this point, the target app process exists and the application
17466 // is either already running or in the process of coming up. mBackupTarget and
17467 // mBackupAppName describe the app, so that when it binds back to the AM we
17468 // know that it's scheduled for a backup-agent operation.
17475 public void clearPendingBackup() {
17476 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17477 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17479 synchronized (this) {
17480 mBackupTarget = null;
17481 mBackupAppName = null;
17485 // A backup agent has just come up
17486 public void backupAgentCreated(String agentPackageName, IBinder agent) {
17487 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17490 synchronized(this) {
17491 if (!agentPackageName.equals(mBackupAppName)) {
17492 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17497 long oldIdent = Binder.clearCallingIdentity();
17499 IBackupManager bm = IBackupManager.Stub.asInterface(
17500 ServiceManager.getService(Context.BACKUP_SERVICE));
17501 bm.agentConnected(agentPackageName, agent);
17502 } catch (RemoteException e) {
17503 // can't happen; the backup manager service is local
17504 } catch (Exception e) {
17505 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17506 e.printStackTrace();
17508 Binder.restoreCallingIdentity(oldIdent);
17512 // done with this agent
17513 public void unbindBackupAgent(ApplicationInfo appInfo) {
17514 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17515 if (appInfo == null) {
17516 Slog.w(TAG, "unbind backup agent for null app");
17520 synchronized(this) {
17522 if (mBackupAppName == null) {
17523 Slog.w(TAG, "Unbinding backup agent with no active backup");
17527 if (!mBackupAppName.equals(appInfo.packageName)) {
17528 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17532 // Not backing this app up any more; reset its OOM adjustment
17533 final ProcessRecord proc = mBackupTarget.app;
17534 updateOomAdjLocked(proc);
17536 // If the app crashed during backup, 'thread' will be null here
17537 if (proc.thread != null) {
17539 proc.thread.scheduleDestroyBackupAgent(appInfo,
17540 compatibilityInfoForPackageLocked(appInfo));
17541 } catch (Exception e) {
17542 Slog.e(TAG, "Exception when unbinding backup agent:");
17543 e.printStackTrace();
17547 mBackupTarget = null;
17548 mBackupAppName = null;
17552 // =========================================================
17554 // =========================================================
17556 boolean isPendingBroadcastProcessLocked(int pid) {
17557 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17558 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17561 void skipPendingBroadcastLocked(int pid) {
17562 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17563 for (BroadcastQueue queue : mBroadcastQueues) {
17564 queue.skipPendingBroadcastLocked(pid);
17568 // The app just attached; send any pending broadcasts that it should receive
17569 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17570 boolean didSomething = false;
17571 for (BroadcastQueue queue : mBroadcastQueues) {
17572 didSomething |= queue.sendPendingBroadcastsLocked(app);
17574 return didSomething;
17577 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17578 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17579 enforceNotIsolatedCaller("registerReceiver");
17580 ArrayList<Intent> stickyIntents = null;
17581 ProcessRecord callerApp = null;
17584 synchronized(this) {
17585 if (caller != null) {
17586 callerApp = getRecordForAppLocked(caller);
17587 if (callerApp == null) {
17588 throw new SecurityException(
17589 "Unable to find app for caller " + caller
17590 + " (pid=" + Binder.getCallingPid()
17591 + ") when registering receiver " + receiver);
17593 if (callerApp.info.uid != Process.SYSTEM_UID &&
17594 !callerApp.pkgList.containsKey(callerPackage) &&
17595 !"android".equals(callerPackage)) {
17596 throw new SecurityException("Given caller package " + callerPackage
17597 + " is not running in process " + callerApp);
17599 callingUid = callerApp.info.uid;
17600 callingPid = callerApp.pid;
17602 callerPackage = null;
17603 callingUid = Binder.getCallingUid();
17604 callingPid = Binder.getCallingPid();
17607 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17608 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17610 Iterator<String> actions = filter.actionsIterator();
17611 if (actions == null) {
17612 ArrayList<String> noAction = new ArrayList<String>(1);
17613 noAction.add(null);
17614 actions = noAction.iterator();
17617 // Collect stickies of users
17618 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17619 while (actions.hasNext()) {
17620 String action = actions.next();
17621 for (int id : userIds) {
17622 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17623 if (stickies != null) {
17624 ArrayList<Intent> intents = stickies.get(action);
17625 if (intents != null) {
17626 if (stickyIntents == null) {
17627 stickyIntents = new ArrayList<Intent>();
17629 stickyIntents.addAll(intents);
17636 ArrayList<Intent> allSticky = null;
17637 if (stickyIntents != null) {
17638 final ContentResolver resolver = mContext.getContentResolver();
17639 // Look for any matching sticky broadcasts...
17640 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17641 Intent intent = stickyIntents.get(i);
17642 // If intent has scheme "content", it will need to acccess
17643 // provider that needs to lock mProviderMap in ActivityThread
17644 // and also it may need to wait application response, so we
17645 // cannot lock ActivityManagerService here.
17646 if (filter.match(resolver, intent, true, TAG) >= 0) {
17647 if (allSticky == null) {
17648 allSticky = new ArrayList<Intent>();
17650 allSticky.add(intent);
17655 // The first sticky in the list is returned directly back to the client.
17656 Intent sticky = allSticky != null ? allSticky.get(0) : null;
17657 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17658 if (receiver == null) {
17662 synchronized (this) {
17663 if (callerApp != null && (callerApp.thread == null
17664 || callerApp.thread.asBinder() != caller.asBinder())) {
17665 // Original caller already died
17668 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17670 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17672 if (rl.app != null) {
17673 rl.app.receivers.add(rl);
17676 receiver.asBinder().linkToDeath(rl, 0);
17677 } catch (RemoteException e) {
17680 rl.linkedToDeath = true;
17682 mRegisteredReceivers.put(receiver.asBinder(), rl);
17683 } else if (rl.uid != callingUid) {
17684 throw new IllegalArgumentException(
17685 "Receiver requested to register for uid " + callingUid
17686 + " was previously registered for uid " + rl.uid);
17687 } else if (rl.pid != callingPid) {
17688 throw new IllegalArgumentException(
17689 "Receiver requested to register for pid " + callingPid
17690 + " was previously registered for pid " + rl.pid);
17691 } else if (rl.userId != userId) {
17692 throw new IllegalArgumentException(
17693 "Receiver requested to register for user " + userId
17694 + " was previously registered for user " + rl.userId);
17696 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17697 permission, callingUid, userId);
17699 if (!bf.debugCheck()) {
17700 Slog.w(TAG, "==> For Dynamic broadcast");
17702 mReceiverResolver.addFilter(bf);
17704 // Enqueue broadcasts for all existing stickies that match
17706 if (allSticky != null) {
17707 ArrayList receivers = new ArrayList();
17710 final int stickyCount = allSticky.size();
17711 for (int i = 0; i < stickyCount; i++) {
17712 Intent intent = allSticky.get(i);
17713 BroadcastQueue queue = broadcastQueueForIntent(intent);
17714 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17715 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17716 null, 0, null, null, false, true, true, -1);
17717 queue.enqueueParallelBroadcastLocked(r);
17718 queue.scheduleBroadcastsLocked();
17726 public void unregisterReceiver(IIntentReceiver receiver) {
17727 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17729 final long origId = Binder.clearCallingIdentity();
17731 boolean doTrim = false;
17733 synchronized(this) {
17734 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17736 final BroadcastRecord r = rl.curBroadcast;
17737 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17738 final boolean doNext = r.queue.finishReceiverLocked(
17739 r, r.resultCode, r.resultData, r.resultExtras,
17740 r.resultAbort, false);
17743 r.queue.processNextBroadcast(false);
17747 if (rl.app != null) {
17748 rl.app.receivers.remove(rl);
17750 removeReceiverLocked(rl);
17751 if (rl.linkedToDeath) {
17752 rl.linkedToDeath = false;
17753 rl.receiver.asBinder().unlinkToDeath(rl, 0);
17758 // If we actually concluded any broadcasts, we might now be able
17759 // to trim the recipients' apps from our working set
17761 trimApplications();
17766 Binder.restoreCallingIdentity(origId);
17770 void removeReceiverLocked(ReceiverList rl) {
17771 mRegisteredReceivers.remove(rl.receiver.asBinder());
17772 for (int i = rl.size() - 1; i >= 0; i--) {
17773 mReceiverResolver.removeFilter(rl.get(i));
17777 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17778 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17779 ProcessRecord r = mLruProcesses.get(i);
17780 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17782 r.thread.dispatchPackageBroadcast(cmd, packages);
17783 } catch (RemoteException ex) {
17789 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17790 int callingUid, int[] users) {
17791 // TODO: come back and remove this assumption to triage all broadcasts
17792 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17794 List<ResolveInfo> receivers = null;
17796 HashSet<ComponentName> singleUserReceivers = null;
17797 boolean scannedFirstReceivers = false;
17798 for (int user : users) {
17799 // Skip users that have Shell restrictions, with exception of always permitted
17800 // Shell broadcasts
17801 if (callingUid == Process.SHELL_UID
17802 && mUserController.hasUserRestriction(
17803 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17804 && !isPermittedShellBroadcast(intent)) {
17807 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17808 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17809 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17810 // If this is not the system user, we need to check for
17811 // any receivers that should be filtered out.
17812 for (int i=0; i<newReceivers.size(); i++) {
17813 ResolveInfo ri = newReceivers.get(i);
17814 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17815 newReceivers.remove(i);
17820 if (newReceivers != null && newReceivers.size() == 0) {
17821 newReceivers = null;
17823 if (receivers == null) {
17824 receivers = newReceivers;
17825 } else if (newReceivers != null) {
17826 // We need to concatenate the additional receivers
17827 // found with what we have do far. This would be easy,
17828 // but we also need to de-dup any receivers that are
17830 if (!scannedFirstReceivers) {
17831 // Collect any single user receivers we had already retrieved.
17832 scannedFirstReceivers = true;
17833 for (int i=0; i<receivers.size(); i++) {
17834 ResolveInfo ri = receivers.get(i);
17835 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17836 ComponentName cn = new ComponentName(
17837 ri.activityInfo.packageName, ri.activityInfo.name);
17838 if (singleUserReceivers == null) {
17839 singleUserReceivers = new HashSet<ComponentName>();
17841 singleUserReceivers.add(cn);
17845 // Add the new results to the existing results, tracking
17846 // and de-dupping single user receivers.
17847 for (int i=0; i<newReceivers.size(); i++) {
17848 ResolveInfo ri = newReceivers.get(i);
17849 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17850 ComponentName cn = new ComponentName(
17851 ri.activityInfo.packageName, ri.activityInfo.name);
17852 if (singleUserReceivers == null) {
17853 singleUserReceivers = new HashSet<ComponentName>();
17855 if (!singleUserReceivers.contains(cn)) {
17856 singleUserReceivers.add(cn);
17865 } catch (RemoteException ex) {
17866 // pm is in same process, this will never happen.
17871 private boolean isPermittedShellBroadcast(Intent intent) {
17872 // remote bugreport should always be allowed to be taken
17873 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17876 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17877 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17878 final String action = intent.getAction();
17879 if (isProtectedBroadcast
17880 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17881 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17882 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17883 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17884 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17885 || Intent.ACTION_MASTER_CLEAR.equals(action)
17886 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17887 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17888 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17889 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17890 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17891 // Broadcast is either protected, or it's a public action that
17892 // we've relaxed, so it's fine for system internals to send.
17896 // This broadcast may be a problem... but there are often system components that
17897 // want to send an internal broadcast to themselves, which is annoying to have to
17898 // explicitly list each action as a protected broadcast, so we will check for that
17899 // one safe case and allow it: an explicit broadcast, only being received by something
17900 // that has protected itself.
17901 if (receivers != null && receivers.size() > 0
17902 && (intent.getPackage() != null || intent.getComponent() != null)) {
17903 boolean allProtected = true;
17904 for (int i = receivers.size()-1; i >= 0; i--) {
17905 Object target = receivers.get(i);
17906 if (target instanceof ResolveInfo) {
17907 ResolveInfo ri = (ResolveInfo)target;
17908 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17909 allProtected = false;
17913 BroadcastFilter bf = (BroadcastFilter)target;
17914 if (bf.requiredPermission == null) {
17915 allProtected = false;
17920 if (allProtected) {
17926 // The vast majority of broadcasts sent from system internals
17927 // should be protected to avoid security holes, so yell loudly
17928 // to ensure we examine these cases.
17929 if (callerApp != null) {
17930 Log.wtf(TAG, "Sending non-protected broadcast " + action
17931 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17934 Log.wtf(TAG, "Sending non-protected broadcast " + action
17935 + " from system uid " + UserHandle.formatUid(callingUid)
17936 + " pkg " + callerPackage,
17941 final int broadcastIntentLocked(ProcessRecord callerApp,
17942 String callerPackage, Intent intent, String resolvedType,
17943 IIntentReceiver resultTo, int resultCode, String resultData,
17944 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17945 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17946 intent = new Intent(intent);
17948 // By default broadcasts do not go to stopped apps.
17949 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17951 // If we have not finished booting, don't allow this to launch new processes.
17952 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17953 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17956 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17957 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17958 + " ordered=" + ordered + " userid=" + userId);
17959 if ((resultTo != null) && !ordered) {
17960 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17963 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17964 ALLOW_NON_FULL, "broadcast", callerPackage);
17966 // Make sure that the user who is receiving this broadcast is running.
17967 // If not, we will just skip it. Make an exception for shutdown broadcasts
17968 // and upgrade steps.
17970 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17971 if ((callingUid != Process.SYSTEM_UID
17972 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17973 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17974 Slog.w(TAG, "Skipping broadcast of " + intent
17975 + ": user " + userId + " is stopped");
17976 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17980 BroadcastOptions brOptions = null;
17981 if (bOptions != null) {
17982 brOptions = new BroadcastOptions(bOptions);
17983 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17984 // See if the caller is allowed to do this. Note we are checking against
17985 // the actual real caller (not whoever provided the operation as say a
17986 // PendingIntent), because that who is actually supplied the arguments.
17987 if (checkComponentPermission(
17988 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17989 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17990 != PackageManager.PERMISSION_GRANTED) {
17991 String msg = "Permission Denial: " + intent.getAction()
17992 + " broadcast from " + callerPackage + " (pid=" + callingPid
17993 + ", uid=" + callingUid + ")"
17995 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17997 throw new SecurityException(msg);
18002 // Verify that protected broadcasts are only being sent by system code,
18003 // and that system code is only sending protected broadcasts.
18004 final String action = intent.getAction();
18005 final boolean isProtectedBroadcast;
18007 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
18008 } catch (RemoteException e) {
18009 Slog.w(TAG, "Remote exception", e);
18010 return ActivityManager.BROADCAST_SUCCESS;
18013 final boolean isCallerSystem;
18014 switch (UserHandle.getAppId(callingUid)) {
18015 case Process.ROOT_UID:
18016 case Process.SYSTEM_UID:
18017 case Process.PHONE_UID:
18018 case Process.BLUETOOTH_UID:
18019 case Process.NFC_UID:
18020 isCallerSystem = true;
18023 isCallerSystem = (callerApp != null) && callerApp.persistent;
18027 // First line security check before anything else: stop non-system apps from
18028 // sending protected broadcasts.
18029 if (!isCallerSystem) {
18030 if (isProtectedBroadcast) {
18031 String msg = "Permission Denial: not allowed to send broadcast "
18032 + action + " from pid="
18033 + callingPid + ", uid=" + callingUid;
18035 throw new SecurityException(msg);
18037 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18038 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18039 // Special case for compatibility: we don't want apps to send this,
18040 // but historically it has not been protected and apps may be using it
18041 // to poke their own app widget. So, instead of making it protected,
18042 // just limit it to the caller.
18043 if (callerPackage == null) {
18044 String msg = "Permission Denial: not allowed to send broadcast "
18045 + action + " from unknown caller.";
18047 throw new SecurityException(msg);
18048 } else if (intent.getComponent() != null) {
18049 // They are good enough to send to an explicit component... verify
18050 // it is being sent to the calling app.
18051 if (!intent.getComponent().getPackageName().equals(
18053 String msg = "Permission Denial: not allowed to send broadcast "
18055 + intent.getComponent().getPackageName() + " from "
18058 throw new SecurityException(msg);
18061 // Limit broadcast to their own package.
18062 intent.setPackage(callerPackage);
18067 if (action != null) {
18069 case Intent.ACTION_UID_REMOVED:
18070 case Intent.ACTION_PACKAGE_REMOVED:
18071 case Intent.ACTION_PACKAGE_CHANGED:
18072 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18073 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18074 case Intent.ACTION_PACKAGES_SUSPENDED:
18075 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18076 // Handle special intents: if this broadcast is from the package
18077 // manager about a package being removed, we need to remove all of
18078 // its activities from the history stack.
18079 if (checkComponentPermission(
18080 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18081 callingPid, callingUid, -1, true)
18082 != PackageManager.PERMISSION_GRANTED) {
18083 String msg = "Permission Denial: " + intent.getAction()
18084 + " broadcast from " + callerPackage + " (pid=" + callingPid
18085 + ", uid=" + callingUid + ")"
18087 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18089 throw new SecurityException(msg);
18092 case Intent.ACTION_UID_REMOVED:
18093 final Bundle intentExtras = intent.getExtras();
18094 final int uid = intentExtras != null
18095 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18097 mBatteryStatsService.removeUid(uid);
18098 mAppOpsService.uidRemoved(uid);
18101 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18102 // If resources are unavailable just force stop all those packages
18103 // and flush the attribute cache as well.
18105 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18106 if (list != null && list.length > 0) {
18107 for (int i = 0; i < list.length; i++) {
18108 forceStopPackageLocked(list[i], -1, false, true, true,
18109 false, false, userId, "storage unmount");
18111 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18112 sendPackageBroadcastLocked(
18113 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18117 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18118 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18120 case Intent.ACTION_PACKAGE_REMOVED:
18121 case Intent.ACTION_PACKAGE_CHANGED:
18122 Uri data = intent.getData();
18124 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18125 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18126 final boolean replacing =
18127 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18128 final boolean killProcess =
18129 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18130 final boolean fullUninstall = removed && !replacing;
18133 forceStopPackageLocked(ssp, UserHandle.getAppId(
18134 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18135 false, true, true, false, fullUninstall, userId,
18136 removed ? "pkg removed" : "pkg changed");
18138 final int cmd = killProcess
18139 ? IApplicationThread.PACKAGE_REMOVED
18140 : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18141 sendPackageBroadcastLocked(cmd,
18142 new String[] {ssp}, userId);
18143 if (fullUninstall) {
18144 mAppOpsService.packageRemoved(
18145 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18147 // Remove all permissions granted from/to this package
18148 removeUriPermissionsForPackageLocked(ssp, userId, true);
18150 removeTasksByPackageNameLocked(ssp, userId);
18152 // Hide the "unsupported display" dialog if necessary.
18153 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18154 mUnsupportedDisplaySizeDialog.getPackageName())) {
18155 mUnsupportedDisplaySizeDialog.dismiss();
18156 mUnsupportedDisplaySizeDialog = null;
18158 mCompatModePackages.handlePackageUninstalledLocked(ssp);
18159 mBatteryStatsService.notePackageUninstalled(ssp);
18163 killPackageProcessesLocked(ssp, UserHandle.getAppId(
18164 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18165 userId, ProcessList.INVALID_ADJ,
18166 false, true, true, false, "change " + ssp);
18168 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18169 intent.getStringArrayExtra(
18170 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18174 case Intent.ACTION_PACKAGES_SUSPENDED:
18175 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18176 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18177 intent.getAction());
18178 final String[] packageNames = intent.getStringArrayExtra(
18179 Intent.EXTRA_CHANGED_PACKAGE_LIST);
18180 final int userHandle = intent.getIntExtra(
18181 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18183 synchronized(ActivityManagerService.this) {
18184 mRecentTasks.onPackagesSuspendedChanged(
18185 packageNames, suspended, userHandle);
18190 case Intent.ACTION_PACKAGE_REPLACED:
18192 final Uri data = intent.getData();
18194 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18195 final ApplicationInfo aInfo =
18196 getPackageManagerInternalLocked().getApplicationInfo(
18199 if (aInfo == null) {
18200 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18201 + " ssp=" + ssp + " data=" + data);
18202 return ActivityManager.BROADCAST_SUCCESS;
18204 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18205 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18206 new String[] {ssp}, userId);
18210 case Intent.ACTION_PACKAGE_ADDED:
18212 // Special case for adding a package: by default turn on compatibility mode.
18213 Uri data = intent.getData();
18215 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18216 final boolean replacing =
18217 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18218 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18221 ApplicationInfo ai = AppGlobals.getPackageManager().
18222 getApplicationInfo(ssp, 0, 0);
18223 mBatteryStatsService.notePackageInstalled(ssp,
18224 ai != null ? ai.versionCode : 0);
18225 } catch (RemoteException e) {
18230 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18232 Uri data = intent.getData();
18234 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18235 // Hide the "unsupported display" dialog if necessary.
18236 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18237 mUnsupportedDisplaySizeDialog.getPackageName())) {
18238 mUnsupportedDisplaySizeDialog.dismiss();
18239 mUnsupportedDisplaySizeDialog = null;
18241 mCompatModePackages.handlePackageDataClearedLocked(ssp);
18245 case Intent.ACTION_TIMEZONE_CHANGED:
18246 // If this is the time zone changed action, queue up a message that will reset
18247 // the timezone of all currently running processes. This message will get
18248 // queued up before the broadcast happens.
18249 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18251 case Intent.ACTION_TIME_CHANGED:
18252 // If the user set the time, let all running processes know.
18253 final int is24Hour =
18254 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18256 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18257 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18258 synchronized (stats) {
18259 stats.noteCurrentTimeChangedLocked();
18262 case Intent.ACTION_CLEAR_DNS_CACHE:
18263 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18265 case Proxy.PROXY_CHANGE_ACTION:
18266 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18267 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18269 case android.hardware.Camera.ACTION_NEW_PICTURE:
18270 case android.hardware.Camera.ACTION_NEW_VIDEO:
18271 // These broadcasts are no longer allowed by the system, since they can
18272 // cause significant thrashing at a crictical point (using the camera).
18273 // Apps should use JobScehduler to monitor for media provider changes.
18274 Slog.w(TAG, action + " no longer allowed; dropping from "
18275 + UserHandle.formatUid(callingUid));
18276 if (resultTo != null) {
18277 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18279 queue.performReceiveLocked(callerApp, resultTo, intent,
18280 Activity.RESULT_CANCELED, null, null,
18281 false, false, userId);
18282 } catch (RemoteException e) {
18283 Slog.w(TAG, "Failure ["
18284 + queue.mQueueName + "] sending broadcast result of "
18289 // Lie; we don't want to crash the app.
18290 return ActivityManager.BROADCAST_SUCCESS;
18294 // Add to the sticky list if requested.
18296 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18297 callingPid, callingUid)
18298 != PackageManager.PERMISSION_GRANTED) {
18299 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18300 + callingPid + ", uid=" + callingUid
18301 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18303 throw new SecurityException(msg);
18305 if (requiredPermissions != null && requiredPermissions.length > 0) {
18306 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18307 + " and enforce permissions " + Arrays.toString(requiredPermissions));
18308 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18310 if (intent.getComponent() != null) {
18311 throw new SecurityException(
18312 "Sticky broadcasts can't target a specific component");
18314 // We use userId directly here, since the "all" target is maintained
18315 // as a separate set of sticky broadcasts.
18316 if (userId != UserHandle.USER_ALL) {
18317 // But first, if this is not a broadcast to all users, then
18318 // make sure it doesn't conflict with an existing broadcast to
18320 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18321 UserHandle.USER_ALL);
18322 if (stickies != null) {
18323 ArrayList<Intent> list = stickies.get(intent.getAction());
18324 if (list != null) {
18325 int N = list.size();
18327 for (i=0; i<N; i++) {
18328 if (intent.filterEquals(list.get(i))) {
18329 throw new IllegalArgumentException(
18330 "Sticky broadcast " + intent + " for user "
18331 + userId + " conflicts with existing global broadcast");
18337 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18338 if (stickies == null) {
18339 stickies = new ArrayMap<>();
18340 mStickyBroadcasts.put(userId, stickies);
18342 ArrayList<Intent> list = stickies.get(intent.getAction());
18343 if (list == null) {
18344 list = new ArrayList<>();
18345 stickies.put(intent.getAction(), list);
18347 final int stickiesCount = list.size();
18349 for (i = 0; i < stickiesCount; i++) {
18350 if (intent.filterEquals(list.get(i))) {
18351 // This sticky already exists, replace it.
18352 list.set(i, new Intent(intent));
18356 if (i >= stickiesCount) {
18357 list.add(new Intent(intent));
18362 if (userId == UserHandle.USER_ALL) {
18363 // Caller wants broadcast to go to all started users.
18364 users = mUserController.getStartedUserArrayLocked();
18366 // Caller wants broadcast to go to one specific user.
18367 users = new int[] {userId};
18370 // Figure out who all will receive this broadcast.
18371 List receivers = null;
18372 List<BroadcastFilter> registeredReceivers = null;
18373 // Need to resolve the intent to interested receivers...
18374 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18376 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18378 if (intent.getComponent() == null) {
18379 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18380 // Query one target user at a time, excluding shell-restricted users
18381 for (int i = 0; i < users.length; i++) {
18382 if (mUserController.hasUserRestriction(
18383 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18386 List<BroadcastFilter> registeredReceiversForUser =
18387 mReceiverResolver.queryIntent(intent,
18388 resolvedType, false, users[i]);
18389 if (registeredReceivers == null) {
18390 registeredReceivers = registeredReceiversForUser;
18391 } else if (registeredReceiversForUser != null) {
18392 registeredReceivers.addAll(registeredReceiversForUser);
18396 registeredReceivers = mReceiverResolver.queryIntent(intent,
18397 resolvedType, false, userId);
18401 final boolean replacePending =
18402 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18404 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18405 + " replacePending=" + replacePending);
18407 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18408 if (!ordered && NR > 0) {
18409 // If we are not serializing this broadcast, then send the
18410 // registered receivers separately so they don't wait for the
18411 // components to be launched.
18412 if (isCallerSystem) {
18413 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18414 isProtectedBroadcast, registeredReceivers);
18416 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18417 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18418 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18419 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18420 resultExtras, ordered, sticky, false, userId);
18421 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18422 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18424 queue.enqueueParallelBroadcastLocked(r);
18425 queue.scheduleBroadcastsLocked();
18427 registeredReceivers = null;
18431 // Merge into one list.
18433 if (receivers != null) {
18434 // A special case for PACKAGE_ADDED: do not allow the package
18435 // being added to see this broadcast. This prevents them from
18436 // using this as a back door to get run as soon as they are
18437 // installed. Maybe in the future we want to have a special install
18438 // broadcast or such for apps, but we'd like to deliberately make
18440 String skipPackages[] = null;
18441 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18442 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18443 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18444 Uri data = intent.getData();
18445 if (data != null) {
18446 String pkgName = data.getSchemeSpecificPart();
18447 if (pkgName != null) {
18448 skipPackages = new String[] { pkgName };
18451 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18452 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18454 if (skipPackages != null && (skipPackages.length > 0)) {
18455 for (String skipPackage : skipPackages) {
18456 if (skipPackage != null) {
18457 int NT = receivers.size();
18458 for (int it=0; it<NT; it++) {
18459 ResolveInfo curt = (ResolveInfo)receivers.get(it);
18460 if (curt.activityInfo.packageName.equals(skipPackage)) {
18461 receivers.remove(it);
18470 int NT = receivers != null ? receivers.size() : 0;
18472 ResolveInfo curt = null;
18473 BroadcastFilter curr = null;
18474 while (it < NT && ir < NR) {
18475 if (curt == null) {
18476 curt = (ResolveInfo)receivers.get(it);
18478 if (curr == null) {
18479 curr = registeredReceivers.get(ir);
18481 if (curr.getPriority() >= curt.priority) {
18482 // Insert this broadcast record into the final list.
18483 receivers.add(it, curr);
18489 // Skip to the next ResolveInfo in the final list.
18496 if (receivers == null) {
18497 receivers = new ArrayList();
18499 receivers.add(registeredReceivers.get(ir));
18503 if (isCallerSystem) {
18504 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18505 isProtectedBroadcast, receivers);
18508 if ((receivers != null && receivers.size() > 0)
18509 || resultTo != null) {
18510 BroadcastQueue queue = broadcastQueueForIntent(intent);
18511 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18512 callerPackage, callingPid, callingUid, resolvedType,
18513 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18514 resultData, resultExtras, ordered, sticky, false, userId);
18516 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18517 + ": prev had " + queue.mOrderedBroadcasts.size());
18518 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18519 "Enqueueing broadcast " + r.intent.getAction());
18521 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18523 queue.enqueueOrderedBroadcastLocked(r);
18524 queue.scheduleBroadcastsLocked();
18527 // There was nobody interested in the broadcast, but we still want to record
18528 // that it happened.
18529 if (intent.getComponent() == null && intent.getPackage() == null
18530 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18531 // This was an implicit broadcast... let's record it for posterity.
18532 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18536 return ActivityManager.BROADCAST_SUCCESS;
18539 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18540 int skipCount, long dispatchTime) {
18541 final long now = SystemClock.elapsedRealtime();
18542 if (mCurBroadcastStats == null ||
18543 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18544 mLastBroadcastStats = mCurBroadcastStats;
18545 if (mLastBroadcastStats != null) {
18546 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18547 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18549 mCurBroadcastStats = new BroadcastStats();
18551 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18554 final Intent verifyBroadcastLocked(Intent intent) {
18555 // Refuse possible leaked file descriptors
18556 if (intent != null && intent.hasFileDescriptors() == true) {
18557 throw new IllegalArgumentException("File descriptors passed in Intent");
18560 int flags = intent.getFlags();
18562 if (!mProcessesReady) {
18563 // if the caller really truly claims to know what they're doing, go
18564 // ahead and allow the broadcast without launching any receivers
18565 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18566 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18567 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18568 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18569 + " before boot completion");
18570 throw new IllegalStateException("Cannot broadcast before boot completed");
18574 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18575 throw new IllegalArgumentException(
18576 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18582 public final int broadcastIntent(IApplicationThread caller,
18583 Intent intent, String resolvedType, IIntentReceiver resultTo,
18584 int resultCode, String resultData, Bundle resultExtras,
18585 String[] requiredPermissions, int appOp, Bundle bOptions,
18586 boolean serialized, boolean sticky, int userId) {
18587 enforceNotIsolatedCaller("broadcastIntent");
18588 synchronized(this) {
18589 intent = verifyBroadcastLocked(intent);
18591 final ProcessRecord callerApp = getRecordForAppLocked(caller);
18592 final int callingPid = Binder.getCallingPid();
18593 final int callingUid = Binder.getCallingUid();
18594 final long origId = Binder.clearCallingIdentity();
18595 int res = broadcastIntentLocked(callerApp,
18596 callerApp != null ? callerApp.info.packageName : null,
18597 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18598 requiredPermissions, appOp, bOptions, serialized, sticky,
18599 callingPid, callingUid, userId);
18600 Binder.restoreCallingIdentity(origId);
18606 int broadcastIntentInPackage(String packageName, int uid,
18607 Intent intent, String resolvedType, IIntentReceiver resultTo,
18608 int resultCode, String resultData, Bundle resultExtras,
18609 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18611 synchronized(this) {
18612 intent = verifyBroadcastLocked(intent);
18614 final long origId = Binder.clearCallingIdentity();
18615 String[] requiredPermissions = requiredPermission == null ? null
18616 : new String[] {requiredPermission};
18617 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18618 resultTo, resultCode, resultData, resultExtras,
18619 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18620 sticky, -1, uid, userId);
18621 Binder.restoreCallingIdentity(origId);
18626 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18627 // Refuse possible leaked file descriptors
18628 if (intent != null && intent.hasFileDescriptors() == true) {
18629 throw new IllegalArgumentException("File descriptors passed in Intent");
18632 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18633 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18635 synchronized(this) {
18636 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18637 != PackageManager.PERMISSION_GRANTED) {
18638 String msg = "Permission Denial: unbroadcastIntent() from pid="
18639 + Binder.getCallingPid()
18640 + ", uid=" + Binder.getCallingUid()
18641 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18643 throw new SecurityException(msg);
18645 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18646 if (stickies != null) {
18647 ArrayList<Intent> list = stickies.get(intent.getAction());
18648 if (list != null) {
18649 int N = list.size();
18651 for (i=0; i<N; i++) {
18652 if (intent.filterEquals(list.get(i))) {
18657 if (list.size() <= 0) {
18658 stickies.remove(intent.getAction());
18661 if (stickies.size() <= 0) {
18662 mStickyBroadcasts.remove(userId);
18668 void backgroundServicesFinishedLocked(int userId) {
18669 for (BroadcastQueue queue : mBroadcastQueues) {
18670 queue.backgroundServicesFinishedLocked(userId);
18674 public void finishReceiver(IBinder who, int resultCode, String resultData,
18675 Bundle resultExtras, boolean resultAbort, int flags) {
18676 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18678 // Refuse possible leaked file descriptors
18679 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18680 throw new IllegalArgumentException("File descriptors passed in Bundle");
18683 final long origId = Binder.clearCallingIdentity();
18685 boolean doNext = false;
18688 synchronized(this) {
18689 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18690 ? mFgBroadcastQueue : mBgBroadcastQueue;
18691 r = queue.getMatchingOrderedReceiver(who);
18693 doNext = r.queue.finishReceiverLocked(r, resultCode,
18694 resultData, resultExtras, resultAbort, true);
18699 r.queue.processNextBroadcast(false);
18701 trimApplications();
18703 Binder.restoreCallingIdentity(origId);
18707 // =========================================================
18709 // =========================================================
18711 public boolean startInstrumentation(ComponentName className,
18712 String profileFile, int flags, Bundle arguments,
18713 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18714 int userId, String abiOverride) {
18715 enforceNotIsolatedCaller("startInstrumentation");
18716 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18717 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18718 // Refuse possible leaked file descriptors
18719 if (arguments != null && arguments.hasFileDescriptors()) {
18720 throw new IllegalArgumentException("File descriptors passed in Bundle");
18723 synchronized(this) {
18724 InstrumentationInfo ii = null;
18725 ApplicationInfo ai = null;
18727 ii = mContext.getPackageManager().getInstrumentationInfo(
18728 className, STOCK_PM_FLAGS);
18729 ai = AppGlobals.getPackageManager().getApplicationInfo(
18730 ii.targetPackage, STOCK_PM_FLAGS, userId);
18731 } catch (PackageManager.NameNotFoundException e) {
18732 } catch (RemoteException e) {
18735 reportStartInstrumentationFailureLocked(watcher, className,
18736 "Unable to find instrumentation info for: " + className);
18740 reportStartInstrumentationFailureLocked(watcher, className,
18741 "Unable to find instrumentation target package: " + ii.targetPackage);
18744 if (!ai.hasCode()) {
18745 reportStartInstrumentationFailureLocked(watcher, className,
18746 "Instrumentation target has no code: " + ii.targetPackage);
18750 int match = mContext.getPackageManager().checkSignatures(
18751 ii.targetPackage, ii.packageName);
18752 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18753 String msg = "Permission Denial: starting instrumentation "
18754 + className + " from pid="
18755 + Binder.getCallingPid()
18756 + ", uid=" + Binder.getCallingPid()
18757 + " not allowed because package " + ii.packageName
18758 + " does not have a signature matching the target "
18759 + ii.targetPackage;
18760 reportStartInstrumentationFailureLocked(watcher, className, msg);
18761 throw new SecurityException(msg);
18764 final long origId = Binder.clearCallingIdentity();
18765 // Instrumentation can kill and relaunch even persistent processes
18766 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18768 ProcessRecord app = addAppLocked(ai, false, abiOverride);
18769 app.instrumentationClass = className;
18770 app.instrumentationInfo = ai;
18771 app.instrumentationProfileFile = profileFile;
18772 app.instrumentationArguments = arguments;
18773 app.instrumentationWatcher = watcher;
18774 app.instrumentationUiAutomationConnection = uiAutomationConnection;
18775 app.instrumentationResultClass = className;
18776 Binder.restoreCallingIdentity(origId);
18783 * Report errors that occur while attempting to start Instrumentation. Always writes the
18784 * error to the logs, but if somebody is watching, send the report there too. This enables
18785 * the "am" command to report errors with more information.
18787 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
18788 * @param cn The component name of the instrumentation.
18789 * @param report The error report.
18791 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18792 ComponentName cn, String report) {
18793 Slog.w(TAG, report);
18794 if (watcher != null) {
18795 Bundle results = new Bundle();
18796 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18797 results.putString("Error", report);
18798 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18802 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18803 if (app.instrumentationWatcher != null) {
18804 mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18805 app.instrumentationClass, resultCode, results);
18808 // Can't call out of the system process with a lock held, so post a message.
18809 if (app.instrumentationUiAutomationConnection != null) {
18810 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18811 app.instrumentationUiAutomationConnection).sendToTarget();
18814 app.instrumentationWatcher = null;
18815 app.instrumentationUiAutomationConnection = null;
18816 app.instrumentationClass = null;
18817 app.instrumentationInfo = null;
18818 app.instrumentationProfileFile = null;
18819 app.instrumentationArguments = null;
18821 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18825 public void finishInstrumentation(IApplicationThread target,
18826 int resultCode, Bundle results) {
18827 int userId = UserHandle.getCallingUserId();
18828 // Refuse possible leaked file descriptors
18829 if (results != null && results.hasFileDescriptors()) {
18830 throw new IllegalArgumentException("File descriptors passed in Intent");
18833 synchronized(this) {
18834 ProcessRecord app = getRecordForAppLocked(target);
18836 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18839 final long origId = Binder.clearCallingIdentity();
18840 finishInstrumentationLocked(app, resultCode, results);
18841 Binder.restoreCallingIdentity(origId);
18845 // =========================================================
18847 // =========================================================
18849 public ConfigurationInfo getDeviceConfigurationInfo() {
18850 ConfigurationInfo config = new ConfigurationInfo();
18851 synchronized (this) {
18852 config.reqTouchScreen = mConfiguration.touchscreen;
18853 config.reqKeyboardType = mConfiguration.keyboard;
18854 config.reqNavigation = mConfiguration.navigation;
18855 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18856 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18857 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18859 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18860 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18861 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18863 config.reqGlEsVersion = GL_ES_VERSION;
18868 ActivityStack getFocusedStack() {
18869 return mStackSupervisor.getFocusedStack();
18873 public int getFocusedStackId() throws RemoteException {
18874 ActivityStack focusedStack = getFocusedStack();
18875 if (focusedStack != null) {
18876 return focusedStack.getStackId();
18881 public Configuration getConfiguration() {
18883 synchronized(this) {
18884 ci = new Configuration(mConfiguration);
18885 ci.userSetLocale = false;
18891 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18892 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18893 synchronized (this) {
18894 mSuppressResizeConfigChanges = suppress;
18899 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18900 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18901 if (fromStackId == HOME_STACK_ID) {
18902 throw new IllegalArgumentException("You can't move tasks from the home stack.");
18904 synchronized (this) {
18905 final long origId = Binder.clearCallingIdentity();
18907 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18909 Binder.restoreCallingIdentity(origId);
18915 public void updatePersistentConfiguration(Configuration values) {
18916 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18917 "updateConfiguration()");
18918 enforceWriteSettingsPermission("updateConfiguration()");
18919 if (values == null) {
18920 throw new NullPointerException("Configuration must not be null");
18923 int userId = UserHandle.getCallingUserId();
18925 synchronized(this) {
18926 updatePersistentConfigurationLocked(values, userId);
18930 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18931 final long origId = Binder.clearCallingIdentity();
18933 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18935 Binder.restoreCallingIdentity(origId);
18939 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18940 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18941 FONT_SCALE, 1.0f, userId);
18942 if (mConfiguration.fontScale != scaleFactor) {
18943 final Configuration configuration = mWindowManager.computeNewConfiguration();
18944 configuration.fontScale = scaleFactor;
18945 synchronized (this) {
18946 updatePersistentConfigurationLocked(configuration, userId);
18951 private void enforceWriteSettingsPermission(String func) {
18952 int uid = Binder.getCallingUid();
18953 if (uid == Process.ROOT_UID) {
18957 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18958 Settings.getPackageNameForUid(mContext, uid), false)) {
18962 String msg = "Permission Denial: " + func + " from pid="
18963 + Binder.getCallingPid()
18965 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18967 throw new SecurityException(msg);
18970 public void updateConfiguration(Configuration values) {
18971 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18972 "updateConfiguration()");
18974 synchronized(this) {
18975 if (values == null && mWindowManager != null) {
18976 // sentinel: fetch the current configuration from the window manager
18977 values = mWindowManager.computeNewConfiguration();
18980 if (mWindowManager != null) {
18981 mProcessList.applyDisplaySize(mWindowManager);
18984 final long origId = Binder.clearCallingIdentity();
18985 if (values != null) {
18986 Settings.System.clearConfiguration(values);
18988 updateConfigurationLocked(values, null, false);
18989 Binder.restoreCallingIdentity(origId);
18993 void updateUserConfigurationLocked() {
18994 Configuration configuration = new Configuration(mConfiguration);
18995 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18996 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18997 updateConfigurationLocked(configuration, null, false);
19000 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19001 boolean initLocale) {
19002 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
19005 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19006 boolean initLocale, boolean deferResume) {
19007 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
19008 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
19009 UserHandle.USER_NULL, deferResume);
19012 // To cache the list of supported system locales
19013 private String[] mSupportedSystemLocales = null;
19016 * Do either or both things: (1) change the current configuration, and (2)
19017 * make sure the given activity is running with the (now) current
19018 * configuration. Returns true if the activity has been left running, or
19019 * false if <var>starting</var> is being destroyed to match the new
19022 * @param userId is only used when persistent parameter is set to true to persist configuration
19023 * for that particular user
19025 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19026 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19029 if (mWindowManager != null) {
19030 mWindowManager.deferSurfaceLayout();
19032 if (values != null) {
19033 Configuration newConfig = new Configuration(mConfiguration);
19034 changes = newConfig.updateFrom(values);
19035 if (changes != 0) {
19036 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19037 "Updating configuration to: " + values);
19039 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19041 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19042 final LocaleList locales = values.getLocales();
19043 int bestLocaleIndex = 0;
19044 if (locales.size() > 1) {
19045 if (mSupportedSystemLocales == null) {
19046 mSupportedSystemLocales =
19047 Resources.getSystem().getAssets().getLocales();
19049 bestLocaleIndex = Math.max(0,
19050 locales.getFirstMatchIndex(mSupportedSystemLocales));
19052 SystemProperties.set("persist.sys.locale",
19053 locales.get(bestLocaleIndex).toLanguageTag());
19054 LocaleList.setDefault(locales, bestLocaleIndex);
19055 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19056 locales.get(bestLocaleIndex)));
19059 mConfigurationSeq++;
19060 if (mConfigurationSeq <= 0) {
19061 mConfigurationSeq = 1;
19063 newConfig.seq = mConfigurationSeq;
19064 mConfiguration = newConfig;
19065 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19066 mUsageStatsService.reportConfigurationChange(newConfig,
19067 mUserController.getCurrentUserIdLocked());
19068 //mUsageStatsService.noteStartConfig(newConfig);
19070 final Configuration configCopy = new Configuration(mConfiguration);
19072 // TODO: If our config changes, should we auto dismiss any currently
19073 // showing dialogs?
19074 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19076 AttributeCache ac = AttributeCache.instance();
19078 ac.updateConfiguration(configCopy);
19081 // Make sure all resources in our process are updated
19082 // right now, so that anyone who is going to retrieve
19083 // resource values after we return will be sure to get
19084 // the new ones. This is especially important during
19085 // boot, where the first config change needs to guarantee
19086 // all resources have that config before following boot
19087 // code is executed.
19088 mSystemThread.applyConfigurationToResources(configCopy);
19090 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19091 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19092 msg.obj = new Configuration(configCopy);
19094 mHandler.sendMessage(msg);
19097 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19098 if (isDensityChange) {
19099 // Reset the unsupported display size dialog.
19100 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19102 killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19103 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19106 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19107 ProcessRecord app = mLruProcesses.get(i);
19109 if (app.thread != null) {
19110 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19111 + app.processName + " new config " + mConfiguration);
19112 app.thread.scheduleConfigurationChanged(configCopy);
19114 } catch (Exception e) {
19117 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19118 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19119 | Intent.FLAG_RECEIVER_REPLACE_PENDING
19120 | Intent.FLAG_RECEIVER_FOREGROUND);
19121 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19122 null, AppOpsManager.OP_NONE, null, false, false,
19123 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19124 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19125 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19126 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19127 if (initLocale || !mProcessesReady) {
19128 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19130 broadcastIntentLocked(null, null, intent,
19131 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19132 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19135 // Update the configuration with WM first and check if any of the stacks need to be
19136 // resized due to the configuration change. If so, resize the stacks now and do any
19137 // relaunches if necessary. This way we don't need to relaunch again below in
19138 // ensureActivityConfigurationLocked().
19139 if (mWindowManager != null) {
19140 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19141 if (resizedStacks != null) {
19142 for (int stackId : resizedStacks) {
19143 final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19144 mStackSupervisor.resizeStackLocked(
19145 stackId, newBounds, null, null, false, false, deferResume);
19151 boolean kept = true;
19152 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19153 // mainStack is null during startup.
19154 if (mainStack != null) {
19155 if (changes != 0 && starting == null) {
19156 // If the configuration changed, and the caller is not already
19157 // in the process of starting an activity, then find the top
19158 // activity to check if its configuration needs to change.
19159 starting = mainStack.topRunningActivityLocked();
19162 if (starting != null) {
19163 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19164 // And we need to make sure at this point that all other activities
19165 // are made visible with the correct configuration.
19166 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19167 !PRESERVE_WINDOWS);
19170 if (mWindowManager != null) {
19171 mWindowManager.continueSurfaceLayout();
19177 * Decide based on the configuration whether we should shouw the ANR,
19178 * crash, etc dialogs. The idea is that if there is no affordence to
19179 * press the on-screen buttons, or the user experience would be more
19180 * greatly impacted than the crash itself, we shouldn't show the dialog.
19182 * A thought: SystemUI might also want to get told about this, the Power
19183 * dialog / global actions also might want different behaviors.
19185 private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19186 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19187 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19188 && config.navigation == Configuration.NAVIGATION_NONAV);
19189 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19190 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19191 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19192 return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19196 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19197 synchronized (this) {
19198 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19199 if (srec != null) {
19200 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19206 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19207 Intent resultData) {
19209 synchronized (this) {
19210 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19212 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19218 public int getLaunchedFromUid(IBinder activityToken) {
19219 ActivityRecord srec;
19220 synchronized (this) {
19221 srec = ActivityRecord.forTokenLocked(activityToken);
19223 if (srec == null) {
19226 return srec.launchedFromUid;
19229 public String getLaunchedFromPackage(IBinder activityToken) {
19230 ActivityRecord srec;
19231 synchronized (this) {
19232 srec = ActivityRecord.forTokenLocked(activityToken);
19234 if (srec == null) {
19237 return srec.launchedFromPackage;
19240 // =========================================================
19241 // LIFETIME MANAGEMENT
19242 // =========================================================
19244 // Returns which broadcast queue the app is the current [or imminent] receiver
19245 // on, or 'null' if the app is not an active broadcast recipient.
19246 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19247 BroadcastRecord r = app.curReceiver;
19252 // It's not the current receiver, but it might be starting up to become one
19253 synchronized (this) {
19254 for (BroadcastQueue queue : mBroadcastQueues) {
19255 r = queue.mPendingBroadcast;
19256 if (r != null && r.curApp == app) {
19257 // found it; report which queue it's in
19266 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19267 int targetUid, ComponentName targetComponent, String targetProcess) {
19268 if (!mTrackingAssociations) {
19271 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19272 = mAssociations.get(targetUid);
19273 if (components == null) {
19274 components = new ArrayMap<>();
19275 mAssociations.put(targetUid, components);
19277 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19278 if (sourceUids == null) {
19279 sourceUids = new SparseArray<>();
19280 components.put(targetComponent, sourceUids);
19282 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19283 if (sourceProcesses == null) {
19284 sourceProcesses = new ArrayMap<>();
19285 sourceUids.put(sourceUid, sourceProcesses);
19287 Association ass = sourceProcesses.get(sourceProcess);
19289 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19291 sourceProcesses.put(sourceProcess, ass);
19295 if (ass.mNesting == 1) {
19296 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19297 ass.mLastState = sourceState;
19302 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19303 ComponentName targetComponent) {
19304 if (!mTrackingAssociations) {
19307 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19308 = mAssociations.get(targetUid);
19309 if (components == null) {
19312 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19313 if (sourceUids == null) {
19316 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19317 if (sourceProcesses == null) {
19320 Association ass = sourceProcesses.get(sourceProcess);
19321 if (ass == null || ass.mNesting <= 0) {
19325 if (ass.mNesting == 0) {
19326 long uptime = SystemClock.uptimeMillis();
19327 ass.mTime += uptime - ass.mStartTime;
19328 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19329 += uptime - ass.mLastStateUptime;
19330 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19334 private void noteUidProcessState(final int uid, final int state) {
19335 mBatteryStatsService.noteUidProcessState(uid, state);
19336 if (mTrackingAssociations) {
19337 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19338 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19339 = mAssociations.valueAt(i1);
19340 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19341 SparseArray<ArrayMap<String, Association>> sourceUids
19342 = targetComponents.valueAt(i2);
19343 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19344 if (sourceProcesses != null) {
19345 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19346 Association ass = sourceProcesses.valueAt(i4);
19347 if (ass.mNesting >= 1) {
19348 // currently associated
19349 long uptime = SystemClock.uptimeMillis();
19350 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19351 += uptime - ass.mLastStateUptime;
19352 ass.mLastState = state;
19353 ass.mLastStateUptime = uptime;
19362 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19363 boolean doingAll, long now) {
19364 if (mAdjSeq == app.adjSeq) {
19365 // This adjustment has already been computed.
19366 return app.curRawAdj;
19369 if (app.thread == null) {
19370 app.adjSeq = mAdjSeq;
19371 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19372 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19373 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19376 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19377 app.adjSource = null;
19378 app.adjTarget = null;
19380 app.cached = false;
19382 final int activitiesSize = app.activities.size();
19384 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19385 // The max adjustment doesn't allow this app to be anything
19386 // below foreground, so it is not worth doing work for it.
19387 app.adjType = "fixed";
19388 app.adjSeq = mAdjSeq;
19389 app.curRawAdj = app.maxAdj;
19390 app.foregroundActivities = false;
19391 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19392 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19393 // System processes can do UI, and when they do we want to have
19394 // them trim their memory after the user leaves the UI. To
19395 // facilitate this, here we need to determine whether or not it
19396 // is currently showing UI.
19397 app.systemNoUi = true;
19398 if (app == TOP_APP) {
19399 app.systemNoUi = false;
19400 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19401 app.adjType = "pers-top-activity";
19402 } else if (app.hasTopUi) {
19403 app.systemNoUi = false;
19404 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19405 app.adjType = "pers-top-ui";
19406 } else if (activitiesSize > 0) {
19407 for (int j = 0; j < activitiesSize; j++) {
19408 final ActivityRecord r = app.activities.get(j);
19410 app.systemNoUi = false;
19414 if (!app.systemNoUi) {
19415 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19417 return (app.curAdj=app.maxAdj);
19420 app.systemNoUi = false;
19422 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19424 // Determine the importance of the process, starting with most
19425 // important to least, and assign an appropriate OOM adjustment.
19429 boolean foregroundActivities = false;
19430 BroadcastQueue queue;
19431 if (app == TOP_APP) {
19432 // The last app on the list is the foreground app.
19433 adj = ProcessList.FOREGROUND_APP_ADJ;
19434 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19435 app.adjType = "top-activity";
19436 foregroundActivities = true;
19437 procState = PROCESS_STATE_CUR_TOP;
19438 } else if (app.instrumentationClass != null) {
19439 // Don't want to kill running instrumentation.
19440 adj = ProcessList.FOREGROUND_APP_ADJ;
19441 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19442 app.adjType = "instrumentation";
19443 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19444 } else if ((queue = isReceivingBroadcast(app)) != null) {
19445 // An app that is currently receiving a broadcast also
19446 // counts as being in the foreground for OOM killer purposes.
19447 // It's placed in a sched group based on the nature of the
19448 // broadcast as reflected by which queue it's active in.
19449 adj = ProcessList.FOREGROUND_APP_ADJ;
19450 schedGroup = (queue == mFgBroadcastQueue)
19451 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19452 app.adjType = "broadcast";
19453 procState = ActivityManager.PROCESS_STATE_RECEIVER;
19454 } else if (app.executingServices.size() > 0) {
19455 // An app that is currently executing a service callback also
19456 // counts as being in the foreground.
19457 adj = ProcessList.FOREGROUND_APP_ADJ;
19458 schedGroup = app.execServicesFg ?
19459 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19460 app.adjType = "exec-service";
19461 procState = ActivityManager.PROCESS_STATE_SERVICE;
19462 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19464 // As far as we know the process is empty. We may change our mind later.
19465 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19466 // At this point we don't actually know the adjustment. Use the cached adj
19467 // value that the caller wants us to.
19469 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19472 app.adjType = "cch-empty";
19475 // Examine all activities if not already foreground.
19476 if (!foregroundActivities && activitiesSize > 0) {
19477 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19478 for (int j = 0; j < activitiesSize; j++) {
19479 final ActivityRecord r = app.activities.get(j);
19480 if (r.app != app) {
19481 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19482 + " instead of expected " + app);
19483 if (r.app == null || (r.app.uid == app.uid)) {
19484 // Only fix things up when they look sane
19491 // App has a visible activity; only upgrade adjustment.
19492 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19493 adj = ProcessList.VISIBLE_APP_ADJ;
19494 app.adjType = "visible";
19496 if (procState > PROCESS_STATE_CUR_TOP) {
19497 procState = PROCESS_STATE_CUR_TOP;
19499 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19500 app.cached = false;
19502 foregroundActivities = true;
19503 if (r.task != null && minLayer > 0) {
19504 final int layer = r.task.mLayerRank;
19505 if (layer >= 0 && minLayer > layer) {
19510 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19511 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19512 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19513 app.adjType = "pausing";
19515 if (procState > PROCESS_STATE_CUR_TOP) {
19516 procState = PROCESS_STATE_CUR_TOP;
19518 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19519 app.cached = false;
19521 foregroundActivities = true;
19522 } else if (r.state == ActivityState.STOPPING) {
19523 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19524 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19525 app.adjType = "stopping";
19527 // For the process state, we will at this point consider the
19528 // process to be cached. It will be cached either as an activity
19529 // or empty depending on whether the activity is finishing. We do
19530 // this so that we can treat the process as cached for purposes of
19531 // memory trimming (determing current memory level, trim command to
19532 // send to process) since there can be an arbitrary number of stopping
19533 // processes and they should soon all go into the cached state.
19534 if (!r.finishing) {
19535 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19536 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19539 app.cached = false;
19541 foregroundActivities = true;
19543 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19544 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19545 app.adjType = "cch-act";
19549 if (adj == ProcessList.VISIBLE_APP_ADJ) {
19554 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19555 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19556 if (app.foregroundServices) {
19557 // The user is aware of this app, so make it visible.
19558 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19559 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19560 app.cached = false;
19561 app.adjType = "fg-service";
19562 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19563 } else if (app.forcingToForeground != null) {
19564 // The user is aware of this app, so make it visible.
19565 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19566 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19567 app.cached = false;
19568 app.adjType = "force-fg";
19569 app.adjSource = app.forcingToForeground;
19570 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19574 if (app == mHeavyWeightProcess) {
19575 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19576 // We don't want to kill the current heavy-weight process.
19577 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19578 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19579 app.cached = false;
19580 app.adjType = "heavy";
19582 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19583 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19587 if (app == mHomeProcess) {
19588 if (adj > ProcessList.HOME_APP_ADJ) {
19589 // This process is hosting what we currently consider to be the
19590 // home app, so we don't want to let it go into the background.
19591 adj = ProcessList.HOME_APP_ADJ;
19592 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19593 app.cached = false;
19594 app.adjType = "home";
19596 if (procState > ActivityManager.PROCESS_STATE_HOME) {
19597 procState = ActivityManager.PROCESS_STATE_HOME;
19601 if (app == mPreviousProcess && app.activities.size() > 0) {
19602 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19603 // This was the previous process that showed UI to the user.
19604 // We want to try to keep it around more aggressively, to give
19605 // a good experience around switching between two apps.
19606 adj = ProcessList.PREVIOUS_APP_ADJ;
19607 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19608 app.cached = false;
19609 app.adjType = "previous";
19611 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19612 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19616 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19617 + " reason=" + app.adjType);
19619 // By default, we use the computed adjustment. It may be changed if
19620 // there are applications dependent on our services or providers, but
19621 // this gives us a baseline and makes sure we don't get into an
19622 // infinite recursion.
19623 app.adjSeq = mAdjSeq;
19624 app.curRawAdj = adj;
19625 app.hasStartedServices = false;
19627 if (mBackupTarget != null && app == mBackupTarget.app) {
19628 // If possible we want to avoid killing apps while they're being backed up
19629 if (adj > ProcessList.BACKUP_APP_ADJ) {
19630 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19631 adj = ProcessList.BACKUP_APP_ADJ;
19632 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19633 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19635 app.adjType = "backup";
19636 app.cached = false;
19638 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19639 procState = ActivityManager.PROCESS_STATE_BACKUP;
19643 boolean mayBeTop = false;
19645 for (int is = app.services.size()-1;
19646 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19647 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19648 || procState > ActivityManager.PROCESS_STATE_TOP);
19650 ServiceRecord s = app.services.valueAt(is);
19651 if (s.startRequested) {
19652 app.hasStartedServices = true;
19653 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19654 procState = ActivityManager.PROCESS_STATE_SERVICE;
19656 if (app.hasShownUi && app != mHomeProcess) {
19657 // If this process has shown some UI, let it immediately
19658 // go to the LRU list because it may be pretty heavy with
19659 // UI stuff. We'll tag it with a label just to help
19660 // debug and understand what is going on.
19661 if (adj > ProcessList.SERVICE_ADJ) {
19662 app.adjType = "cch-started-ui-services";
19665 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19666 // This service has seen some activity within
19667 // recent memory, so we will keep its process ahead
19668 // of the background processes.
19669 if (adj > ProcessList.SERVICE_ADJ) {
19670 adj = ProcessList.SERVICE_ADJ;
19671 app.adjType = "started-services";
19672 app.cached = false;
19675 // If we have let the service slide into the background
19676 // state, still have some text describing what it is doing
19677 // even though the service no longer has an impact.
19678 if (adj > ProcessList.SERVICE_ADJ) {
19679 app.adjType = "cch-started-services";
19684 for (int conni = s.connections.size()-1;
19685 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19686 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19687 || procState > ActivityManager.PROCESS_STATE_TOP);
19689 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19691 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19692 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19693 || procState > ActivityManager.PROCESS_STATE_TOP);
19695 // XXX should compute this based on the max of
19696 // all connected clients.
19697 ConnectionRecord cr = clist.get(i);
19698 if (cr.binding.client == app) {
19699 // Binding to ourself is not interesting.
19703 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19704 ProcessRecord client = cr.binding.client;
19705 int clientAdj = computeOomAdjLocked(client, cachedAdj,
19706 TOP_APP, doingAll, now);
19707 int clientProcState = client.curProcState;
19708 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19709 // If the other app is cached for any reason, for purposes here
19710 // we are going to consider it empty. The specific cached state
19711 // doesn't propagate except under certain conditions.
19712 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19714 String adjType = null;
19715 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19716 // Not doing bind OOM management, so treat
19717 // this guy more like a started service.
19718 if (app.hasShownUi && app != mHomeProcess) {
19719 // If this process has shown some UI, let it immediately
19720 // go to the LRU list because it may be pretty heavy with
19721 // UI stuff. We'll tag it with a label just to help
19722 // debug and understand what is going on.
19723 if (adj > clientAdj) {
19724 adjType = "cch-bound-ui-services";
19726 app.cached = false;
19728 clientProcState = procState;
19730 if (now >= (s.lastActivity
19731 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19732 // This service has not seen activity within
19733 // recent memory, so allow it to drop to the
19734 // LRU list if there is no other reason to keep
19735 // it around. We'll also tag it with a label just
19736 // to help debug and undertand what is going on.
19737 if (adj > clientAdj) {
19738 adjType = "cch-bound-services";
19744 if (adj > clientAdj) {
19745 // If this process has recently shown UI, and
19746 // the process that is binding to it is less
19747 // important than being visible, then we don't
19748 // care about the binding as much as we care
19749 // about letting this process get into the LRU
19750 // list to be killed and restarted if needed for
19752 if (app.hasShownUi && app != mHomeProcess
19753 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19754 adjType = "cch-bound-ui-services";
19756 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19757 |Context.BIND_IMPORTANT)) != 0) {
19758 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19759 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19760 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19761 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19762 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19763 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19764 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19767 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19768 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19771 if (!client.cached) {
19772 app.cached = false;
19774 adjType = "service";
19777 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19778 // This will treat important bound services identically to
19779 // the top app, which may behave differently than generic
19780 // foreground work.
19781 if (client.curSchedGroup > schedGroup) {
19782 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19783 schedGroup = client.curSchedGroup;
19785 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19788 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19789 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19790 // Special handling of clients who are in the top state.
19791 // We *may* want to consider this process to be in the
19792 // top state as well, but only if there is not another
19793 // reason for it to be running. Being on the top is a
19794 // special state, meaning you are specifically running
19795 // for the current top app. If the process is already
19796 // running in the background for some other reason, it
19797 // is more important to continue considering it to be
19798 // in the background state.
19800 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19802 // Special handling for above-top states (persistent
19803 // processes). These should not bring the current process
19804 // into the top state, since they are not on top. Instead
19805 // give them the best state after that.
19806 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19808 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19809 } else if (mWakefulness
19810 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19811 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19814 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19817 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19822 if (clientProcState <
19823 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19825 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19828 if (procState > clientProcState) {
19829 procState = clientProcState;
19831 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19832 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19833 app.pendingUiClean = true;
19835 if (adjType != null) {
19836 app.adjType = adjType;
19837 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19838 .REASON_SERVICE_IN_USE;
19839 app.adjSource = cr.binding.client;
19840 app.adjSourceProcState = clientProcState;
19841 app.adjTarget = s.name;
19844 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19845 app.treatLikeActivity = true;
19847 final ActivityRecord a = cr.activity;
19848 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19849 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19850 (a.visible || a.state == ActivityState.RESUMED ||
19851 a.state == ActivityState.PAUSING)) {
19852 adj = ProcessList.FOREGROUND_APP_ADJ;
19853 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19854 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19855 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19857 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19860 app.cached = false;
19861 app.adjType = "service";
19862 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19863 .REASON_SERVICE_IN_USE;
19865 app.adjSourceProcState = procState;
19866 app.adjTarget = s.name;
19873 for (int provi = app.pubProviders.size()-1;
19874 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19875 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19876 || procState > ActivityManager.PROCESS_STATE_TOP);
19878 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19879 for (int i = cpr.connections.size()-1;
19880 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19881 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19882 || procState > ActivityManager.PROCESS_STATE_TOP);
19884 ContentProviderConnection conn = cpr.connections.get(i);
19885 ProcessRecord client = conn.client;
19886 if (client == app) {
19887 // Being our own client is not interesting.
19890 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19891 int clientProcState = client.curProcState;
19892 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19893 // If the other app is cached for any reason, for purposes here
19894 // we are going to consider it empty.
19895 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19897 if (adj > clientAdj) {
19898 if (app.hasShownUi && app != mHomeProcess
19899 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19900 app.adjType = "cch-ui-provider";
19902 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19903 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19904 app.adjType = "provider";
19906 app.cached &= client.cached;
19907 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19908 .REASON_PROVIDER_IN_USE;
19909 app.adjSource = client;
19910 app.adjSourceProcState = clientProcState;
19911 app.adjTarget = cpr.name;
19913 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19914 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19915 // Special handling of clients who are in the top state.
19916 // We *may* want to consider this process to be in the
19917 // top state as well, but only if there is not another
19918 // reason for it to be running. Being on the top is a
19919 // special state, meaning you are specifically running
19920 // for the current top app. If the process is already
19921 // running in the background for some other reason, it
19922 // is more important to continue considering it to be
19923 // in the background state.
19925 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19927 // Special handling for above-top states (persistent
19928 // processes). These should not bring the current process
19929 // into the top state, since they are not on top. Instead
19930 // give them the best state after that.
19932 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19935 if (procState > clientProcState) {
19936 procState = clientProcState;
19938 if (client.curSchedGroup > schedGroup) {
19939 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19942 // If the provider has external (non-framework) process
19943 // dependencies, ensure that its adjustment is at least
19944 // FOREGROUND_APP_ADJ.
19945 if (cpr.hasExternalProcessHandles()) {
19946 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19947 adj = ProcessList.FOREGROUND_APP_ADJ;
19948 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19949 app.cached = false;
19950 app.adjType = "provider";
19951 app.adjTarget = cpr.name;
19953 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19954 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19959 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19960 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19961 adj = ProcessList.PREVIOUS_APP_ADJ;
19962 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19963 app.cached = false;
19964 app.adjType = "provider";
19966 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19967 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19971 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19972 // A client of one of our services or providers is in the top state. We
19973 // *may* want to be in the top state, but not if we are already running in
19974 // the background for some other reason. For the decision here, we are going
19975 // to pick out a few specific states that we want to remain in when a client
19976 // is top (states that tend to be longer-term) and otherwise allow it to go
19977 // to the top state.
19978 switch (procState) {
19979 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19980 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19981 case ActivityManager.PROCESS_STATE_SERVICE:
19982 // These all are longer-term states, so pull them up to the top
19983 // of the background states, but not all the way to the top state.
19984 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19987 // Otherwise, top is a better choice, so take it.
19988 procState = ActivityManager.PROCESS_STATE_TOP;
19993 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19994 if (app.hasClientActivities) {
19995 // This is a cached process, but with client activities. Mark it so.
19996 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19997 app.adjType = "cch-client-act";
19998 } else if (app.treatLikeActivity) {
19999 // This is a cached process, but somebody wants us to treat it like it has
20000 // an activity, okay!
20001 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
20002 app.adjType = "cch-as-act";
20006 if (adj == ProcessList.SERVICE_ADJ) {
20008 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
20009 mNewNumServiceProcs++;
20010 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
20011 if (!app.serviceb) {
20012 // This service isn't far enough down on the LRU list to
20013 // normally be a B service, but if we are low on RAM and it
20014 // is large we want to force it down since we would prefer to
20015 // keep launcher over it.
20016 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
20017 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20018 app.serviceHighRam = true;
20019 app.serviceb = true;
20020 //Slog.i(TAG, "ADJ " + app + " high ram!");
20022 mNewNumAServiceProcs++;
20023 //Slog.i(TAG, "ADJ " + app + " not high ram!");
20026 app.serviceHighRam = false;
20029 if (app.serviceb) {
20030 adj = ProcessList.SERVICE_B_ADJ;
20034 app.curRawAdj = adj;
20036 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20037 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20038 if (adj > app.maxAdj) {
20040 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20041 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20045 // Do final modification to adj. Everything we do between here and applying
20046 // the final setAdj must be done in this function, because we will also use
20047 // it when computing the final cached adj later. Note that we don't need to
20048 // worry about this for max adj above, since max adj will always be used to
20049 // keep it out of the cached vaues.
20050 app.curAdj = app.modifyRawOomAdj(adj);
20051 app.curSchedGroup = schedGroup;
20052 app.curProcState = procState;
20053 app.foregroundActivities = foregroundActivities;
20055 return app.curRawAdj;
20059 * Record new PSS sample for a process.
20061 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20063 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20065 proc.lastPssTime = now;
20066 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20067 if (DEBUG_PSS) Slog.d(TAG_PSS,
20068 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20069 + " state=" + ProcessList.makeProcStateString(procState));
20070 if (proc.initialIdlePss == 0) {
20071 proc.initialIdlePss = pss;
20073 proc.lastPss = pss;
20074 proc.lastSwapPss = swapPss;
20075 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20076 proc.lastCachedPss = pss;
20077 proc.lastCachedSwapPss = swapPss;
20080 final SparseArray<Pair<Long, String>> watchUids
20081 = mMemWatchProcesses.getMap().get(proc.processName);
20083 if (watchUids != null) {
20084 Pair<Long, String> val = watchUids.get(proc.uid);
20086 val = watchUids.get(0);
20092 if (check != null) {
20093 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20094 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20095 if (!isDebuggable) {
20096 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20097 isDebuggable = true;
20100 if (isDebuggable) {
20101 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20102 final ProcessRecord myProc = proc;
20103 final File heapdumpFile = DumpHeapProvider.getJavaFile();
20104 mMemWatchDumpProcName = proc.processName;
20105 mMemWatchDumpFile = heapdumpFile.toString();
20106 mMemWatchDumpPid = proc.pid;
20107 mMemWatchDumpUid = proc.uid;
20108 BackgroundThread.getHandler().post(new Runnable() {
20110 public void run() {
20111 revokeUriPermission(ActivityThread.currentActivityThread()
20112 .getApplicationThread(),
20113 DumpHeapActivity.JAVA_URI,
20114 Intent.FLAG_GRANT_READ_URI_PERMISSION
20115 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20116 UserHandle.myUserId());
20117 ParcelFileDescriptor fd = null;
20119 heapdumpFile.delete();
20120 fd = ParcelFileDescriptor.open(heapdumpFile,
20121 ParcelFileDescriptor.MODE_CREATE |
20122 ParcelFileDescriptor.MODE_TRUNCATE |
20123 ParcelFileDescriptor.MODE_WRITE_ONLY |
20124 ParcelFileDescriptor.MODE_APPEND);
20125 IApplicationThread thread = myProc.thread;
20126 if (thread != null) {
20128 if (DEBUG_PSS) Slog.d(TAG_PSS,
20129 "Requesting dump heap from "
20130 + myProc + " to " + heapdumpFile);
20131 thread.dumpHeap(true, heapdumpFile.toString(), fd);
20132 } catch (RemoteException e) {
20135 } catch (FileNotFoundException e) {
20136 e.printStackTrace();
20141 } catch (IOException e) {
20148 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20149 + ", but debugging not enabled");
20156 * Schedule PSS collection of a process.
20158 void requestPssLocked(ProcessRecord proc, int procState) {
20159 if (mPendingPssProcesses.contains(proc)) {
20162 if (mPendingPssProcesses.size() == 0) {
20163 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20165 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20166 proc.pssProcState = procState;
20167 mPendingPssProcesses.add(proc);
20171 * Schedule PSS collection of all processes.
20173 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20175 if (now < (mLastFullPssTime +
20176 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20180 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
20181 mLastFullPssTime = now;
20182 mFullPssPending = true;
20183 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20184 mPendingPssProcesses.clear();
20185 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20186 ProcessRecord app = mLruProcesses.get(i);
20187 if (app.thread == null
20188 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20191 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20192 app.pssProcState = app.setProcState;
20193 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20194 mTestPssMode, isSleepingLocked(), now);
20195 mPendingPssProcesses.add(app);
20198 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20201 public void setTestPssMode(boolean enabled) {
20202 synchronized (this) {
20203 mTestPssMode = enabled;
20205 // Whenever we enable the mode, we want to take a snapshot all of current
20206 // process mem use.
20207 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20213 * Ask a given process to GC right now.
20215 final void performAppGcLocked(ProcessRecord app) {
20217 app.lastRequestedGc = SystemClock.uptimeMillis();
20218 if (app.thread != null) {
20219 if (app.reportLowMemory) {
20220 app.reportLowMemory = false;
20221 app.thread.scheduleLowMemory();
20223 app.thread.processInBackground();
20226 } catch (Exception e) {
20232 * Returns true if things are idle enough to perform GCs.
20234 private final boolean canGcNowLocked() {
20235 boolean processingBroadcasts = false;
20236 for (BroadcastQueue q : mBroadcastQueues) {
20237 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20238 processingBroadcasts = true;
20241 return !processingBroadcasts
20242 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20246 * Perform GCs on all processes that are waiting for it, but only
20247 * if things are idle.
20249 final void performAppGcsLocked() {
20250 final int N = mProcessesToGc.size();
20254 if (canGcNowLocked()) {
20255 while (mProcessesToGc.size() > 0) {
20256 ProcessRecord proc = mProcessesToGc.remove(0);
20257 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20258 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20259 <= SystemClock.uptimeMillis()) {
20260 // To avoid spamming the system, we will GC processes one
20261 // at a time, waiting a few seconds between each.
20262 performAppGcLocked(proc);
20263 scheduleAppGcsLocked();
20266 // It hasn't been long enough since we last GCed this
20267 // process... put it in the list to wait for its time.
20268 addProcessToGcListLocked(proc);
20274 scheduleAppGcsLocked();
20279 * If all looks good, perform GCs on all processes waiting for them.
20281 final void performAppGcsIfAppropriateLocked() {
20282 if (canGcNowLocked()) {
20283 performAppGcsLocked();
20286 // Still not idle, wait some more.
20287 scheduleAppGcsLocked();
20291 * Schedule the execution of all pending app GCs.
20293 final void scheduleAppGcsLocked() {
20294 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20296 if (mProcessesToGc.size() > 0) {
20297 // Schedule a GC for the time to the next process.
20298 ProcessRecord proc = mProcessesToGc.get(0);
20299 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20301 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20302 long now = SystemClock.uptimeMillis();
20303 if (when < (now+GC_TIMEOUT)) {
20304 when = now + GC_TIMEOUT;
20306 mHandler.sendMessageAtTime(msg, when);
20311 * Add a process to the array of processes waiting to be GCed. Keeps the
20312 * list in sorted order by the last GC time. The process can't already be
20315 final void addProcessToGcListLocked(ProcessRecord proc) {
20316 boolean added = false;
20317 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20318 if (mProcessesToGc.get(i).lastRequestedGc <
20319 proc.lastRequestedGc) {
20321 mProcessesToGc.add(i+1, proc);
20326 mProcessesToGc.add(0, proc);
20331 * Set up to ask a process to GC itself. This will either do it
20332 * immediately, or put it on the list of processes to gc the next
20333 * time things are idle.
20335 final void scheduleAppGcLocked(ProcessRecord app) {
20336 long now = SystemClock.uptimeMillis();
20337 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20340 if (!mProcessesToGc.contains(app)) {
20341 addProcessToGcListLocked(app);
20342 scheduleAppGcsLocked();
20346 final void checkExcessivePowerUsageLocked(boolean doKills) {
20347 updateCpuStatsNow();
20349 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20350 boolean doWakeKills = doKills;
20351 boolean doCpuKills = doKills;
20352 if (mLastPowerCheckRealtime == 0) {
20353 doWakeKills = false;
20355 if (mLastPowerCheckUptime == 0) {
20356 doCpuKills = false;
20358 if (stats.isScreenOn()) {
20359 doWakeKills = false;
20361 final long curRealtime = SystemClock.elapsedRealtime();
20362 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20363 final long curUptime = SystemClock.uptimeMillis();
20364 final long uptimeSince = curUptime - mLastPowerCheckUptime;
20365 mLastPowerCheckRealtime = curRealtime;
20366 mLastPowerCheckUptime = curUptime;
20367 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20368 doWakeKills = false;
20370 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20371 doCpuKills = false;
20373 int i = mLruProcesses.size();
20376 ProcessRecord app = mLruProcesses.get(i);
20377 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20379 synchronized (stats) {
20380 wtime = stats.getProcessWakeTime(app.info.uid,
20381 app.pid, curRealtime);
20383 long wtimeUsed = wtime - app.lastWakeTime;
20384 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20386 StringBuilder sb = new StringBuilder(128);
20387 sb.append("Wake for ");
20388 app.toShortString(sb);
20389 sb.append(": over ");
20390 TimeUtils.formatDuration(realtimeSince, sb);
20391 sb.append(" used ");
20392 TimeUtils.formatDuration(wtimeUsed, sb);
20394 sb.append((wtimeUsed*100)/realtimeSince);
20396 Slog.i(TAG_POWER, sb.toString());
20398 sb.append("CPU for ");
20399 app.toShortString(sb);
20400 sb.append(": over ");
20401 TimeUtils.formatDuration(uptimeSince, sb);
20402 sb.append(" used ");
20403 TimeUtils.formatDuration(cputimeUsed, sb);
20405 sb.append((cputimeUsed*100)/uptimeSince);
20407 Slog.i(TAG_POWER, sb.toString());
20409 // If a process has held a wake lock for more
20410 // than 50% of the time during this period,
20411 // that sounds bad. Kill!
20412 if (doWakeKills && realtimeSince > 0
20413 && ((wtimeUsed*100)/realtimeSince) >= 50) {
20414 synchronized (stats) {
20415 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20416 realtimeSince, wtimeUsed);
20418 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20419 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20420 } else if (doCpuKills && uptimeSince > 0
20421 && ((cputimeUsed*100)/uptimeSince) >= 25) {
20422 synchronized (stats) {
20423 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20424 uptimeSince, cputimeUsed);
20426 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20427 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20429 app.lastWakeTime = wtime;
20430 app.lastCpuTime = app.curCpuTime;
20436 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20438 boolean success = true;
20440 if (app.curRawAdj != app.setRawAdj) {
20441 app.setRawAdj = app.curRawAdj;
20446 if (app.curAdj != app.setAdj) {
20447 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20448 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20449 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20451 app.setAdj = app.curAdj;
20452 app.verifiedAdj = ProcessList.INVALID_ADJ;
20455 if (app.setSchedGroup != app.curSchedGroup) {
20456 int oldSchedGroup = app.setSchedGroup;
20457 app.setSchedGroup = app.curSchedGroup;
20458 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20459 "Setting sched group of " + app.processName
20460 + " to " + app.curSchedGroup);
20461 if (app.waitingToKill != null && app.curReceiver == null
20462 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20463 app.kill(app.waitingToKill, true);
20467 switch (app.curSchedGroup) {
20468 case ProcessList.SCHED_GROUP_BACKGROUND:
20469 processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20471 case ProcessList.SCHED_GROUP_TOP_APP:
20472 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20473 processGroup = Process.THREAD_GROUP_TOP_APP;
20476 processGroup = Process.THREAD_GROUP_DEFAULT;
20479 long oldId = Binder.clearCallingIdentity();
20481 Process.setProcessGroup(app.pid, processGroup);
20482 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20483 // do nothing if we already switched to RT
20484 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20485 // Switch VR thread for app to SCHED_FIFO
20486 if (mInVrMode && app.vrThreadTid != 0) {
20488 Process.setThreadScheduler(app.vrThreadTid,
20489 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20490 } catch (IllegalArgumentException e) {
20491 // thread died, ignore
20494 if (mUseFifoUiScheduling) {
20495 // Switch UI pipeline for app to SCHED_FIFO
20496 app.savedPriority = Process.getThreadPriority(app.pid);
20498 Process.setThreadScheduler(app.pid,
20499 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20500 } catch (IllegalArgumentException e) {
20501 // thread died, ignore
20503 if (app.renderThreadTid != 0) {
20505 Process.setThreadScheduler(app.renderThreadTid,
20506 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20507 } catch (IllegalArgumentException e) {
20508 // thread died, ignore
20510 if (DEBUG_OOM_ADJ) {
20511 Slog.d("UI_FIFO", "Set RenderThread (TID " +
20512 app.renderThreadTid + ") to FIFO");
20515 if (DEBUG_OOM_ADJ) {
20516 Slog.d("UI_FIFO", "Not setting RenderThread TID");
20520 // Boost priority for top app UI and render threads
20521 Process.setThreadPriority(app.pid, -10);
20522 if (app.renderThreadTid != 0) {
20524 Process.setThreadPriority(app.renderThreadTid, -10);
20525 } catch (IllegalArgumentException e) {
20526 // thread died, ignore
20531 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20532 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20533 // Reset VR thread to SCHED_OTHER
20534 // Safe to do even if we're not in VR mode
20535 if (app.vrThreadTid != 0) {
20536 Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20538 if (mUseFifoUiScheduling) {
20539 // Reset UI pipeline to SCHED_OTHER
20540 Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20541 Process.setThreadPriority(app.pid, app.savedPriority);
20542 if (app.renderThreadTid != 0) {
20543 Process.setThreadScheduler(app.renderThreadTid,
20544 Process.SCHED_OTHER, 0);
20545 Process.setThreadPriority(app.renderThreadTid, -4);
20548 // Reset priority for top app UI and render threads
20549 Process.setThreadPriority(app.pid, 0);
20550 if (app.renderThreadTid != 0) {
20551 Process.setThreadPriority(app.renderThreadTid, 0);
20555 } catch (Exception e) {
20556 Slog.w(TAG, "Failed setting process group of " + app.pid
20557 + " to " + app.curSchedGroup);
20558 e.printStackTrace();
20560 Binder.restoreCallingIdentity(oldId);
20564 if (app.repForegroundActivities != app.foregroundActivities) {
20565 app.repForegroundActivities = app.foregroundActivities;
20566 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20568 if (app.repProcState != app.curProcState) {
20569 app.repProcState = app.curProcState;
20570 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20571 if (app.thread != null) {
20574 //RuntimeException h = new RuntimeException("here");
20575 Slog.i(TAG, "Sending new process state " + app.repProcState
20576 + " to " + app /*, h*/);
20578 app.thread.setProcessState(app.repProcState);
20579 } catch (RemoteException e) {
20583 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20584 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20585 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20586 // Experimental code to more aggressively collect pss while
20587 // running test... the problem is that this tends to collect
20588 // the data right when a process is transitioning between process
20589 // states, which well tend to give noisy data.
20590 long start = SystemClock.uptimeMillis();
20591 long pss = Debug.getPss(app.pid, mTmpLong, null);
20592 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20593 mPendingPssProcesses.remove(app);
20594 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20595 + " to " + app.curProcState + ": "
20596 + (SystemClock.uptimeMillis()-start) + "ms");
20598 app.lastStateTime = now;
20599 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20600 mTestPssMode, isSleepingLocked(), now);
20601 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20602 + ProcessList.makeProcStateString(app.setProcState) + " to "
20603 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20604 + (app.nextPssTime-now) + ": " + app);
20606 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20607 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20609 requestPssLocked(app, app.setProcState);
20610 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20611 mTestPssMode, isSleepingLocked(), now);
20612 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20613 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20615 if (app.setProcState != app.curProcState) {
20616 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20617 "Proc state change of " + app.processName
20618 + " to " + app.curProcState);
20619 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20620 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20621 if (setImportant && !curImportant) {
20622 // This app is no longer something we consider important enough to allow to
20623 // use arbitrary amounts of battery power. Note
20624 // its current wake lock time to later know to kill it if
20625 // it is not behaving well.
20626 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20627 synchronized (stats) {
20628 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20629 app.pid, nowElapsed);
20631 app.lastCpuTime = app.curCpuTime;
20634 // Inform UsageStats of important process state change
20635 // Must be called before updating setProcState
20636 maybeUpdateUsageStatsLocked(app, nowElapsed);
20638 app.setProcState = app.curProcState;
20639 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20640 app.notCachedSinceIdle = false;
20643 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20645 app.procStateChanged = true;
20647 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20648 > USAGE_STATS_INTERACTION_INTERVAL) {
20649 // For apps that sit around for a long time in the interactive state, we need
20650 // to report this at least once a day so they don't go idle.
20651 maybeUpdateUsageStatsLocked(app, nowElapsed);
20654 if (changes != 0) {
20655 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20656 "Changes in " + app + ": " + changes);
20657 int i = mPendingProcessChanges.size()-1;
20658 ProcessChangeItem item = null;
20660 item = mPendingProcessChanges.get(i);
20661 if (item.pid == app.pid) {
20662 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20663 "Re-using existing item: " + item);
20669 // No existing item in pending changes; need a new one.
20670 final int NA = mAvailProcessChanges.size();
20672 item = mAvailProcessChanges.remove(NA-1);
20673 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20674 "Retrieving available item: " + item);
20676 item = new ProcessChangeItem();
20677 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20678 "Allocating new item: " + item);
20681 item.pid = app.pid;
20682 item.uid = app.info.uid;
20683 if (mPendingProcessChanges.size() == 0) {
20684 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20685 "*** Enqueueing dispatch processes changed!");
20686 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20688 mPendingProcessChanges.add(item);
20690 item.changes |= changes;
20691 item.processState = app.repProcState;
20692 item.foregroundActivities = app.repForegroundActivities;
20693 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20694 "Item " + Integer.toHexString(System.identityHashCode(item))
20695 + " " + app.toShortString() + ": changes=" + item.changes
20696 + " procState=" + item.processState
20697 + " foreground=" + item.foregroundActivities
20698 + " type=" + app.adjType + " source=" + app.adjSource
20699 + " target=" + app.adjTarget);
20705 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20706 final UidRecord.ChangeItem pendingChange;
20707 if (uidRec == null || uidRec.pendingChange == null) {
20708 if (mPendingUidChanges.size() == 0) {
20709 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20710 "*** Enqueueing dispatch uid changed!");
20711 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20713 final int NA = mAvailUidChanges.size();
20715 pendingChange = mAvailUidChanges.remove(NA-1);
20716 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20717 "Retrieving available item: " + pendingChange);
20719 pendingChange = new UidRecord.ChangeItem();
20720 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20721 "Allocating new item: " + pendingChange);
20723 if (uidRec != null) {
20724 uidRec.pendingChange = pendingChange;
20725 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20726 // If this uid is going away, and we haven't yet reported it is gone,
20728 change = UidRecord.CHANGE_GONE_IDLE;
20730 } else if (uid < 0) {
20731 throw new IllegalArgumentException("No UidRecord or uid");
20733 pendingChange.uidRecord = uidRec;
20734 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20735 mPendingUidChanges.add(pendingChange);
20737 pendingChange = uidRec.pendingChange;
20738 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20739 change = UidRecord.CHANGE_GONE_IDLE;
20742 pendingChange.change = change;
20743 pendingChange.processState = uidRec != null
20744 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20747 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20748 String authority) {
20749 if (app == null) return;
20750 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20751 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20752 if (userState == null) return;
20753 final long now = SystemClock.elapsedRealtime();
20754 Long lastReported = userState.mProviderLastReportedFg.get(authority);
20755 if (lastReported == null || lastReported < now - 60 * 1000L) {
20756 if (mSystemReady) {
20757 // Cannot touch the user stats if not system ready
20758 mUsageStatsService.reportContentProviderUsage(
20759 authority, providerPkgName, app.userId);
20761 userState.mProviderLastReportedFg.put(authority, now);
20766 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20767 if (DEBUG_USAGE_STATS) {
20768 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20769 + "] state changes: old = " + app.setProcState + ", new = "
20770 + app.curProcState);
20772 if (mUsageStatsService == null) {
20775 boolean isInteraction;
20776 // To avoid some abuse patterns, we are going to be careful about what we consider
20777 // to be an app interaction. Being the top activity doesn't count while the display
20778 // is sleeping, nor do short foreground services.
20779 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20780 isInteraction = true;
20781 app.fgInteractionTime = 0;
20782 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20783 if (app.fgInteractionTime == 0) {
20784 app.fgInteractionTime = nowElapsed;
20785 isInteraction = false;
20787 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20790 // If the app was being forced to the foreground, by say a Toast, then
20791 // no need to treat it as an interaction
20792 isInteraction = app.forcingToForeground == null
20793 && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20794 app.fgInteractionTime = 0;
20796 if (isInteraction && (!app.reportedInteraction
20797 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20798 app.interactionEventTime = nowElapsed;
20799 String[] packages = app.getPackageList();
20800 if (packages != null) {
20801 for (int i = 0; i < packages.length; i++) {
20802 mUsageStatsService.reportEvent(packages[i], app.userId,
20803 UsageEvents.Event.SYSTEM_INTERACTION);
20807 app.reportedInteraction = isInteraction;
20808 if (!isInteraction) {
20809 app.interactionEventTime = 0;
20813 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20814 if (proc.thread != null) {
20815 if (proc.baseProcessTracker != null) {
20816 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20821 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20822 ProcessRecord TOP_APP, boolean doingAll, long now) {
20823 if (app.thread == null) {
20827 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20829 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20832 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20834 if (isForeground != proc.foregroundServices) {
20835 proc.foregroundServices = isForeground;
20836 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20838 if (isForeground) {
20839 if (curProcs == null) {
20840 curProcs = new ArrayList<ProcessRecord>();
20841 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20843 if (!curProcs.contains(proc)) {
20844 curProcs.add(proc);
20845 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20846 proc.info.packageName, proc.info.uid);
20849 if (curProcs != null) {
20850 if (curProcs.remove(proc)) {
20851 mBatteryStatsService.noteEvent(
20852 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20853 proc.info.packageName, proc.info.uid);
20854 if (curProcs.size() <= 0) {
20855 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20861 updateOomAdjLocked();
20866 private final ActivityRecord resumedAppLocked() {
20867 ActivityRecord act = mStackSupervisor.resumedAppLocked();
20871 pkg = act.packageName;
20872 uid = act.info.applicationInfo.uid;
20877 // Has the UID or resumed package name changed?
20878 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20879 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20880 if (mCurResumedPackage != null) {
20881 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20882 mCurResumedPackage, mCurResumedUid);
20884 mCurResumedPackage = pkg;
20885 mCurResumedUid = uid;
20886 if (mCurResumedPackage != null) {
20887 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20888 mCurResumedPackage, mCurResumedUid);
20894 final boolean updateOomAdjLocked(ProcessRecord app) {
20895 final ActivityRecord TOP_ACT = resumedAppLocked();
20896 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20897 final boolean wasCached = app.cached;
20901 // This is the desired cached adjusment we want to tell it to use.
20902 // If our app is currently cached, we know it, and that is it. Otherwise,
20903 // we don't know it yet, and it needs to now be cached we will then
20904 // need to do a complete oom adj.
20905 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20906 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20907 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20908 SystemClock.uptimeMillis());
20909 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20910 // Changed to/from cached state, so apps after it in the LRU
20911 // list may also be changed.
20912 updateOomAdjLocked();
20917 final void updateOomAdjLocked() {
20918 final ActivityRecord TOP_ACT = resumedAppLocked();
20919 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20920 final long now = SystemClock.uptimeMillis();
20921 final long nowElapsed = SystemClock.elapsedRealtime();
20922 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20923 final int N = mLruProcesses.size();
20926 RuntimeException e = new RuntimeException();
20927 e.fillInStackTrace();
20928 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20931 // Reset state in all uid records.
20932 for (int i=mActiveUids.size()-1; i>=0; i--) {
20933 final UidRecord uidRec = mActiveUids.valueAt(i);
20934 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20935 "Starting update of " + uidRec);
20939 mStackSupervisor.rankTaskLayersIfNeeded();
20942 mNewNumServiceProcs = 0;
20943 mNewNumAServiceProcs = 0;
20945 final int emptyProcessLimit;
20946 final int cachedProcessLimit;
20947 if (mProcessLimit <= 0) {
20948 emptyProcessLimit = cachedProcessLimit = 0;
20949 } else if (mProcessLimit == 1) {
20950 emptyProcessLimit = 1;
20951 cachedProcessLimit = 0;
20953 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20954 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20957 // Let's determine how many processes we have running vs.
20958 // how many slots we have for background processes; we may want
20959 // to put multiple processes in a slot of there are enough of
20961 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20962 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20963 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20964 if (numEmptyProcs > cachedProcessLimit) {
20965 // If there are more empty processes than our limit on cached
20966 // processes, then use the cached process limit for the factor.
20967 // This ensures that the really old empty processes get pushed
20968 // down to the bottom, so if we are running low on memory we will
20969 // have a better chance at keeping around more cached processes
20970 // instead of a gazillion empty processes.
20971 numEmptyProcs = cachedProcessLimit;
20973 int emptyFactor = numEmptyProcs/numSlots;
20974 if (emptyFactor < 1) emptyFactor = 1;
20975 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20976 if (cachedFactor < 1) cachedFactor = 1;
20977 int stepCached = 0;
20981 int numTrimming = 0;
20983 mNumNonCachedProcs = 0;
20984 mNumCachedHiddenProcs = 0;
20986 // First update the OOM adjustment for each of the
20987 // application processes based on their current state.
20988 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20989 int nextCachedAdj = curCachedAdj+1;
20990 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20991 int nextEmptyAdj = curEmptyAdj+2;
20992 for (int i=N-1; i>=0; i--) {
20993 ProcessRecord app = mLruProcesses.get(i);
20994 if (!app.killedByAm && app.thread != null) {
20995 app.procStateChanged = false;
20996 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20998 // If we haven't yet assigned the final cached adj
20999 // to the process, do that now.
21000 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
21001 switch (app.curProcState) {
21002 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21003 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21004 // This process is a cached process holding activities...
21005 // assign it the next cached value for that type, and then
21006 // step that cached level.
21007 app.curRawAdj = curCachedAdj;
21008 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
21009 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
21010 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
21012 if (curCachedAdj != nextCachedAdj) {
21014 if (stepCached >= cachedFactor) {
21016 curCachedAdj = nextCachedAdj;
21017 nextCachedAdj += 2;
21018 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21019 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21025 // For everything else, assign next empty cached process
21026 // level and bump that up. Note that this means that
21027 // long-running services that have dropped down to the
21028 // cached level will be treated as empty (since their process
21029 // state is still as a service), which is what we want.
21030 app.curRawAdj = curEmptyAdj;
21031 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21032 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21033 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21035 if (curEmptyAdj != nextEmptyAdj) {
21037 if (stepEmpty >= emptyFactor) {
21039 curEmptyAdj = nextEmptyAdj;
21041 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21042 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21050 applyOomAdjLocked(app, true, now, nowElapsed);
21052 // Count the number of process types.
21053 switch (app.curProcState) {
21054 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21055 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21056 mNumCachedHiddenProcs++;
21058 if (numCached > cachedProcessLimit) {
21059 app.kill("cached #" + numCached, true);
21062 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21063 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21064 && app.lastActivityTime < oldTime) {
21065 app.kill("empty for "
21066 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21067 / 1000) + "s", true);
21070 if (numEmpty > emptyProcessLimit) {
21071 app.kill("empty #" + numEmpty, true);
21076 mNumNonCachedProcs++;
21080 if (app.isolated && app.services.size() <= 0) {
21081 // If this is an isolated process, and there are no
21082 // services running in it, then the process is no longer
21083 // needed. We agressively kill these because we can by
21084 // definition not re-use the same process again, and it is
21085 // good to avoid having whatever code was running in them
21086 // left sitting around after no longer needed.
21087 app.kill("isolated not needed", true);
21089 // Keeping this process, update its uid.
21090 final UidRecord uidRec = app.uidRecord;
21091 if (uidRec != null && uidRec.curProcState > app.curProcState) {
21092 uidRec.curProcState = app.curProcState;
21096 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21097 && !app.killedByAm) {
21103 mNumServiceProcs = mNewNumServiceProcs;
21105 // Now determine the memory trimming level of background processes.
21106 // Unfortunately we need to start at the back of the list to do this
21107 // properly. We only do this if the number of background apps we
21108 // are managing to keep around is less than half the maximum we desire;
21109 // if we are keeping a good number around, we'll let them use whatever
21110 // memory they want.
21111 final int numCachedAndEmpty = numCached + numEmpty;
21113 if (numCached <= ProcessList.TRIM_CACHED_APPS
21114 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21115 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21116 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21117 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21118 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21120 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21123 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21125 // We always allow the memory level to go up (better). We only allow it to go
21126 // down if we are in a state where that is allowed, *and* the total number of processes
21127 // has gone down since last time.
21128 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21129 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21130 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21131 if (memFactor > mLastMemoryLevel) {
21132 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21133 memFactor = mLastMemoryLevel;
21134 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21137 if (memFactor != mLastMemoryLevel) {
21138 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21140 mLastMemoryLevel = memFactor;
21141 mLastNumProcesses = mLruProcesses.size();
21142 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21143 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21144 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21145 if (mLowRamStartTime == 0) {
21146 mLowRamStartTime = now;
21150 switch (memFactor) {
21151 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21152 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21154 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21155 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21158 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21161 int factor = numTrimming/3;
21163 if (mHomeProcess != null) minFactor++;
21164 if (mPreviousProcess != null) minFactor++;
21165 if (factor < minFactor) factor = minFactor;
21166 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21167 for (int i=N-1; i>=0; i--) {
21168 ProcessRecord app = mLruProcesses.get(i);
21169 if (allChanged || app.procStateChanged) {
21170 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21171 app.procStateChanged = false;
21173 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21174 && !app.killedByAm) {
21175 if (app.trimMemoryLevel < curLevel && app.thread != null) {
21177 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21178 "Trimming memory of " + app.processName + " to " + curLevel);
21179 app.thread.scheduleTrimMemory(curLevel);
21180 } catch (RemoteException e) {
21183 // For now we won't do this; our memory trimming seems
21184 // to be good enough at this point that destroying
21185 // activities causes more harm than good.
21186 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21187 && app != mHomeProcess && app != mPreviousProcess) {
21188 // Need to do this on its own message because the stack may not
21189 // be in a consistent state at this point.
21190 // For these apps we will also finish their activities
21191 // to help them free memory.
21192 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21196 app.trimMemoryLevel = curLevel;
21198 if (step >= factor) {
21200 switch (curLevel) {
21201 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21202 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21204 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21205 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21209 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21210 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21211 && app.thread != null) {
21213 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21214 "Trimming memory of heavy-weight " + app.processName
21215 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21216 app.thread.scheduleTrimMemory(
21217 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21218 } catch (RemoteException e) {
21221 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21223 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21224 || app.systemNoUi) && app.pendingUiClean) {
21225 // If this application is now in the background and it
21226 // had done UI, then give it the special trim level to
21227 // have it free UI resources.
21228 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21229 if (app.trimMemoryLevel < level && app.thread != null) {
21231 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21232 "Trimming memory of bg-ui " + app.processName
21234 app.thread.scheduleTrimMemory(level);
21235 } catch (RemoteException e) {
21238 app.pendingUiClean = false;
21240 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21242 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21243 "Trimming memory of fg " + app.processName
21244 + " to " + fgTrimLevel);
21245 app.thread.scheduleTrimMemory(fgTrimLevel);
21246 } catch (RemoteException e) {
21249 app.trimMemoryLevel = fgTrimLevel;
21253 if (mLowRamStartTime != 0) {
21254 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21255 mLowRamStartTime = 0;
21257 for (int i=N-1; i>=0; i--) {
21258 ProcessRecord app = mLruProcesses.get(i);
21259 if (allChanged || app.procStateChanged) {
21260 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21261 app.procStateChanged = false;
21263 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21264 || app.systemNoUi) && app.pendingUiClean) {
21265 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21266 && app.thread != null) {
21268 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21269 "Trimming memory of ui hidden " + app.processName
21270 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21271 app.thread.scheduleTrimMemory(
21272 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21273 } catch (RemoteException e) {
21276 app.pendingUiClean = false;
21278 app.trimMemoryLevel = 0;
21282 if (mAlwaysFinishActivities) {
21283 // Need to do this on its own message because the stack may not
21284 // be in a consistent state at this point.
21285 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21289 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21292 // Update from any uid changes.
21293 for (int i=mActiveUids.size()-1; i>=0; i--) {
21294 final UidRecord uidRec = mActiveUids.valueAt(i);
21295 int uidChange = UidRecord.CHANGE_PROCSTATE;
21296 if (uidRec.setProcState != uidRec.curProcState) {
21297 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21298 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21299 + " to " + uidRec.curProcState);
21300 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21301 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21302 uidRec.lastBackgroundTime = nowElapsed;
21303 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21304 // Note: the background settle time is in elapsed realtime, while
21305 // the handler time base is uptime. All this means is that we may
21306 // stop background uids later than we had intended, but that only
21307 // happens because the device was sleeping so we are okay anyway.
21308 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21313 uidChange = UidRecord.CHANGE_ACTIVE;
21314 uidRec.idle = false;
21316 uidRec.lastBackgroundTime = 0;
21318 uidRec.setProcState = uidRec.curProcState;
21319 enqueueUidChangeLocked(uidRec, -1, uidChange);
21320 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21324 if (mProcessStats.shouldWriteNowLocked(now)) {
21325 mHandler.post(new Runnable() {
21326 @Override public void run() {
21327 synchronized (ActivityManagerService.this) {
21328 mProcessStats.writeStateAsyncLocked();
21334 if (DEBUG_OOM_ADJ) {
21335 final long duration = SystemClock.uptimeMillis() - now;
21337 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21338 new RuntimeException("here").fillInStackTrace());
21340 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21345 final void idleUids() {
21346 synchronized (this) {
21347 final long nowElapsed = SystemClock.elapsedRealtime();
21348 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21350 for (int i=mActiveUids.size()-1; i>=0; i--) {
21351 final UidRecord uidRec = mActiveUids.valueAt(i);
21352 final long bgTime = uidRec.lastBackgroundTime;
21353 if (bgTime > 0 && !uidRec.idle) {
21354 if (bgTime <= maxBgTime) {
21355 uidRec.idle = true;
21356 doStopUidLocked(uidRec.uid, uidRec);
21358 if (nextTime == 0 || nextTime > bgTime) {
21364 if (nextTime > 0) {
21365 mHandler.removeMessages(IDLE_UIDS_MSG);
21366 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21367 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21372 final void runInBackgroundDisabled(int uid) {
21373 synchronized (this) {
21374 UidRecord uidRec = mActiveUids.get(uid);
21375 if (uidRec != null) {
21376 // This uid is actually running... should it be considered background now?
21378 doStopUidLocked(uidRec.uid, uidRec);
21381 // This uid isn't actually running... still send a report about it being "stopped".
21382 doStopUidLocked(uid, null);
21387 final void doStopUidLocked(int uid, final UidRecord uidRec) {
21388 mServices.stopInBackgroundLocked(uid);
21389 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21392 final void trimApplications() {
21393 synchronized (this) {
21396 // First remove any unused application processes whose package
21397 // has been removed.
21398 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21399 final ProcessRecord app = mRemovedProcesses.get(i);
21400 if (app.activities.size() == 0
21401 && app.curReceiver == null && app.services.size() == 0) {
21403 TAG, "Exiting empty application process "
21404 + app.toShortString() + " ("
21405 + (app.thread != null ? app.thread.asBinder() : null)
21407 if (app.pid > 0 && app.pid != MY_PID) {
21408 app.kill("empty", false);
21411 app.thread.scheduleExit();
21412 } catch (Exception e) {
21413 // Ignore exceptions.
21416 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21417 mRemovedProcesses.remove(i);
21419 if (app.persistent) {
21420 addAppLocked(app.info, false, null /* ABI override */);
21425 // Now update the oom adj for all processes.
21426 updateOomAdjLocked();
21430 /** This method sends the specified signal to each of the persistent apps */
21431 public void signalPersistentProcesses(int sig) throws RemoteException {
21432 if (sig != Process.SIGNAL_USR1) {
21433 throw new SecurityException("Only SIGNAL_USR1 is allowed");
21436 synchronized (this) {
21437 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21438 != PackageManager.PERMISSION_GRANTED) {
21439 throw new SecurityException("Requires permission "
21440 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21443 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21444 ProcessRecord r = mLruProcesses.get(i);
21445 if (r.thread != null && r.persistent) {
21446 Process.sendSignal(r.pid, sig);
21452 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21453 if (proc == null || proc == mProfileProc) {
21454 proc = mProfileProc;
21455 profileType = mProfileType;
21456 clearProfilerLocked();
21458 if (proc == null) {
21462 proc.thread.profilerControl(false, null, profileType);
21463 } catch (RemoteException e) {
21464 throw new IllegalStateException("Process disappeared");
21468 private void clearProfilerLocked() {
21469 if (mProfileFd != null) {
21471 mProfileFd.close();
21472 } catch (IOException e) {
21475 mProfileApp = null;
21476 mProfileProc = null;
21477 mProfileFile = null;
21479 mAutoStopProfiler = false;
21480 mSamplingInterval = 0;
21483 public boolean profileControl(String process, int userId, boolean start,
21484 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21487 synchronized (this) {
21488 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21489 // its own permission.
21490 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21491 != PackageManager.PERMISSION_GRANTED) {
21492 throw new SecurityException("Requires permission "
21493 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21496 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21497 throw new IllegalArgumentException("null profile info or fd");
21500 ProcessRecord proc = null;
21501 if (process != null) {
21502 proc = findProcessLocked(process, userId, "profileControl");
21505 if (start && (proc == null || proc.thread == null)) {
21506 throw new IllegalArgumentException("Unknown process: " + process);
21510 stopProfilerLocked(null, 0);
21511 setProfileApp(proc.info, proc.processName, profilerInfo);
21512 mProfileProc = proc;
21513 mProfileType = profileType;
21514 ParcelFileDescriptor fd = profilerInfo.profileFd;
21517 } catch (IOException e) {
21520 profilerInfo.profileFd = fd;
21521 proc.thread.profilerControl(start, profilerInfo, profileType);
21525 stopProfilerLocked(proc, profileType);
21526 if (profilerInfo != null && profilerInfo.profileFd != null) {
21528 profilerInfo.profileFd.close();
21529 } catch (IOException e) {
21536 } catch (RemoteException e) {
21537 throw new IllegalStateException("Process disappeared");
21539 if (profilerInfo != null && profilerInfo.profileFd != null) {
21541 profilerInfo.profileFd.close();
21542 } catch (IOException e) {
21548 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21549 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21550 userId, true, ALLOW_FULL_ONLY, callName, null);
21551 ProcessRecord proc = null;
21553 int pid = Integer.parseInt(process);
21554 synchronized (mPidsSelfLocked) {
21555 proc = mPidsSelfLocked.get(pid);
21557 } catch (NumberFormatException e) {
21560 if (proc == null) {
21561 ArrayMap<String, SparseArray<ProcessRecord>> all
21562 = mProcessNames.getMap();
21563 SparseArray<ProcessRecord> procs = all.get(process);
21564 if (procs != null && procs.size() > 0) {
21565 proc = procs.valueAt(0);
21566 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21567 for (int i=1; i<procs.size(); i++) {
21568 ProcessRecord thisProc = procs.valueAt(i);
21569 if (thisProc.userId == userId) {
21581 public boolean dumpHeap(String process, int userId, boolean managed,
21582 String path, ParcelFileDescriptor fd) throws RemoteException {
21585 synchronized (this) {
21586 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21587 // its own permission (same as profileControl).
21588 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21589 != PackageManager.PERMISSION_GRANTED) {
21590 throw new SecurityException("Requires permission "
21591 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21595 throw new IllegalArgumentException("null fd");
21598 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21599 if (proc == null || proc.thread == null) {
21600 throw new IllegalArgumentException("Unknown process: " + process);
21603 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21604 if (!isDebuggable) {
21605 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21606 throw new SecurityException("Process not debuggable: " + proc);
21610 proc.thread.dumpHeap(managed, path, fd);
21614 } catch (RemoteException e) {
21615 throw new IllegalStateException("Process disappeared");
21620 } catch (IOException e) {
21627 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21628 String reportPackage) {
21629 if (processName != null) {
21630 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21631 "setDumpHeapDebugLimit()");
21633 synchronized (mPidsSelfLocked) {
21634 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21635 if (proc == null) {
21636 throw new SecurityException("No process found for calling pid "
21637 + Binder.getCallingPid());
21639 if (!Build.IS_DEBUGGABLE
21640 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21641 throw new SecurityException("Not running a debuggable build");
21643 processName = proc.processName;
21645 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21646 throw new SecurityException("Package " + reportPackage + " is not running in "
21651 synchronized (this) {
21652 if (maxMemSize > 0) {
21653 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21656 mMemWatchProcesses.remove(processName, uid);
21658 mMemWatchProcesses.getMap().remove(processName);
21665 public void dumpHeapFinished(String path) {
21666 synchronized (this) {
21667 if (Binder.getCallingPid() != mMemWatchDumpPid) {
21668 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21669 + " does not match last pid " + mMemWatchDumpPid);
21672 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21673 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21674 + " does not match last path " + mMemWatchDumpFile);
21677 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21678 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21682 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21683 public void monitor() {
21684 synchronized (this) { }
21687 void onCoreSettingsChange(Bundle settings) {
21688 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21689 ProcessRecord processRecord = mLruProcesses.get(i);
21691 if (processRecord.thread != null) {
21692 processRecord.thread.setCoreSettings(settings);
21694 } catch (RemoteException re) {
21700 // Multi-user methods
21703 * Start user, if its not already running, but don't bring it to foreground.
21706 public boolean startUserInBackground(final int userId) {
21707 return mUserController.startUser(userId, /* foreground */ false);
21711 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21712 return mUserController.unlockUser(userId, token, secret, listener);
21716 public boolean switchUser(final int targetUserId) {
21717 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21718 UserInfo currentUserInfo;
21719 UserInfo targetUserInfo;
21720 synchronized (this) {
21721 int currentUserId = mUserController.getCurrentUserIdLocked();
21722 currentUserInfo = mUserController.getUserInfo(currentUserId);
21723 targetUserInfo = mUserController.getUserInfo(targetUserId);
21724 if (targetUserInfo == null) {
21725 Slog.w(TAG, "No user info for user #" + targetUserId);
21728 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21729 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21730 + " when device is in demo mode");
21733 if (!targetUserInfo.supportsSwitchTo()) {
21734 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21737 if (targetUserInfo.isManagedProfile()) {
21738 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21741 mUserController.setTargetUserIdLocked(targetUserId);
21743 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21744 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21745 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21749 void scheduleStartProfilesLocked() {
21750 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21751 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21752 DateUtils.SECOND_IN_MILLIS);
21757 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21758 return mUserController.stopUser(userId, force, callback);
21762 public UserInfo getCurrentUser() {
21763 return mUserController.getCurrentUser();
21767 public boolean isUserRunning(int userId, int flags) {
21768 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21769 && checkCallingPermission(INTERACT_ACROSS_USERS)
21770 != PackageManager.PERMISSION_GRANTED) {
21771 String msg = "Permission Denial: isUserRunning() from pid="
21772 + Binder.getCallingPid()
21773 + ", uid=" + Binder.getCallingUid()
21774 + " requires " + INTERACT_ACROSS_USERS;
21776 throw new SecurityException(msg);
21778 synchronized (this) {
21779 return mUserController.isUserRunningLocked(userId, flags);
21784 public int[] getRunningUserIds() {
21785 if (checkCallingPermission(INTERACT_ACROSS_USERS)
21786 != PackageManager.PERMISSION_GRANTED) {
21787 String msg = "Permission Denial: isUserRunning() from pid="
21788 + Binder.getCallingPid()
21789 + ", uid=" + Binder.getCallingUid()
21790 + " requires " + INTERACT_ACROSS_USERS;
21792 throw new SecurityException(msg);
21794 synchronized (this) {
21795 return mUserController.getStartedUserArrayLocked();
21800 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21801 mUserController.registerUserSwitchObserver(observer, name);
21805 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21806 mUserController.unregisterUserSwitchObserver(observer);
21809 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21810 if (info == null) return null;
21811 ApplicationInfo newInfo = new ApplicationInfo(info);
21812 newInfo.initForUser(userId);
21816 public boolean isUserStopped(int userId) {
21817 synchronized (this) {
21818 return mUserController.getStartedUserStateLocked(userId) == null;
21822 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21824 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21828 ActivityInfo info = new ActivityInfo(aInfo);
21829 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21833 private boolean processSanityChecksLocked(ProcessRecord process) {
21834 if (process == null || process.thread == null) {
21838 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21839 if (!isDebuggable) {
21840 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21848 public boolean startBinderTracking() throws RemoteException {
21849 synchronized (this) {
21850 mBinderTransactionTrackingEnabled = true;
21851 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21852 // permission (same as profileControl).
21853 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21854 != PackageManager.PERMISSION_GRANTED) {
21855 throw new SecurityException("Requires permission "
21856 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21859 for (int i = 0; i < mLruProcesses.size(); i++) {
21860 ProcessRecord process = mLruProcesses.get(i);
21861 if (!processSanityChecksLocked(process)) {
21865 process.thread.startBinderTracking();
21866 } catch (RemoteException e) {
21867 Log.v(TAG, "Process disappared");
21874 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21876 synchronized (this) {
21877 mBinderTransactionTrackingEnabled = false;
21878 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21879 // permission (same as profileControl).
21880 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21881 != PackageManager.PERMISSION_GRANTED) {
21882 throw new SecurityException("Requires permission "
21883 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21887 throw new IllegalArgumentException("null fd");
21890 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21891 pw.println("Binder transaction traces for all processes.\n");
21892 for (ProcessRecord process : mLruProcesses) {
21893 if (!processSanityChecksLocked(process)) {
21897 pw.println("Traces for process: " + process.processName);
21900 TransferPipe tp = new TransferPipe();
21902 process.thread.stopBinderTrackingAndDump(
21903 tp.getWriteFd().getFileDescriptor());
21904 tp.go(fd.getFileDescriptor());
21908 } catch (IOException e) {
21909 pw.println("Failure while dumping IPC traces from " + process +
21910 ". Exception: " + e);
21912 } catch (RemoteException e) {
21913 pw.println("Got a RemoteException while dumping IPC traces from " +
21914 process + ". Exception: " + e);
21925 } catch (IOException e) {
21931 private final class LocalService extends ActivityManagerInternal {
21933 public String checkContentProviderAccess(String authority, int userId) {
21934 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21938 public void onWakefulnessChanged(int wakefulness) {
21939 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21943 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21944 String processName, String abiOverride, int uid, Runnable crashHandler) {
21945 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21946 processName, abiOverride, uid, crashHandler);
21950 public SleepToken acquireSleepToken(String tag) {
21951 Preconditions.checkNotNull(tag);
21953 synchronized (ActivityManagerService.this) {
21954 SleepTokenImpl token = new SleepTokenImpl(tag);
21955 mSleepTokens.add(token);
21956 updateSleepIfNeededLocked();
21962 public ComponentName getHomeActivityForUser(int userId) {
21963 synchronized (ActivityManagerService.this) {
21964 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21965 return homeActivity == null ? null : homeActivity.realActivity;
21970 public void onUserRemoved(int userId) {
21971 synchronized (ActivityManagerService.this) {
21972 ActivityManagerService.this.onUserStoppedLocked(userId);
21977 public void onLocalVoiceInteractionStarted(IBinder activity,
21978 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21979 synchronized (ActivityManagerService.this) {
21980 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21981 voiceSession, voiceInteractor);
21986 public void notifyStartingWindowDrawn() {
21987 synchronized (ActivityManagerService.this) {
21988 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21993 public void notifyAppTransitionStarting(int reason) {
21994 synchronized (ActivityManagerService.this) {
21995 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22000 public void notifyAppTransitionFinished() {
22001 synchronized (ActivityManagerService.this) {
22002 mStackSupervisor.notifyAppTransitionDone();
22007 public void notifyAppTransitionCancelled() {
22008 synchronized (ActivityManagerService.this) {
22009 mStackSupervisor.notifyAppTransitionDone();
22014 public List<IBinder> getTopVisibleActivities() {
22015 synchronized (ActivityManagerService.this) {
22016 return mStackSupervisor.getTopVisibleActivities();
22021 public void notifyDockedStackMinimizedChanged(boolean minimized) {
22022 synchronized (ActivityManagerService.this) {
22023 mStackSupervisor.setDockedStackMinimized(minimized);
22028 public void killForegroundAppsForUser(int userHandle) {
22029 synchronized (ActivityManagerService.this) {
22030 final ArrayList<ProcessRecord> procs = new ArrayList<>();
22031 final int NP = mProcessNames.getMap().size();
22032 for (int ip = 0; ip < NP; ip++) {
22033 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22034 final int NA = apps.size();
22035 for (int ia = 0; ia < NA; ia++) {
22036 final ProcessRecord app = apps.valueAt(ia);
22037 if (app.persistent) {
22038 // We don't kill persistent processes.
22043 } else if (app.userId == userHandle && app.foregroundActivities) {
22044 app.removed = true;
22050 final int N = procs.size();
22051 for (int i = 0; i < N; i++) {
22052 removeProcessLocked(procs.get(i), false, true, "kill all fg");
22058 public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22059 if (!(target instanceof PendingIntentRecord)) {
22060 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22063 ((PendingIntentRecord) target).setWhitelistDuration(duration);
22067 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22069 Preconditions.checkNotNull(values, "Configuration must not be null");
22070 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22071 synchronized (ActivityManagerService.this) {
22072 updateConfigurationLocked(values, null, false, true, userId,
22073 false /* deferResume */);
22078 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22080 Preconditions.checkNotNull(intents, "intents");
22081 final String[] resolvedTypes = new String[intents.length];
22082 for (int i = 0; i < intents.length; i++) {
22083 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22086 // UID of the package on user userId.
22087 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22088 // packageUid may not be initialized.
22089 int packageUid = 0;
22091 packageUid = AppGlobals.getPackageManager().getPackageUid(
22092 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22093 } catch (RemoteException e) {
22094 // Shouldn't happen.
22097 synchronized (ActivityManagerService.this) {
22098 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22099 /*resultTo*/ null, bOptions, userId);
22104 public int getUidProcessState(int uid) {
22105 return getUidState(uid);
22109 private final class SleepTokenImpl extends SleepToken {
22110 private final String mTag;
22111 private final long mAcquireTime;
22113 public SleepTokenImpl(String tag) {
22115 mAcquireTime = SystemClock.uptimeMillis();
22119 public void release() {
22120 synchronized (ActivityManagerService.this) {
22121 if (mSleepTokens.remove(this)) {
22122 updateSleepIfNeededLocked();
22128 public String toString() {
22129 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22134 * An implementation of IAppTask, that allows an app to manage its own tasks via
22135 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
22136 * only the process that calls getAppTasks() can call the AppTask methods.
22138 class AppTaskImpl extends IAppTask.Stub {
22139 private int mTaskId;
22140 private int mCallingUid;
22142 public AppTaskImpl(int taskId, int callingUid) {
22144 mCallingUid = callingUid;
22147 private void checkCaller() {
22148 if (mCallingUid != Binder.getCallingUid()) {
22149 throw new SecurityException("Caller " + mCallingUid
22150 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22155 public void finishAndRemoveTask() {
22158 synchronized (ActivityManagerService.this) {
22159 long origId = Binder.clearCallingIdentity();
22161 // We remove the task from recents to preserve backwards
22162 if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22163 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22166 Binder.restoreCallingIdentity(origId);
22172 public ActivityManager.RecentTaskInfo getTaskInfo() {
22175 synchronized (ActivityManagerService.this) {
22176 long origId = Binder.clearCallingIdentity();
22178 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22180 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22182 return createRecentTaskInfoFromTaskRecord(tr);
22184 Binder.restoreCallingIdentity(origId);
22190 public void moveToFront() {
22192 // Will bring task to front if it already has a root activity.
22193 final long origId = Binder.clearCallingIdentity();
22195 synchronized (this) {
22196 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22199 Binder.restoreCallingIdentity(origId);
22204 public int startActivity(IBinder whoThread, String callingPackage,
22205 Intent intent, String resolvedType, Bundle bOptions) {
22208 int callingUser = UserHandle.getCallingUserId();
22210 IApplicationThread appThread;
22211 synchronized (ActivityManagerService.this) {
22212 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22214 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22216 appThread = ApplicationThreadNative.asInterface(whoThread);
22217 if (appThread == null) {
22218 throw new IllegalArgumentException("Bad app thread " + appThread);
22221 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22222 resolvedType, null, null, null, null, 0, 0, null, null,
22223 null, bOptions, false, callingUser, null, tr);
22227 public void setExcludeFromRecents(boolean exclude) {
22230 synchronized (ActivityManagerService.this) {
22231 long origId = Binder.clearCallingIdentity();
22233 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22235 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22237 Intent intent = tr.getBaseIntent();
22239 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22241 intent.setFlags(intent.getFlags()
22242 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22245 Binder.restoreCallingIdentity(origId);
22252 * Kill processes for the user with id userId and that depend on the package named packageName
22255 public void killPackageDependents(String packageName, int userId) {
22256 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22257 if (packageName == null) {
22258 throw new NullPointerException(
22259 "Cannot kill the dependents of a package without its name.");
22262 long callingId = Binder.clearCallingIdentity();
22263 IPackageManager pm = AppGlobals.getPackageManager();
22266 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22267 } catch (RemoteException e) {
22269 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22270 throw new IllegalArgumentException(
22271 "Cannot kill dependents of non-existing package " + packageName);
22274 synchronized(this) {
22275 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22276 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22277 "dep: " + packageName);
22280 Binder.restoreCallingIdentity(callingId);
22285 public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22286 final int userId = intent.getCreatorUserHandle().getIdentifier();
22287 if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22290 IIntentSender target = intent.getTarget();
22291 if (!(target instanceof PendingIntentRecord)) {
22294 final PendingIntentRecord record = (PendingIntentRecord) target;
22295 final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22296 record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22297 // For direct boot aware activities, they can be shown without triggering a work challenge
22298 // before the profile user is unlocked.
22299 return rInfo != null && rInfo.activityInfo != null;