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.internal.util.ProgressReporter;
45 import com.android.server.AppOpsService;
46 import com.android.server.AttributeCache;
47 import com.android.server.DeviceIdleController;
48 import com.android.server.IntentResolver;
49 import com.android.server.LocalServices;
50 import com.android.server.LockGuard;
51 import com.android.server.ServiceThread;
52 import com.android.server.SystemService;
53 import com.android.server.SystemServiceManager;
54 import com.android.server.Watchdog;
55 import com.android.server.am.ActivityStack.ActivityState;
56 import com.android.server.firewall.IntentFirewall;
57 import com.android.server.pm.Installer;
58 import com.android.server.statusbar.StatusBarManagerInternal;
59 import com.android.server.vr.VrManagerInternal;
60 import com.android.server.wm.WindowManagerService;
62 import org.xmlpull.v1.XmlPullParser;
63 import org.xmlpull.v1.XmlPullParserException;
64 import org.xmlpull.v1.XmlSerializer;
66 import android.Manifest;
67 import android.annotation.UserIdInt;
68 import android.app.Activity;
69 import android.app.ActivityManager;
70 import android.app.ActivityManager.RunningTaskInfo;
71 import android.app.ActivityManager.StackId;
72 import android.app.ActivityManager.StackInfo;
73 import android.app.ActivityManager.TaskThumbnailInfo;
74 import android.app.ActivityManagerInternal;
75 import android.app.ActivityManagerInternal.SleepToken;
76 import android.app.ActivityManagerNative;
77 import android.app.ActivityOptions;
78 import android.app.ActivityThread;
79 import android.app.AlertDialog;
80 import android.app.AppGlobals;
81 import android.app.AppOpsManager;
82 import android.app.ApplicationErrorReport;
83 import android.app.ApplicationThreadNative;
84 import android.app.BroadcastOptions;
85 import android.app.Dialog;
86 import android.app.IActivityContainer;
87 import android.app.IActivityContainerCallback;
88 import android.app.IActivityController;
89 import android.app.IAppTask;
90 import android.app.IApplicationThread;
91 import android.app.IInstrumentationWatcher;
92 import android.app.INotificationManager;
93 import android.app.IProcessObserver;
94 import android.app.IServiceConnection;
95 import android.app.IStopUserCallback;
96 import android.app.ITaskStackListener;
97 import android.app.IUiAutomationConnection;
98 import android.app.IUidObserver;
99 import android.app.IUserSwitchObserver;
100 import android.app.Instrumentation;
101 import android.app.KeyguardManager;
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.admin.DevicePolicyManagerInternal;
108 import android.app.assist.AssistContent;
109 import android.app.assist.AssistStructure;
110 import android.app.backup.IBackupManager;
111 import android.app.usage.UsageEvents;
112 import android.app.usage.UsageStatsManagerInternal;
113 import android.appwidget.AppWidgetManager;
114 import android.content.ActivityNotFoundException;
115 import android.content.BroadcastReceiver;
116 import android.content.ClipData;
117 import android.content.ComponentCallbacks2;
118 import android.content.ComponentName;
119 import android.content.ContentProvider;
120 import android.content.ContentResolver;
121 import android.content.Context;
122 import android.content.DialogInterface;
123 import android.content.IContentProvider;
124 import android.content.IIntentReceiver;
125 import android.content.IIntentSender;
126 import android.content.Intent;
127 import android.content.IntentFilter;
128 import android.content.IntentSender;
129 import android.content.pm.ActivityInfo;
130 import android.content.pm.ApplicationInfo;
131 import android.content.pm.ConfigurationInfo;
132 import android.content.pm.IPackageDataObserver;
133 import android.content.pm.IPackageManager;
134 import android.content.pm.InstrumentationInfo;
135 import android.content.pm.PackageInfo;
136 import android.content.pm.PackageManager;
137 import android.content.pm.PackageManager.NameNotFoundException;
138 import android.content.pm.PackageManagerInternal;
139 import android.content.pm.ParceledListSlice;
140 import android.content.pm.PathPermission;
141 import android.content.pm.PermissionInfo;
142 import android.content.pm.ProviderInfo;
143 import android.content.pm.ResolveInfo;
144 import android.content.pm.ServiceInfo;
145 import android.content.pm.ShortcutServiceInternal;
146 import android.content.pm.UserInfo;
147 import android.content.res.CompatibilityInfo;
148 import android.content.res.Configuration;
149 import android.content.res.Resources;
150 import android.database.ContentObserver;
151 import android.graphics.Bitmap;
152 import android.graphics.Point;
153 import android.graphics.Rect;
154 import android.location.LocationManager;
155 import android.net.Proxy;
156 import android.net.ProxyInfo;
157 import android.net.Uri;
158 import android.os.BatteryStats;
159 import android.os.Binder;
160 import android.os.Build;
161 import android.os.Bundle;
162 import android.os.Debug;
163 import android.os.DropBoxManager;
164 import android.os.Environment;
165 import android.os.FactoryTest;
166 import android.os.FileObserver;
167 import android.os.FileUtils;
168 import android.os.Handler;
169 import android.os.IBinder;
170 import android.os.IPermissionController;
171 import android.os.IProcessInfoService;
172 import android.os.IProgressListener;
173 import android.os.LocaleList;
174 import android.os.Looper;
175 import android.os.Message;
176 import android.os.Parcel;
177 import android.os.ParcelFileDescriptor;
178 import android.os.PersistableBundle;
179 import android.os.PowerManager;
180 import android.os.PowerManagerInternal;
181 import android.os.Process;
182 import android.os.RemoteCallbackList;
183 import android.os.RemoteException;
184 import android.os.ResultReceiver;
185 import android.os.ServiceManager;
186 import android.os.StrictMode;
187 import android.os.SystemClock;
188 import android.os.SystemProperties;
189 import android.os.Trace;
190 import android.os.TransactionTooLargeException;
191 import android.os.UpdateLock;
192 import android.os.UserHandle;
193 import android.os.UserManager;
194 import android.os.WorkSource;
195 import android.os.storage.IMountService;
196 import android.os.storage.MountServiceInternal;
197 import android.os.storage.StorageManager;
198 import android.provider.Settings;
199 import android.service.voice.IVoiceInteractionSession;
200 import android.service.voice.VoiceInteractionManagerInternal;
201 import android.service.voice.VoiceInteractionSession;
202 import android.telecom.TelecomManager;
203 import android.text.format.DateUtils;
204 import android.text.format.Time;
205 import android.text.style.SuggestionSpan;
206 import android.util.ArrayMap;
207 import android.util.ArraySet;
208 import android.util.AtomicFile;
209 import android.util.DebugUtils;
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.FIRST_STATIC_STACK_ID;
263 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
264 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
265 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
266 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
267 import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
268 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
269 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
270 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
271 import static android.content.pm.PackageManager.GET_PROVIDERS;
272 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
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.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
279 import static android.provider.Settings.Global.DEBUG_APP;
280 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
281 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
282 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
283 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
284 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
285 import static android.provider.Settings.System.FONT_SCALE;
286 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
287 import static com.android.internal.util.XmlUtils.readIntAttribute;
288 import static com.android.internal.util.XmlUtils.readLongAttribute;
289 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
290 import static com.android.internal.util.XmlUtils.writeIntAttribute;
291 import static com.android.internal.util.XmlUtils.writeLongAttribute;
292 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
293 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
294 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
295 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
324 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
325 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
326 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
327 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
328 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
348 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
349 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
350 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
351 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
352 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
353 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
354 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
355 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
356 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
357 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
358 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
359 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
360 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
361 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
362 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
363 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
364 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
365 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
366 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
367 import static org.xmlpull.v1.XmlPullParser.START_TAG;
369 public final class ActivityManagerService extends ActivityManagerNative
370 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
372 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
373 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
374 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
375 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
376 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
377 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
378 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
379 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
380 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
381 private static final String TAG_LRU = TAG + POSTFIX_LRU;
382 private static final String TAG_MU = TAG + POSTFIX_MU;
383 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
384 private static final String TAG_POWER = TAG + POSTFIX_POWER;
385 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
386 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
387 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
388 private static final String TAG_PSS = TAG + POSTFIX_PSS;
389 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
390 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
391 private static final String TAG_STACK = TAG + POSTFIX_STACK;
392 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
393 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
394 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
395 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
396 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
398 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
399 // here so that while the job scheduler can depend on AMS, the other way around
400 // need not be the case.
401 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
403 /** Control over CPU and battery monitoring */
404 // write battery stats every 30 minutes.
405 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
406 static final boolean MONITOR_CPU_USAGE = true;
407 // don't sample cpu less than every 5 seconds.
408 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
409 // wait possibly forever for next cpu sample.
410 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
411 static final boolean MONITOR_THREAD_CPU_USAGE = false;
413 // The flags that are set for all calls we make to the package manager.
414 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
416 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
418 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
420 // Amount of time after a call to stopAppSwitches() during which we will
421 // prevent further untrusted switches from happening.
422 static final long APP_SWITCH_DELAY_TIME = 5*1000;
424 // How long we wait for a launched process to attach to the activity manager
425 // before we decide it's never going to come up for real.
426 static final int PROC_START_TIMEOUT = 10*1000;
427 // How long we wait for an attached process to publish its content providers
428 // before we decide it must be hung.
429 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
431 // How long we will retain processes hosting content providers in the "last activity"
432 // state before allowing them to drop down to the regular cached LRU list. This is
433 // to avoid thrashing of provider processes under low memory situations.
434 static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
436 // How long we wait for a launched process to attach to the activity manager
437 // before we decide it's never going to come up for real, when the process was
438 // started with a wrapper for instrumentation (such as Valgrind) because it
439 // could take much longer than usual.
440 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
442 // How long to wait after going idle before forcing apps to GC.
443 static final int GC_TIMEOUT = 5*1000;
445 // The minimum amount of time between successive GC requests for a process.
446 static final int GC_MIN_INTERVAL = 60*1000;
448 // The minimum amount of time between successive PSS requests for a process.
449 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
451 // The minimum amount of time between successive PSS requests for a process
452 // when the request is due to the memory state being lowered.
453 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
455 // The rate at which we check for apps using excessive power -- 15 mins.
456 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
458 // The minimum sample duration we will allow before deciding we have
459 // enough data on wake locks to start killing things.
460 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
462 // The minimum sample duration we will allow before deciding we have
463 // enough data on CPU usage to start killing things.
464 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
466 // How long we allow a receiver to run before giving up on it.
467 static final int BROADCAST_FG_TIMEOUT = 10*1000;
468 static final int BROADCAST_BG_TIMEOUT = 60*1000;
470 // How long we wait until we timeout on key dispatching.
471 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
473 // How long we wait until we timeout on key dispatching during instrumentation.
474 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
476 // This is the amount of time an app needs to be running a foreground service before
477 // we will consider it to be doing interaction for usage stats.
478 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
480 // Maximum amount of time we will allow to elapse before re-reporting usage stats
481 // interaction with foreground processes.
482 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
484 // This is the amount of time we allow an app to settle after it goes into the background,
485 // before we start restricting what it can do.
486 static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
488 // How long to wait in getAssistContextExtras for the activity and foreground services
489 // to respond with the result.
490 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
492 // How long top wait when going through the modern assist (which doesn't need to block
493 // on getting this result before starting to launch its UI).
494 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
496 // Maximum number of persisted Uri grants a package is allowed
497 static final int MAX_PERSISTED_URI_GRANTS = 128;
499 static final int MY_PID = Process.myPid();
501 static final String[] EMPTY_STRING_ARRAY = new String[0];
503 // How many bytes to write into the dropbox log before truncating
504 static final int DROPBOX_MAX_SIZE = 256 * 1024;
506 // Access modes for handleIncomingUser.
507 static final int ALLOW_NON_FULL = 0;
508 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
509 static final int ALLOW_FULL_ONLY = 2;
511 // Delay in notifying task stack change listeners (in millis)
512 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
514 // Necessary ApplicationInfo flags to mark an app as persistent
515 private static final int PERSISTENT_MASK =
516 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
518 // Intent sent when remote bugreport collection has been completed
519 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
520 "android.intent.action.REMOTE_BUGREPORT_FINISHED";
522 // Delay to disable app launch boost
523 static final int APP_BOOST_MESSAGE_DELAY = 3000;
524 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
525 static final int APP_BOOST_TIMEOUT = 2500;
527 // Used to indicate that a task is removed it should also be removed from recents.
528 private static final boolean REMOVE_FROM_RECENTS = true;
529 // Used to indicate that an app transition should be animated.
530 static final boolean ANIMATE = true;
532 // Determines whether to take full screen screenshots
533 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
534 public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
536 private static native int nativeMigrateToBoost();
537 private static native int nativeMigrateFromBoost();
538 private boolean mIsBoosted = false;
539 private long mBoostStartTime = 0;
541 /** All system services */
542 SystemServiceManager mSystemServiceManager;
544 private Installer mInstaller;
546 /** Run all ActivityStacks through this */
547 final ActivityStackSupervisor mStackSupervisor;
549 final ActivityStarter mActivityStarter;
551 /** Task stack change listeners. */
552 private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
553 new RemoteCallbackList<ITaskStackListener>();
555 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
557 public IntentFirewall mIntentFirewall;
559 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
560 // default actuion automatically. Important for devices without direct input
562 private boolean mShowDialogs = true;
563 private boolean mInVrMode = false;
565 BroadcastQueue mFgBroadcastQueue;
566 BroadcastQueue mBgBroadcastQueue;
567 // Convenient for easy iteration over the queues. Foreground is first
568 // so that dispatch of foreground broadcasts gets precedence.
569 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
571 BroadcastQueue broadcastQueueForIntent(Intent intent) {
572 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
573 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
574 "Broadcast intent " + intent + " on "
575 + (isFg ? "foreground" : "background") + " queue");
576 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
580 * Activity we have told the window manager to have key focus.
582 ActivityRecord mFocusedActivity = null;
585 * User id of the last activity mFocusedActivity was set to.
587 private int mLastFocusedUserId;
590 * If non-null, we are tracking the time the user spends in the currently focused app.
592 private AppTimeTracker mCurAppTimeTracker;
595 * List of intents that were used to start the most recent tasks.
597 final RecentTasks mRecentTasks;
600 * For addAppTask: cached of the last activity component that was added.
602 ComponentName mLastAddedTaskComponent;
605 * For addAppTask: cached of the last activity uid that was added.
607 int mLastAddedTaskUid;
610 * For addAppTask: cached of the last ActivityInfo that was added.
612 ActivityInfo mLastAddedTaskActivity;
615 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
617 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
620 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
622 String mDeviceOwnerName;
624 final UserController mUserController;
626 final AppErrors mAppErrors;
628 boolean mDoingSetFocusedActivity;
630 public boolean canShowErrorDialogs() {
631 return mShowDialogs && !mSleeping && !mShuttingDown;
634 // it's a semaphore; boost when 0->1, reset when 1->0
635 static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
636 @Override protected Integer initialValue() {
641 static void boostPriorityForLockedSection() {
642 if (sIsBoosted.get() == 0) {
643 // boost to prio 118 while holding a global lock
644 Process.setThreadPriority(Process.myTid(), -2);
645 //Log.e(TAG, "PRIORITY BOOST: set priority on TID " + Process.myTid());
647 int cur = sIsBoosted.get();
648 sIsBoosted.set(cur + 1);
651 static void resetPriorityAfterLockedSection() {
652 sIsBoosted.set(sIsBoosted.get() - 1);
653 if (sIsBoosted.get() == 0) {
654 //Log.e(TAG, "PRIORITY BOOST: reset priority on TID " + Process.myTid());
655 Process.setThreadPriority(Process.myTid(), 0);
658 public class PendingAssistExtras extends Binder implements Runnable {
659 public final ActivityRecord activity;
660 public final Bundle extras;
661 public final Intent intent;
662 public final String hint;
663 public final IResultReceiver receiver;
664 public final int userHandle;
665 public boolean haveResult = false;
666 public Bundle result = null;
667 public AssistStructure structure = null;
668 public AssistContent content = null;
669 public Bundle receiverExtras;
671 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
672 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
673 activity = _activity;
677 receiver = _receiver;
678 receiverExtras = _receiverExtras;
679 userHandle = _userHandle;
683 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
684 synchronized (this) {
688 pendingAssistExtrasTimedOut(this);
692 final ArrayList<PendingAssistExtras> mPendingAssistExtras
693 = new ArrayList<PendingAssistExtras>();
696 * Process management.
698 final ProcessList mProcessList = new ProcessList();
701 * All of the applications we currently have running organized by name.
702 * The keys are strings of the application package name (as
703 * returned by the package manager), and the keys are ApplicationRecord
706 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
709 * Tracking long-term execution of processes to look for abuse and other
712 final ProcessStatsService mProcessStats;
715 * The currently running isolated processes.
717 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
720 * Counter for assigning isolated process uids, to avoid frequently reusing the
723 int mNextIsolatedProcessUid = 0;
726 * The currently running heavy-weight process, if any.
728 ProcessRecord mHeavyWeightProcess = null;
731 * All of the processes we currently have running organized by pid.
732 * The keys are the pid running the application.
734 * <p>NOTE: This object is protected by its own lock, NOT the global
735 * activity manager lock!
737 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
740 * All of the processes that have been forced to be foreground. The key
741 * is the pid of the caller who requested it (we hold a death
744 abstract class ForegroundToken implements IBinder.DeathRecipient {
748 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
751 * List of records for processes that someone had tried to start before the
752 * system was ready. We don't start them at that point, but ensure they
753 * are started by the time booting is complete.
755 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
758 * List of persistent applications that are in the process
761 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
764 * Processes that are being forcibly torn down.
766 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
769 * List of running applications, sorted by recent usage.
770 * The first entry in the list is the least recently used.
772 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
775 * Where in mLruProcesses that the processes hosting activities start.
777 int mLruProcessActivityStart = 0;
780 * Where in mLruProcesses that the processes hosting services start.
781 * This is after (lower index) than mLruProcessesActivityStart.
783 int mLruProcessServiceStart = 0;
786 * List of processes that should gc as soon as things are idle.
788 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
791 * Processes we want to collect PSS data from.
793 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
795 private boolean mBinderTransactionTrackingEnabled = false;
798 * Last time we requested PSS data of all processes.
800 long mLastFullPssTime = SystemClock.uptimeMillis();
803 * If set, the next time we collect PSS data we should do a full collection
804 * with data from native processes and the kernel.
806 boolean mFullPssPending = false;
809 * This is the process holding what we currently consider to be
810 * the "home" activity.
812 ProcessRecord mHomeProcess;
815 * This is the process holding the activity the user last visited that
816 * is in a different process from the one they are currently in.
818 ProcessRecord mPreviousProcess;
821 * The time at which the previous process was last visible.
823 long mPreviousProcessVisibleTime;
826 * Track all uids that have actively running processes.
828 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
831 * This is for verifying the UID report flow.
833 static final boolean VALIDATE_UID_STATES = true;
834 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
837 * Packages that the user has asked to have run in screen size
838 * compatibility mode instead of filling the screen.
840 final CompatModePackages mCompatModePackages;
843 * Set of IntentSenderRecord objects that are currently active.
845 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
846 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
849 * Fingerprints (hashCode()) of stack traces that we've
850 * already logged DropBox entries for. Guarded by itself. If
851 * something (rogue user app) forces this over
852 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
854 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
855 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
858 * Strict Mode background batched logging state.
860 * The string buffer is guarded by itself, and its lock is also
861 * used to determine if another batched write is already
864 private final StringBuilder mStrictModeBuffer = new StringBuilder();
867 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
868 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
870 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
873 * Resolver for broadcast intents to registered receivers.
874 * Holds BroadcastFilter (subclass of IntentFilter).
876 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
877 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
879 protected boolean allowFilterResult(
880 BroadcastFilter filter, List<BroadcastFilter> dest) {
881 IBinder target = filter.receiverList.receiver.asBinder();
882 for (int i = dest.size() - 1; i >= 0; i--) {
883 if (dest.get(i).receiverList.receiver.asBinder() == target) {
891 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
892 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
893 || userId == filter.owningUserId) {
894 return super.newResult(filter, match, userId);
900 protected BroadcastFilter[] newArray(int size) {
901 return new BroadcastFilter[size];
905 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
906 return packageName.equals(filter.packageName);
911 * State of all active sticky broadcasts per user. Keys are the action of the
912 * sticky Intent, values are an ArrayList of all broadcasted intents with
913 * that action (which should usually be one). The SparseArray is keyed
914 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
915 * for stickies that are sent to all users.
917 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
918 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
920 final ActiveServices mServices;
922 final static class Association {
923 final int mSourceUid;
924 final String mSourceProcess;
925 final int mTargetUid;
926 final ComponentName mTargetComponent;
927 final String mTargetProcess;
935 // states of the source process when the bind occurred.
936 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
937 long mLastStateUptime;
938 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
939 - ActivityManager.MIN_PROCESS_STATE+1];
941 Association(int sourceUid, String sourceProcess, int targetUid,
942 ComponentName targetComponent, String targetProcess) {
943 mSourceUid = sourceUid;
944 mSourceProcess = sourceProcess;
945 mTargetUid = targetUid;
946 mTargetComponent = targetComponent;
947 mTargetProcess = targetProcess;
952 * When service association tracking is enabled, this is all of the associations we
953 * have seen. Mapping is target uid -> target component -> source uid -> source process name
954 * -> association data.
956 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
957 mAssociations = new SparseArray<>();
958 boolean mTrackingAssociations;
961 * Backup/restore process management
963 String mBackupAppName = null;
964 BackupRecord mBackupTarget = null;
966 final ProviderMap mProviderMap;
969 * List of content providers who have clients waiting for them. The
970 * application is currently being launched and the provider will be
971 * removed from this list once it is published.
973 final ArrayList<ContentProviderRecord> mLaunchingProviders
974 = new ArrayList<ContentProviderRecord>();
977 * File storing persisted {@link #mGrantedUriPermissions}.
979 private final AtomicFile mGrantFile;
981 /** XML constants used in {@link #mGrantFile} */
982 private static final String TAG_URI_GRANTS = "uri-grants";
983 private static final String TAG_URI_GRANT = "uri-grant";
984 private static final String ATTR_USER_HANDLE = "userHandle";
985 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
986 private static final String ATTR_TARGET_USER_ID = "targetUserId";
987 private static final String ATTR_SOURCE_PKG = "sourcePkg";
988 private static final String ATTR_TARGET_PKG = "targetPkg";
989 private static final String ATTR_URI = "uri";
990 private static final String ATTR_MODE_FLAGS = "modeFlags";
991 private static final String ATTR_CREATED_TIME = "createdTime";
992 private static final String ATTR_PREFIX = "prefix";
995 * Global set of specific {@link Uri} permissions that have been granted.
996 * This optimized lookup structure maps from {@link UriPermission#targetUid}
997 * to {@link UriPermission#uri} to {@link UriPermission}.
1000 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1001 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1003 public static class GrantUri {
1004 public final int sourceUserId;
1005 public final Uri uri;
1006 public boolean prefix;
1008 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1009 this.sourceUserId = sourceUserId;
1011 this.prefix = prefix;
1015 public int hashCode() {
1017 hashCode = 31 * hashCode + sourceUserId;
1018 hashCode = 31 * hashCode + uri.hashCode();
1019 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1024 public boolean equals(Object o) {
1025 if (o instanceof GrantUri) {
1026 GrantUri other = (GrantUri) o;
1027 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1028 && prefix == other.prefix;
1034 public String toString() {
1035 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1036 if (prefix) result += " [prefix]";
1040 public String toSafeString() {
1041 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1042 if (prefix) result += " [prefix]";
1046 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1047 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1048 ContentProvider.getUriWithoutUserId(uri), false);
1052 CoreSettingsObserver mCoreSettingsObserver;
1054 FontScaleSettingObserver mFontScaleSettingObserver;
1056 private final class FontScaleSettingObserver extends ContentObserver {
1057 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1059 public FontScaleSettingObserver() {
1061 ContentResolver resolver = mContext.getContentResolver();
1062 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1066 public void onChange(boolean selfChange, Uri uri) {
1067 if (mFontScaleUri.equals(uri)) {
1068 updateFontScaleIfNeeded();
1074 * Thread-local storage used to carry caller permissions over through
1075 * indirect content-provider access.
1077 private class Identity {
1078 public final IBinder token;
1079 public final int pid;
1080 public final int uid;
1082 Identity(IBinder _token, int _pid, int _uid) {
1089 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1092 * All information we have collected about the runtime performance of
1093 * any user id that can impact battery performance.
1095 final BatteryStatsService mBatteryStatsService;
1098 * Information about component usage
1100 UsageStatsManagerInternal mUsageStatsService;
1103 * Access to DeviceIdleController service.
1105 DeviceIdleController.LocalService mLocalDeviceIdleController;
1108 * Information about and control over application operations
1110 final AppOpsService mAppOpsService;
1113 * Current configuration information. HistoryRecord objects are given
1114 * a reference to this object to indicate which configuration they are
1115 * currently running in, so this object must be kept immutable.
1117 Configuration mConfiguration = new Configuration();
1120 * Current sequencing integer of the configuration, for skipping old
1123 int mConfigurationSeq = 0;
1125 boolean mSuppressResizeConfigChanges = false;
1128 * Hardware-reported OpenGLES version.
1130 final int GL_ES_VERSION;
1133 * List of initialization arguments to pass to all processes when binding applications to them.
1134 * For example, references to the commonly used services.
1136 HashMap<String, IBinder> mAppBindArgs;
1139 * Temporary to avoid allocations. Protected by main lock.
1141 final StringBuilder mStringBuilder = new StringBuilder(256);
1144 * Used to control how we initialize the service.
1146 ComponentName mTopComponent;
1147 String mTopAction = Intent.ACTION_MAIN;
1150 volatile boolean mProcessesReady = false;
1151 volatile boolean mSystemReady = false;
1152 volatile boolean mOnBattery = false;
1153 volatile int mFactoryTest;
1155 @GuardedBy("this") boolean mBooting = false;
1156 @GuardedBy("this") boolean mCallFinishBooting = false;
1157 @GuardedBy("this") boolean mBootAnimationComplete = false;
1158 @GuardedBy("this") boolean mLaunchWarningShown = false;
1159 @GuardedBy("this") boolean mCheckedForSetup = false;
1164 * The time at which we will allow normal application switches again,
1165 * after a call to {@link #stopAppSwitches()}.
1167 long mAppSwitchesAllowedTime;
1170 * This is set to true after the first switch after mAppSwitchesAllowedTime
1171 * is set; any switches after that will clear the time.
1173 boolean mDidAppSwitch;
1176 * Last time (in realtime) at which we checked for power usage.
1178 long mLastPowerCheckRealtime;
1181 * Last time (in uptime) at which we checked for power usage.
1183 long mLastPowerCheckUptime;
1186 * Set while we are wanting to sleep, to prevent any
1187 * activities from being started/resumed.
1189 private boolean mSleeping = false;
1192 * The process state used for processes that are running the top activities.
1193 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1195 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1198 * Set while we are running a voice interaction. This overrides
1199 * sleeping while it is active.
1201 private IVoiceInteractionSession mRunningVoice;
1204 * For some direct access we need to power manager.
1206 PowerManagerInternal mLocalPowerManager;
1209 * We want to hold a wake lock while running a voice interaction session, since
1210 * this may happen with the screen off and we need to keep the CPU running to
1211 * be able to continue to interact with the user.
1213 PowerManager.WakeLock mVoiceWakeLock;
1216 * State of external calls telling us if the device is awake or asleep.
1218 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1221 * A list of tokens that cause the top activity to be put to sleep.
1222 * They are used by components that may hide and block interaction with underlying
1225 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1227 static final int LOCK_SCREEN_HIDDEN = 0;
1228 static final int LOCK_SCREEN_LEAVING = 1;
1229 static final int LOCK_SCREEN_SHOWN = 2;
1231 * State of external call telling us if the lock screen is shown.
1233 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1236 * Set if we are shutting down the system, similar to sleeping.
1238 boolean mShuttingDown = false;
1241 * Current sequence id for oom_adj computation traversal.
1246 * Current sequence id for process LRU updating.
1251 * Keep track of the non-cached/empty process we last found, to help
1252 * determine how to distribute cached/empty processes next time.
1254 int mNumNonCachedProcs = 0;
1257 * Keep track of the number of cached hidden procs, to balance oom adj
1258 * distribution between those and empty procs.
1260 int mNumCachedHiddenProcs = 0;
1263 * Keep track of the number of service processes we last found, to
1264 * determine on the next iteration which should be B services.
1266 int mNumServiceProcs = 0;
1267 int mNewNumAServiceProcs = 0;
1268 int mNewNumServiceProcs = 0;
1271 * Allow the current computed overall memory level of the system to go down?
1272 * This is set to false when we are killing processes for reasons other than
1273 * memory management, so that the now smaller process list will not be taken as
1274 * an indication that memory is tighter.
1276 boolean mAllowLowerMemLevel = false;
1279 * The last computed memory level, for holding when we are in a state that
1280 * processes are going away for other reasons.
1282 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1285 * The last total number of process we have, to determine if changes actually look
1286 * like a shrinking number of process due to lower RAM.
1288 int mLastNumProcesses;
1291 * The uptime of the last time we performed idle maintenance.
1293 long mLastIdleTime = SystemClock.uptimeMillis();
1296 * Total time spent with RAM that has been added in the past since the last idle time.
1298 long mLowRamTimeSinceLastIdle = 0;
1301 * If RAM is currently low, when that horrible situation started.
1303 long mLowRamStartTime = 0;
1306 * For reporting to battery stats the current top application.
1308 private String mCurResumedPackage = null;
1309 private int mCurResumedUid = -1;
1312 * For reporting to battery stats the apps currently running foreground
1313 * service. The ProcessMap is package/uid tuples; each of these contain
1314 * an array of the currently foreground processes.
1316 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1317 = new ProcessMap<ArrayList<ProcessRecord>>();
1320 * This is set if we had to do a delayed dexopt of an app before launching
1321 * it, to increase the ANR timeouts in that case.
1326 * Set if the systemServer made a call to enterSafeMode.
1331 * If true, we are running under a test environment so will sample PSS from processes
1332 * much more rapidly to try to collect better data when the tests are rapidly
1333 * running through apps.
1335 boolean mTestPssMode = false;
1337 String mDebugApp = null;
1338 boolean mWaitForDebugger = false;
1339 boolean mDebugTransient = false;
1340 String mOrigDebugApp = null;
1341 boolean mOrigWaitForDebugger = false;
1342 boolean mAlwaysFinishActivities = false;
1343 boolean mLenientBackgroundCheck = false;
1344 boolean mForceResizableActivities;
1345 boolean mSupportsMultiWindow;
1346 boolean mSupportsFreeformWindowManagement;
1347 boolean mSupportsPictureInPicture;
1348 Rect mDefaultPinnedStackBounds;
1349 IActivityController mController = null;
1350 boolean mControllerIsAMonkey = false;
1351 String mProfileApp = null;
1352 ProcessRecord mProfileProc = null;
1353 String mProfileFile;
1354 ParcelFileDescriptor mProfileFd;
1355 int mSamplingInterval = 0;
1356 boolean mAutoStopProfiler = false;
1357 int mProfileType = 0;
1358 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1359 String mMemWatchDumpProcName;
1360 String mMemWatchDumpFile;
1361 int mMemWatchDumpPid;
1362 int mMemWatchDumpUid;
1363 String mTrackAllocationApp = null;
1364 String mNativeDebuggingApp = null;
1366 final long[] mTmpLong = new long[2];
1368 static final class ProcessChangeItem {
1369 static final int CHANGE_ACTIVITIES = 1<<0;
1370 static final int CHANGE_PROCESS_STATE = 1<<1;
1375 boolean foregroundActivities;
1378 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1379 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1381 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1382 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1384 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1385 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1387 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1388 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1391 * Runtime CPU use collection thread. This object's lock is used to
1392 * perform synchronization with the thread (notifying it to run).
1394 final Thread mProcessCpuThread;
1397 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1398 * Must acquire this object's lock when accessing it.
1399 * NOTE: this lock will be held while doing long operations (trawling
1400 * through all processes in /proc), so it should never be acquired by
1401 * any critical paths such as when holding the main activity manager lock.
1403 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1404 MONITOR_THREAD_CPU_USAGE);
1405 final AtomicLong mLastCpuTime = new AtomicLong(0);
1406 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1408 long mLastWriteTime = 0;
1411 * Used to retain an update lock when the foreground activity is in
1414 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1417 * Set to true after the system has finished booting.
1419 boolean mBooted = false;
1421 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1422 int mProcessLimitOverride = -1;
1424 WindowManagerService mWindowManager;
1425 final ActivityThread mSystemThread;
1427 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1428 final ProcessRecord mApp;
1430 final IApplicationThread mAppThread;
1432 AppDeathRecipient(ProcessRecord app, int pid,
1433 IApplicationThread thread) {
1434 if (DEBUG_ALL) Slog.v(
1435 TAG, "New death recipient " + this
1436 + " for thread " + thread.asBinder());
1439 mAppThread = thread;
1443 public void binderDied() {
1444 if (DEBUG_ALL) Slog.v(
1445 TAG, "Death received in " + this
1446 + " for thread " + mAppThread.asBinder());
1447 synchronized(ActivityManagerService.this) {
1448 appDiedLocked(mApp, mPid, mAppThread, true);
1453 static final int SHOW_ERROR_UI_MSG = 1;
1454 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1455 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1456 static final int UPDATE_CONFIGURATION_MSG = 4;
1457 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1458 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1459 static final int SERVICE_TIMEOUT_MSG = 12;
1460 static final int UPDATE_TIME_ZONE = 13;
1461 static final int SHOW_UID_ERROR_UI_MSG = 14;
1462 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1463 static final int PROC_START_TIMEOUT_MSG = 20;
1464 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1465 static final int KILL_APPLICATION_MSG = 22;
1466 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1467 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1468 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1469 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1470 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1471 static final int CLEAR_DNS_CACHE_MSG = 28;
1472 static final int UPDATE_HTTP_PROXY_MSG = 29;
1473 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1474 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1475 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1476 static final int REPORT_MEM_USAGE_MSG = 33;
1477 static final int REPORT_USER_SWITCH_MSG = 34;
1478 static final int CONTINUE_USER_SWITCH_MSG = 35;
1479 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1480 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1481 static final int PERSIST_URI_GRANTS_MSG = 38;
1482 static final int REQUEST_ALL_PSS_MSG = 39;
1483 static final int START_PROFILES_MSG = 40;
1484 static final int UPDATE_TIME = 41;
1485 static final int SYSTEM_USER_START_MSG = 42;
1486 static final int SYSTEM_USER_CURRENT_MSG = 43;
1487 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1488 static final int FINISH_BOOTING_MSG = 45;
1489 static final int START_USER_SWITCH_UI_MSG = 46;
1490 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1491 static final int DISMISS_DIALOG_UI_MSG = 48;
1492 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1493 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1494 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1495 static final int DELETE_DUMPHEAP_MSG = 52;
1496 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1497 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1498 static final int REPORT_TIME_TRACKER_MSG = 55;
1499 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1500 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1501 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1502 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1503 static final int IDLE_UIDS_MSG = 60;
1504 static final int SYSTEM_USER_UNLOCK_MSG = 61;
1505 static final int LOG_STACK_STATE = 62;
1506 static final int VR_MODE_CHANGE_MSG = 63;
1507 static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1508 static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1509 static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1510 static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1511 static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1512 static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1514 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1515 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1516 static final int FIRST_COMPAT_MODE_MSG = 300;
1517 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1519 static ServiceThread sKillThread = null;
1520 static KillHandler sKillHandler = null;
1522 CompatModeDialog mCompatModeDialog;
1523 long mLastMemUsageReportTime = 0;
1526 * Flag whether the current user is a "monkey", i.e. whether
1527 * the UI is driven by a UI automation tool.
1529 private boolean mUserIsMonkey;
1531 /** Flag whether the device has a Recents UI */
1532 boolean mHasRecents;
1534 /** The dimensions of the thumbnails in the Recents UI. */
1535 int mThumbnailWidth;
1536 int mThumbnailHeight;
1537 float mFullscreenThumbnailScale;
1539 final ServiceThread mHandlerThread;
1540 final MainHandler mHandler;
1541 final UiHandler mUiHandler;
1543 PackageManagerInternal mPackageManagerInt;
1545 // VoiceInteraction session ID that changes for each new request except when
1546 // being called for multiwindow assist in a single session.
1547 private int mViSessionId = 1000;
1549 final class KillHandler extends Handler {
1550 static final int KILL_PROCESS_GROUP_MSG = 4000;
1552 public KillHandler(Looper looper) {
1553 super(looper, null, true);
1557 public void handleMessage(Message msg) {
1559 case KILL_PROCESS_GROUP_MSG:
1561 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1562 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1563 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1568 super.handleMessage(msg);
1573 final class UiHandler extends Handler {
1574 public UiHandler() {
1575 super(com.android.server.UiThread.get().getLooper(), null, true);
1579 public void handleMessage(Message msg) {
1581 case SHOW_ERROR_UI_MSG: {
1582 mAppErrors.handleShowAppErrorUi(msg);
1583 ensureBootCompleted();
1585 case SHOW_NOT_RESPONDING_UI_MSG: {
1586 mAppErrors.handleShowAnrUi(msg);
1587 ensureBootCompleted();
1589 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1590 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1591 synchronized (ActivityManagerService.this) {
1592 ProcessRecord proc = (ProcessRecord) data.get("app");
1594 Slog.e(TAG, "App not found when showing strict mode dialog.");
1597 if (proc.crashDialog != null) {
1598 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1601 AppErrorResult res = (AppErrorResult) data.get("result");
1602 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1603 Dialog d = new StrictModeViolationDialog(mContext,
1604 ActivityManagerService.this, res, proc);
1606 proc.crashDialog = d;
1608 // The device is asleep, so just pretend that the user
1609 // saw a crash dialog and hit "force quit".
1613 ensureBootCompleted();
1615 case SHOW_FACTORY_ERROR_UI_MSG: {
1616 Dialog d = new FactoryErrorDialog(
1617 mContext, msg.getData().getCharSequence("msg"));
1619 ensureBootCompleted();
1621 case WAIT_FOR_DEBUGGER_UI_MSG: {
1622 synchronized (ActivityManagerService.this) {
1623 ProcessRecord app = (ProcessRecord)msg.obj;
1624 if (msg.arg1 != 0) {
1625 if (!app.waitedForDebugger) {
1626 Dialog d = new AppWaitingForDebuggerDialog(
1627 ActivityManagerService.this,
1630 app.waitedForDebugger = true;
1634 if (app.waitDialog != null) {
1635 app.waitDialog.dismiss();
1636 app.waitDialog = null;
1641 case SHOW_UID_ERROR_UI_MSG: {
1643 AlertDialog d = new BaseErrorDialog(mContext);
1644 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1645 d.setCancelable(false);
1646 d.setTitle(mContext.getText(R.string.android_system_label));
1647 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1648 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1649 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1653 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1655 AlertDialog d = new BaseErrorDialog(mContext);
1656 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1657 d.setCancelable(false);
1658 d.setTitle(mContext.getText(R.string.android_system_label));
1659 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1660 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1661 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1665 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1666 synchronized (ActivityManagerService.this) {
1667 ActivityRecord ar = (ActivityRecord) msg.obj;
1668 if (mCompatModeDialog != null) {
1669 if (mCompatModeDialog.mAppInfo.packageName.equals(
1670 ar.info.applicationInfo.packageName)) {
1673 mCompatModeDialog.dismiss();
1674 mCompatModeDialog = null;
1676 if (ar != null && false) {
1677 if (mCompatModePackages.getPackageAskCompatModeLocked(
1679 int mode = mCompatModePackages.computeCompatModeLocked(
1680 ar.info.applicationInfo);
1681 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1682 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1683 mCompatModeDialog = new CompatModeDialog(
1684 ActivityManagerService.this, mContext,
1685 ar.info.applicationInfo);
1686 mCompatModeDialog.show();
1693 case START_USER_SWITCH_UI_MSG: {
1694 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1697 case DISMISS_DIALOG_UI_MSG: {
1698 final Dialog d = (Dialog) msg.obj;
1702 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1703 dispatchProcessesChanged();
1706 case DISPATCH_PROCESS_DIED_UI_MSG: {
1707 final int pid = msg.arg1;
1708 final int uid = msg.arg2;
1709 dispatchProcessDied(pid, uid);
1712 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1713 dispatchUidsChanged();
1719 final class MainHandler extends Handler {
1720 public MainHandler(Looper looper) {
1721 super(looper, null, true);
1725 public void handleMessage(Message msg) {
1727 case UPDATE_CONFIGURATION_MSG: {
1728 final ContentResolver resolver = mContext.getContentResolver();
1729 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1732 case GC_BACKGROUND_PROCESSES_MSG: {
1733 synchronized (ActivityManagerService.this) {
1734 performAppGcsIfAppropriateLocked();
1737 case SERVICE_TIMEOUT_MSG: {
1740 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1742 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1745 mServices.serviceTimeout((ProcessRecord)msg.obj);
1747 case UPDATE_TIME_ZONE: {
1748 synchronized (ActivityManagerService.this) {
1749 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1750 ProcessRecord r = mLruProcesses.get(i);
1751 if (r.thread != null) {
1753 r.thread.updateTimeZone();
1754 } catch (RemoteException ex) {
1755 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1761 case CLEAR_DNS_CACHE_MSG: {
1762 synchronized (ActivityManagerService.this) {
1763 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1764 ProcessRecord r = mLruProcesses.get(i);
1765 if (r.thread != null) {
1767 r.thread.clearDnsCache();
1768 } catch (RemoteException ex) {
1769 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1775 case UPDATE_HTTP_PROXY_MSG: {
1776 ProxyInfo proxy = (ProxyInfo)msg.obj;
1779 String exclList = "";
1780 Uri pacFileUrl = Uri.EMPTY;
1781 if (proxy != null) {
1782 host = proxy.getHost();
1783 port = Integer.toString(proxy.getPort());
1784 exclList = proxy.getExclusionListAsString();
1785 pacFileUrl = proxy.getPacFileUrl();
1787 synchronized (ActivityManagerService.this) {
1788 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1789 ProcessRecord r = mLruProcesses.get(i);
1790 if (r.thread != null) {
1792 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1793 } catch (RemoteException ex) {
1794 Slog.w(TAG, "Failed to update http proxy for: " +
1795 r.info.processName);
1801 case PROC_START_TIMEOUT_MSG: {
1804 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1806 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1809 ProcessRecord app = (ProcessRecord)msg.obj;
1810 synchronized (ActivityManagerService.this) {
1811 processStartTimedOutLocked(app);
1814 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1815 ProcessRecord app = (ProcessRecord)msg.obj;
1816 synchronized (ActivityManagerService.this) {
1817 processContentProviderPublishTimedOutLocked(app);
1820 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1821 synchronized (ActivityManagerService.this) {
1822 mActivityStarter.doPendingActivityLaunchesLocked(true);
1825 case KILL_APPLICATION_MSG: {
1826 synchronized (ActivityManagerService.this) {
1827 int appid = msg.arg1;
1828 boolean restart = (msg.arg2 == 1);
1829 Bundle bundle = (Bundle)msg.obj;
1830 String pkg = bundle.getString("pkg");
1831 String reason = bundle.getString("reason");
1832 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1833 false, UserHandle.USER_ALL, reason);
1836 case FINALIZE_PENDING_INTENT_MSG: {
1837 ((PendingIntentRecord)msg.obj).completeFinalize();
1839 case POST_HEAVY_NOTIFICATION_MSG: {
1840 INotificationManager inm = NotificationManager.getService();
1845 ActivityRecord root = (ActivityRecord)msg.obj;
1846 ProcessRecord process = root.app;
1847 if (process == null) {
1852 Context context = mContext.createPackageContext(process.info.packageName, 0);
1853 String text = mContext.getString(R.string.heavy_weight_notification,
1854 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1855 Notification notification = new Notification.Builder(context)
1856 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1860 .setColor(mContext.getColor(
1861 com.android.internal.R.color.system_notification_accent_color))
1862 .setContentTitle(text)
1864 mContext.getText(R.string.heavy_weight_notification_detail))
1865 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1866 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1867 new UserHandle(root.userId)))
1870 int[] outId = new int[1];
1871 inm.enqueueNotificationWithTag("android", "android", null,
1872 R.string.heavy_weight_notification,
1873 notification, outId, root.userId);
1874 } catch (RuntimeException e) {
1875 Slog.w(ActivityManagerService.TAG,
1876 "Error showing notification for heavy-weight app", e);
1877 } catch (RemoteException e) {
1879 } catch (NameNotFoundException e) {
1880 Slog.w(TAG, "Unable to create context for heavy notification", e);
1883 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1884 INotificationManager inm = NotificationManager.getService();
1889 inm.cancelNotificationWithTag("android", null,
1890 R.string.heavy_weight_notification, msg.arg1);
1891 } catch (RuntimeException e) {
1892 Slog.w(ActivityManagerService.TAG,
1893 "Error canceling notification for service", e);
1894 } catch (RemoteException e) {
1897 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1898 synchronized (ActivityManagerService.this) {
1899 checkExcessivePowerUsageLocked(true);
1900 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1901 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1902 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1905 case REPORT_MEM_USAGE_MSG: {
1906 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1907 Thread thread = new Thread() {
1908 @Override public void run() {
1909 reportMemUsage(memInfos);
1915 case REPORT_USER_SWITCH_MSG: {
1916 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1919 case CONTINUE_USER_SWITCH_MSG: {
1920 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1923 case USER_SWITCH_TIMEOUT_MSG: {
1924 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1927 case IMMERSIVE_MODE_LOCK_MSG: {
1928 final boolean nextState = (msg.arg1 != 0);
1929 if (mUpdateLock.isHeld() != nextState) {
1930 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1931 "Applying new update lock state '" + nextState
1932 + "' for " + (ActivityRecord)msg.obj);
1934 mUpdateLock.acquire();
1936 mUpdateLock.release();
1941 case PERSIST_URI_GRANTS_MSG: {
1942 writeGrantedUriPermissions();
1945 case REQUEST_ALL_PSS_MSG: {
1946 synchronized (ActivityManagerService.this) {
1947 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1951 case START_PROFILES_MSG: {
1952 synchronized (ActivityManagerService.this) {
1953 mUserController.startProfilesLocked();
1958 synchronized (ActivityManagerService.this) {
1959 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1960 ProcessRecord r = mLruProcesses.get(i);
1961 if (r.thread != null) {
1963 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1964 } catch (RemoteException ex) {
1965 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1972 case SYSTEM_USER_START_MSG: {
1973 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1974 Integer.toString(msg.arg1), msg.arg1);
1975 mSystemServiceManager.startUser(msg.arg1);
1978 case SYSTEM_USER_UNLOCK_MSG: {
1979 final int userId = msg.arg1;
1980 mSystemServiceManager.unlockUser(userId);
1981 synchronized (ActivityManagerService.this) {
1982 mRecentTasks.loadUserRecentsLocked(userId);
1984 if (userId == UserHandle.USER_SYSTEM) {
1985 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1987 installEncryptionUnawareProviders(userId);
1988 mUserController.finishUserUnlocked((UserState) msg.obj);
1991 case SYSTEM_USER_CURRENT_MSG: {
1992 mBatteryStatsService.noteEvent(
1993 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1994 Integer.toString(msg.arg2), msg.arg2);
1995 mBatteryStatsService.noteEvent(
1996 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1997 Integer.toString(msg.arg1), msg.arg1);
1998 mSystemServiceManager.switchUser(msg.arg1);
2001 case ENTER_ANIMATION_COMPLETE_MSG: {
2002 synchronized (ActivityManagerService.this) {
2003 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2004 if (r != null && r.app != null && r.app.thread != null) {
2006 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2007 } catch (RemoteException e) {
2013 case FINISH_BOOTING_MSG: {
2014 if (msg.arg1 != 0) {
2015 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2017 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2019 if (msg.arg2 != 0) {
2020 enableScreenAfterBoot();
2024 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2026 Locale l = (Locale) msg.obj;
2027 IBinder service = ServiceManager.getService("mount");
2028 IMountService mountService = IMountService.Stub.asInterface(service);
2029 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2030 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2031 } catch (RemoteException e) {
2032 Log.e(TAG, "Error storing locale for decryption UI", e);
2036 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2037 synchronized (ActivityManagerService.this) {
2038 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2040 // Make a one-way callback to the listener
2041 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2042 } catch (RemoteException e){
2043 // Handled by the RemoteCallbackList
2046 mTaskStackListeners.finishBroadcast();
2050 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2051 synchronized (ActivityManagerService.this) {
2052 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2054 // Make a one-way callback to the listener
2055 mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2056 } catch (RemoteException e){
2057 // Handled by the RemoteCallbackList
2060 mTaskStackListeners.finishBroadcast();
2064 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2065 synchronized (ActivityManagerService.this) {
2066 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2068 // Make a one-way callback to the listener
2069 mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2070 } catch (RemoteException e){
2071 // Handled by the RemoteCallbackList
2074 mTaskStackListeners.finishBroadcast();
2078 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2079 synchronized (ActivityManagerService.this) {
2080 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2082 // Make a one-way callback to the listener
2083 mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2084 } catch (RemoteException e){
2085 // Handled by the RemoteCallbackList
2088 mTaskStackListeners.finishBroadcast();
2092 case NOTIFY_FORCED_RESIZABLE_MSG: {
2093 synchronized (ActivityManagerService.this) {
2094 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2096 // Make a one-way callback to the listener
2097 mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2098 (String) msg.obj, msg.arg1);
2099 } catch (RemoteException e){
2100 // Handled by the RemoteCallbackList
2103 mTaskStackListeners.finishBroadcast();
2107 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_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)
2113 .onActivityDismissingDockedStack();
2114 } catch (RemoteException e){
2115 // Handled by the RemoteCallbackList
2118 mTaskStackListeners.finishBroadcast();
2122 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2123 final int uid = msg.arg1;
2124 final byte[] firstPacket = (byte[]) msg.obj;
2126 synchronized (mPidsSelfLocked) {
2127 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2128 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2131 p.thread.notifyCleartextNetwork(firstPacket);
2132 } catch (RemoteException ignored) {
2139 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2140 final String procName;
2142 final long memLimit;
2143 final String reportPackage;
2144 synchronized (ActivityManagerService.this) {
2145 procName = mMemWatchDumpProcName;
2146 uid = mMemWatchDumpUid;
2147 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2149 val = mMemWatchProcesses.get(procName, 0);
2152 memLimit = val.first;
2153 reportPackage = val.second;
2156 reportPackage = null;
2159 if (procName == null) {
2163 if (DEBUG_PSS) Slog.d(TAG_PSS,
2164 "Showing dump heap notification from " + procName + "/" + uid);
2166 INotificationManager inm = NotificationManager.getService();
2171 String text = mContext.getString(R.string.dump_heap_notification, procName);
2174 Intent deleteIntent = new Intent();
2175 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2176 Intent intent = new Intent();
2177 intent.setClassName("android", DumpHeapActivity.class.getName());
2178 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2179 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2180 if (reportPackage != null) {
2181 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2183 int userId = UserHandle.getUserId(uid);
2184 Notification notification = new Notification.Builder(mContext)
2185 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2188 .setAutoCancel(true)
2190 .setColor(mContext.getColor(
2191 com.android.internal.R.color.system_notification_accent_color))
2192 .setContentTitle(text)
2194 mContext.getText(R.string.dump_heap_notification_detail))
2195 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2196 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2197 new UserHandle(userId)))
2198 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2199 deleteIntent, 0, UserHandle.SYSTEM))
2203 int[] outId = new int[1];
2204 inm.enqueueNotificationWithTag("android", "android", null,
2205 R.string.dump_heap_notification,
2206 notification, outId, userId);
2207 } catch (RuntimeException e) {
2208 Slog.w(ActivityManagerService.TAG,
2209 "Error showing notification for dump heap", e);
2210 } catch (RemoteException e) {
2213 case DELETE_DUMPHEAP_MSG: {
2214 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2215 DumpHeapActivity.JAVA_URI,
2216 Intent.FLAG_GRANT_READ_URI_PERMISSION
2217 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2218 UserHandle.myUserId());
2219 synchronized (ActivityManagerService.this) {
2220 mMemWatchDumpFile = null;
2221 mMemWatchDumpProcName = null;
2222 mMemWatchDumpPid = -1;
2223 mMemWatchDumpUid = -1;
2226 case FOREGROUND_PROFILE_CHANGED_MSG: {
2227 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2229 case REPORT_TIME_TRACKER_MSG: {
2230 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2231 tracker.deliverResult(mContext);
2233 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2234 mUserController.dispatchUserSwitchComplete(msg.arg1);
2236 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2237 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2239 connection.shutdown();
2240 } catch (RemoteException e) {
2241 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2243 // Only a UiAutomation can set this flag and now that
2244 // it is finished we make sure it is reset to its default.
2245 mUserIsMonkey = false;
2247 case APP_BOOST_DEACTIVATE_MSG: {
2248 synchronized(ActivityManagerService.this) {
2250 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2251 nativeMigrateFromBoost();
2253 mBoostStartTime = 0;
2255 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2256 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2261 case IDLE_UIDS_MSG: {
2264 case LOG_STACK_STATE: {
2265 synchronized (ActivityManagerService.this) {
2266 mStackSupervisor.logStackState();
2269 case VR_MODE_CHANGE_MSG: {
2270 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2271 final ActivityRecord r = (ActivityRecord) msg.obj;
2273 ComponentName requestedPackage;
2274 ComponentName callingPackage;
2276 synchronized (ActivityManagerService.this) {
2277 vrMode = r.requestedVrComponent != null;
2278 requestedPackage = r.requestedVrComponent;
2280 callingPackage = r.info.getComponentName();
2281 if (mInVrMode != vrMode) {
2283 mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2286 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2288 case VR_MODE_APPLY_IF_NEEDED_MSG: {
2289 final ActivityRecord r = (ActivityRecord) msg.obj;
2290 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2292 VrManagerInternal vrService =
2293 LocalServices.getService(VrManagerInternal.class);
2294 boolean enable = msg.arg1 == 1;
2295 vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2296 r.info.getComponentName());
2303 static final int COLLECT_PSS_BG_MSG = 1;
2305 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2307 public void handleMessage(Message msg) {
2309 case COLLECT_PSS_BG_MSG: {
2310 long start = SystemClock.uptimeMillis();
2311 MemInfoReader memInfo = null;
2312 synchronized (ActivityManagerService.this) {
2313 if (mFullPssPending) {
2314 mFullPssPending = false;
2315 memInfo = new MemInfoReader();
2318 if (memInfo != null) {
2319 updateCpuStatsNow();
2320 long nativeTotalPss = 0;
2321 synchronized (mProcessCpuTracker) {
2322 final int N = mProcessCpuTracker.countStats();
2323 for (int j=0; j<N; j++) {
2324 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2325 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2326 // This is definitely an application process; skip it.
2329 synchronized (mPidsSelfLocked) {
2330 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2331 // This is one of our own processes; skip it.
2335 nativeTotalPss += Debug.getPss(st.pid, null, null);
2338 memInfo.readMemInfo();
2339 synchronized (ActivityManagerService.this) {
2340 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2341 + (SystemClock.uptimeMillis()-start) + "ms");
2342 final long cachedKb = memInfo.getCachedSizeKb();
2343 final long freeKb = memInfo.getFreeSizeKb();
2344 final long zramKb = memInfo.getZramTotalSizeKb();
2345 final long kernelKb = memInfo.getKernelUsedSizeKb();
2346 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2347 kernelKb*1024, nativeTotalPss*1024);
2348 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2354 long[] tmp = new long[2];
2360 synchronized (ActivityManagerService.this) {
2361 if (mPendingPssProcesses.size() <= 0) {
2362 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2363 "Collected PSS of " + num + " processes in "
2364 + (SystemClock.uptimeMillis() - start) + "ms");
2365 mPendingPssProcesses.clear();
2368 proc = mPendingPssProcesses.remove(0);
2369 procState = proc.pssProcState;
2370 lastPssTime = proc.lastPssTime;
2371 if (proc.thread != null && procState == proc.setProcState
2372 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2373 < SystemClock.uptimeMillis()) {
2381 long pss = Debug.getPss(pid, tmp, null);
2382 synchronized (ActivityManagerService.this) {
2383 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2384 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2386 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2387 SystemClock.uptimeMillis());
2397 public void setSystemProcess() {
2399 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2400 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2401 ServiceManager.addService("meminfo", new MemBinder(this));
2402 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2403 ServiceManager.addService("dbinfo", new DbBinder(this));
2404 if (MONITOR_CPU_USAGE) {
2405 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2407 ServiceManager.addService("permission", new PermissionController(this));
2408 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2410 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2411 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2412 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2414 synchronized (this) {
2415 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2416 app.persistent = true;
2418 app.maxAdj = ProcessList.SYSTEM_ADJ;
2419 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2420 synchronized (mPidsSelfLocked) {
2421 mPidsSelfLocked.put(app.pid, app);
2423 updateLruProcessLocked(app, false, null);
2424 updateOomAdjLocked();
2426 } catch (PackageManager.NameNotFoundException e) {
2427 throw new RuntimeException(
2428 "Unable to find android system package", e);
2432 public void setWindowManager(WindowManagerService wm) {
2433 mWindowManager = wm;
2434 mStackSupervisor.setWindowManager(wm);
2435 mActivityStarter.setWindowManager(wm);
2438 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2439 mUsageStatsService = usageStatsManager;
2442 public void startObservingNativeCrashes() {
2443 final NativeCrashListener ncl = new NativeCrashListener(this);
2447 public IAppOpsService getAppOpsService() {
2448 return mAppOpsService;
2451 static class MemBinder extends Binder {
2452 ActivityManagerService mActivityManagerService;
2453 MemBinder(ActivityManagerService activityManagerService) {
2454 mActivityManagerService = activityManagerService;
2458 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2459 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2460 != PackageManager.PERMISSION_GRANTED) {
2461 pw.println("Permission Denial: can't dump meminfo from from pid="
2462 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2463 + " without permission " + android.Manifest.permission.DUMP);
2467 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2471 static class GraphicsBinder extends Binder {
2472 ActivityManagerService mActivityManagerService;
2473 GraphicsBinder(ActivityManagerService activityManagerService) {
2474 mActivityManagerService = activityManagerService;
2478 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2479 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2480 != PackageManager.PERMISSION_GRANTED) {
2481 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2482 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2483 + " without permission " + android.Manifest.permission.DUMP);
2487 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2491 static class DbBinder extends Binder {
2492 ActivityManagerService mActivityManagerService;
2493 DbBinder(ActivityManagerService activityManagerService) {
2494 mActivityManagerService = activityManagerService;
2498 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2499 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2500 != PackageManager.PERMISSION_GRANTED) {
2501 pw.println("Permission Denial: can't dump dbinfo from from pid="
2502 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2503 + " without permission " + android.Manifest.permission.DUMP);
2507 mActivityManagerService.dumpDbInfo(fd, pw, args);
2511 static class CpuBinder extends Binder {
2512 ActivityManagerService mActivityManagerService;
2513 CpuBinder(ActivityManagerService activityManagerService) {
2514 mActivityManagerService = activityManagerService;
2518 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2519 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2520 != PackageManager.PERMISSION_GRANTED) {
2521 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2522 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2523 + " without permission " + android.Manifest.permission.DUMP);
2527 synchronized (mActivityManagerService.mProcessCpuTracker) {
2528 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2529 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2530 SystemClock.uptimeMillis()));
2535 public static final class Lifecycle extends SystemService {
2536 private final ActivityManagerService mService;
2538 public Lifecycle(Context context) {
2540 mService = new ActivityManagerService(context);
2544 public void onStart() {
2548 public ActivityManagerService getService() {
2553 // Note: This method is invoked on the main thread but may need to attach various
2554 // handlers to other threads. So take care to be explicit about the looper.
2555 public ActivityManagerService(Context systemContext) {
2556 mContext = systemContext;
2557 mFactoryTest = FactoryTest.getMode();
2558 mSystemThread = ActivityThread.currentActivityThread();
2560 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2562 mHandlerThread = new ServiceThread(TAG,
2563 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2564 mHandlerThread.start();
2565 mHandler = new MainHandler(mHandlerThread.getLooper());
2566 mUiHandler = new UiHandler();
2568 /* static; one-time init here */
2569 if (sKillHandler == null) {
2570 sKillThread = new ServiceThread(TAG + ":kill",
2571 android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2572 sKillThread.start();
2573 sKillHandler = new KillHandler(sKillThread.getLooper());
2576 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2577 "foreground", BROADCAST_FG_TIMEOUT, false);
2578 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2579 "background", BROADCAST_BG_TIMEOUT, true);
2580 mBroadcastQueues[0] = mFgBroadcastQueue;
2581 mBroadcastQueues[1] = mBgBroadcastQueue;
2583 mServices = new ActiveServices(this);
2584 mProviderMap = new ProviderMap(this);
2585 mAppErrors = new AppErrors(mContext, this);
2587 // TODO: Move creation of battery stats service outside of activity manager service.
2588 File dataDir = Environment.getDataDirectory();
2589 File systemDir = new File(dataDir, "system");
2591 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2592 mBatteryStatsService.getActiveStatistics().readLocked();
2593 mBatteryStatsService.scheduleWriteToDisk();
2594 mOnBattery = DEBUG_POWER ? true
2595 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2596 mBatteryStatsService.getActiveStatistics().setCallback(this);
2598 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2600 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2601 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2602 new IAppOpsCallback.Stub() {
2603 @Override public void opChanged(int op, int uid, String packageName) {
2604 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2605 if (mAppOpsService.checkOperation(op, uid, packageName)
2606 != AppOpsManager.MODE_ALLOWED) {
2607 runInBackgroundDisabled(uid);
2613 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2615 mUserController = new UserController(this);
2617 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2618 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2620 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2622 mConfiguration.setToDefaults();
2623 mConfiguration.setLocales(LocaleList.getDefault());
2625 mConfigurationSeq = mConfiguration.seq = 1;
2626 mProcessCpuTracker.init();
2628 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2629 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2630 mStackSupervisor = new ActivityStackSupervisor(this);
2631 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2632 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2634 mProcessCpuThread = new Thread("CpuTracker") {
2640 synchronized(this) {
2641 final long now = SystemClock.uptimeMillis();
2642 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2643 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2644 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2645 // + ", write delay=" + nextWriteDelay);
2646 if (nextWriteDelay < nextCpuDelay) {
2647 nextCpuDelay = nextWriteDelay;
2649 if (nextCpuDelay > 0) {
2650 mProcessCpuMutexFree.set(true);
2651 this.wait(nextCpuDelay);
2654 } catch (InterruptedException e) {
2656 updateCpuStatsNow();
2657 } catch (Exception e) {
2658 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2664 Watchdog.getInstance().addMonitor(this);
2665 Watchdog.getInstance().addThread(mHandler);
2668 public void setSystemServiceManager(SystemServiceManager mgr) {
2669 mSystemServiceManager = mgr;
2672 public void setInstaller(Installer installer) {
2673 mInstaller = installer;
2676 private void start() {
2677 Process.removeAllProcessGroups();
2678 mProcessCpuThread.start();
2680 mBatteryStatsService.publish(mContext);
2681 mAppOpsService.publish(mContext);
2682 Slog.d("AppOps", "AppOpsService published");
2683 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2686 void onUserStoppedLocked(int userId) {
2687 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2690 public void initPowerManagement() {
2691 mStackSupervisor.initPowerManagement();
2692 mBatteryStatsService.initPowerManagement();
2693 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2694 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2695 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2696 mVoiceWakeLock.setReferenceCounted(false);
2700 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2701 throws RemoteException {
2702 if (code == SYSPROPS_TRANSACTION) {
2703 // We need to tell all apps about the system property change.
2704 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2705 synchronized(this) {
2706 final int NP = mProcessNames.getMap().size();
2707 for (int ip=0; ip<NP; ip++) {
2708 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2709 final int NA = apps.size();
2710 for (int ia=0; ia<NA; ia++) {
2711 ProcessRecord app = apps.valueAt(ia);
2712 if (app.thread != null) {
2713 procs.add(app.thread.asBinder());
2719 int N = procs.size();
2720 for (int i=0; i<N; i++) {
2721 Parcel data2 = Parcel.obtain();
2723 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2724 } catch (RemoteException e) {
2730 return super.onTransact(code, data, reply, flags);
2731 } catch (RuntimeException e) {
2732 // The activity manager only throws security exceptions, so let's
2734 if (!(e instanceof SecurityException)) {
2735 Slog.wtf(TAG, "Activity Manager Crash", e);
2741 void updateCpuStats() {
2742 final long now = SystemClock.uptimeMillis();
2743 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2746 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2747 synchronized (mProcessCpuThread) {
2748 mProcessCpuThread.notify();
2753 void updateCpuStatsNow() {
2754 synchronized (mProcessCpuTracker) {
2755 mProcessCpuMutexFree.set(false);
2756 final long now = SystemClock.uptimeMillis();
2757 boolean haveNewCpuStats = false;
2759 if (MONITOR_CPU_USAGE &&
2760 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2761 mLastCpuTime.set(now);
2762 mProcessCpuTracker.update();
2763 if (mProcessCpuTracker.hasGoodLastStats()) {
2764 haveNewCpuStats = true;
2765 //Slog.i(TAG, mProcessCpu.printCurrentState());
2766 //Slog.i(TAG, "Total CPU usage: "
2767 // + mProcessCpu.getTotalCpuPercent() + "%");
2769 // Slog the cpu usage if the property is set.
2770 if ("true".equals(SystemProperties.get("events.cpu"))) {
2771 int user = mProcessCpuTracker.getLastUserTime();
2772 int system = mProcessCpuTracker.getLastSystemTime();
2773 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2774 int irq = mProcessCpuTracker.getLastIrqTime();
2775 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2776 int idle = mProcessCpuTracker.getLastIdleTime();
2778 int total = user + system + iowait + irq + softIrq + idle;
2779 if (total == 0) total = 1;
2781 EventLog.writeEvent(EventLogTags.CPU,
2782 ((user+system+iowait+irq+softIrq) * 100) / total,
2783 (user * 100) / total,
2784 (system * 100) / total,
2785 (iowait * 100) / total,
2786 (irq * 100) / total,
2787 (softIrq * 100) / total);
2792 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2793 synchronized(bstats) {
2794 synchronized(mPidsSelfLocked) {
2795 if (haveNewCpuStats) {
2796 if (bstats.startAddingCpuLocked()) {
2799 final int N = mProcessCpuTracker.countStats();
2800 for (int i=0; i<N; i++) {
2801 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2805 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2806 totalUTime += st.rel_utime;
2807 totalSTime += st.rel_stime;
2809 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2810 if (ps == null || !ps.isActive()) {
2811 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2812 pr.info.uid, pr.processName);
2814 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2815 pr.curCpuTime += st.rel_utime + st.rel_stime;
2817 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2818 if (ps == null || !ps.isActive()) {
2819 st.batteryStats = ps = bstats.getProcessStatsLocked(
2820 bstats.mapUid(st.uid), st.name);
2822 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2825 final int userTime = mProcessCpuTracker.getLastUserTime();
2826 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2827 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2828 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2829 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2830 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2831 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2832 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2837 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2838 mLastWriteTime = now;
2839 mBatteryStatsService.scheduleWriteToDisk();
2846 public void batteryNeedsCpuUpdate() {
2847 updateCpuStatsNow();
2851 public void batteryPowerChanged(boolean onBattery) {
2852 // When plugging in, update the CPU stats first before changing
2854 updateCpuStatsNow();
2855 synchronized (this) {
2856 synchronized(mPidsSelfLocked) {
2857 mOnBattery = DEBUG_POWER ? true : onBattery;
2863 public void batterySendBroadcast(Intent intent) {
2864 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2865 AppOpsManager.OP_NONE, null, false, false,
2866 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2870 * Initialize the application bind args. These are passed to each
2871 * process when the bindApplication() IPC is sent to the process. They're
2872 * lazily setup to make sure the services are running when they're asked for.
2874 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2875 if (mAppBindArgs == null) {
2876 mAppBindArgs = new HashMap<>();
2878 // Isolated processes won't get this optimization, so that we don't
2879 // violate the rules about which services they have access to.
2881 // Setup the application init args
2882 mAppBindArgs.put("package", ServiceManager.getService("package"));
2883 mAppBindArgs.put("window", ServiceManager.getService("window"));
2884 mAppBindArgs.put(Context.ALARM_SERVICE,
2885 ServiceManager.getService(Context.ALARM_SERVICE));
2888 return mAppBindArgs;
2891 boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2892 if (r == null || mFocusedActivity == r) {
2896 if (!r.isFocusable()) {
2897 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2901 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2903 final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2904 if (wasDoingSetFocusedActivity) Slog.w(TAG,
2905 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2906 mDoingSetFocusedActivity = true;
2908 final ActivityRecord last = mFocusedActivity;
2909 mFocusedActivity = r;
2910 if (r.task.isApplicationTask()) {
2911 if (mCurAppTimeTracker != r.appTimeTracker) {
2912 // We are switching app tracking. Complete the current one.
2913 if (mCurAppTimeTracker != null) {
2914 mCurAppTimeTracker.stop();
2915 mHandler.obtainMessage(
2916 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2917 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2918 mCurAppTimeTracker = null;
2920 if (r.appTimeTracker != null) {
2921 mCurAppTimeTracker = r.appTimeTracker;
2922 startTimeTrackingFocusedActivityLocked();
2925 startTimeTrackingFocusedActivityLocked();
2928 r.appTimeTracker = null;
2930 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2931 // TODO: Probably not, because we don't want to resume voice on switching
2932 // back to this activity
2933 if (r.task.voiceInteractor != null) {
2934 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2936 finishRunningVoiceLocked();
2937 IVoiceInteractionSession session;
2938 if (last != null && ((session = last.task.voiceSession) != null
2939 || (session = last.voiceSession) != null)) {
2940 // We had been in a voice interaction session, but now focused has
2941 // move to something different. Just finish the session, we can't
2942 // return to it and retain the proper state and synchronization with
2943 // the voice interaction service.
2944 finishVoiceTask(session);
2947 if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2948 mWindowManager.setFocusedApp(r.appToken, true);
2950 applyUpdateLockStateLocked(r);
2951 applyUpdateVrModeLocked(r);
2952 if (mFocusedActivity.userId != mLastFocusedUserId) {
2953 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2954 mHandler.obtainMessage(
2955 FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2956 mLastFocusedUserId = mFocusedActivity.userId;
2959 // Log a warning if the focused app is changed during the process. This could
2960 // indicate a problem of the focus setting logic!
2961 if (mFocusedActivity != r) Slog.w(TAG,
2962 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2963 mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2965 EventLogTags.writeAmFocusedActivity(
2966 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2967 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2972 final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2973 if (mFocusedActivity != goingAway) {
2977 final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2978 if (focusedStack != null) {
2979 final ActivityRecord top = focusedStack.topActivity();
2980 if (top != null && top.userId != mLastFocusedUserId) {
2981 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2982 mHandler.sendMessage(
2983 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2984 mLastFocusedUserId = top.userId;
2988 // Try to move focus to another activity if possible.
2989 if (setFocusedActivityLocked(
2990 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2994 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2995 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2996 mFocusedActivity = null;
2997 EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3001 public void setFocusedStack(int stackId) {
3002 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3003 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3004 final long callingId = Binder.clearCallingIdentity();
3006 synchronized (this) {
3007 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3008 if (stack == null) {
3011 final ActivityRecord r = stack.topRunningActivityLocked();
3012 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3013 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3017 Binder.restoreCallingIdentity(callingId);
3022 public void setFocusedTask(int taskId) {
3023 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3024 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3025 final long callingId = Binder.clearCallingIdentity();
3027 synchronized (this) {
3028 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3032 final ActivityRecord r = task.topRunningActivityLocked();
3033 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3034 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3038 Binder.restoreCallingIdentity(callingId);
3042 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3044 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3045 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3046 synchronized (this) {
3047 if (listener != null) {
3048 mTaskStackListeners.register(listener);
3054 public void notifyActivityDrawn(IBinder token) {
3055 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3056 synchronized (this) {
3057 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3059 r.task.stack.notifyActivityDrawnLocked(r);
3064 final void applyUpdateLockStateLocked(ActivityRecord r) {
3065 // Modifications to the UpdateLock state are done on our handler, outside
3066 // the activity manager's locks. The new state is determined based on the
3067 // state *now* of the relevant activity record. The object is passed to
3068 // the handler solely for logging detail, not to be consulted/modified.
3069 final boolean nextState = r != null && r.immersive;
3070 mHandler.sendMessage(
3071 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3074 final void applyUpdateVrModeLocked(ActivityRecord r) {
3075 mHandler.sendMessage(
3076 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3079 private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3080 mHandler.sendMessage(
3081 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3084 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3085 Message msg = Message.obtain();
3086 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3087 msg.obj = r.task.askedCompatMode ? null : r;
3088 mUiHandler.sendMessage(msg);
3091 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3092 String what, Object obj, ProcessRecord srcApp) {
3093 app.lastActivityTime = now;
3095 if (app.activities.size() > 0) {
3096 // Don't want to touch dependent processes that are hosting activities.
3100 int lrui = mLruProcesses.lastIndexOf(app);
3102 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3103 + what + " " + obj + " from " + srcApp);
3107 if (lrui >= index) {
3108 // Don't want to cause this to move dependent processes *back* in the
3109 // list as if they were less frequently used.
3113 if (lrui >= mLruProcessActivityStart) {
3114 // Don't want to touch dependent processes that are hosting activities.
3118 mLruProcesses.remove(lrui);
3122 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3123 + " in LRU list: " + app);
3124 mLruProcesses.add(index, app);
3128 static void killProcessGroup(int uid, int pid) {
3129 if (sKillHandler != null) {
3130 sKillHandler.sendMessage(
3131 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3133 Slog.w(TAG, "Asked to kill process group before system bringup!");
3134 Process.killProcessGroup(uid, pid);
3138 final void removeLruProcessLocked(ProcessRecord app) {
3139 int lrui = mLruProcesses.lastIndexOf(app);
3142 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3143 Process.killProcessQuiet(app.pid);
3144 killProcessGroup(app.uid, app.pid);
3146 if (lrui <= mLruProcessActivityStart) {
3147 mLruProcessActivityStart--;
3149 if (lrui <= mLruProcessServiceStart) {
3150 mLruProcessServiceStart--;
3152 mLruProcesses.remove(lrui);
3156 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3157 ProcessRecord client) {
3158 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3159 || app.treatLikeActivity;
3160 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3161 if (!activityChange && hasActivity) {
3162 // The process has activities, so we are only allowing activity-based adjustments
3163 // to move it. It should be kept in the front of the list with other
3164 // processes that have activities, and we don't want those to change their
3165 // order except due to activity operations.
3170 final long now = SystemClock.uptimeMillis();
3171 app.lastActivityTime = now;
3173 // First a quick reject: if the app is already at the position we will
3174 // put it, then there is nothing to do.
3176 final int N = mLruProcesses.size();
3177 if (N > 0 && mLruProcesses.get(N-1) == app) {
3178 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3182 if (mLruProcessServiceStart > 0
3183 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3184 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3189 int lrui = mLruProcesses.lastIndexOf(app);
3191 if (app.persistent && lrui >= 0) {
3192 // We don't care about the position of persistent processes, as long as
3193 // they are in the list.
3194 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3198 /* In progress: compute new position first, so we can avoid doing work
3199 if the process is not actually going to move. Not yet working.
3202 boolean inActivity = false, inService = false;
3204 // Process has activities, put it at the very tipsy-top.
3205 addIndex = mLruProcesses.size();
3206 nextIndex = mLruProcessServiceStart;
3208 } else if (hasService) {
3209 // Process has services, put it at the top of the service list.
3210 addIndex = mLruProcessActivityStart;
3211 nextIndex = mLruProcessServiceStart;
3215 // Process not otherwise of interest, it goes to the top of the non-service area.
3216 addIndex = mLruProcessServiceStart;
3217 if (client != null) {
3218 int clientIndex = mLruProcesses.lastIndexOf(client);
3219 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3221 if (clientIndex >= 0 && addIndex > clientIndex) {
3222 addIndex = clientIndex;
3225 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3228 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3229 + mLruProcessActivityStart + "): " + app);
3233 if (lrui < mLruProcessActivityStart) {
3234 mLruProcessActivityStart--;
3236 if (lrui < mLruProcessServiceStart) {
3237 mLruProcessServiceStart--;
3240 if (addIndex > lrui) {
3243 if (nextIndex > lrui) {
3247 mLruProcesses.remove(lrui);
3251 mLruProcesses.add(addIndex, app);
3253 mLruProcessActivityStart++;
3256 mLruProcessActivityStart++;
3262 final int N = mLruProcesses.size();
3263 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3264 // Process doesn't have activities, but has clients with
3265 // activities... move it up, but one below the top (the top
3266 // should always have a real activity).
3267 if (DEBUG_LRU) Slog.d(TAG_LRU,
3268 "Adding to second-top of LRU activity list: " + app);
3269 mLruProcesses.add(N - 1, app);
3270 // To keep it from spamming the LRU list (by making a bunch of clients),
3271 // we will push down any other entries owned by the app.
3272 final int uid = app.info.uid;
3273 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3274 ProcessRecord subProc = mLruProcesses.get(i);
3275 if (subProc.info.uid == uid) {
3276 // We want to push this one down the list. If the process after
3277 // it is for the same uid, however, don't do so, because we don't
3278 // want them internally to be re-ordered.
3279 if (mLruProcesses.get(i - 1).info.uid != uid) {
3280 if (DEBUG_LRU) Slog.d(TAG_LRU,
3281 "Pushing uid " + uid + " swapping at " + i + ": "
3282 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3283 ProcessRecord tmp = mLruProcesses.get(i);
3284 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3285 mLruProcesses.set(i - 1, tmp);
3289 // A gap, we can stop here.
3294 // Process has activities, put it at the very tipsy-top.
3295 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3296 mLruProcesses.add(app);
3298 nextIndex = mLruProcessServiceStart;
3299 } else if (hasService) {
3300 // Process has services, put it at the top of the service list.
3301 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3302 mLruProcesses.add(mLruProcessActivityStart, app);
3303 nextIndex = mLruProcessServiceStart;
3304 mLruProcessActivityStart++;
3306 // Process not otherwise of interest, it goes to the top of the non-service area.
3307 int index = mLruProcessServiceStart;
3308 if (client != null) {
3309 // If there is a client, don't allow the process to be moved up higher
3310 // in the list than that client.
3311 int clientIndex = mLruProcesses.lastIndexOf(client);
3312 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3313 + " when updating " + app);
3314 if (clientIndex <= lrui) {
3315 // Don't allow the client index restriction to push it down farther in the
3316 // list than it already is.
3319 if (clientIndex >= 0 && index > clientIndex) {
3320 index = clientIndex;
3323 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3324 mLruProcesses.add(index, app);
3325 nextIndex = index-1;
3326 mLruProcessActivityStart++;
3327 mLruProcessServiceStart++;
3330 // If the app is currently using a content provider or service,
3331 // bump those processes as well.
3332 for (int j=app.connections.size()-1; j>=0; j--) {
3333 ConnectionRecord cr = app.connections.valueAt(j);
3334 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3335 && cr.binding.service.app != null
3336 && cr.binding.service.app.lruSeq != mLruSeq
3337 && !cr.binding.service.app.persistent) {
3338 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3339 "service connection", cr, app);
3342 for (int j=app.conProviders.size()-1; j>=0; j--) {
3343 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3344 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3345 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3346 "provider reference", cpr, app);
3351 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3352 if (uid == Process.SYSTEM_UID) {
3353 // The system gets to run in any process. If there are multiple
3354 // processes with the same uid, just pick the first (this
3355 // should never happen).
3356 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3357 if (procs == null) return null;
3358 final int procCount = procs.size();
3359 for (int i = 0; i < procCount; i++) {
3360 final int procUid = procs.keyAt(i);
3361 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3362 // Don't use an app process or different user process for system component.
3365 return procs.valueAt(i);
3368 ProcessRecord proc = mProcessNames.get(processName, uid);
3369 if (false && proc != null && !keepIfLarge
3370 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3371 && proc.lastCachedPss >= 4000) {
3372 // Turn this condition on to cause killing to happen regularly, for testing.
3373 if (proc.baseProcessTracker != null) {
3374 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3376 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3377 } else if (proc != null && !keepIfLarge
3378 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3379 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3380 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3381 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3382 if (proc.baseProcessTracker != null) {
3383 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3385 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3391 void notifyPackageUse(String packageName, int reason) {
3392 IPackageManager pm = AppGlobals.getPackageManager();
3394 pm.notifyPackageUse(packageName, reason);
3395 } catch (RemoteException e) {
3399 boolean isNextTransitionForward() {
3400 int transit = mWindowManager.getPendingAppTransition();
3401 return transit == TRANSIT_ACTIVITY_OPEN
3402 || transit == TRANSIT_TASK_OPEN
3403 || transit == TRANSIT_TASK_TO_FRONT;
3406 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3407 String processName, String abiOverride, int uid, Runnable crashHandler) {
3408 synchronized(this) {
3409 ApplicationInfo info = new ApplicationInfo();
3410 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3411 // For isolated processes, the former contains the parent's uid and the latter the
3412 // actual uid of the isolated process.
3413 // In the special case introduced by this method (which is, starting an isolated
3414 // process directly from the SystemServer without an actual parent app process) the
3415 // closest thing to a parent's uid is SYSTEM_UID.
3416 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3417 // the |isolated| logic in the ProcessRecord constructor.
3418 info.uid = Process.SYSTEM_UID;
3419 info.processName = processName;
3420 info.className = entryPoint;
3421 info.packageName = "android";
3422 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3423 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3424 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3425 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3427 return proc != null ? proc.pid : 0;
3431 final ProcessRecord startProcessLocked(String processName,
3432 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3433 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3434 boolean isolated, boolean keepIfLarge) {
3435 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3436 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3437 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3438 null /* crashHandler */);
3441 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3442 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3443 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3444 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3445 long startTime = SystemClock.elapsedRealtime();
3448 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3449 checkTime(startTime, "startProcess: after getProcessRecord");
3451 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3452 // If we are in the background, then check to see if this process
3453 // is bad. If so, we will just silently fail.
3454 if (mAppErrors.isBadProcessLocked(info)) {
3455 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3456 + "/" + info.processName);
3460 // When the user is explicitly starting a process, then clear its
3461 // crash count so that we won't make it bad until they see at
3462 // least one crash dialog again, and make the process good again
3463 // if it had been bad.
3464 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3465 + "/" + info.processName);
3466 mAppErrors.resetProcessCrashTimeLocked(info);
3467 if (mAppErrors.isBadProcessLocked(info)) {
3468 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3469 UserHandle.getUserId(info.uid), info.uid,
3471 mAppErrors.clearBadProcessLocked(info);
3478 // If this is an isolated process, it can't re-use an existing process.
3482 // app launch boost for big.little configurations
3483 // use cpusets to migrate freshly launched tasks to big cores
3484 synchronized(ActivityManagerService.this) {
3485 nativeMigrateToBoost();
3487 mBoostStartTime = SystemClock.uptimeMillis();
3488 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3489 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3492 // We don't have to do anything more if:
3493 // (1) There is an existing application record; and
3494 // (2) The caller doesn't think it is dead, OR there is no thread
3495 // object attached to it so we know it couldn't have crashed; and
3496 // (3) There is a pid assigned to it, so it is either starting or
3498 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3499 + " app=" + app + " knownToBeDead=" + knownToBeDead
3500 + " thread=" + (app != null ? app.thread : null)
3501 + " pid=" + (app != null ? app.pid : -1));
3502 if (app != null && app.pid > 0) {
3503 if (!knownToBeDead || app.thread == null) {
3504 // We already have the app running, or are waiting for it to
3505 // come up (we have a pid but not yet its thread), so keep it.
3506 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3507 // If this is a new package in the process, add the package to the list
3508 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3509 checkTime(startTime, "startProcess: done, added package to proc");
3513 // An application record is attached to a previous process,
3515 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3516 checkTime(startTime, "startProcess: bad proc running, killing");
3517 killProcessGroup(app.uid, app.pid);
3518 handleAppDiedLocked(app, true, true);
3519 checkTime(startTime, "startProcess: done killing old proc");
3522 String hostingNameStr = hostingName != null
3523 ? hostingName.flattenToShortString() : null;
3526 checkTime(startTime, "startProcess: creating new process record");
3527 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3529 Slog.w(TAG, "Failed making new process record for "
3530 + processName + "/" + info.uid + " isolated=" + isolated);
3533 app.crashHandler = crashHandler;
3534 checkTime(startTime, "startProcess: done creating new process record");
3536 // If this is a new package in the process, add the package to the list
3537 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3538 checkTime(startTime, "startProcess: added package to existing proc");
3541 // If the system is not ready yet, then hold off on starting this
3542 // process until it is.
3543 if (!mProcessesReady
3544 && !isAllowedWhileBooting(info)
3545 && !allowWhileBooting) {
3546 if (!mProcessesOnHold.contains(app)) {
3547 mProcessesOnHold.add(app);
3549 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3550 "System not ready, putting on hold: " + app);
3551 checkTime(startTime, "startProcess: returning with proc on hold");
3555 checkTime(startTime, "startProcess: stepping in to startProcess");
3557 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3558 checkTime(startTime, "startProcess: done starting proc!");
3559 return (app.pid != 0) ? app : null;
3562 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3563 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3566 private final void startProcessLocked(ProcessRecord app,
3567 String hostingType, String hostingNameStr) {
3568 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3569 null /* entryPoint */, null /* entryPointArgs */);
3572 private final void startProcessLocked(ProcessRecord app, String hostingType,
3573 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3574 long startTime = SystemClock.elapsedRealtime();
3575 if (app.pid > 0 && app.pid != MY_PID) {
3576 checkTime(startTime, "startProcess: removing from pids map");
3577 synchronized (mPidsSelfLocked) {
3578 mPidsSelfLocked.remove(app.pid);
3579 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3581 checkTime(startTime, "startProcess: done removing from pids map");
3585 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3586 "startProcessLocked removing on hold: " + app);
3587 mProcessesOnHold.remove(app);
3589 checkTime(startTime, "startProcess: starting to update cpu stats");
3591 checkTime(startTime, "startProcess: done updating cpu stats");
3595 final int userId = UserHandle.getUserId(app.uid);
3596 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3597 } catch (RemoteException e) {
3598 throw e.rethrowAsRuntimeException();
3603 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3604 if (!app.isolated) {
3605 int[] permGids = null;
3607 checkTime(startTime, "startProcess: getting gids from package manager");
3608 final IPackageManager pm = AppGlobals.getPackageManager();
3609 permGids = pm.getPackageGids(app.info.packageName,
3610 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3611 MountServiceInternal mountServiceInternal = LocalServices.getService(
3612 MountServiceInternal.class);
3613 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3614 app.info.packageName);
3615 } catch (RemoteException e) {
3616 throw e.rethrowAsRuntimeException();
3620 * Add shared application and profile GIDs so applications can share some
3621 * resources like shared libraries and access user-wide resources
3623 if (ArrayUtils.isEmpty(permGids)) {
3626 gids = new int[permGids.length + 2];
3627 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3629 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3630 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3632 checkTime(startTime, "startProcess: building args");
3633 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3634 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3635 && mTopComponent != null
3636 && app.processName.equals(mTopComponent.getPackageName())) {
3639 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3640 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3645 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3646 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3647 // Also turn on CheckJNI for debuggable apps. It's quite
3648 // awkward to turn on otherwise.
3649 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3651 // Run the app in safe mode if its manifest requests so or the
3652 // system is booted in safe mode.
3653 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3654 mSafeMode == true) {
3655 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3657 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3658 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3660 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3661 if ("true".equals(genDebugInfoProperty)) {
3662 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3664 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3665 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3667 if ("1".equals(SystemProperties.get("debug.assert"))) {
3668 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3670 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3671 // Enable all debug flags required by the native debugger.
3672 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3673 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3674 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3675 mNativeDebuggingApp = null;
3678 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3679 if (requiredAbi == null) {
3680 requiredAbi = Build.SUPPORTED_ABIS[0];
3683 String instructionSet = null;
3684 if (app.info.primaryCpuAbi != null) {
3685 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3689 app.requiredAbi = requiredAbi;
3690 app.instructionSet = instructionSet;
3692 // Start the process. It will either succeed and return a result containing
3693 // the PID of the new process, or else throw a RuntimeException.
3694 boolean isActivityProcess = (entryPoint == null);
3695 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3696 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3698 checkTime(startTime, "startProcess: asking zygote to start proc");
3699 Process.ProcessStartResult startResult = Process.start(entryPoint,
3700 app.processName, uid, uid, gids, debugFlags, mountExternal,
3701 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3702 app.info.dataDir, entryPointArgs);
3703 checkTime(startTime, "startProcess: returned from zygote!");
3704 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3707 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3709 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3710 checkTime(startTime, "startProcess: done updating battery stats");
3712 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3713 UserHandle.getUserId(uid), startResult.pid, uid,
3714 app.processName, hostingType,
3715 hostingNameStr != null ? hostingNameStr : "");
3718 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3719 app.info.seinfo, app.info.sourceDir, startResult.pid);
3720 } catch (RemoteException ex) {
3724 if (app.persistent) {
3725 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3728 checkTime(startTime, "startProcess: building log message");
3729 StringBuilder buf = mStringBuilder;
3731 buf.append("Start proc ");
3732 buf.append(startResult.pid);
3734 buf.append(app.processName);
3736 UserHandle.formatUid(buf, uid);
3737 if (!isActivityProcess) {
3739 buf.append(entryPoint);
3742 buf.append(" for ");
3743 buf.append(hostingType);
3744 if (hostingNameStr != null) {
3746 buf.append(hostingNameStr);
3748 Slog.i(TAG, buf.toString());
3749 app.setPid(startResult.pid);
3750 app.usingWrapper = startResult.usingWrapper;
3751 app.removed = false;
3753 app.killedByAm = false;
3754 checkTime(startTime, "startProcess: starting to update pids map");
3755 synchronized (mPidsSelfLocked) {
3756 this.mPidsSelfLocked.put(startResult.pid, app);
3757 if (isActivityProcess) {
3758 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3760 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3761 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3764 checkTime(startTime, "startProcess: done updating pids map");
3765 } catch (RuntimeException e) {
3766 Slog.e(TAG, "Failure starting process " + app.processName, e);
3768 // Something went very wrong while trying to start this process; one
3769 // common case is when the package is frozen due to an active
3770 // upgrade. To recover, clean up any active bookkeeping related to
3771 // starting this process. (We already invoked this method once when
3772 // the package was initially frozen through KILL_APPLICATION_MSG, so
3773 // it doesn't hurt to use it again.)
3774 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3775 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3779 void updateUsageStats(ActivityRecord component, boolean resumed) {
3780 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3781 "updateUsageStats: comp=" + component + "res=" + resumed);
3782 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3784 if (mUsageStatsService != null) {
3785 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3786 UsageEvents.Event.MOVE_TO_FOREGROUND);
3788 synchronized (stats) {
3789 stats.noteActivityResumedLocked(component.app.uid);
3792 if (mUsageStatsService != null) {
3793 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3794 UsageEvents.Event.MOVE_TO_BACKGROUND);
3796 synchronized (stats) {
3797 stats.noteActivityPausedLocked(component.app.uid);
3802 Intent getHomeIntent() {
3803 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3804 intent.setComponent(mTopComponent);
3805 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3806 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3807 intent.addCategory(Intent.CATEGORY_HOME);
3812 boolean startHomeActivityLocked(int userId, String reason) {
3813 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3814 && mTopAction == null) {
3815 // We are running in factory test mode, but unable to find
3816 // the factory test app, so just sit around displaying the
3817 // error message and don't try to start anything.
3820 Intent intent = getHomeIntent();
3821 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3822 if (aInfo != null) {
3823 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3824 // Don't do this if the home app is currently being
3826 aInfo = new ActivityInfo(aInfo);
3827 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3828 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3829 aInfo.applicationInfo.uid, true);
3830 if (app == null || app.instrumentationClass == null) {
3831 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3832 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3835 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3841 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3842 ActivityInfo ai = null;
3843 ComponentName comp = intent.getComponent();
3847 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3849 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3851 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3855 ai = info.activityInfo;
3858 } catch (RemoteException e) {
3866 * Starts the "new version setup screen" if appropriate.
3868 void startSetupActivityLocked() {
3869 // Only do this once per boot.
3870 if (mCheckedForSetup) {
3874 // We will show this screen if the current one is a different
3875 // version than the last one shown, and we are not running in
3876 // low-level factory test mode.
3877 final ContentResolver resolver = mContext.getContentResolver();
3878 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3879 Settings.Global.getInt(resolver,
3880 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3881 mCheckedForSetup = true;
3883 // See if we should be showing the platform update setup UI.
3884 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3885 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3886 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3887 if (!ris.isEmpty()) {
3888 final ResolveInfo ri = ris.get(0);
3889 String vers = ri.activityInfo.metaData != null
3890 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3892 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3893 vers = ri.activityInfo.applicationInfo.metaData.getString(
3894 Intent.METADATA_SETUP_VERSION);
3896 String lastVers = Settings.Secure.getString(
3897 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3898 if (vers != null && !vers.equals(lastVers)) {
3899 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3900 intent.setComponent(new ComponentName(
3901 ri.activityInfo.packageName, ri.activityInfo.name));
3902 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3903 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3904 null, 0, 0, 0, null, false, false, null, null, null);
3910 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3911 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3914 void enforceNotIsolatedCaller(String caller) {
3915 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3916 throw new SecurityException("Isolated process not allowed to call " + caller);
3920 void enforceShellRestriction(String restriction, int userHandle) {
3921 if (Binder.getCallingUid() == Process.SHELL_UID) {
3922 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3923 throw new SecurityException("Shell does not have permission to access user "
3930 public int getFrontActivityScreenCompatMode() {
3931 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3932 synchronized (this) {
3933 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3938 public void setFrontActivityScreenCompatMode(int mode) {
3939 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3940 "setFrontActivityScreenCompatMode");
3941 synchronized (this) {
3942 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3947 public int getPackageScreenCompatMode(String packageName) {
3948 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3949 synchronized (this) {
3950 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3955 public void setPackageScreenCompatMode(String packageName, int mode) {
3956 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3957 "setPackageScreenCompatMode");
3958 synchronized (this) {
3959 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3964 public boolean getPackageAskScreenCompat(String packageName) {
3965 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3966 synchronized (this) {
3967 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3972 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3973 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3974 "setPackageAskScreenCompat");
3975 synchronized (this) {
3976 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3980 private boolean hasUsageStatsPermission(String callingPackage) {
3981 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3982 Binder.getCallingUid(), callingPackage);
3983 if (mode == AppOpsManager.MODE_DEFAULT) {
3984 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3985 == PackageManager.PERMISSION_GRANTED;
3987 return mode == AppOpsManager.MODE_ALLOWED;
3991 public int getPackageProcessState(String packageName, String callingPackage) {
3992 if (!hasUsageStatsPermission(callingPackage)) {
3993 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3994 "getPackageProcessState");
3997 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3998 synchronized (this) {
3999 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4000 final ProcessRecord proc = mLruProcesses.get(i);
4001 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4002 || procState > proc.setProcState) {
4003 boolean found = false;
4004 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4005 if (proc.pkgList.keyAt(j).equals(packageName)) {
4006 procState = proc.setProcState;
4010 if (proc.pkgDeps != null && !found) {
4011 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4012 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4013 procState = proc.setProcState;
4025 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4026 synchronized (this) {
4027 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4031 if (app.trimMemoryLevel < level && app.thread != null &&
4032 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4033 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4035 app.thread.scheduleTrimMemory(level);
4036 app.trimMemoryLevel = level;
4038 } catch (RemoteException e) {
4039 // Fallthrough to failure case.
4046 private void dispatchProcessesChanged() {
4048 synchronized (this) {
4049 N = mPendingProcessChanges.size();
4050 if (mActiveProcessChanges.length < N) {
4051 mActiveProcessChanges = new ProcessChangeItem[N];
4053 mPendingProcessChanges.toArray(mActiveProcessChanges);
4054 mPendingProcessChanges.clear();
4055 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4056 "*** Delivering " + N + " process changes");
4059 int i = mProcessObservers.beginBroadcast();
4062 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4063 if (observer != null) {
4065 for (int j=0; j<N; j++) {
4066 ProcessChangeItem item = mActiveProcessChanges[j];
4067 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4068 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4069 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4070 + item.uid + ": " + item.foregroundActivities);
4071 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4072 item.foregroundActivities);
4074 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4075 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4076 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4077 + ": " + item.processState);
4078 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4081 } catch (RemoteException e) {
4085 mProcessObservers.finishBroadcast();
4087 synchronized (this) {
4088 for (int j=0; j<N; j++) {
4089 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4094 private void dispatchProcessDied(int pid, int uid) {
4095 int i = mProcessObservers.beginBroadcast();
4098 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4099 if (observer != null) {
4101 observer.onProcessDied(pid, uid);
4102 } catch (RemoteException e) {
4106 mProcessObservers.finishBroadcast();
4109 private void dispatchUidsChanged() {
4111 synchronized (this) {
4112 N = mPendingUidChanges.size();
4113 if (mActiveUidChanges.length < N) {
4114 mActiveUidChanges = new UidRecord.ChangeItem[N];
4116 for (int i=0; i<N; i++) {
4117 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4118 mActiveUidChanges[i] = change;
4119 if (change.uidRecord != null) {
4120 change.uidRecord.pendingChange = null;
4121 change.uidRecord = null;
4124 mPendingUidChanges.clear();
4125 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4126 "*** Delivering " + N + " uid changes");
4129 if (mLocalPowerManager != null) {
4130 for (int j=0; j<N; j++) {
4131 UidRecord.ChangeItem item = mActiveUidChanges[j];
4132 if (item.change == UidRecord.CHANGE_GONE
4133 || item.change == UidRecord.CHANGE_GONE_IDLE) {
4134 mLocalPowerManager.uidGone(item.uid);
4136 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4141 int i = mUidObservers.beginBroadcast();
4144 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4145 final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4146 if (observer != null) {
4148 for (int j=0; j<N; j++) {
4149 UidRecord.ChangeItem item = mActiveUidChanges[j];
4150 final int change = item.change;
4151 UidRecord validateUid = null;
4152 if (VALIDATE_UID_STATES && i == 0) {
4153 validateUid = mValidateUids.get(item.uid);
4154 if (validateUid == null && change != UidRecord.CHANGE_GONE
4155 && change != UidRecord.CHANGE_GONE_IDLE) {
4156 validateUid = new UidRecord(item.uid);
4157 mValidateUids.put(item.uid, validateUid);
4160 if (change == UidRecord.CHANGE_IDLE
4161 || change == UidRecord.CHANGE_GONE_IDLE) {
4162 if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4163 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4164 "UID idle uid=" + item.uid);
4165 observer.onUidIdle(item.uid);
4167 if (VALIDATE_UID_STATES && i == 0) {
4168 if (validateUid != null) {
4169 validateUid.idle = true;
4172 } else if (change == UidRecord.CHANGE_ACTIVE) {
4173 if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4174 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4175 "UID active uid=" + item.uid);
4176 observer.onUidActive(item.uid);
4178 if (VALIDATE_UID_STATES && i == 0) {
4179 validateUid.idle = false;
4182 if (change == UidRecord.CHANGE_GONE
4183 || change == UidRecord.CHANGE_GONE_IDLE) {
4184 if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4185 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4186 "UID gone uid=" + item.uid);
4187 observer.onUidGone(item.uid);
4189 if (VALIDATE_UID_STATES && i == 0) {
4190 if (validateUid != null) {
4191 mValidateUids.remove(item.uid);
4195 if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4196 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4197 "UID CHANGED uid=" + item.uid
4198 + ": " + item.processState);
4199 observer.onUidStateChanged(item.uid, item.processState);
4201 if (VALIDATE_UID_STATES && i == 0) {
4202 validateUid.curProcState = validateUid.setProcState
4203 = item.processState;
4207 } catch (RemoteException e) {
4211 mUidObservers.finishBroadcast();
4213 synchronized (this) {
4214 for (int j=0; j<N; j++) {
4215 mAvailUidChanges.add(mActiveUidChanges[j]);
4221 public final int startActivity(IApplicationThread caller, String callingPackage,
4222 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4223 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4224 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4225 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4226 UserHandle.getCallingUserId());
4229 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4230 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4231 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4232 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4233 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4235 // TODO: Switch to user app stacks here.
4236 String mimeType = intent.getType();
4237 final Uri data = intent.getData();
4238 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4239 mimeType = getProviderMimeType(data, userId);
4241 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4243 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4244 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4245 null, 0, 0, null, null, null, null, false, userId, container, null);
4249 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4250 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4251 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4252 enforceNotIsolatedCaller("startActivity");
4253 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4254 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4255 // TODO: Switch to user app stacks here.
4256 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4257 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4258 profilerInfo, null, null, bOptions, false, userId, null, null);
4262 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4263 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4264 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4267 // This is very dangerous -- it allows you to perform a start activity (including
4268 // permission grants) as any app that may launch one of your own activities. So
4269 // we will only allow this to be done from activities that are part of the core framework,
4270 // and then only when they are running as the system.
4271 final ActivityRecord sourceRecord;
4272 final int targetUid;
4273 final String targetPackage;
4274 synchronized (this) {
4275 if (resultTo == null) {
4276 throw new SecurityException("Must be called from an activity");
4278 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4279 if (sourceRecord == null) {
4280 throw new SecurityException("Called with bad activity token: " + resultTo);
4282 if (!sourceRecord.info.packageName.equals("android")) {
4283 throw new SecurityException(
4284 "Must be called from an activity that is declared in the android package");
4286 if (sourceRecord.app == null) {
4287 throw new SecurityException("Called without a process attached to activity");
4289 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4290 // This is still okay, as long as this activity is running under the
4291 // uid of the original calling activity.
4292 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4293 throw new SecurityException(
4294 "Calling activity in uid " + sourceRecord.app.uid
4295 + " must be system uid or original calling uid "
4296 + sourceRecord.launchedFromUid);
4299 if (ignoreTargetSecurity) {
4300 if (intent.getComponent() == null) {
4301 throw new SecurityException(
4302 "Component must be specified with ignoreTargetSecurity");
4304 if (intent.getSelector() != null) {
4305 throw new SecurityException(
4306 "Selector not allowed with ignoreTargetSecurity");
4309 targetUid = sourceRecord.launchedFromUid;
4310 targetPackage = sourceRecord.launchedFromPackage;
4313 if (userId == UserHandle.USER_NULL) {
4314 userId = UserHandle.getUserId(sourceRecord.app.uid);
4317 // TODO: Switch to user app stacks here.
4319 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4320 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4321 null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4323 } catch (SecurityException e) {
4324 // XXX need to figure out how to propagate to original app.
4325 // A SecurityException here is generally actually a fault of the original
4326 // calling activity (such as a fairly granting permissions), so propagate it
4329 StringBuilder msg = new StringBuilder();
4330 msg.append("While launching");
4331 msg.append(intent.toString());
4333 msg.append(e.getMessage());
4340 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4341 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4342 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4343 enforceNotIsolatedCaller("startActivityAndWait");
4344 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4345 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4346 WaitResult res = new WaitResult();
4347 // TODO: Switch to user app stacks here.
4348 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4349 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4350 bOptions, false, userId, null, null);
4355 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4356 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4357 int startFlags, Configuration config, Bundle bOptions, int userId) {
4358 enforceNotIsolatedCaller("startActivityWithConfig");
4359 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4360 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4361 // TODO: Switch to user app stacks here.
4362 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4363 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4364 null, null, config, bOptions, false, userId, null, null);
4369 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4370 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4371 int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4372 throws TransactionTooLargeException {
4373 enforceNotIsolatedCaller("startActivityIntentSender");
4374 // Refuse possible leaked file descriptors
4375 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4376 throw new IllegalArgumentException("File descriptors passed in Intent");
4379 IIntentSender sender = intent.getTarget();
4380 if (!(sender instanceof PendingIntentRecord)) {
4381 throw new IllegalArgumentException("Bad PendingIntent object");
4384 PendingIntentRecord pir = (PendingIntentRecord)sender;
4386 synchronized (this) {
4387 // If this is coming from the currently resumed activity, it is
4388 // effectively saying that app switches are allowed at this point.
4389 final ActivityStack stack = getFocusedStack();
4390 if (stack.mResumedActivity != null &&
4391 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4392 mAppSwitchesAllowedTime = 0;
4395 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4396 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4401 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4402 Intent intent, String resolvedType, IVoiceInteractionSession session,
4403 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4404 Bundle bOptions, int userId) {
4405 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4406 != PackageManager.PERMISSION_GRANTED) {
4407 String msg = "Permission Denial: startVoiceActivity() from pid="
4408 + Binder.getCallingPid()
4409 + ", uid=" + Binder.getCallingUid()
4410 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4412 throw new SecurityException(msg);
4414 if (session == null || interactor == null) {
4415 throw new NullPointerException("null session or interactor");
4417 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4418 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4419 // TODO: Switch to user app stacks here.
4420 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4421 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4422 null, bOptions, false, userId, null, null);
4426 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4427 throws RemoteException {
4428 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4429 synchronized (this) {
4430 ActivityRecord activity = getFocusedStack().topActivity();
4431 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4432 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4434 if (mRunningVoice != null || activity.task.voiceSession != null
4435 || activity.voiceSession != null) {
4436 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4439 if (activity.pendingVoiceInteractionStart) {
4440 Slog.w(TAG, "Pending start of voice interaction already.");
4443 activity.pendingVoiceInteractionStart = true;
4445 LocalServices.getService(VoiceInteractionManagerInternal.class)
4446 .startLocalVoiceInteraction(callingActivity, options);
4450 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4451 LocalServices.getService(VoiceInteractionManagerInternal.class)
4452 .stopLocalVoiceInteraction(callingActivity);
4456 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4457 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4458 .supportsLocalVoiceInteraction();
4461 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4462 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4463 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4464 if (activityToCallback == null) return;
4465 activityToCallback.setVoiceSessionLocked(voiceSession);
4467 // Inform the activity
4469 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4471 long token = Binder.clearCallingIdentity();
4473 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4475 Binder.restoreCallingIdentity(token);
4477 // TODO: VI Should we cache the activity so that it's easier to find later
4478 // rather than scan through all the stacks and activities?
4479 } catch (RemoteException re) {
4480 activityToCallback.clearVoiceSessionLocked();
4481 // TODO: VI Should this terminate the voice session?
4486 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4487 synchronized (this) {
4488 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4490 mVoiceWakeLock.acquire();
4492 mVoiceWakeLock.release();
4499 public boolean startNextMatchingActivity(IBinder callingActivity,
4500 Intent intent, Bundle bOptions) {
4501 // Refuse possible leaked file descriptors
4502 if (intent != null && intent.hasFileDescriptors() == true) {
4503 throw new IllegalArgumentException("File descriptors passed in Intent");
4505 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4507 synchronized (this) {
4508 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4510 ActivityOptions.abort(options);
4513 if (r.app == null || r.app.thread == null) {
4514 // The caller is not running... d'oh!
4515 ActivityOptions.abort(options);
4518 intent = new Intent(intent);
4519 // The caller is not allowed to change the data.
4520 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4521 // And we are resetting to find the next component...
4522 intent.setComponent(null);
4524 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4526 ActivityInfo aInfo = null;
4528 List<ResolveInfo> resolves =
4529 AppGlobals.getPackageManager().queryIntentActivities(
4530 intent, r.resolvedType,
4531 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4532 UserHandle.getCallingUserId()).getList();
4534 // Look for the original activity in the list...
4535 final int N = resolves != null ? resolves.size() : 0;
4536 for (int i=0; i<N; i++) {
4537 ResolveInfo rInfo = resolves.get(i);
4538 if (rInfo.activityInfo.packageName.equals(r.packageName)
4539 && rInfo.activityInfo.name.equals(r.info.name)) {
4540 // We found the current one... the next matching is
4544 aInfo = resolves.get(i).activityInfo;
4547 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4548 + "/" + r.info.name);
4549 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4550 ? "null" : aInfo.packageName + "/" + aInfo.name));
4555 } catch (RemoteException e) {
4558 if (aInfo == null) {
4559 // Nobody who is next!
4560 ActivityOptions.abort(options);
4561 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4565 intent.setComponent(new ComponentName(
4566 aInfo.applicationInfo.packageName, aInfo.name));
4567 intent.setFlags(intent.getFlags()&~(
4568 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4569 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4570 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4571 Intent.FLAG_ACTIVITY_NEW_TASK));
4573 // Okay now we need to start the new activity, replacing the
4574 // currently running activity. This is a little tricky because
4575 // we want to start the new one as if the current one is finished,
4576 // but not finish the current one first so that there is no flicker.
4578 final boolean wasFinishing = r.finishing;
4581 // Propagate reply information over to the new activity.
4582 final ActivityRecord resultTo = r.resultTo;
4583 final String resultWho = r.resultWho;
4584 final int requestCode = r.requestCode;
4586 if (resultTo != null) {
4587 resultTo.removeResultsLocked(r, resultWho, requestCode);
4590 final long origId = Binder.clearCallingIdentity();
4591 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4592 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4593 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4594 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4595 false, false, null, null, null);
4596 Binder.restoreCallingIdentity(origId);
4598 r.finishing = wasFinishing;
4599 if (res != ActivityManager.START_SUCCESS) {
4607 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4608 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4609 String msg = "Permission Denial: startActivityFromRecents called without " +
4610 START_TASKS_FROM_RECENTS;
4612 throw new SecurityException(msg);
4614 final long origId = Binder.clearCallingIdentity();
4616 synchronized (this) {
4617 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4620 Binder.restoreCallingIdentity(origId);
4624 final int startActivityInPackage(int uid, String callingPackage,
4625 Intent intent, String resolvedType, IBinder resultTo,
4626 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4627 IActivityContainer container, TaskRecord inTask) {
4629 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4630 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4632 // TODO: Switch to user app stacks here.
4633 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4634 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4635 null, null, null, bOptions, false, userId, container, inTask);
4640 public final int startActivities(IApplicationThread caller, String callingPackage,
4641 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4643 enforceNotIsolatedCaller("startActivities");
4644 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4645 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4646 // TODO: Switch to user app stacks here.
4647 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4648 resolvedTypes, resultTo, bOptions, userId);
4652 final int startActivitiesInPackage(int uid, String callingPackage,
4653 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4654 Bundle bOptions, int userId) {
4656 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4657 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4658 // TODO: Switch to user app stacks here.
4659 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4660 resultTo, bOptions, userId);
4665 public void reportActivityFullyDrawn(IBinder token) {
4666 synchronized (this) {
4667 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4671 r.reportFullyDrawnLocked();
4676 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4677 synchronized (this) {
4678 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4682 TaskRecord task = r.task;
4683 if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4684 // Fixed screen orientation isn't supported when activities aren't in full screen
4688 final long origId = Binder.clearCallingIdentity();
4689 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4690 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4691 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4692 if (config != null) {
4693 r.frozenBeforeDestroy = true;
4694 if (!updateConfigurationLocked(config, r, false)) {
4695 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4698 Binder.restoreCallingIdentity(origId);
4703 public int getRequestedOrientation(IBinder token) {
4704 synchronized (this) {
4705 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4707 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4709 return mWindowManager.getAppOrientation(r.appToken);
4714 * This is the internal entry point for handling Activity.finish().
4716 * @param token The Binder token referencing the Activity we want to finish.
4717 * @param resultCode Result code, if any, from this Activity.
4718 * @param resultData Result data (Intent), if any, from this Activity.
4719 * @param finishTask Whether to finish the task associated with this Activity.
4721 * @return Returns true if the activity successfully finished, or false if it is still running.
4724 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4726 // Refuse possible leaked file descriptors
4727 if (resultData != null && resultData.hasFileDescriptors() == true) {
4728 throw new IllegalArgumentException("File descriptors passed in Intent");
4731 synchronized(this) {
4732 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4736 // Keep track of the root activity of the task before we finish it
4737 TaskRecord tr = r.task;
4738 ActivityRecord rootR = tr.getRootActivity();
4739 if (rootR == null) {
4740 Slog.w(TAG, "Finishing task with all activities already finished");
4742 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4744 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4745 mStackSupervisor.isLastLockedTask(tr)) {
4746 Slog.i(TAG, "Not finishing task in lock task mode");
4747 mStackSupervisor.showLockTaskToast();
4750 if (mController != null) {
4751 // Find the first activity that is not finishing.
4752 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4754 // ask watcher if this is allowed
4755 boolean resumeOK = true;
4757 resumeOK = mController.activityResuming(next.packageName);
4758 } catch (RemoteException e) {
4760 Watchdog.getInstance().setActivityController(null);
4764 Slog.i(TAG, "Not finishing activity because controller resumed");
4769 final long origId = Binder.clearCallingIdentity();
4772 final boolean finishWithRootActivity =
4773 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4774 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4775 || (finishWithRootActivity && r == rootR)) {
4776 // If requested, remove the task that is associated to this activity only if it
4777 // was the root activity in the task. The result code and data is ignored
4778 // because we don't support returning them across task boundaries. Also, to
4779 // keep backwards compatibility we remove the task from recents when finishing
4780 // task with root activity.
4781 res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4783 Slog.i(TAG, "Removing task failed to finish activity");
4786 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4787 resultData, "app-request", true);
4789 Slog.i(TAG, "Failed to finish by app-request");
4794 Binder.restoreCallingIdentity(origId);
4800 public final void finishHeavyWeightApp() {
4801 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4802 != PackageManager.PERMISSION_GRANTED) {
4803 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4804 + Binder.getCallingPid()
4805 + ", uid=" + Binder.getCallingUid()
4806 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4808 throw new SecurityException(msg);
4811 synchronized(this) {
4812 if (mHeavyWeightProcess == null) {
4816 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4817 for (int i = 0; i < activities.size(); i++) {
4818 ActivityRecord r = activities.get(i);
4819 if (!r.finishing && r.isInStackLocked()) {
4820 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4821 null, "finish-heavy", true);
4825 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4826 mHeavyWeightProcess.userId, 0));
4827 mHeavyWeightProcess = null;
4832 public void crashApplication(int uid, int initialPid, String packageName,
4834 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4835 != PackageManager.PERMISSION_GRANTED) {
4836 String msg = "Permission Denial: crashApplication() from pid="
4837 + Binder.getCallingPid()
4838 + ", uid=" + Binder.getCallingUid()
4839 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4841 throw new SecurityException(msg);
4844 synchronized(this) {
4845 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4850 public final void finishSubActivity(IBinder token, String resultWho,
4852 synchronized(this) {
4853 final long origId = Binder.clearCallingIdentity();
4854 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4856 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4858 Binder.restoreCallingIdentity(origId);
4863 public boolean finishActivityAffinity(IBinder token) {
4864 synchronized(this) {
4865 final long origId = Binder.clearCallingIdentity();
4867 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4872 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4874 final TaskRecord task = r.task;
4875 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4876 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4877 mStackSupervisor.showLockTaskToast();
4880 return task.stack.finishActivityAffinityLocked(r);
4882 Binder.restoreCallingIdentity(origId);
4888 public void finishVoiceTask(IVoiceInteractionSession session) {
4889 synchronized (this) {
4890 final long origId = Binder.clearCallingIdentity();
4892 // TODO: VI Consider treating local voice interactions and voice tasks
4894 mStackSupervisor.finishVoiceTask(session);
4896 Binder.restoreCallingIdentity(origId);
4903 public boolean releaseActivityInstance(IBinder token) {
4904 synchronized(this) {
4905 final long origId = Binder.clearCallingIdentity();
4907 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4911 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4913 Binder.restoreCallingIdentity(origId);
4919 public void releaseSomeActivities(IApplicationThread appInt) {
4920 synchronized(this) {
4921 final long origId = Binder.clearCallingIdentity();
4923 ProcessRecord app = getRecordForAppLocked(appInt);
4924 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4926 Binder.restoreCallingIdentity(origId);
4932 public boolean willActivityBeVisible(IBinder token) {
4933 synchronized(this) {
4934 ActivityStack stack = ActivityRecord.getStackLocked(token);
4935 if (stack != null) {
4936 return stack.willActivityBeVisibleLocked(token);
4943 public void overridePendingTransition(IBinder token, String packageName,
4944 int enterAnim, int exitAnim) {
4945 synchronized(this) {
4946 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4951 final long origId = Binder.clearCallingIdentity();
4953 if (self.state == ActivityState.RESUMED
4954 || self.state == ActivityState.PAUSING) {
4955 mWindowManager.overridePendingAppTransition(packageName,
4956 enterAnim, exitAnim, null);
4959 Binder.restoreCallingIdentity(origId);
4964 * Main function for removing an existing process from the activity manager
4965 * as a result of that process going away. Clears out all connections
4968 private final void handleAppDiedLocked(ProcessRecord app,
4969 boolean restarting, boolean allowRestart) {
4971 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4972 if (!kept && !restarting) {
4973 removeLruProcessLocked(app);
4975 ProcessList.remove(pid);
4979 if (mProfileProc == app) {
4980 clearProfilerLocked();
4983 // Remove this application's activities from active lists.
4984 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4986 app.activities.clear();
4988 if (app.instrumentationClass != null) {
4989 Slog.w(TAG, "Crash of app " + app.processName
4990 + " running instrumentation " + app.instrumentationClass);
4991 Bundle info = new Bundle();
4992 info.putString("shortMsg", "Process crashed.");
4993 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4996 if (!restarting && hasVisibleActivities
4997 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4998 // If there was nothing to resume, and we are not already restarting this process, but
4999 // there is a visible activity that is hosted by the process... then make sure all
5000 // visible activities are running, taking care of restarting this process.
5001 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5005 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5006 IBinder threadBinder = thread.asBinder();
5007 // Find the application record.
5008 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5009 ProcessRecord rec = mLruProcesses.get(i);
5010 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5017 final ProcessRecord getRecordForAppLocked(
5018 IApplicationThread thread) {
5019 if (thread == null) {
5023 int appIndex = getLRURecordIndexForAppLocked(thread);
5024 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5027 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5028 // If there are no longer any background processes running,
5029 // and the app that died was not running instrumentation,
5030 // then tell everyone we are now low on memory.
5031 boolean haveBg = false;
5032 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5033 ProcessRecord rec = mLruProcesses.get(i);
5034 if (rec.thread != null
5035 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5042 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5044 long now = SystemClock.uptimeMillis();
5045 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5048 mLastMemUsageReportTime = now;
5051 final ArrayList<ProcessMemInfo> memInfos
5052 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5053 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5054 long now = SystemClock.uptimeMillis();
5055 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5056 ProcessRecord rec = mLruProcesses.get(i);
5057 if (rec == dyingProc || rec.thread == null) {
5061 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5062 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5064 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5065 // The low memory report is overriding any current
5066 // state for a GC request. Make sure to do
5067 // heavy/important/visible/foreground processes first.
5068 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5069 rec.lastRequestedGc = 0;
5071 rec.lastRequestedGc = rec.lastLowMemory;
5073 rec.reportLowMemory = true;
5074 rec.lastLowMemory = now;
5075 mProcessesToGc.remove(rec);
5076 addProcessToGcListLocked(rec);
5080 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5081 mHandler.sendMessage(msg);
5083 scheduleAppGcsLocked();
5087 final void appDiedLocked(ProcessRecord app) {
5088 appDiedLocked(app, app.pid, app.thread, false);
5091 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5092 boolean fromBinderDied) {
5093 // First check if this ProcessRecord is actually active for the pid.
5094 synchronized (mPidsSelfLocked) {
5095 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5096 if (curProc != app) {
5097 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5102 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5103 synchronized (stats) {
5104 stats.noteProcessDiedLocked(app.info.uid, pid);
5108 if (!fromBinderDied) {
5109 Process.killProcessQuiet(pid);
5111 killProcessGroup(app.uid, pid);
5115 // Clean up already done if the process has been re-started.
5116 if (app.pid == pid && app.thread != null &&
5117 app.thread.asBinder() == thread.asBinder()) {
5118 boolean doLowMem = app.instrumentationClass == null;
5119 boolean doOomAdj = doLowMem;
5120 if (!app.killedByAm) {
5121 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5123 mAllowLowerMemLevel = true;
5125 // Note that we always want to do oom adj to update our state with the
5126 // new number of procs.
5127 mAllowLowerMemLevel = false;
5130 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5131 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5132 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5133 handleAppDiedLocked(app, false, true);
5136 updateOomAdjLocked();
5139 doLowMemReportIfNeededLocked(app);
5141 } else if (app.pid != pid) {
5142 // A new process has already been started.
5143 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5144 + ") has died and restarted (pid " + app.pid + ").");
5145 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5146 } else if (DEBUG_PROCESSES) {
5147 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5148 + thread.asBinder());
5153 * If a stack trace dump file is configured, dump process stack traces.
5154 * @param clearTraces causes the dump file to be erased prior to the new
5155 * traces being written, if true; when false, the new traces will be
5156 * appended to any existing file content.
5157 * @param firstPids of dalvik VM processes to dump stack traces for first
5158 * @param lastPids of dalvik VM processes to dump stack traces for last
5159 * @param nativeProcs optional list of native process names to dump stack crawls
5160 * @return file containing stack traces, or null if no dump file is configured
5162 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5163 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5164 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5165 if (tracesPath == null || tracesPath.length() == 0) {
5169 File tracesFile = new File(tracesPath);
5171 if (clearTraces && tracesFile.exists()) tracesFile.delete();
5172 tracesFile.createNewFile();
5173 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5174 } catch (IOException e) {
5175 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5179 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5183 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5184 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5185 // Use a FileObserver to detect when traces finish writing.
5186 // The order of traces is considered important to maintain for legibility.
5187 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5189 public synchronized void onEvent(int event, String path) { notify(); }
5193 observer.startWatching();
5195 // First collect all of the stacks of the most important pids.
5196 if (firstPids != null) {
5198 int num = firstPids.size();
5199 for (int i = 0; i < num; i++) {
5200 synchronized (observer) {
5201 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5202 + firstPids.get(i));
5203 final long sime = SystemClock.elapsedRealtime();
5204 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5205 observer.wait(1000); // Wait for write-close, give up after 1 sec
5206 if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5207 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5210 } catch (InterruptedException e) {
5215 // Next collect the stacks of the native pids
5216 if (nativeProcs != null) {
5217 int[] pids = Process.getPidsForCommands(nativeProcs);
5219 for (int pid : pids) {
5220 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5221 final long sime = SystemClock.elapsedRealtime();
5222 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5223 if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5224 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5229 // Lastly, measure CPU usage.
5230 if (processCpuTracker != null) {
5231 processCpuTracker.init();
5233 processCpuTracker.update();
5235 synchronized (processCpuTracker) {
5236 processCpuTracker.wait(500); // measure over 1/2 second.
5238 } catch (InterruptedException e) {
5240 processCpuTracker.update();
5242 // We'll take the stack crawls of just the top apps using CPU.
5243 final int N = processCpuTracker.countWorkingStats();
5245 for (int i=0; i<N && numProcs<5; i++) {
5246 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5247 if (lastPids.indexOfKey(stats.pid) >= 0) {
5250 synchronized (observer) {
5251 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5253 final long stime = SystemClock.elapsedRealtime();
5254 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5255 observer.wait(1000); // Wait for write-close, give up after 1 sec
5256 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5257 + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5259 } catch (InterruptedException e) {
5262 } else if (DEBUG_ANR) {
5263 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5269 observer.stopWatching();
5273 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5274 if (true || IS_USER_BUILD) {
5277 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5278 if (tracesPath == null || tracesPath.length() == 0) {
5282 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5283 StrictMode.allowThreadDiskWrites();
5285 final File tracesFile = new File(tracesPath);
5286 final File tracesDir = tracesFile.getParentFile();
5287 final File tracesTmp = new File(tracesDir, "__tmp__");
5289 if (tracesFile.exists()) {
5291 tracesFile.renameTo(tracesTmp);
5293 StringBuilder sb = new StringBuilder();
5294 Time tobj = new Time();
5295 tobj.set(System.currentTimeMillis());
5296 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5298 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5299 sb.append(" since ");
5301 FileOutputStream fos = new FileOutputStream(tracesFile);
5302 fos.write(sb.toString().getBytes());
5304 fos.write("\n*** No application process!".getBytes());
5307 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5308 } catch (IOException e) {
5309 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5314 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5315 firstPids.add(app.pid);
5316 dumpStackTraces(tracesPath, firstPids, null, null, null);
5319 File lastTracesFile = null;
5320 File curTracesFile = null;
5321 for (int i=9; i>=0; i--) {
5322 String name = String.format(Locale.US, "slow%02d.txt", i);
5323 curTracesFile = new File(tracesDir, name);
5324 if (curTracesFile.exists()) {
5325 if (lastTracesFile != null) {
5326 curTracesFile.renameTo(lastTracesFile);
5328 curTracesFile.delete();
5331 lastTracesFile = curTracesFile;
5333 tracesFile.renameTo(curTracesFile);
5334 if (tracesTmp.exists()) {
5335 tracesTmp.renameTo(tracesFile);
5338 StrictMode.setThreadPolicy(oldPolicy);
5342 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5343 if (!mLaunchWarningShown) {
5344 mLaunchWarningShown = true;
5345 mUiHandler.post(new Runnable() {
5348 synchronized (ActivityManagerService.this) {
5349 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5351 mUiHandler.postDelayed(new Runnable() {
5354 synchronized (ActivityManagerService.this) {
5356 mLaunchWarningShown = false;
5367 public boolean clearApplicationUserData(final String packageName,
5368 final IPackageDataObserver observer, int userId) {
5369 enforceNotIsolatedCaller("clearApplicationUserData");
5370 int uid = Binder.getCallingUid();
5371 int pid = Binder.getCallingPid();
5372 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5373 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5375 final DevicePolicyManagerInternal dpmi = LocalServices
5376 .getService(DevicePolicyManagerInternal.class);
5377 if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5378 throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5381 long callingId = Binder.clearCallingIdentity();
5383 IPackageManager pm = AppGlobals.getPackageManager();
5385 synchronized(this) {
5387 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5388 } catch (RemoteException e) {
5391 Slog.w(TAG, "Invalid packageName: " + packageName);
5392 if (observer != null) {
5394 observer.onRemoveCompleted(packageName, false);
5395 } catch (RemoteException e) {
5396 Slog.i(TAG, "Observer no longer exists.");
5401 if (uid == pkgUid || checkComponentPermission(
5402 android.Manifest.permission.CLEAR_APP_USER_DATA,
5404 == PackageManager.PERMISSION_GRANTED) {
5405 forceStopPackageLocked(packageName, pkgUid, "clear data");
5407 throw new SecurityException("PID " + pid + " does not have permission "
5408 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5409 + " of package " + packageName);
5412 // Remove all tasks match the cleared application package and user
5413 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5414 final TaskRecord tr = mRecentTasks.get(i);
5415 final String taskPackageName =
5416 tr.getBaseIntent().getComponent().getPackageName();
5417 if (tr.userId != userId) continue;
5418 if (!taskPackageName.equals(packageName)) continue;
5419 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5423 final int pkgUidF = pkgUid;
5424 final int userIdF = userId;
5425 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5427 public void onRemoveCompleted(String packageName, boolean succeeded)
5428 throws RemoteException {
5429 synchronized (ActivityManagerService.this) {
5430 finishForceStopPackageLocked(packageName, pkgUidF);
5433 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5434 Uri.fromParts("package", packageName, null));
5435 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5436 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5437 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5438 null, null, 0, null, null, null, null, false, false, userIdF);
5440 if (observer != null) {
5441 observer.onRemoveCompleted(packageName, succeeded);
5447 // Clear application user data
5448 pm.clearApplicationUserData(packageName, localObserver, userId);
5450 synchronized(this) {
5451 // Remove all permissions granted from/to this package
5452 removeUriPermissionsForPackageLocked(packageName, userId, true);
5455 // Remove all zen rules created by this package; revoke it's zen access.
5456 INotificationManager inm = NotificationManager.getService();
5457 inm.removeAutomaticZenRules(packageName);
5458 inm.setNotificationPolicyAccessGranted(packageName, false);
5460 } catch (RemoteException e) {
5463 Binder.restoreCallingIdentity(callingId);
5469 public void killBackgroundProcesses(final String packageName, int userId) {
5470 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5471 != PackageManager.PERMISSION_GRANTED &&
5472 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5473 != PackageManager.PERMISSION_GRANTED) {
5474 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5475 + Binder.getCallingPid()
5476 + ", uid=" + Binder.getCallingUid()
5477 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5479 throw new SecurityException(msg);
5482 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5483 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5484 long callingId = Binder.clearCallingIdentity();
5486 IPackageManager pm = AppGlobals.getPackageManager();
5487 synchronized(this) {
5490 appId = UserHandle.getAppId(
5491 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5492 } catch (RemoteException e) {
5495 Slog.w(TAG, "Invalid packageName: " + packageName);
5498 killPackageProcessesLocked(packageName, appId, userId,
5499 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5502 Binder.restoreCallingIdentity(callingId);
5507 public void killAllBackgroundProcesses() {
5508 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5509 != PackageManager.PERMISSION_GRANTED) {
5510 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5511 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5512 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5514 throw new SecurityException(msg);
5517 final long callingId = Binder.clearCallingIdentity();
5519 synchronized (this) {
5520 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5521 final int NP = mProcessNames.getMap().size();
5522 for (int ip = 0; ip < NP; ip++) {
5523 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5524 final int NA = apps.size();
5525 for (int ia = 0; ia < NA; ia++) {
5526 final ProcessRecord app = apps.valueAt(ia);
5527 if (app.persistent) {
5528 // We don't kill persistent processes.
5533 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5540 final int N = procs.size();
5541 for (int i = 0; i < N; i++) {
5542 removeProcessLocked(procs.get(i), false, true, "kill all background");
5545 mAllowLowerMemLevel = true;
5547 updateOomAdjLocked();
5548 doLowMemReportIfNeededLocked(null);
5551 Binder.restoreCallingIdentity(callingId);
5556 * Kills all background processes, except those matching any of the
5557 * specified properties.
5559 * @param minTargetSdk the target SDK version at or above which to preserve
5560 * processes, or {@code -1} to ignore the target SDK
5561 * @param maxProcState the process state at or below which to preserve
5562 * processes, or {@code -1} to ignore the process state
5564 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5565 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5566 != PackageManager.PERMISSION_GRANTED) {
5567 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5568 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5569 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5571 throw new SecurityException(msg);
5574 final long callingId = Binder.clearCallingIdentity();
5576 synchronized (this) {
5577 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5578 final int NP = mProcessNames.getMap().size();
5579 for (int ip = 0; ip < NP; ip++) {
5580 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5581 final int NA = apps.size();
5582 for (int ia = 0; ia < NA; ia++) {
5583 final ProcessRecord app = apps.valueAt(ia);
5586 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5587 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5594 final int N = procs.size();
5595 for (int i = 0; i < N; i++) {
5596 removeProcessLocked(procs.get(i), false, true, "kill all background except");
5600 Binder.restoreCallingIdentity(callingId);
5605 public void forceStopPackage(final String packageName, int userId) {
5606 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5607 != PackageManager.PERMISSION_GRANTED) {
5608 String msg = "Permission Denial: forceStopPackage() from pid="
5609 + Binder.getCallingPid()
5610 + ", uid=" + Binder.getCallingUid()
5611 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5613 throw new SecurityException(msg);
5615 final int callingPid = Binder.getCallingPid();
5616 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5617 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5618 long callingId = Binder.clearCallingIdentity();
5620 IPackageManager pm = AppGlobals.getPackageManager();
5621 synchronized(this) {
5622 int[] users = userId == UserHandle.USER_ALL
5623 ? mUserController.getUsers() : new int[] { userId };
5624 for (int user : users) {
5627 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5629 } catch (RemoteException e) {
5632 Slog.w(TAG, "Invalid packageName: " + packageName);
5636 pm.setPackageStoppedState(packageName, true, user);
5637 } catch (RemoteException e) {
5638 } catch (IllegalArgumentException e) {
5639 Slog.w(TAG, "Failed trying to unstop package "
5640 + packageName + ": " + e);
5642 if (mUserController.isUserRunningLocked(user, 0)) {
5643 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5644 finishForceStopPackageLocked(packageName, pkgUid);
5649 Binder.restoreCallingIdentity(callingId);
5654 public void addPackageDependency(String packageName) {
5655 synchronized (this) {
5656 int callingPid = Binder.getCallingPid();
5657 if (callingPid == Process.myPid()) {
5662 synchronized (mPidsSelfLocked) {
5663 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5666 if (proc.pkgDeps == null) {
5667 proc.pkgDeps = new ArraySet<String>(1);
5669 proc.pkgDeps.add(packageName);
5675 * The pkg name and app id have to be specified.
5678 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5682 // Make sure the uid is valid.
5684 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5687 int callerUid = Binder.getCallingUid();
5688 // Only the system server can kill an application
5689 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5690 // Post an aysnc message to kill the application
5691 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5694 Bundle bundle = new Bundle();
5695 bundle.putString("pkg", pkg);
5696 bundle.putString("reason", reason);
5698 mHandler.sendMessage(msg);
5700 throw new SecurityException(callerUid + " cannot kill pkg: " +
5706 public void closeSystemDialogs(String reason) {
5707 enforceNotIsolatedCaller("closeSystemDialogs");
5709 final int pid = Binder.getCallingPid();
5710 final int uid = Binder.getCallingUid();
5711 final long origId = Binder.clearCallingIdentity();
5713 synchronized (this) {
5714 // Only allow this from foreground processes, so that background
5715 // applications can't abuse it to prevent system UI from being shown.
5716 if (uid >= Process.FIRST_APPLICATION_UID) {
5718 synchronized (mPidsSelfLocked) {
5719 proc = mPidsSelfLocked.get(pid);
5721 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5722 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5723 + " from background process " + proc);
5727 closeSystemDialogsLocked(reason);
5730 Binder.restoreCallingIdentity(origId);
5734 void closeSystemDialogsLocked(String reason) {
5735 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5736 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5737 | Intent.FLAG_RECEIVER_FOREGROUND);
5738 if (reason != null) {
5739 intent.putExtra("reason", reason);
5741 mWindowManager.closeSystemDialogs(reason);
5743 mStackSupervisor.closeSystemDialogsLocked();
5745 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5746 AppOpsManager.OP_NONE, null, false, false,
5747 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5751 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5752 enforceNotIsolatedCaller("getProcessMemoryInfo");
5753 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5754 for (int i=pids.length-1; i>=0; i--) {
5757 synchronized (this) {
5758 synchronized (mPidsSelfLocked) {
5759 proc = mPidsSelfLocked.get(pids[i]);
5760 oomAdj = proc != null ? proc.setAdj : 0;
5763 infos[i] = new Debug.MemoryInfo();
5764 Debug.getMemoryInfo(pids[i], infos[i]);
5766 synchronized (this) {
5767 if (proc.thread != null && proc.setAdj == oomAdj) {
5768 // Record this for posterity if the process has been stable.
5769 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5770 infos[i].getTotalUss(), false, proc.pkgList);
5779 public long[] getProcessPss(int[] pids) {
5780 enforceNotIsolatedCaller("getProcessPss");
5781 long[] pss = new long[pids.length];
5782 for (int i=pids.length-1; i>=0; i--) {
5785 synchronized (this) {
5786 synchronized (mPidsSelfLocked) {
5787 proc = mPidsSelfLocked.get(pids[i]);
5788 oomAdj = proc != null ? proc.setAdj : 0;
5791 long[] tmpUss = new long[1];
5792 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5794 synchronized (this) {
5795 if (proc.thread != null && proc.setAdj == oomAdj) {
5796 // Record this for posterity if the process has been stable.
5797 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5806 public void killApplicationProcess(String processName, int uid) {
5807 if (processName == null) {
5811 int callerUid = Binder.getCallingUid();
5812 // Only the system server can kill an application
5813 if (callerUid == Process.SYSTEM_UID) {
5814 synchronized (this) {
5815 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5816 if (app != null && app.thread != null) {
5818 app.thread.scheduleSuicide();
5819 } catch (RemoteException e) {
5820 // If the other end already died, then our work here is done.
5823 Slog.w(TAG, "Process/uid not found attempting kill of "
5824 + processName + " / " + uid);
5828 throw new SecurityException(callerUid + " cannot kill app process: " +
5833 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5834 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5835 false, true, false, false, UserHandle.getUserId(uid), reason);
5838 private void finishForceStopPackageLocked(final String packageName, int uid) {
5839 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5840 Uri.fromParts("package", packageName, null));
5841 if (!mProcessesReady) {
5842 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5843 | Intent.FLAG_RECEIVER_FOREGROUND);
5845 intent.putExtra(Intent.EXTRA_UID, uid);
5846 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5847 broadcastIntentLocked(null, null, intent,
5848 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5849 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5853 private final boolean killPackageProcessesLocked(String packageName, int appId,
5854 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5855 boolean doit, boolean evenPersistent, String reason) {
5856 ArrayList<ProcessRecord> procs = new ArrayList<>();
5858 // Remove all processes this package may have touched: all with the
5859 // same UID (except for the system or root user), and all whose name
5860 // matches the package name.
5861 final int NP = mProcessNames.getMap().size();
5862 for (int ip=0; ip<NP; ip++) {
5863 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5864 final int NA = apps.size();
5865 for (int ia=0; ia<NA; ia++) {
5866 ProcessRecord app = apps.valueAt(ia);
5867 if (app.persistent && !evenPersistent) {
5868 // we don't kill persistent processes
5878 // Skip process if it doesn't meet our oom adj requirement.
5879 if (app.setAdj < minOomAdj) {
5883 // If no package is specified, we call all processes under the
5885 if (packageName == null) {
5886 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5889 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5892 // Package has been specified, we want to hit all processes
5893 // that match it. We need to qualify this by the processes
5894 // that are running under the specified app and user ID.
5896 final boolean isDep = app.pkgDeps != null
5897 && app.pkgDeps.contains(packageName);
5898 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5901 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5904 if (!app.pkgList.containsKey(packageName) && !isDep) {
5909 // Process has passed all conditions, kill it!
5918 int N = procs.size();
5919 for (int i=0; i<N; i++) {
5920 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5922 updateOomAdjLocked();
5926 private void cleanupDisabledPackageComponentsLocked(
5927 String packageName, int userId, boolean killProcess, String[] changedClasses) {
5929 Set<String> disabledClasses = null;
5930 boolean packageDisabled = false;
5931 IPackageManager pm = AppGlobals.getPackageManager();
5933 if (changedClasses == null) {
5934 // Nothing changed...
5938 // Determine enable/disable state of the package and its components.
5939 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5940 for (int i = changedClasses.length - 1; i >= 0; i--) {
5941 final String changedClass = changedClasses[i];
5943 if (changedClass.equals(packageName)) {
5945 // Entire package setting changed
5946 enabled = pm.getApplicationEnabledSetting(packageName,
5947 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5948 } catch (Exception e) {
5949 // No such package/component; probably racing with uninstall. In any
5950 // event it means we have nothing further to do here.
5953 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5954 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5955 if (packageDisabled) {
5956 // Entire package is disabled.
5957 // No need to continue to check component states.
5958 disabledClasses = null;
5963 enabled = pm.getComponentEnabledSetting(
5964 new ComponentName(packageName, changedClass),
5965 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5966 } catch (Exception e) {
5967 // As above, probably racing with uninstall.
5970 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5971 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5972 if (disabledClasses == null) {
5973 disabledClasses = new ArraySet<>(changedClasses.length);
5975 disabledClasses.add(changedClass);
5980 if (!packageDisabled && disabledClasses == null) {
5981 // Nothing to do here...
5985 // Clean-up disabled activities.
5986 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5987 packageName, disabledClasses, true, false, userId) && mBooted) {
5988 mStackSupervisor.resumeFocusedStackTopActivityLocked();
5989 mStackSupervisor.scheduleIdleLocked();
5992 // Clean-up disabled tasks
5993 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5995 // Clean-up disabled services.
5996 mServices.bringDownDisabledPackageServicesLocked(
5997 packageName, disabledClasses, userId, false, killProcess, true);
5999 // Clean-up disabled providers.
6000 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6001 mProviderMap.collectPackageProvidersLocked(
6002 packageName, disabledClasses, true, false, userId, providers);
6003 for (int i = providers.size() - 1; i >= 0; i--) {
6004 removeDyingProviderLocked(null, providers.get(i), true);
6007 // Clean-up disabled broadcast receivers.
6008 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6009 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6010 packageName, disabledClasses, userId, true);
6015 final boolean clearBroadcastQueueForUserLocked(int userId) {
6016 boolean didSomething = false;
6017 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6018 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6019 null, null, userId, true);
6021 return didSomething;
6024 final boolean forceStopPackageLocked(String packageName, int appId,
6025 boolean callerWillRestart, boolean purgeCache, boolean doit,
6026 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6029 if (userId == UserHandle.USER_ALL && packageName == null) {
6030 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6033 if (appId < 0 && packageName != null) {
6035 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6036 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6037 } catch (RemoteException e) {
6042 if (packageName != null) {
6043 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6044 + " user=" + userId + ": " + reason);
6046 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6049 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6052 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6053 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6054 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6056 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6057 packageName, null, doit, evenPersistent, userId)) {
6061 didSomething = true;
6064 if (mServices.bringDownDisabledPackageServicesLocked(
6065 packageName, null, userId, evenPersistent, true, doit)) {
6069 didSomething = true;
6072 if (packageName == null) {
6073 // Remove all sticky broadcasts from this user.
6074 mStickyBroadcasts.remove(userId);
6077 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6078 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6079 userId, providers)) {
6083 didSomething = true;
6085 for (i = providers.size() - 1; i >= 0; i--) {
6086 removeDyingProviderLocked(null, providers.get(i), true);
6089 // Remove transient permissions granted from/to this package/user
6090 removeUriPermissionsForPackageLocked(packageName, userId, false);
6093 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6094 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6095 packageName, null, userId, doit);
6099 if (packageName == null || uninstalling) {
6100 // Remove pending intents. For now we only do this when force
6101 // stopping users, because we have some problems when doing this
6102 // for packages -- app widgets are not currently cleaned up for
6103 // such packages, so they can be left with bad pending intents.
6104 if (mIntentSenderRecords.size() > 0) {
6105 Iterator<WeakReference<PendingIntentRecord>> it
6106 = mIntentSenderRecords.values().iterator();
6107 while (it.hasNext()) {
6108 WeakReference<PendingIntentRecord> wpir = it.next();
6113 PendingIntentRecord pir = wpir.get();
6118 if (packageName == null) {
6119 // Stopping user, remove all objects for the user.
6120 if (pir.key.userId != userId) {
6121 // Not the same user, skip it.
6125 if (UserHandle.getAppId(pir.uid) != appId) {
6126 // Different app id, skip it.
6129 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6130 // Different user, skip it.
6133 if (!pir.key.packageName.equals(packageName)) {
6134 // Different package, skip it.
6141 didSomething = true;
6143 pir.canceled = true;
6144 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6145 pir.key.activity.pendingResults.remove(pir.ref);
6152 if (purgeCache && packageName != null) {
6153 AttributeCache ac = AttributeCache.instance();
6155 ac.removePackage(packageName);
6159 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6160 mStackSupervisor.scheduleIdleLocked();
6164 return didSomething;
6167 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6168 ProcessRecord old = mProcessNames.remove(name, uid);
6170 old.uidRecord.numProcs--;
6171 if (old.uidRecord.numProcs == 0) {
6172 // No more processes using this uid, tell clients it is gone.
6173 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6174 "No more processes in " + old.uidRecord);
6175 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6176 mActiveUids.remove(uid);
6177 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6179 old.uidRecord = null;
6181 mIsolatedProcesses.remove(uid);
6185 private final void addProcessNameLocked(ProcessRecord proc) {
6186 // We shouldn't already have a process under this name, but just in case we
6187 // need to clean up whatever may be there now.
6188 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6189 if (old == proc && proc.persistent) {
6190 // We are re-adding a persistent process. Whatevs! Just leave it there.
6191 Slog.w(TAG, "Re-adding persistent process " + proc);
6192 } else if (old != null) {
6193 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6195 UidRecord uidRec = mActiveUids.get(proc.uid);
6196 if (uidRec == null) {
6197 uidRec = new UidRecord(proc.uid);
6198 // This is the first appearance of the uid, report it now!
6199 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6200 "Creating new process uid: " + uidRec);
6201 mActiveUids.put(proc.uid, uidRec);
6202 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6203 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6205 proc.uidRecord = uidRec;
6207 mProcessNames.put(proc.processName, proc.uid, proc);
6208 if (proc.isolated) {
6209 mIsolatedProcesses.put(proc.uid, proc);
6213 boolean removeProcessLocked(ProcessRecord app,
6214 boolean callerWillRestart, boolean allowRestart, String reason) {
6215 final String name = app.processName;
6216 final int uid = app.uid;
6217 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6218 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6220 ProcessRecord old = mProcessNames.get(name, uid);
6222 // This process is no longer active, so nothing to do.
6223 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6226 removeProcessNameLocked(name, uid);
6227 if (mHeavyWeightProcess == app) {
6228 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6229 mHeavyWeightProcess.userId, 0));
6230 mHeavyWeightProcess = null;
6232 boolean needRestart = false;
6233 if (app.pid > 0 && app.pid != MY_PID) {
6235 synchronized (mPidsSelfLocked) {
6236 mPidsSelfLocked.remove(pid);
6237 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6239 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6241 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6243 boolean willRestart = false;
6244 if (app.persistent && !app.isolated) {
6245 if (!callerWillRestart) {
6251 app.kill(reason, true);
6252 handleAppDiedLocked(app, willRestart, allowRestart);
6254 removeLruProcessLocked(app);
6255 addAppLocked(app.info, false, null /* ABI override */);
6258 mRemovedProcesses.add(app);
6264 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6265 cleanupAppInLaunchingProvidersLocked(app, true);
6266 removeProcessLocked(app, false, true, "timeout publishing content providers");
6269 private final void processStartTimedOutLocked(ProcessRecord app) {
6270 final int pid = app.pid;
6271 boolean gone = false;
6272 synchronized (mPidsSelfLocked) {
6273 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6274 if (knownApp != null && knownApp.thread == null) {
6275 mPidsSelfLocked.remove(pid);
6281 Slog.w(TAG, "Process " + app + " failed to attach");
6282 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6283 pid, app.uid, app.processName);
6284 removeProcessNameLocked(app.processName, app.uid);
6285 if (mHeavyWeightProcess == app) {
6286 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6287 mHeavyWeightProcess.userId, 0));
6288 mHeavyWeightProcess = null;
6290 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6292 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6294 // Take care of any launching providers waiting for this process.
6295 cleanupAppInLaunchingProvidersLocked(app, true);
6296 // Take care of any services that are waiting for the process.
6297 mServices.processStartTimedOutLocked(app);
6298 app.kill("start timeout", true);
6299 removeLruProcessLocked(app);
6300 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6301 Slog.w(TAG, "Unattached app died before backup, skipping");
6303 IBackupManager bm = IBackupManager.Stub.asInterface(
6304 ServiceManager.getService(Context.BACKUP_SERVICE));
6305 bm.agentDisconnected(app.info.packageName);
6306 } catch (RemoteException e) {
6307 // Can't happen; the backup manager is local
6310 if (isPendingBroadcastProcessLocked(pid)) {
6311 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6312 skipPendingBroadcastLocked(pid);
6315 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6319 private final boolean attachApplicationLocked(IApplicationThread thread,
6322 // Find the application record that is being attached... either via
6323 // the pid if we are running in multiple processes, or just pull the
6324 // next app record if we are emulating process with anonymous threads.
6326 if (pid != MY_PID && pid >= 0) {
6327 synchronized (mPidsSelfLocked) {
6328 app = mPidsSelfLocked.get(pid);
6335 Slog.w(TAG, "No pending application record for pid " + pid
6336 + " (IApplicationThread " + thread + "); dropping process");
6337 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6338 if (pid > 0 && pid != MY_PID) {
6339 Process.killProcessQuiet(pid);
6340 //TODO: killProcessGroup(app.info.uid, pid);
6343 thread.scheduleExit();
6344 } catch (Exception e) {
6345 // Ignore exceptions.
6351 // If this application record is still attached to a previous
6352 // process, clean it up now.
6353 if (app.thread != null) {
6354 handleAppDiedLocked(app, true, true);
6357 // Tell the process all about itself.
6359 if (DEBUG_ALL) Slog.v(
6360 TAG, "Binding process pid " + pid + " to record " + app);
6362 final String processName = app.processName;
6364 AppDeathRecipient adr = new AppDeathRecipient(
6366 thread.asBinder().linkToDeath(adr, 0);
6367 app.deathRecipient = adr;
6368 } catch (RemoteException e) {
6369 app.resetPackageList(mProcessStats);
6370 startProcessLocked(app, "link fail", processName);
6374 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6376 app.makeActive(thread, mProcessStats);
6377 app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6378 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6379 app.forcingToForeground = null;
6380 updateProcessForegroundLocked(app, false, false);
6381 app.hasShownUi = false;
6382 app.debugging = false;
6384 app.killedByAm = false;
6386 // We carefully use the same state that PackageManager uses for
6387 // filtering, since we use this flag to decide if we need to install
6388 // providers when user is unlocked later
6389 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6391 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6393 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6394 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6396 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6397 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6399 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6403 Slog.i(TAG, "Launching preboot mode app: " + app);
6406 if (DEBUG_ALL) Slog.v(
6407 TAG, "New app record " + app
6408 + " thread=" + thread.asBinder() + " pid=" + pid);
6410 int testMode = IApplicationThread.DEBUG_OFF;
6411 if (mDebugApp != null && mDebugApp.equals(processName)) {
6412 testMode = mWaitForDebugger
6413 ? IApplicationThread.DEBUG_WAIT
6414 : IApplicationThread.DEBUG_ON;
6415 app.debugging = true;
6416 if (mDebugTransient) {
6417 mDebugApp = mOrigDebugApp;
6418 mWaitForDebugger = mOrigWaitForDebugger;
6421 String profileFile = app.instrumentationProfileFile;
6422 ParcelFileDescriptor profileFd = null;
6423 int samplingInterval = 0;
6424 boolean profileAutoStop = false;
6425 if (mProfileApp != null && mProfileApp.equals(processName)) {
6427 profileFile = mProfileFile;
6428 profileFd = mProfileFd;
6429 samplingInterval = mSamplingInterval;
6430 profileAutoStop = mAutoStopProfiler;
6432 boolean enableTrackAllocation = false;
6433 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6434 enableTrackAllocation = true;
6435 mTrackAllocationApp = null;
6438 // If the app is being launched for restore or full backup, set it up specially
6439 boolean isRestrictedBackupMode = false;
6440 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6441 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6442 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6443 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6444 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6447 if (app.instrumentationClass != null) {
6448 notifyPackageUse(app.instrumentationClass.getPackageName(),
6449 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6451 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6452 + processName + " with config " + mConfiguration);
6453 ApplicationInfo appInfo = app.instrumentationInfo != null
6454 ? app.instrumentationInfo : app.info;
6455 app.compat = compatibilityInfoForPackageLocked(appInfo);
6456 if (profileFd != null) {
6457 profileFd = profileFd.dup();
6459 ProfilerInfo profilerInfo = profileFile == null ? null
6460 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6461 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6462 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6463 app.instrumentationUiAutomationConnection, testMode,
6464 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6465 isRestrictedBackupMode || !normalMode, app.persistent,
6466 new Configuration(mConfiguration), app.compat,
6467 getCommonServicesLocked(app.isolated),
6468 mCoreSettingsObserver.getCoreSettingsLocked());
6469 updateLruProcessLocked(app, false, null);
6470 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6471 } catch (Exception e) {
6472 // todo: Yikes! What should we do? For now we will try to
6473 // start another process, but that could easily get us in
6474 // an infinite loop of restarting processes...
6475 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6477 app.resetPackageList(mProcessStats);
6478 app.unlinkDeathRecipient();
6479 startProcessLocked(app, "bind fail", processName);
6483 // Remove this record from the list of starting applications.
6484 mPersistentStartingProcesses.remove(app);
6485 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6486 "Attach application locked removing on hold: " + app);
6487 mProcessesOnHold.remove(app);
6489 boolean badApp = false;
6490 boolean didSomething = false;
6492 // See if the top visible activity is waiting to run in this process...
6495 if (mStackSupervisor.attachApplicationLocked(app)) {
6496 didSomething = true;
6498 } catch (Exception e) {
6499 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6504 // Find any services that should be running in this process...
6507 didSomething |= mServices.attachApplicationLocked(app, processName);
6508 } catch (Exception e) {
6509 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6514 // Check if a next-broadcast receiver is in this process...
6515 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6517 didSomething |= sendPendingBroadcastsLocked(app);
6518 } catch (Exception e) {
6519 // If the app died trying to launch the receiver we declare it 'bad'
6520 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6525 // Check whether the next backup agent is in this process...
6526 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6527 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6528 "New app is backup target, launching agent for " + app);
6529 notifyPackageUse(mBackupTarget.appInfo.packageName,
6530 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6532 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6533 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6534 mBackupTarget.backupMode);
6535 } catch (Exception e) {
6536 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6542 app.kill("error during init", true);
6543 handleAppDiedLocked(app, false, true);
6547 if (!didSomething) {
6548 updateOomAdjLocked();
6555 public final void attachApplication(IApplicationThread thread) {
6556 synchronized (this) {
6557 int callingPid = Binder.getCallingPid();
6558 final long origId = Binder.clearCallingIdentity();
6559 attachApplicationLocked(thread, callingPid);
6560 Binder.restoreCallingIdentity(origId);
6565 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6566 final long origId = Binder.clearCallingIdentity();
6567 synchronized (this) {
6568 ActivityStack stack = ActivityRecord.getStackLocked(token);
6569 if (stack != null) {
6571 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6572 if (stopProfiling) {
6573 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6576 } catch (IOException e) {
6578 clearProfilerLocked();
6583 Binder.restoreCallingIdentity(origId);
6586 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6587 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6588 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6591 void enableScreenAfterBoot() {
6592 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6593 SystemClock.uptimeMillis());
6594 mWindowManager.enableScreenAfterBoot();
6596 synchronized (this) {
6597 updateEventDispatchingLocked();
6602 public void showBootMessage(final CharSequence msg, final boolean always) {
6603 if (Binder.getCallingUid() != Process.myUid()) {
6604 // These days only the core system can call this, so apps can't get in
6605 // the way of what we show about running them.
6607 mWindowManager.showBootMessage(msg, always);
6611 public void keyguardWaitingForActivityDrawn() {
6612 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6613 final long token = Binder.clearCallingIdentity();
6615 synchronized (this) {
6616 if (DEBUG_LOCKSCREEN) logLockScreen("");
6617 mWindowManager.keyguardWaitingForActivityDrawn();
6618 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6619 mLockScreenShown = LOCK_SCREEN_LEAVING;
6620 updateSleepIfNeededLocked();
6624 Binder.restoreCallingIdentity(token);
6629 public void keyguardGoingAway(int flags) {
6630 enforceNotIsolatedCaller("keyguardGoingAway");
6631 final long token = Binder.clearCallingIdentity();
6633 synchronized (this) {
6634 if (DEBUG_LOCKSCREEN) logLockScreen("");
6635 mWindowManager.keyguardGoingAway(flags);
6636 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6637 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6638 updateSleepIfNeededLocked();
6640 // Some stack visibility might change (e.g. docked stack)
6641 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6642 applyVrModeIfNeededLocked(mFocusedActivity, true);
6646 Binder.restoreCallingIdentity(token);
6650 final void finishBooting() {
6651 synchronized (this) {
6652 if (!mBootAnimationComplete) {
6653 mCallFinishBooting = true;
6656 mCallFinishBooting = false;
6659 ArraySet<String> completedIsas = new ArraySet<String>();
6660 for (String abi : Build.SUPPORTED_ABIS) {
6661 Process.establishZygoteConnectionForAbi(abi);
6662 final String instructionSet = VMRuntime.getInstructionSet(abi);
6663 if (!completedIsas.contains(instructionSet)) {
6665 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6666 } catch (InstallerException e) {
6667 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6668 e.getMessage() +")");
6670 completedIsas.add(instructionSet);
6674 IntentFilter pkgFilter = new IntentFilter();
6675 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6676 pkgFilter.addDataScheme("package");
6677 mContext.registerReceiver(new BroadcastReceiver() {
6679 public void onReceive(Context context, Intent intent) {
6680 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6682 for (String pkg : pkgs) {
6683 synchronized (ActivityManagerService.this) {
6684 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6685 0, "query restart")) {
6686 setResultCode(Activity.RESULT_OK);
6695 IntentFilter dumpheapFilter = new IntentFilter();
6696 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6697 mContext.registerReceiver(new BroadcastReceiver() {
6699 public void onReceive(Context context, Intent intent) {
6700 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6701 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6703 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6708 // Let system services know.
6709 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6711 synchronized (this) {
6712 // Ensure that any processes we had put on hold are now started
6714 final int NP = mProcessesOnHold.size();
6716 ArrayList<ProcessRecord> procs =
6717 new ArrayList<ProcessRecord>(mProcessesOnHold);
6718 for (int ip=0; ip<NP; ip++) {
6719 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6721 startProcessLocked(procs.get(ip), "on-hold", null);
6725 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6726 // Start looking for apps that are abusing wake locks.
6727 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6728 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6729 // Tell anyone interested that we are done booting!
6730 SystemProperties.set("sys.boot_completed", "1");
6732 // And trigger dev.bootcomplete if we are not showing encryption progress
6733 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6734 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6735 SystemProperties.set("dev.bootcomplete", "1");
6737 mUserController.sendBootCompletedLocked(
6738 new IIntentReceiver.Stub() {
6740 public void performReceive(Intent intent, int resultCode,
6741 String data, Bundle extras, boolean ordered,
6742 boolean sticky, int sendingUser) {
6743 synchronized (ActivityManagerService.this) {
6744 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6749 scheduleStartProfilesLocked();
6755 public void bootAnimationComplete() {
6756 final boolean callFinishBooting;
6757 synchronized (this) {
6758 callFinishBooting = mCallFinishBooting;
6759 mBootAnimationComplete = true;
6761 if (callFinishBooting) {
6762 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6764 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6768 final void ensureBootCompleted() {
6770 boolean enableScreen;
6771 synchronized (this) {
6774 enableScreen = !mBooted;
6779 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6781 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6785 enableScreenAfterBoot();
6790 public final void activityResumed(IBinder token) {
6791 final long origId = Binder.clearCallingIdentity();
6792 synchronized(this) {
6793 ActivityStack stack = ActivityRecord.getStackLocked(token);
6794 if (stack != null) {
6795 stack.activityResumedLocked(token);
6798 Binder.restoreCallingIdentity(origId);
6802 public final void activityPaused(IBinder token) {
6803 final long origId = Binder.clearCallingIdentity();
6804 synchronized(this) {
6805 ActivityStack stack = ActivityRecord.getStackLocked(token);
6806 if (stack != null) {
6807 stack.activityPausedLocked(token, false);
6810 Binder.restoreCallingIdentity(origId);
6814 public final void activityStopped(IBinder token, Bundle icicle,
6815 PersistableBundle persistentState, CharSequence description) {
6816 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6818 // Refuse possible leaked file descriptors
6819 if (icicle != null && icicle.hasFileDescriptors()) {
6820 throw new IllegalArgumentException("File descriptors passed in Bundle");
6823 final long origId = Binder.clearCallingIdentity();
6825 synchronized (this) {
6826 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6828 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6834 Binder.restoreCallingIdentity(origId);
6838 public final void activityDestroyed(IBinder token) {
6839 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6840 synchronized (this) {
6841 ActivityStack stack = ActivityRecord.getStackLocked(token);
6842 if (stack != null) {
6843 stack.activityDestroyedLocked(token, "activityDestroyed");
6849 public final void activityRelaunched(IBinder token) {
6850 final long origId = Binder.clearCallingIdentity();
6851 synchronized (this) {
6852 mStackSupervisor.activityRelaunchedLocked(token);
6854 Binder.restoreCallingIdentity(origId);
6858 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6859 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6860 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6861 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6862 synchronized (this) {
6863 ActivityRecord record = ActivityRecord.isInStackLocked(token);
6864 if (record == null) {
6865 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6866 + "found for: " + token);
6868 record.setSizeConfigurations(horizontalSizeConfiguration,
6869 verticalSizeConfigurations, smallestSizeConfigurations);
6874 public final void backgroundResourcesReleased(IBinder token) {
6875 final long origId = Binder.clearCallingIdentity();
6877 synchronized (this) {
6878 ActivityStack stack = ActivityRecord.getStackLocked(token);
6879 if (stack != null) {
6880 stack.backgroundResourcesReleased();
6884 Binder.restoreCallingIdentity(origId);
6889 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6890 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6894 public final void notifyEnterAnimationComplete(IBinder token) {
6895 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6899 public String getCallingPackage(IBinder token) {
6900 synchronized (this) {
6901 ActivityRecord r = getCallingRecordLocked(token);
6902 return r != null ? r.info.packageName : null;
6907 public ComponentName getCallingActivity(IBinder token) {
6908 synchronized (this) {
6909 ActivityRecord r = getCallingRecordLocked(token);
6910 return r != null ? r.intent.getComponent() : null;
6914 private ActivityRecord getCallingRecordLocked(IBinder token) {
6915 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6923 public ComponentName getActivityClassForToken(IBinder token) {
6924 synchronized(this) {
6925 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6929 return r.intent.getComponent();
6934 public String getPackageForToken(IBinder token) {
6935 synchronized(this) {
6936 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6940 return r.packageName;
6945 public boolean isRootVoiceInteraction(IBinder token) {
6946 synchronized(this) {
6947 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6951 return r.rootVoiceInteraction;
6956 public IIntentSender getIntentSender(int type,
6957 String packageName, IBinder token, String resultWho,
6958 int requestCode, Intent[] intents, String[] resolvedTypes,
6959 int flags, Bundle bOptions, int userId) {
6960 enforceNotIsolatedCaller("getIntentSender");
6961 // Refuse possible leaked file descriptors
6962 if (intents != null) {
6963 if (intents.length < 1) {
6964 throw new IllegalArgumentException("Intents array length must be >= 1");
6966 for (int i=0; i<intents.length; i++) {
6967 Intent intent = intents[i];
6968 if (intent != null) {
6969 if (intent.hasFileDescriptors()) {
6970 throw new IllegalArgumentException("File descriptors passed in Intent");
6972 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6973 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6974 throw new IllegalArgumentException(
6975 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6977 intents[i] = new Intent(intent);
6980 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6981 throw new IllegalArgumentException(
6982 "Intent array length does not match resolvedTypes length");
6985 if (bOptions != null) {
6986 if (bOptions.hasFileDescriptors()) {
6987 throw new IllegalArgumentException("File descriptors passed in options");
6991 synchronized(this) {
6992 int callingUid = Binder.getCallingUid();
6993 int origUserId = userId;
6994 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6995 type == ActivityManager.INTENT_SENDER_BROADCAST,
6996 ALLOW_NON_FULL, "getIntentSender", null);
6997 if (origUserId == UserHandle.USER_CURRENT) {
6998 // We don't want to evaluate this until the pending intent is
6999 // actually executed. However, we do want to always do the
7000 // security checking for it above.
7001 userId = UserHandle.USER_CURRENT;
7004 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7005 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7006 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7007 if (!UserHandle.isSameApp(callingUid, uid)) {
7008 String msg = "Permission Denial: getIntentSender() from pid="
7009 + Binder.getCallingPid()
7010 + ", uid=" + Binder.getCallingUid()
7011 + ", (need uid=" + uid + ")"
7012 + " is not allowed to send as package " + packageName;
7014 throw new SecurityException(msg);
7018 return getIntentSenderLocked(type, packageName, callingUid, userId,
7019 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7021 } catch (RemoteException e) {
7022 throw new SecurityException(e);
7027 IIntentSender getIntentSenderLocked(int type, String packageName,
7028 int callingUid, int userId, IBinder token, String resultWho,
7029 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7031 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7032 ActivityRecord activity = null;
7033 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7034 activity = ActivityRecord.isInStackLocked(token);
7035 if (activity == null) {
7036 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7039 if (activity.finishing) {
7040 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7045 // We're going to be splicing together extras before sending, so we're
7046 // okay poking into any contained extras.
7047 if (intents != null) {
7048 for (int i = 0; i < intents.length; i++) {
7049 intents[i].setDefusable(true);
7052 Bundle.setDefusable(bOptions, true);
7054 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7055 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7056 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7057 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7058 |PendingIntent.FLAG_UPDATE_CURRENT);
7060 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7061 type, packageName, activity, resultWho,
7062 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7063 WeakReference<PendingIntentRecord> ref;
7064 ref = mIntentSenderRecords.get(key);
7065 PendingIntentRecord rec = ref != null ? ref.get() : null;
7067 if (!cancelCurrent) {
7068 if (updateCurrent) {
7069 if (rec.key.requestIntent != null) {
7070 rec.key.requestIntent.replaceExtras(intents != null ?
7071 intents[intents.length - 1] : null);
7073 if (intents != null) {
7074 intents[intents.length-1] = rec.key.requestIntent;
7075 rec.key.allIntents = intents;
7076 rec.key.allResolvedTypes = resolvedTypes;
7078 rec.key.allIntents = null;
7079 rec.key.allResolvedTypes = null;
7084 rec.canceled = true;
7085 mIntentSenderRecords.remove(key);
7090 rec = new PendingIntentRecord(this, key, callingUid);
7091 mIntentSenderRecords.put(key, rec.ref);
7092 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7093 if (activity.pendingResults == null) {
7094 activity.pendingResults
7095 = new HashSet<WeakReference<PendingIntentRecord>>();
7097 activity.pendingResults.add(rec.ref);
7103 public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7104 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7105 if (target instanceof PendingIntentRecord) {
7106 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7107 finishedReceiver, requiredPermission, options);
7109 if (intent == null) {
7110 // Weird case: someone has given us their own custom IIntentSender, and now
7111 // they have someone else trying to send to it but of course this isn't
7112 // really a PendingIntent, so there is no base Intent, and the caller isn't
7113 // supplying an Intent... but we never want to dispatch a null Intent to
7114 // a receiver, so um... let's make something up.
7115 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7116 intent = new Intent(Intent.ACTION_MAIN);
7119 target.send(code, intent, resolvedType, null, requiredPermission, options);
7120 } catch (RemoteException e) {
7122 // Platform code can rely on getting a result back when the send is done, but if
7123 // this intent sender is from outside of the system we can't rely on it doing that.
7124 // So instead we don't give it the result receiver, and instead just directly
7125 // report the finish immediately.
7126 if (finishedReceiver != null) {
7128 finishedReceiver.performReceive(intent, 0,
7129 null, null, false, false, UserHandle.getCallingUserId());
7130 } catch (RemoteException e) {
7138 public void cancelIntentSender(IIntentSender sender) {
7139 if (!(sender instanceof PendingIntentRecord)) {
7142 synchronized(this) {
7143 PendingIntentRecord rec = (PendingIntentRecord)sender;
7145 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7146 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7147 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7148 String msg = "Permission Denial: cancelIntentSender() from pid="
7149 + Binder.getCallingPid()
7150 + ", uid=" + Binder.getCallingUid()
7151 + " is not allowed to cancel packges "
7152 + rec.key.packageName;
7154 throw new SecurityException(msg);
7156 } catch (RemoteException e) {
7157 throw new SecurityException(e);
7159 cancelIntentSenderLocked(rec, true);
7163 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7164 rec.canceled = true;
7165 mIntentSenderRecords.remove(rec.key);
7166 if (cleanActivity && rec.key.activity != null) {
7167 rec.key.activity.pendingResults.remove(rec.ref);
7172 public String getPackageForIntentSender(IIntentSender pendingResult) {
7173 if (!(pendingResult instanceof PendingIntentRecord)) {
7177 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7178 return res.key.packageName;
7179 } catch (ClassCastException e) {
7185 public int getUidForIntentSender(IIntentSender sender) {
7186 if (sender instanceof PendingIntentRecord) {
7188 PendingIntentRecord res = (PendingIntentRecord)sender;
7190 } catch (ClassCastException e) {
7197 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7198 if (!(pendingResult instanceof PendingIntentRecord)) {
7202 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7203 if (res.key.allIntents == null) {
7206 for (int i=0; i<res.key.allIntents.length; i++) {
7207 Intent intent = res.key.allIntents[i];
7208 if (intent.getPackage() != null && intent.getComponent() != null) {
7213 } catch (ClassCastException e) {
7219 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7220 if (!(pendingResult instanceof PendingIntentRecord)) {
7224 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7225 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7229 } catch (ClassCastException e) {
7235 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7236 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7237 "getIntentForIntentSender()");
7238 if (!(pendingResult instanceof PendingIntentRecord)) {
7242 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7243 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7244 } catch (ClassCastException e) {
7250 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7251 if (!(pendingResult instanceof PendingIntentRecord)) {
7255 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7256 synchronized (this) {
7257 return getTagForIntentSenderLocked(res, prefix);
7259 } catch (ClassCastException e) {
7264 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7265 final Intent intent = res.key.requestIntent;
7266 if (intent != null) {
7267 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7268 || res.lastTagPrefix.equals(prefix))) {
7271 res.lastTagPrefix = prefix;
7272 final StringBuilder sb = new StringBuilder(128);
7273 if (prefix != null) {
7276 if (intent.getAction() != null) {
7277 sb.append(intent.getAction());
7278 } else if (intent.getComponent() != null) {
7279 intent.getComponent().appendShortString(sb);
7283 return res.lastTag = sb.toString();
7289 public void setProcessLimit(int max) {
7290 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7291 "setProcessLimit()");
7292 synchronized (this) {
7293 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7294 mProcessLimitOverride = max;
7300 public int getProcessLimit() {
7301 synchronized (this) {
7302 return mProcessLimitOverride;
7306 void foregroundTokenDied(ForegroundToken token) {
7307 synchronized (ActivityManagerService.this) {
7308 synchronized (mPidsSelfLocked) {
7310 = mForegroundProcesses.get(token.pid);
7314 mForegroundProcesses.remove(token.pid);
7315 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7319 pr.forcingToForeground = null;
7320 updateProcessForegroundLocked(pr, false, false);
7322 updateOomAdjLocked();
7327 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7328 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7329 "setProcessForeground()");
7330 synchronized(this) {
7331 boolean changed = false;
7333 synchronized (mPidsSelfLocked) {
7334 ProcessRecord pr = mPidsSelfLocked.get(pid);
7335 if (pr == null && isForeground) {
7336 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7339 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7340 if (oldToken != null) {
7341 oldToken.token.unlinkToDeath(oldToken, 0);
7342 mForegroundProcesses.remove(pid);
7344 pr.forcingToForeground = null;
7348 if (isForeground && token != null) {
7349 ForegroundToken newToken = new ForegroundToken() {
7351 public void binderDied() {
7352 foregroundTokenDied(this);
7356 newToken.token = token;
7358 token.linkToDeath(newToken, 0);
7359 mForegroundProcesses.put(pid, newToken);
7360 pr.forcingToForeground = token;
7362 } catch (RemoteException e) {
7363 // If the process died while doing this, we will later
7364 // do the cleanup with the process death link.
7370 updateOomAdjLocked();
7376 public boolean isAppForeground(int uid) throws RemoteException {
7377 synchronized (this) {
7378 UidRecord uidRec = mActiveUids.get(uid);
7379 if (uidRec == null || uidRec.idle) {
7382 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7386 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7387 // be guarded by permission checking.
7388 int getUidState(int uid) {
7389 synchronized (this) {
7390 UidRecord uidRec = mActiveUids.get(uid);
7391 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7396 public boolean isInMultiWindowMode(IBinder token) {
7397 final long origId = Binder.clearCallingIdentity();
7399 synchronized(this) {
7400 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7404 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7405 return !r.task.mFullscreen;
7408 Binder.restoreCallingIdentity(origId);
7413 public boolean isInPictureInPictureMode(IBinder token) {
7414 final long origId = Binder.clearCallingIdentity();
7416 synchronized(this) {
7417 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7418 if (stack == null) {
7421 return stack.mStackId == PINNED_STACK_ID;
7424 Binder.restoreCallingIdentity(origId);
7429 public void enterPictureInPictureMode(IBinder token) {
7430 final long origId = Binder.clearCallingIdentity();
7432 synchronized(this) {
7433 if (!mSupportsPictureInPicture) {
7434 throw new IllegalStateException("enterPictureInPictureMode: "
7435 + "Device doesn't support picture-in-picture mode.");
7438 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7441 throw new IllegalStateException("enterPictureInPictureMode: "
7442 + "Can't find activity for token=" + token);
7445 if (!r.supportsPictureInPicture()) {
7446 throw new IllegalArgumentException("enterPictureInPictureMode: "
7447 + "Picture-In-Picture not supported for r=" + r);
7450 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7452 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7453 final Rect bounds = (pinnedStack != null)
7454 ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7456 mStackSupervisor.moveActivityToPinnedStackLocked(
7457 r, "enterPictureInPictureMode", bounds);
7460 Binder.restoreCallingIdentity(origId);
7464 // =========================================================
7466 // =========================================================
7468 static class ProcessInfoService extends IProcessInfoService.Stub {
7469 final ActivityManagerService mActivityManagerService;
7470 ProcessInfoService(ActivityManagerService activityManagerService) {
7471 mActivityManagerService = activityManagerService;
7475 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7476 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7477 /*in*/ pids, /*out*/ states, null);
7481 public void getProcessStatesAndOomScoresFromPids(
7482 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7483 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7484 /*in*/ pids, /*out*/ states, /*out*/ scores);
7489 * For each PID in the given input array, write the current process state
7490 * for that process into the states array, or -1 to indicate that no
7491 * process with the given PID exists. If scores array is provided, write
7492 * the oom score for the process into the scores array, with INVALID_ADJ
7493 * indicating the PID doesn't exist.
7495 public void getProcessStatesAndOomScoresForPIDs(
7496 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7497 if (scores != null) {
7498 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7499 "getProcessStatesAndOomScoresForPIDs()");
7503 throw new NullPointerException("pids");
7504 } else if (states == null) {
7505 throw new NullPointerException("states");
7506 } else if (pids.length != states.length) {
7507 throw new IllegalArgumentException("pids and states arrays have different lengths!");
7508 } else if (scores != null && pids.length != scores.length) {
7509 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7512 synchronized (mPidsSelfLocked) {
7513 for (int i = 0; i < pids.length; i++) {
7514 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7515 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7517 if (scores != null) {
7518 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7524 // =========================================================
7526 // =========================================================
7528 static class PermissionController extends IPermissionController.Stub {
7529 ActivityManagerService mActivityManagerService;
7530 PermissionController(ActivityManagerService activityManagerService) {
7531 mActivityManagerService = activityManagerService;
7535 public boolean checkPermission(String permission, int pid, int uid) {
7536 return mActivityManagerService.checkPermission(permission, pid,
7537 uid) == PackageManager.PERMISSION_GRANTED;
7541 public String[] getPackagesForUid(int uid) {
7542 return mActivityManagerService.mContext.getPackageManager()
7543 .getPackagesForUid(uid);
7547 public boolean isRuntimePermission(String permission) {
7549 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7550 .getPermissionInfo(permission, 0);
7551 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7552 } catch (NameNotFoundException nnfe) {
7553 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7559 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7561 public int checkComponentPermission(String permission, int pid, int uid,
7562 int owningUid, boolean exported) {
7563 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7564 owningUid, exported);
7568 public Object getAMSLock() {
7569 return ActivityManagerService.this;
7574 * This can be called with or without the global lock held.
7576 int checkComponentPermission(String permission, int pid, int uid,
7577 int owningUid, boolean exported) {
7578 if (pid == MY_PID) {
7579 return PackageManager.PERMISSION_GRANTED;
7581 return ActivityManager.checkComponentPermission(permission, uid,
7582 owningUid, exported);
7586 * As the only public entry point for permissions checking, this method
7587 * can enforce the semantic that requesting a check on a null global
7588 * permission is automatically denied. (Internally a null permission
7589 * string is used when calling {@link #checkComponentPermission} in cases
7590 * when only uid-based security is needed.)
7592 * This can be called with or without the global lock held.
7595 public int checkPermission(String permission, int pid, int uid) {
7596 if (permission == null) {
7597 return PackageManager.PERMISSION_DENIED;
7599 return checkComponentPermission(permission, pid, uid, -1, true);
7603 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7604 if (permission == null) {
7605 return PackageManager.PERMISSION_DENIED;
7608 // We might be performing an operation on behalf of an indirect binder
7609 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7610 // client identity accordingly before proceeding.
7611 Identity tlsIdentity = sCallerIdentity.get();
7612 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7613 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7614 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7615 uid = tlsIdentity.uid;
7616 pid = tlsIdentity.pid;
7619 return checkComponentPermission(permission, pid, uid, -1, true);
7623 * Binder IPC calls go through the public entry point.
7624 * This can be called with or without the global lock held.
7626 int checkCallingPermission(String permission) {
7627 return checkPermission(permission,
7628 Binder.getCallingPid(),
7629 UserHandle.getAppId(Binder.getCallingUid()));
7633 * This can be called with or without the global lock held.
7635 void enforceCallingPermission(String permission, String func) {
7636 if (checkCallingPermission(permission)
7637 == PackageManager.PERMISSION_GRANTED) {
7641 String msg = "Permission Denial: " + func + " from pid="
7642 + Binder.getCallingPid()
7643 + ", uid=" + Binder.getCallingUid()
7644 + " requires " + permission;
7646 throw new SecurityException(msg);
7650 * Determine if UID is holding permissions required to access {@link Uri} in
7651 * the given {@link ProviderInfo}. Final permission checking is always done
7652 * in {@link ContentProvider}.
7654 private final boolean checkHoldingPermissionsLocked(
7655 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7656 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7657 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7658 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7659 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7660 != PERMISSION_GRANTED) {
7664 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7667 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7668 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7669 if (pi.applicationInfo.uid == uid) {
7671 } else if (!pi.exported) {
7675 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7676 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7678 // check if target holds top-level <provider> permissions
7679 if (!readMet && pi.readPermission != null && considerUidPermissions
7680 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7683 if (!writeMet && pi.writePermission != null && considerUidPermissions
7684 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7688 // track if unprotected read/write is allowed; any denied
7689 // <path-permission> below removes this ability
7690 boolean allowDefaultRead = pi.readPermission == null;
7691 boolean allowDefaultWrite = pi.writePermission == null;
7693 // check if target holds any <path-permission> that match uri
7694 final PathPermission[] pps = pi.pathPermissions;
7696 final String path = grantUri.uri.getPath();
7698 while (i > 0 && (!readMet || !writeMet)) {
7700 PathPermission pp = pps[i];
7701 if (pp.match(path)) {
7703 final String pprperm = pp.getReadPermission();
7704 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7705 "Checking read perm for " + pprperm + " for " + pp.getPath()
7706 + ": match=" + pp.match(path)
7707 + " check=" + pm.checkUidPermission(pprperm, uid));
7708 if (pprperm != null) {
7709 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7710 == PERMISSION_GRANTED) {
7713 allowDefaultRead = false;
7718 final String ppwperm = pp.getWritePermission();
7719 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7720 "Checking write perm " + ppwperm + " for " + pp.getPath()
7721 + ": match=" + pp.match(path)
7722 + " check=" + pm.checkUidPermission(ppwperm, uid));
7723 if (ppwperm != null) {
7724 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7725 == PERMISSION_GRANTED) {
7728 allowDefaultWrite = false;
7736 // grant unprotected <provider> read/write, if not blocked by
7737 // <path-permission> above
7738 if (allowDefaultRead) readMet = true;
7739 if (allowDefaultWrite) writeMet = true;
7741 } catch (RemoteException e) {
7745 return readMet && writeMet;
7748 public int getAppStartMode(int uid, String packageName) {
7749 synchronized (this) {
7750 return checkAllowBackgroundLocked(uid, packageName, -1, true);
7754 int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7755 boolean allowWhenForeground) {
7756 UidRecord uidRec = mActiveUids.get(uid);
7757 if (!mLenientBackgroundCheck) {
7758 if (!allowWhenForeground || uidRec == null
7759 || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7760 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7761 packageName) != AppOpsManager.MODE_ALLOWED) {
7762 return ActivityManager.APP_START_MODE_DELAYED;
7766 } else if (uidRec == null || uidRec.idle) {
7767 if (callingPid >= 0) {
7769 synchronized (mPidsSelfLocked) {
7770 proc = mPidsSelfLocked.get(callingPid);
7772 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7773 // Whoever is instigating this is in the foreground, so we will allow it
7775 return ActivityManager.APP_START_MODE_NORMAL;
7778 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7779 != AppOpsManager.MODE_ALLOWED) {
7780 return ActivityManager.APP_START_MODE_DELAYED;
7783 return ActivityManager.APP_START_MODE_NORMAL;
7786 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7787 ProviderInfo pi = null;
7788 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7793 pi = AppGlobals.getPackageManager().resolveContentProvider(
7794 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7795 } catch (RemoteException ex) {
7801 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7802 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7803 if (targetUris != null) {
7804 return targetUris.get(grantUri);
7809 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7810 String targetPkg, int targetUid, GrantUri grantUri) {
7811 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7812 if (targetUris == null) {
7813 targetUris = Maps.newArrayMap();
7814 mGrantedUriPermissions.put(targetUid, targetUris);
7817 UriPermission perm = targetUris.get(grantUri);
7819 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7820 targetUris.put(grantUri, perm);
7826 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7827 final int modeFlags) {
7828 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7829 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7830 : UriPermission.STRENGTH_OWNED;
7832 // Root gets to do everything.
7837 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7838 if (perms == null) return false;
7840 // First look for exact match
7841 final UriPermission exactPerm = perms.get(grantUri);
7842 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7846 // No exact match, look for prefixes
7847 final int N = perms.size();
7848 for (int i = 0; i < N; i++) {
7849 final UriPermission perm = perms.valueAt(i);
7850 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7851 && perm.getStrength(modeFlags) >= minStrength) {
7860 * @param uri This uri must NOT contain an embedded userId.
7861 * @param userId The userId in which the uri is to be resolved.
7864 public int checkUriPermission(Uri uri, int pid, int uid,
7865 final int modeFlags, int userId, IBinder callerToken) {
7866 enforceNotIsolatedCaller("checkUriPermission");
7868 // Another redirected-binder-call permissions check as in
7869 // {@link checkPermissionWithToken}.
7870 Identity tlsIdentity = sCallerIdentity.get();
7871 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7872 uid = tlsIdentity.uid;
7873 pid = tlsIdentity.pid;
7876 // Our own process gets to do everything.
7877 if (pid == MY_PID) {
7878 return PackageManager.PERMISSION_GRANTED;
7880 synchronized (this) {
7881 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7882 ? PackageManager.PERMISSION_GRANTED
7883 : PackageManager.PERMISSION_DENIED;
7888 * Check if the targetPkg can be granted permission to access uri by
7889 * the callingUid using the given modeFlags. Throws a security exception
7890 * if callingUid is not allowed to do this. Returns the uid of the target
7891 * if the URI permission grant should be performed; returns -1 if it is not
7892 * needed (for example targetPkg already has permission to access the URI).
7893 * If you already know the uid of the target, you can supply it in
7894 * lastTargetUid else set that to -1.
7896 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7897 final int modeFlags, int lastTargetUid) {
7898 if (!Intent.isAccessUriMode(modeFlags)) {
7902 if (targetPkg != null) {
7903 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7904 "Checking grant " + targetPkg + " permission to " + grantUri);
7907 final IPackageManager pm = AppGlobals.getPackageManager();
7909 // If this is not a content: uri, we can't do anything with it.
7910 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7911 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7912 "Can't grant URI permission for non-content URI: " + grantUri);
7916 final String authority = grantUri.uri.getAuthority();
7917 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7919 Slog.w(TAG, "No content provider found for permission check: " +
7920 grantUri.uri.toSafeString());
7924 int targetUid = lastTargetUid;
7925 if (targetUid < 0 && targetPkg != null) {
7927 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7928 UserHandle.getUserId(callingUid));
7929 if (targetUid < 0) {
7930 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7931 "Can't grant URI permission no uid for: " + targetPkg);
7934 } catch (RemoteException ex) {
7939 if (targetUid >= 0) {
7940 // First... does the target actually need this permission?
7941 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7942 // No need to grant the target this permission.
7943 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7944 "Target " + targetPkg + " already has full permission to " + grantUri);
7948 // First... there is no target package, so can anyone access it?
7949 boolean allowed = pi.exported;
7950 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7951 if (pi.readPermission != null) {
7955 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7956 if (pi.writePermission != null) {
7965 /* There is a special cross user grant if:
7966 * - The target is on another user.
7967 * - Apps on the current user can access the uri without any uid permissions.
7968 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7969 * grant uri permissions.
7971 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7972 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7973 modeFlags, false /*without considering the uid permissions*/);
7975 // Second... is the provider allowing granting of URI permissions?
7976 if (!specialCrossUserGrant) {
7977 if (!pi.grantUriPermissions) {
7978 throw new SecurityException("Provider " + pi.packageName
7980 + " does not allow granting of Uri permissions (uri "
7983 if (pi.uriPermissionPatterns != null) {
7984 final int N = pi.uriPermissionPatterns.length;
7985 boolean allowed = false;
7986 for (int i=0; i<N; i++) {
7987 if (pi.uriPermissionPatterns[i] != null
7988 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7994 throw new SecurityException("Provider " + pi.packageName
7996 + " does not allow granting of permission to path of Uri "
8002 // Third... does the caller itself have permission to access
8004 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8005 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8006 // Require they hold a strong enough Uri permission
8007 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8008 throw new SecurityException("Uid " + callingUid
8009 + " does not have permission to uri " + grantUri);
8017 * @param uri This uri must NOT contain an embedded userId.
8018 * @param userId The userId in which the uri is to be resolved.
8021 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8022 final int modeFlags, int userId) {
8023 enforceNotIsolatedCaller("checkGrantUriPermission");
8024 synchronized(this) {
8025 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8026 new GrantUri(userId, uri, false), modeFlags, -1);
8030 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8031 final int modeFlags, UriPermissionOwner owner) {
8032 if (!Intent.isAccessUriMode(modeFlags)) {
8036 // So here we are: the caller has the assumed permission
8037 // to the uri, and the target doesn't. Let's now give this to
8040 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8041 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8043 final String authority = grantUri.uri.getAuthority();
8044 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8046 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8050 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8051 grantUri.prefix = true;
8053 final UriPermission perm = findOrCreateUriPermissionLocked(
8054 pi.packageName, targetPkg, targetUid, grantUri);
8055 perm.grantModes(modeFlags, owner);
8058 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8059 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8060 if (targetPkg == null) {
8061 throw new NullPointerException("targetPkg");
8064 final IPackageManager pm = AppGlobals.getPackageManager();
8066 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8067 } catch (RemoteException ex) {
8071 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8073 if (targetUid < 0) {
8077 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8081 static class NeededUriGrants extends ArrayList<GrantUri> {
8082 final String targetPkg;
8083 final int targetUid;
8086 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8087 this.targetPkg = targetPkg;
8088 this.targetUid = targetUid;
8094 * Like checkGrantUriPermissionLocked, but takes an Intent.
8096 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8097 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8098 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8099 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8100 + " clip=" + (intent != null ? intent.getClipData() : null)
8101 + " from " + intent + "; flags=0x"
8102 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8104 if (targetPkg == null) {
8105 throw new NullPointerException("targetPkg");
8108 if (intent == null) {
8111 Uri data = intent.getData();
8112 ClipData clip = intent.getClipData();
8113 if (data == null && clip == null) {
8116 // Default userId for uris in the intent (if they don't specify it themselves)
8117 int contentUserHint = intent.getContentUserHint();
8118 if (contentUserHint == UserHandle.USER_CURRENT) {
8119 contentUserHint = UserHandle.getUserId(callingUid);
8121 final IPackageManager pm = AppGlobals.getPackageManager();
8123 if (needed != null) {
8124 targetUid = needed.targetUid;
8127 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8129 } catch (RemoteException ex) {
8132 if (targetUid < 0) {
8133 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8134 "Can't grant URI permission no uid for: " + targetPkg
8135 + " on user " + targetUserId);
8140 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8141 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8143 if (targetUid > 0) {
8144 if (needed == null) {
8145 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8147 needed.add(grantUri);
8151 for (int i=0; i<clip.getItemCount(); i++) {
8152 Uri uri = clip.getItemAt(i).getUri();
8154 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8155 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8157 if (targetUid > 0) {
8158 if (needed == null) {
8159 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8161 needed.add(grantUri);
8164 Intent clipIntent = clip.getItemAt(i).getIntent();
8165 if (clipIntent != null) {
8166 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8167 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8168 if (newNeeded != null) {
8180 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8182 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8183 UriPermissionOwner owner) {
8184 if (needed != null) {
8185 for (int i=0; i<needed.size(); i++) {
8186 GrantUri grantUri = needed.get(i);
8187 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8188 grantUri, needed.flags, owner);
8193 void grantUriPermissionFromIntentLocked(int callingUid,
8194 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8195 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8196 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8197 if (needed == null) {
8201 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8205 * @param uri This uri must NOT contain an embedded userId.
8206 * @param userId The userId in which the uri is to be resolved.
8209 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8210 final int modeFlags, int userId) {
8211 enforceNotIsolatedCaller("grantUriPermission");
8212 GrantUri grantUri = new GrantUri(userId, uri, false);
8213 synchronized(this) {
8214 final ProcessRecord r = getRecordForAppLocked(caller);
8216 throw new SecurityException("Unable to find app for caller "
8218 + " when granting permission to uri " + grantUri);
8220 if (targetPkg == null) {
8221 throw new IllegalArgumentException("null target");
8223 if (grantUri == null) {
8224 throw new IllegalArgumentException("null uri");
8227 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8228 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8229 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8230 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8232 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8233 UserHandle.getUserId(r.uid));
8237 void removeUriPermissionIfNeededLocked(UriPermission perm) {
8238 if (perm.modeFlags == 0) {
8239 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8241 if (perms != null) {
8242 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8243 "Removing " + perm.targetUid + " permission to " + perm.uri);
8245 perms.remove(perm.uri);
8246 if (perms.isEmpty()) {
8247 mGrantedUriPermissions.remove(perm.targetUid);
8253 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8254 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8255 "Revoking all granted permissions to " + grantUri);
8257 final IPackageManager pm = AppGlobals.getPackageManager();
8258 final String authority = grantUri.uri.getAuthority();
8259 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8261 Slog.w(TAG, "No content provider found for permission revoke: "
8262 + grantUri.toSafeString());
8266 // Does the caller have this permission on the URI?
8267 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8268 // If they don't have direct access to the URI, then revoke any
8269 // ownerless URI permissions that have been granted to them.
8270 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8271 if (perms != null) {
8272 boolean persistChanged = false;
8273 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8274 final UriPermission perm = it.next();
8275 if (perm.uri.sourceUserId == grantUri.sourceUserId
8276 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8277 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8278 "Revoking non-owned " + perm.targetUid
8279 + " permission to " + perm.uri);
8280 persistChanged |= perm.revokeModes(
8281 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8282 if (perm.modeFlags == 0) {
8287 if (perms.isEmpty()) {
8288 mGrantedUriPermissions.remove(callingUid);
8290 if (persistChanged) {
8291 schedulePersistUriGrants();
8297 boolean persistChanged = false;
8299 // Go through all of the permissions and remove any that match.
8300 int N = mGrantedUriPermissions.size();
8301 for (int i = 0; i < N; i++) {
8302 final int targetUid = mGrantedUriPermissions.keyAt(i);
8303 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8305 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8306 final UriPermission perm = it.next();
8307 if (perm.uri.sourceUserId == grantUri.sourceUserId
8308 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8309 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8310 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8311 persistChanged |= perm.revokeModes(
8312 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8313 if (perm.modeFlags == 0) {
8319 if (perms.isEmpty()) {
8320 mGrantedUriPermissions.remove(targetUid);
8326 if (persistChanged) {
8327 schedulePersistUriGrants();
8332 * @param uri This uri must NOT contain an embedded userId.
8333 * @param userId The userId in which the uri is to be resolved.
8336 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8338 enforceNotIsolatedCaller("revokeUriPermission");
8339 synchronized(this) {
8340 final ProcessRecord r = getRecordForAppLocked(caller);
8342 throw new SecurityException("Unable to find app for caller "
8344 + " when revoking permission to uri " + uri);
8347 Slog.w(TAG, "revokeUriPermission: null uri");
8351 if (!Intent.isAccessUriMode(modeFlags)) {
8355 final String authority = uri.getAuthority();
8356 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8358 Slog.w(TAG, "No content provider found for permission revoke: "
8359 + uri.toSafeString());
8363 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8368 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8371 * @param packageName Package name to match, or {@code null} to apply to all
8373 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8375 * @param persistable If persistable grants should be removed.
8377 private void removeUriPermissionsForPackageLocked(
8378 String packageName, int userHandle, boolean persistable) {
8379 if (userHandle == UserHandle.USER_ALL && packageName == null) {
8380 throw new IllegalArgumentException("Must narrow by either package or user");
8383 boolean persistChanged = false;
8385 int N = mGrantedUriPermissions.size();
8386 for (int i = 0; i < N; i++) {
8387 final int targetUid = mGrantedUriPermissions.keyAt(i);
8388 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8390 // Only inspect grants matching user
8391 if (userHandle == UserHandle.USER_ALL
8392 || userHandle == UserHandle.getUserId(targetUid)) {
8393 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8394 final UriPermission perm = it.next();
8396 // Only inspect grants matching package
8397 if (packageName == null || perm.sourcePkg.equals(packageName)
8398 || perm.targetPkg.equals(packageName)) {
8399 persistChanged |= perm.revokeModes(persistable
8400 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8402 // Only remove when no modes remain; any persisted grants
8403 // will keep this alive.
8404 if (perm.modeFlags == 0) {
8410 if (perms.isEmpty()) {
8411 mGrantedUriPermissions.remove(targetUid);
8418 if (persistChanged) {
8419 schedulePersistUriGrants();
8424 public IBinder newUriPermissionOwner(String name) {
8425 enforceNotIsolatedCaller("newUriPermissionOwner");
8426 synchronized(this) {
8427 UriPermissionOwner owner = new UriPermissionOwner(this, name);
8428 return owner.getExternalTokenLocked();
8433 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8434 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8435 synchronized(this) {
8436 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8438 throw new IllegalArgumentException("Activity does not exist; token="
8441 return r.getUriPermissionsLocked().getExternalTokenLocked();
8445 * @param uri This uri must NOT contain an embedded userId.
8446 * @param sourceUserId The userId in which the uri is to be resolved.
8447 * @param targetUserId The userId of the app that receives the grant.
8450 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8451 final int modeFlags, int sourceUserId, int targetUserId) {
8452 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8453 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8454 "grantUriPermissionFromOwner", null);
8455 synchronized(this) {
8456 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8457 if (owner == null) {
8458 throw new IllegalArgumentException("Unknown owner: " + token);
8460 if (fromUid != Binder.getCallingUid()) {
8461 if (Binder.getCallingUid() != Process.myUid()) {
8462 // Only system code can grant URI permissions on behalf
8464 throw new SecurityException("nice try");
8467 if (targetPkg == null) {
8468 throw new IllegalArgumentException("null target");
8471 throw new IllegalArgumentException("null uri");
8474 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8475 modeFlags, owner, targetUserId);
8480 * @param uri This uri must NOT contain an embedded userId.
8481 * @param userId The userId in which the uri is to be resolved.
8484 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8485 synchronized(this) {
8486 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8487 if (owner == null) {
8488 throw new IllegalArgumentException("Unknown owner: " + token);
8492 owner.removeUriPermissionsLocked(mode);
8494 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8499 private void schedulePersistUriGrants() {
8500 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8501 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8502 10 * DateUtils.SECOND_IN_MILLIS);
8506 private void writeGrantedUriPermissions() {
8507 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8509 // Snapshot permissions so we can persist without lock
8510 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8511 synchronized (this) {
8512 final int size = mGrantedUriPermissions.size();
8513 for (int i = 0; i < size; i++) {
8514 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8515 for (UriPermission perm : perms.values()) {
8516 if (perm.persistedModeFlags != 0) {
8517 persist.add(perm.snapshot());
8523 FileOutputStream fos = null;
8525 fos = mGrantFile.startWrite();
8527 XmlSerializer out = new FastXmlSerializer();
8528 out.setOutput(fos, StandardCharsets.UTF_8.name());
8529 out.startDocument(null, true);
8530 out.startTag(null, TAG_URI_GRANTS);
8531 for (UriPermission.Snapshot perm : persist) {
8532 out.startTag(null, TAG_URI_GRANT);
8533 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8534 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8535 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8536 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8537 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8538 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8539 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8540 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8541 out.endTag(null, TAG_URI_GRANT);
8543 out.endTag(null, TAG_URI_GRANTS);
8546 mGrantFile.finishWrite(fos);
8547 } catch (IOException e) {
8549 mGrantFile.failWrite(fos);
8554 private void readGrantedUriPermissionsLocked() {
8555 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8557 final long now = System.currentTimeMillis();
8559 FileInputStream fis = null;
8561 fis = mGrantFile.openRead();
8562 final XmlPullParser in = Xml.newPullParser();
8563 in.setInput(fis, StandardCharsets.UTF_8.name());
8566 while ((type = in.next()) != END_DOCUMENT) {
8567 final String tag = in.getName();
8568 if (type == START_TAG) {
8569 if (TAG_URI_GRANT.equals(tag)) {
8570 final int sourceUserId;
8571 final int targetUserId;
8572 final int userHandle = readIntAttribute(in,
8573 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8574 if (userHandle != UserHandle.USER_NULL) {
8575 // For backwards compatibility.
8576 sourceUserId = userHandle;
8577 targetUserId = userHandle;
8579 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8580 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8582 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8583 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8584 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8585 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8586 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8587 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8589 // Sanity check that provider still belongs to source package
8590 final ProviderInfo pi = getProviderInfoLocked(
8591 uri.getAuthority(), sourceUserId);
8592 if (pi != null && sourcePkg.equals(pi.packageName)) {
8595 targetUid = AppGlobals.getPackageManager().getPackageUid(
8596 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8597 } catch (RemoteException e) {
8599 if (targetUid != -1) {
8600 final UriPermission perm = findOrCreateUriPermissionLocked(
8601 sourcePkg, targetPkg, targetUid,
8602 new GrantUri(sourceUserId, uri, prefix));
8603 perm.initPersistedModes(modeFlags, createdTime);
8606 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8607 + " but instead found " + pi);
8612 } catch (FileNotFoundException e) {
8613 // Missing grants is okay
8614 } catch (IOException e) {
8615 Slog.wtf(TAG, "Failed reading Uri grants", e);
8616 } catch (XmlPullParserException e) {
8617 Slog.wtf(TAG, "Failed reading Uri grants", e);
8619 IoUtils.closeQuietly(fis);
8624 * @param uri This uri must NOT contain an embedded userId.
8625 * @param userId The userId in which the uri is to be resolved.
8628 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8629 enforceNotIsolatedCaller("takePersistableUriPermission");
8631 Preconditions.checkFlagsArgument(modeFlags,
8632 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8634 synchronized (this) {
8635 final int callingUid = Binder.getCallingUid();
8636 boolean persistChanged = false;
8637 GrantUri grantUri = new GrantUri(userId, uri, false);
8639 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8640 new GrantUri(userId, uri, false));
8641 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8642 new GrantUri(userId, uri, true));
8644 final boolean exactValid = (exactPerm != null)
8645 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8646 final boolean prefixValid = (prefixPerm != null)
8647 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8649 if (!(exactValid || prefixValid)) {
8650 throw new SecurityException("No persistable permission grants found for UID "
8651 + callingUid + " and Uri " + grantUri.toSafeString());
8655 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8658 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8661 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8663 if (persistChanged) {
8664 schedulePersistUriGrants();
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 releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8675 enforceNotIsolatedCaller("releasePersistableUriPermission");
8677 Preconditions.checkFlagsArgument(modeFlags,
8678 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8680 synchronized (this) {
8681 final int callingUid = Binder.getCallingUid();
8682 boolean persistChanged = false;
8684 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8685 new GrantUri(userId, uri, false));
8686 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8687 new GrantUri(userId, uri, true));
8688 if (exactPerm == null && prefixPerm == null) {
8689 throw new SecurityException("No permission grants found for UID " + callingUid
8690 + " and Uri " + uri.toSafeString());
8693 if (exactPerm != null) {
8694 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8695 removeUriPermissionIfNeededLocked(exactPerm);
8697 if (prefixPerm != null) {
8698 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8699 removeUriPermissionIfNeededLocked(prefixPerm);
8702 if (persistChanged) {
8703 schedulePersistUriGrants();
8709 * Prune any older {@link UriPermission} for the given UID until outstanding
8710 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8712 * @return if any mutations occured that require persisting.
8714 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8715 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8716 if (perms == null) return false;
8717 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8719 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8720 for (UriPermission perm : perms.values()) {
8721 if (perm.persistedModeFlags != 0) {
8722 persisted.add(perm);
8726 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8727 if (trimCount <= 0) return false;
8729 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8730 for (int i = 0; i < trimCount; i++) {
8731 final UriPermission perm = persisted.get(i);
8733 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8734 "Trimming grant created at " + perm.persistedCreateTime);
8736 perm.releasePersistableModes(~0);
8737 removeUriPermissionIfNeededLocked(perm);
8744 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8745 String packageName, boolean incoming) {
8746 enforceNotIsolatedCaller("getPersistedUriPermissions");
8747 Preconditions.checkNotNull(packageName, "packageName");
8749 final int callingUid = Binder.getCallingUid();
8750 final IPackageManager pm = AppGlobals.getPackageManager();
8752 final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8753 UserHandle.getUserId(callingUid));
8754 if (packageUid != callingUid) {
8755 throw new SecurityException(
8756 "Package " + packageName + " does not belong to calling UID " + callingUid);
8758 } catch (RemoteException e) {
8759 throw new SecurityException("Failed to verify package name ownership");
8762 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8763 synchronized (this) {
8765 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8767 if (perms == null) {
8768 Slog.w(TAG, "No permission grants found for " + packageName);
8770 for (UriPermission perm : perms.values()) {
8771 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8772 result.add(perm.buildPersistedPublicApiObject());
8777 final int size = mGrantedUriPermissions.size();
8778 for (int i = 0; i < size; i++) {
8779 final ArrayMap<GrantUri, UriPermission> perms =
8780 mGrantedUriPermissions.valueAt(i);
8781 for (UriPermission perm : perms.values()) {
8782 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8783 result.add(perm.buildPersistedPublicApiObject());
8789 return new ParceledListSlice<android.content.UriPermission>(result);
8793 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8794 String packageName, int userId) {
8795 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8796 "getGrantedUriPermissions");
8798 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8799 synchronized (this) {
8800 final int size = mGrantedUriPermissions.size();
8801 for (int i = 0; i < size; i++) {
8802 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8803 for (UriPermission perm : perms.values()) {
8804 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8805 && perm.persistedModeFlags != 0) {
8806 result.add(perm.buildPersistedPublicApiObject());
8811 return new ParceledListSlice<android.content.UriPermission>(result);
8815 public void clearGrantedUriPermissions(String packageName, int userId) {
8816 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8817 "clearGrantedUriPermissions");
8818 removeUriPermissionsForPackageLocked(packageName, userId, true);
8822 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8823 synchronized (this) {
8825 who != null ? getRecordForAppLocked(who) : null;
8826 if (app == null) return;
8828 Message msg = Message.obtain();
8829 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8831 msg.arg1 = waiting ? 1 : 0;
8832 mUiHandler.sendMessage(msg);
8837 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8838 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8839 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8840 outInfo.availMem = Process.getFreeMemory();
8841 outInfo.totalMem = Process.getTotalMemory();
8842 outInfo.threshold = homeAppMem;
8843 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8844 outInfo.hiddenAppThreshold = cachedAppMem;
8845 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8846 ProcessList.SERVICE_ADJ);
8847 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8848 ProcessList.VISIBLE_APP_ADJ);
8849 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8850 ProcessList.FOREGROUND_APP_ADJ);
8853 // =========================================================
8855 // =========================================================
8858 public List<IAppTask> getAppTasks(String callingPackage) {
8859 int callingUid = Binder.getCallingUid();
8860 long ident = Binder.clearCallingIdentity();
8862 synchronized(this) {
8863 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8865 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8867 final int N = mRecentTasks.size();
8868 for (int i = 0; i < N; i++) {
8869 TaskRecord tr = mRecentTasks.get(i);
8870 // Skip tasks that do not match the caller. We don't need to verify
8871 // callingPackage, because we are also limiting to callingUid and know
8872 // that will limit to the correct security sandbox.
8873 if (tr.effectiveUid != callingUid) {
8876 Intent intent = tr.getBaseIntent();
8877 if (intent == null ||
8878 !callingPackage.equals(intent.getComponent().getPackageName())) {
8881 ActivityManager.RecentTaskInfo taskInfo =
8882 createRecentTaskInfoFromTaskRecord(tr);
8883 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8887 Binder.restoreCallingIdentity(ident);
8894 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8895 final int callingUid = Binder.getCallingUid();
8896 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8898 synchronized(this) {
8899 if (DEBUG_ALL) Slog.v(
8900 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8902 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8905 // TODO: Improve with MRU list from all ActivityStacks.
8906 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8913 * Creates a new RecentTaskInfo from a TaskRecord.
8915 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8916 // Update the task description to reflect any changes in the task stack
8917 tr.updateTaskDescription();
8919 // Compose the recent task info
8920 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8921 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8922 rti.persistentId = tr.taskId;
8923 rti.baseIntent = new Intent(tr.getBaseIntent());
8924 rti.origActivity = tr.origActivity;
8925 rti.realActivity = tr.realActivity;
8926 rti.description = tr.lastDescription;
8927 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8928 rti.userId = tr.userId;
8929 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8930 rti.firstActiveTime = tr.firstActiveTime;
8931 rti.lastActiveTime = tr.lastActiveTime;
8932 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8933 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8934 rti.numActivities = 0;
8935 if (tr.mBounds != null) {
8936 rti.bounds = new Rect(tr.mBounds);
8938 rti.isDockable = tr.canGoInDockedStack();
8939 rti.resizeMode = tr.mResizeMode;
8941 ActivityRecord base = null;
8942 ActivityRecord top = null;
8945 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8946 tmp = tr.mActivities.get(i);
8947 if (tmp.finishing) {
8951 if (top == null || (top.state == ActivityState.INITIALIZING)) {
8954 rti.numActivities++;
8957 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8958 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8963 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8964 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8965 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8967 if (checkPermission(android.Manifest.permission.GET_TASKS,
8968 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8969 // Temporary compatibility: some existing apps on the system image may
8970 // still be requesting the old permission and not switched to the new
8971 // one; if so, we'll still allow them full access. This means we need
8972 // to see if they are holding the old permission and are a system app.
8974 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8976 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8977 + " is using old GET_TASKS but privileged; allowing");
8979 } catch (RemoteException e) {
8984 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8985 + " does not hold REAL_GET_TASKS; limiting output");
8991 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8992 final int callingUid = Binder.getCallingUid();
8993 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8994 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8996 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8997 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8998 synchronized (this) {
8999 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9001 final boolean detailed = checkCallingPermission(
9002 android.Manifest.permission.GET_DETAILED_TASKS)
9003 == PackageManager.PERMISSION_GRANTED;
9005 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9006 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9007 return Collections.emptyList();
9009 mRecentTasks.loadUserRecentsLocked(userId);
9011 final int recentsCount = mRecentTasks.size();
9012 ArrayList<ActivityManager.RecentTaskInfo> res =
9013 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9015 final Set<Integer> includedUsers;
9016 if (includeProfiles) {
9017 includedUsers = mUserController.getProfileIds(userId);
9019 includedUsers = new HashSet<>();
9021 includedUsers.add(Integer.valueOf(userId));
9023 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9024 TaskRecord tr = mRecentTasks.get(i);
9025 // Only add calling user or related users recent tasks
9026 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9027 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9031 if (tr.realActivitySuspended) {
9032 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9036 // Return the entry if desired by the caller. We always return
9037 // the first entry, because callers always expect this to be the
9038 // foreground app. We may filter others if the caller has
9039 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9040 // we should exclude the entry.
9044 || (tr.intent == null)
9045 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9048 // If the caller doesn't have the GET_TASKS permission, then only
9049 // allow them to see a small subset of tasks -- their own and home.
9050 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9051 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9055 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9056 if (tr.stack != null && tr.stack.isHomeStack()) {
9057 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9058 "Skipping, home stack task: " + tr);
9062 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9063 final ActivityStack stack = tr.stack;
9064 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9065 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9066 "Skipping, top task in docked stack: " + tr);
9070 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9071 if (tr.stack != null && tr.stack.isPinnedStack()) {
9072 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9073 "Skipping, pinned stack task: " + tr);
9077 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9078 // Don't include auto remove tasks that are finished or finishing.
9079 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9080 "Skipping, auto-remove without activity: " + tr);
9083 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9084 && !tr.isAvailable) {
9085 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9086 "Skipping, unavail real act: " + tr);
9090 if (!tr.mUserSetupComplete) {
9091 // Don't include task launched while user is not done setting-up.
9092 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9093 "Skipping, user setup not complete: " + tr);
9097 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9099 rti.baseIntent.replaceExtras((Bundle)null);
9111 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9112 synchronized (this) {
9113 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9114 "getTaskThumbnail()");
9115 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9116 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9118 return tr.getTaskThumbnailLocked();
9125 public int addAppTask(IBinder activityToken, Intent intent,
9126 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9127 final int callingUid = Binder.getCallingUid();
9128 final long callingIdent = Binder.clearCallingIdentity();
9131 synchronized (this) {
9132 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9134 throw new IllegalArgumentException("Activity does not exist; token="
9137 ComponentName comp = intent.getComponent();
9139 throw new IllegalArgumentException("Intent " + intent
9140 + " must specify explicit component");
9142 if (thumbnail.getWidth() != mThumbnailWidth
9143 || thumbnail.getHeight() != mThumbnailHeight) {
9144 throw new IllegalArgumentException("Bad thumbnail size: got "
9145 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9146 + mThumbnailWidth + "x" + mThumbnailHeight);
9148 if (intent.getSelector() != null) {
9149 intent.setSelector(null);
9151 if (intent.getSourceBounds() != null) {
9152 intent.setSourceBounds(null);
9154 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9155 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9156 // The caller has added this as an auto-remove task... that makes no
9157 // sense, so turn off auto-remove.
9158 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9160 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9161 // Must be a new task.
9162 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9164 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9165 mLastAddedTaskActivity = null;
9167 ActivityInfo ainfo = mLastAddedTaskActivity;
9168 if (ainfo == null) {
9169 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9170 comp, 0, UserHandle.getUserId(callingUid));
9171 if (ainfo.applicationInfo.uid != callingUid) {
9172 throw new SecurityException(
9173 "Can't add task for another application: target uid="
9174 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9178 // Use the full screen as the context for the task thumbnail
9179 final Point displaySize = new Point();
9180 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9181 r.task.stack.getDisplaySize(displaySize);
9182 thumbnailInfo.taskWidth = displaySize.x;
9183 thumbnailInfo.taskHeight = displaySize.y;
9184 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9186 TaskRecord task = new TaskRecord(this,
9187 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9188 ainfo, intent, description, thumbnailInfo);
9190 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9192 // If this would have caused a trim, then we'll abort because that
9193 // means it would be added at the end of the list but then just removed.
9194 return INVALID_TASK_ID;
9197 final int N = mRecentTasks.size();
9198 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9199 final TaskRecord tr = mRecentTasks.remove(N - 1);
9200 tr.removedFromRecents();
9203 task.inRecents = true;
9204 mRecentTasks.add(task);
9205 r.task.stack.addTask(task, false, "addAppTask");
9207 task.setLastThumbnailLocked(thumbnail);
9208 task.freeLastThumbnail();
9213 Binder.restoreCallingIdentity(callingIdent);
9218 public Point getAppTaskThumbnailSize() {
9219 synchronized (this) {
9220 return new Point(mThumbnailWidth, mThumbnailHeight);
9225 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9226 synchronized (this) {
9227 ActivityRecord r = ActivityRecord.isInStackLocked(token);
9229 r.setTaskDescription(td);
9230 r.task.updateTaskDescription();
9236 public void setTaskResizeable(int taskId, int resizeableMode) {
9237 synchronized (this) {
9238 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9239 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9241 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9244 if (task.mResizeMode != resizeableMode) {
9245 task.mResizeMode = resizeableMode;
9246 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9247 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9248 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9254 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9255 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9256 long ident = Binder.clearCallingIdentity();
9258 synchronized (this) {
9259 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9261 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9264 int stackId = task.stack.mStackId;
9265 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9266 // in crop windows resize mode or if the task size is affected by the docked stack
9267 // changing size. No need to update configuration.
9268 if (bounds != null && task.inCropWindowsResizeMode()
9269 && mStackSupervisor.isStackDockedInEffect(stackId)) {
9270 mWindowManager.scrollTask(task.taskId, bounds);
9274 // Place the task in the right stack if it isn't there already based on
9275 // the requested bounds.
9276 // The stack transition logic is:
9277 // - a null bounds on a freeform task moves that task to fullscreen
9278 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9279 // that task to freeform
9280 // - otherwise the task is not moved
9281 if (!StackId.isTaskResizeAllowed(stackId)) {
9282 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9284 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9285 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9286 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9287 stackId = FREEFORM_WORKSPACE_STACK_ID;
9289 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9290 if (stackId != task.stack.mStackId) {
9291 mStackSupervisor.moveTaskToStackUncheckedLocked(
9292 task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9293 preserveWindow = false;
9296 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9297 false /* deferResume */);
9300 Binder.restoreCallingIdentity(ident);
9305 public Rect getTaskBounds(int taskId) {
9306 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9307 long ident = Binder.clearCallingIdentity();
9308 Rect rect = new Rect();
9310 synchronized (this) {
9311 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9312 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9314 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9317 if (task.stack != null) {
9318 // Return the bounds from window manager since it will be adjusted for various
9319 // things like the presense of a docked stack for tasks that aren't resizeable.
9320 mWindowManager.getTaskBounds(task.taskId, rect);
9322 // Task isn't in window manager yet since it isn't associated with a stack.
9323 // Return the persist value from activity manager
9324 if (task.mBounds != null) {
9325 rect.set(task.mBounds);
9326 } else if (task.mLastNonFullscreenBounds != null) {
9327 rect.set(task.mLastNonFullscreenBounds);
9332 Binder.restoreCallingIdentity(ident);
9338 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9339 if (userId != UserHandle.getCallingUserId()) {
9340 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9341 "getTaskDescriptionIcon");
9343 final File passedIconFile = new File(filePath);
9344 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9345 passedIconFile.getName());
9346 if (!legitIconFile.getPath().equals(filePath)
9347 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9348 throw new IllegalArgumentException("Bad file path: " + filePath
9349 + " passed for userId " + userId);
9351 return mRecentTasks.getTaskDescriptionIcon(filePath);
9355 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9356 throws RemoteException {
9357 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9358 opts.getCustomInPlaceResId() == 0) {
9359 throw new IllegalArgumentException("Expected in-place ActivityOption " +
9360 "with valid animation");
9362 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9363 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9364 opts.getCustomInPlaceResId());
9365 mWindowManager.executeAppTransition();
9368 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9369 boolean removeFromRecents) {
9370 if (removeFromRecents) {
9371 mRecentTasks.remove(tr);
9372 tr.removedFromRecents();
9374 ComponentName component = tr.getBaseIntent().getComponent();
9375 if (component == null) {
9376 Slog.w(TAG, "No component for base intent of task: " + tr);
9380 // Find any running services associated with this app and stop if needed.
9381 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9387 // Determine if the process(es) for this task should be killed.
9388 final String pkg = component.getPackageName();
9389 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9390 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9391 for (int i = 0; i < pmap.size(); i++) {
9393 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9394 for (int j = 0; j < uids.size(); j++) {
9395 ProcessRecord proc = uids.valueAt(j);
9396 if (proc.userId != tr.userId) {
9397 // Don't kill process for a different user.
9400 if (proc == mHomeProcess) {
9401 // Don't kill the home process along with tasks from the same package.
9404 if (!proc.pkgList.containsKey(pkg)) {
9405 // Don't kill process that is not associated with this task.
9409 for (int k = 0; k < proc.activities.size(); k++) {
9410 TaskRecord otherTask = proc.activities.get(k).task;
9411 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9412 // Don't kill process(es) that has an activity in a different task that is
9418 if (proc.foregroundServices) {
9419 // Don't kill process(es) with foreground service.
9423 // Add process to kill list.
9424 procsToKill.add(proc);
9428 // Kill the running processes.
9429 for (int i = 0; i < procsToKill.size(); i++) {
9430 ProcessRecord pr = procsToKill.get(i);
9431 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9432 && pr.curReceiver == null) {
9433 pr.kill("remove task", true);
9435 // We delay killing processes that are not in the background or running a receiver.
9436 pr.waitingToKill = "remove task";
9441 private void removeTasksByPackageNameLocked(String packageName, int userId) {
9442 // Remove all tasks with activities in the specified package from the list of recent tasks
9443 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9444 TaskRecord tr = mRecentTasks.get(i);
9445 if (tr.userId != userId) continue;
9447 ComponentName cn = tr.intent.getComponent();
9448 if (cn != null && cn.getPackageName().equals(packageName)) {
9449 // If the package name matches, remove the task.
9450 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9455 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9458 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9459 TaskRecord tr = mRecentTasks.get(i);
9460 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9464 ComponentName cn = tr.intent.getComponent();
9465 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9466 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9467 if (sameComponent) {
9468 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9474 * Removes the task with the specified task id.
9476 * @param taskId Identifier of the task to be removed.
9477 * @param killProcess Kill any process associated with the task if possible.
9478 * @param removeFromRecents Whether to also remove the task from recents.
9479 * @return Returns true if the given task was found and removed.
9481 private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9482 boolean removeFromRecents) {
9483 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9484 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9486 tr.removeTaskActivitiesLocked();
9487 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9488 if (tr.isPersistable) {
9489 notifyTaskPersisterLocked(null, true);
9493 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9498 public void removeStack(int stackId) {
9499 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9500 if (stackId == HOME_STACK_ID) {
9501 throw new IllegalArgumentException("Removing home stack is not allowed.");
9504 synchronized (this) {
9505 final long ident = Binder.clearCallingIdentity();
9507 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9508 if (stack == null) {
9511 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9512 for (int i = tasks.size() - 1; i >= 0; i--) {
9513 removeTaskByIdLocked(
9514 tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9517 Binder.restoreCallingIdentity(ident);
9523 public boolean removeTask(int taskId) {
9524 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9525 synchronized (this) {
9526 final long ident = Binder.clearCallingIdentity();
9528 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9530 Binder.restoreCallingIdentity(ident);
9536 * TODO: Add mController hook
9539 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9540 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9542 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9543 synchronized(this) {
9544 moveTaskToFrontLocked(taskId, flags, bOptions);
9548 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9549 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9551 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9552 Binder.getCallingUid(), -1, -1, "Task to front")) {
9553 ActivityOptions.abort(options);
9556 final long origId = Binder.clearCallingIdentity();
9558 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9560 Slog.d(TAG, "Could not find task for id: "+ taskId);
9563 if (mStackSupervisor.isLockTaskModeViolation(task)) {
9564 mStackSupervisor.showLockTaskToast();
9565 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9568 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9569 if (prev != null && prev.isRecentsActivity()) {
9570 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9572 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9573 false /* forceNonResizable */);
9575 Binder.restoreCallingIdentity(origId);
9577 ActivityOptions.abort(options);
9581 * Moves an activity, and all of the other activities within the same task, to the bottom
9582 * of the history stack. The activity's order within the task is unchanged.
9584 * @param token A reference to the activity we wish to move
9585 * @param nonRoot If false then this only works if the activity is the root
9586 * of a task; if true it will work for any activity in a task.
9587 * @return Returns true if the move completed, false if not.
9590 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9591 enforceNotIsolatedCaller("moveActivityTaskToBack");
9592 synchronized(this) {
9593 final long origId = Binder.clearCallingIdentity();
9595 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9596 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9598 if (mStackSupervisor.isLockedTask(task)) {
9599 mStackSupervisor.showLockTaskToast();
9602 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9605 Binder.restoreCallingIdentity(origId);
9612 public void moveTaskBackwards(int task) {
9613 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9614 "moveTaskBackwards()");
9616 synchronized(this) {
9617 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9618 Binder.getCallingUid(), -1, -1, "Task backwards")) {
9621 final long origId = Binder.clearCallingIdentity();
9622 moveTaskBackwardsLocked(task);
9623 Binder.restoreCallingIdentity(origId);
9627 private final void moveTaskBackwardsLocked(int task) {
9628 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9632 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9633 IActivityContainerCallback callback) throws RemoteException {
9634 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9635 synchronized (this) {
9636 if (parentActivityToken == null) {
9637 throw new IllegalArgumentException("parent token must not be null");
9639 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9643 if (callback == null) {
9644 throw new IllegalArgumentException("callback must not be null");
9646 return mStackSupervisor.createVirtualActivityContainer(r, callback);
9651 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9652 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9653 synchronized (this) {
9654 mStackSupervisor.deleteActivityContainer(container);
9659 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9660 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9661 synchronized (this) {
9662 final int stackId = mStackSupervisor.getNextStackId();
9663 final ActivityStack stack =
9664 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9665 if (stack == null) {
9668 return stack.mActivityContainer;
9673 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9674 synchronized (this) {
9675 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9676 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9677 return stack.mActivityContainer.getDisplayId();
9679 return Display.DEFAULT_DISPLAY;
9684 public int getActivityStackId(IBinder token) throws RemoteException {
9685 synchronized (this) {
9686 ActivityStack stack = ActivityRecord.getStackLocked(token);
9687 if (stack == null) {
9688 return INVALID_STACK_ID;
9690 return stack.mStackId;
9695 public void exitFreeformMode(IBinder token) throws RemoteException {
9696 synchronized (this) {
9697 long ident = Binder.clearCallingIdentity();
9699 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9701 throw new IllegalArgumentException(
9702 "exitFreeformMode: No activity record matching token=" + token);
9704 final ActivityStack stack = r.getStackLocked(token);
9705 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9706 throw new IllegalStateException(
9707 "exitFreeformMode: You can only go fullscreen from freeform.");
9709 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9710 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9711 ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9713 Binder.restoreCallingIdentity(ident);
9719 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9720 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9721 if (stackId == HOME_STACK_ID) {
9722 throw new IllegalArgumentException(
9723 "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9725 synchronized (this) {
9726 long ident = Binder.clearCallingIdentity();
9728 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9729 + " to stackId=" + stackId + " toTop=" + toTop);
9730 if (stackId == DOCKED_STACK_ID) {
9731 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9732 null /* initialBounds */);
9734 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9735 !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9736 if (result && stackId == DOCKED_STACK_ID) {
9737 // If task moved to docked stack - show recents if needed.
9738 mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9739 "moveTaskToDockedStack");
9742 Binder.restoreCallingIdentity(ident);
9748 public void swapDockedAndFullscreenStack() throws RemoteException {
9749 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9750 synchronized (this) {
9751 long ident = Binder.clearCallingIdentity();
9753 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9754 FULLSCREEN_WORKSPACE_STACK_ID);
9755 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9757 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9758 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9760 if (topTask == null || tasks == null || tasks.size() == 0) {
9762 "Unable to swap tasks, either docked or fullscreen stack is empty.");
9766 // TODO: App transition
9767 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9769 // Defer the resume so resume/pausing while moving stacks is dangerous.
9770 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9771 false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9772 ANIMATE, true /* deferResume */);
9773 final int size = tasks.size();
9774 for (int i = 0; i < size; i++) {
9775 final int id = tasks.get(i).taskId;
9776 if (id == topTask.taskId) {
9779 mStackSupervisor.moveTaskToStackLocked(id,
9780 FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9781 "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9784 // Because we deferred the resume, to avoid conflicts with stack switches while
9785 // resuming, we need to do it after all the tasks are moved.
9786 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9787 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9789 mWindowManager.executeAppTransition();
9791 Binder.restoreCallingIdentity(ident);
9797 * Moves the input task to the docked stack.
9799 * @param taskId Id of task to move.
9800 * @param createMode The mode the docked stack should be created in if it doesn't exist
9802 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9804 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9805 * @param toTop If the task and stack should be moved to the top.
9806 * @param animate Whether we should play an animation for the moving the task
9807 * @param initialBounds If the docked stack gets created, it will use these bounds for the
9808 * docked stack. Pass {@code null} to use default bounds.
9811 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9812 Rect initialBounds, boolean moveHomeStackFront) {
9813 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9814 synchronized (this) {
9815 long ident = Binder.clearCallingIdentity();
9817 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9818 + " to createMode=" + createMode + " toTop=" + toTop);
9819 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9820 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9821 taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9822 animate, DEFER_RESUME);
9824 if (moveHomeStackFront) {
9825 mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9827 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9831 Binder.restoreCallingIdentity(ident);
9837 * Moves the top activity in the input stackId to the pinned stack.
9839 * @param stackId Id of stack to move the top activity to pinned stack.
9840 * @param bounds Bounds to use for pinned stack.
9842 * @return True if the top activity of the input stack was successfully moved to the pinned
9846 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9847 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9848 synchronized (this) {
9849 if (!mSupportsPictureInPicture) {
9850 throw new IllegalStateException("moveTopActivityToPinnedStack:"
9851 + "Device doesn't support picture-in-pciture mode");
9854 long ident = Binder.clearCallingIdentity();
9856 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9858 Binder.restoreCallingIdentity(ident);
9864 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9865 boolean preserveWindows, boolean animate, int animationDuration) {
9866 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9867 long ident = Binder.clearCallingIdentity();
9869 synchronized (this) {
9871 if (stackId == PINNED_STACK_ID) {
9872 mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9874 throw new IllegalArgumentException("Stack: " + stackId
9875 + " doesn't support animated resize.");
9878 mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9879 null /* tempTaskInsetBounds */, preserveWindows,
9880 allowResizeInDockedMode, !DEFER_RESUME);
9884 Binder.restoreCallingIdentity(ident);
9889 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9890 Rect tempDockedTaskInsetBounds,
9891 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9892 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9893 "resizeDockedStack()");
9894 long ident = Binder.clearCallingIdentity();
9896 synchronized (this) {
9897 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9898 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9902 Binder.restoreCallingIdentity(ident);
9907 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9908 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9909 "resizePinnedStack()");
9910 final long ident = Binder.clearCallingIdentity();
9912 synchronized (this) {
9913 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9916 Binder.restoreCallingIdentity(ident);
9921 public void positionTaskInStack(int taskId, int stackId, int position) {
9922 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9923 if (stackId == HOME_STACK_ID) {
9924 throw new IllegalArgumentException(
9925 "positionTaskInStack: Attempt to change the position of task "
9926 + taskId + " in/to home stack");
9928 synchronized (this) {
9929 long ident = Binder.clearCallingIdentity();
9931 if (DEBUG_STACK) Slog.d(TAG_STACK,
9932 "positionTaskInStack: positioning task=" + taskId
9933 + " in stackId=" + stackId + " at position=" + position);
9934 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9936 Binder.restoreCallingIdentity(ident);
9942 public List<StackInfo> getAllStackInfos() {
9943 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9944 long ident = Binder.clearCallingIdentity();
9946 synchronized (this) {
9947 return mStackSupervisor.getAllStackInfosLocked();
9950 Binder.restoreCallingIdentity(ident);
9955 public StackInfo getStackInfo(int stackId) {
9956 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9957 long ident = Binder.clearCallingIdentity();
9959 synchronized (this) {
9960 return mStackSupervisor.getStackInfoLocked(stackId);
9963 Binder.restoreCallingIdentity(ident);
9968 public boolean isInHomeStack(int taskId) {
9969 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9970 long ident = Binder.clearCallingIdentity();
9972 synchronized (this) {
9973 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9974 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9975 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9978 Binder.restoreCallingIdentity(ident);
9983 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9984 synchronized(this) {
9985 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9990 public void updateDeviceOwner(String packageName) {
9991 final int callingUid = Binder.getCallingUid();
9992 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9993 throw new SecurityException("updateDeviceOwner called from non-system process");
9995 synchronized (this) {
9996 mDeviceOwnerName = packageName;
10001 public void updateLockTaskPackages(int userId, String[] packages) {
10002 final int callingUid = Binder.getCallingUid();
10003 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10004 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10005 "updateLockTaskPackages()");
10007 synchronized (this) {
10008 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10009 Arrays.toString(packages));
10010 mLockTaskPackages.put(userId, packages);
10011 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10016 void startLockTaskModeLocked(TaskRecord task) {
10017 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10018 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10022 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10023 // is initiated by system after the pinning request was shown and locked mode is initiated
10024 // by an authorized app directly
10025 final int callingUid = Binder.getCallingUid();
10026 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10027 long ident = Binder.clearCallingIdentity();
10029 if (!isSystemInitiated) {
10030 task.mLockTaskUid = callingUid;
10031 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10032 // startLockTask() called by app and task mode is lockTaskModeDefault.
10033 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10034 StatusBarManagerInternal statusBarManager =
10035 LocalServices.getService(StatusBarManagerInternal.class);
10036 if (statusBarManager != null) {
10037 statusBarManager.showScreenPinningRequest(task.taskId);
10042 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10043 if (stack == null || task != stack.topTask()) {
10044 throw new IllegalArgumentException("Invalid task, not in foreground");
10047 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10049 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10050 ActivityManager.LOCK_TASK_MODE_PINNED :
10051 ActivityManager.LOCK_TASK_MODE_LOCKED,
10052 "startLockTask", true);
10054 Binder.restoreCallingIdentity(ident);
10059 public void startLockTaskMode(int taskId) {
10060 synchronized (this) {
10061 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10062 if (task != null) {
10063 startLockTaskModeLocked(task);
10069 public void startLockTaskMode(IBinder token) {
10070 synchronized (this) {
10071 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10075 final TaskRecord task = r.task;
10076 if (task != null) {
10077 startLockTaskModeLocked(task);
10083 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10084 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10085 // This makes inner call to look as if it was initiated by system.
10086 long ident = Binder.clearCallingIdentity();
10088 synchronized (this) {
10089 startLockTaskMode(taskId);
10092 Binder.restoreCallingIdentity(ident);
10097 public void stopLockTaskMode() {
10098 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10099 if (lockTask == null) {
10100 // Our work here is done.
10104 final int callingUid = Binder.getCallingUid();
10105 final int lockTaskUid = lockTask.mLockTaskUid;
10106 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10107 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10111 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10112 // It is possible lockTaskMode was started by the system process because
10113 // android:lockTaskMode is set to a locking value in the application manifest
10114 // instead of the app calling startLockTaskMode. In this case
10115 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10116 // {@link TaskRecord.effectiveUid} instead. Also caller with
10117 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10118 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10119 && callingUid != lockTaskUid
10120 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10121 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10122 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10125 long ident = Binder.clearCallingIdentity();
10127 Log.d(TAG, "stopLockTaskMode");
10129 synchronized (this) {
10130 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10131 "stopLockTask", true);
10133 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10135 tm.showInCallScreen(false);
10138 Binder.restoreCallingIdentity(ident);
10143 * This API should be called by SystemUI only when user perform certain action to dismiss
10144 * lock task mode. We should only dismiss pinned lock task mode in this case.
10147 public void stopSystemLockTaskMode() throws RemoteException {
10148 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10149 stopLockTaskMode();
10151 mStackSupervisor.showLockTaskToast();
10156 public boolean isInLockTaskMode() {
10157 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10161 public int getLockTaskModeState() {
10162 synchronized (this) {
10163 return mStackSupervisor.getLockTaskModeState();
10168 public void showLockTaskEscapeMessage(IBinder token) {
10169 synchronized (this) {
10170 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10174 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10178 // =========================================================
10179 // CONTENT PROVIDERS
10180 // =========================================================
10182 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10183 List<ProviderInfo> providers = null;
10185 providers = AppGlobals.getPackageManager()
10186 .queryContentProviders(app.processName, app.uid,
10187 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10188 | MATCH_DEBUG_TRIAGED_MISSING)
10190 } catch (RemoteException ex) {
10192 if (DEBUG_MU) Slog.v(TAG_MU,
10193 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10194 int userId = app.userId;
10195 if (providers != null) {
10196 int N = providers.size();
10197 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10198 for (int i=0; i<N; i++) {
10199 // TODO: keep logic in sync with installEncryptionUnawareProviders
10201 (ProviderInfo)providers.get(i);
10202 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10203 cpi.name, cpi.flags);
10204 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10205 // This is a singleton provider, but a user besides the
10206 // default user is asking to initialize a process it runs
10207 // in... well, no, it doesn't actually run in this process,
10208 // it runs in the process of the default user. Get rid of it.
10209 providers.remove(i);
10215 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10216 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10218 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10219 mProviderMap.putProviderByClass(comp, cpr);
10221 if (DEBUG_MU) Slog.v(TAG_MU,
10222 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10223 app.pubProviders.put(cpi.name, cpr);
10224 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10225 // Don't add this if it is a platform component that is marked
10226 // to run in multiple processes, because this is actually
10227 // part of the framework so doesn't make sense to track as a
10228 // separate apk in the process.
10229 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10232 notifyPackageUse(cpi.applicationInfo.packageName,
10233 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10240 * Check if {@link ProcessRecord} has a possible chance at accessing the
10241 * given {@link ProviderInfo}. Final permission checking is always done
10242 * in {@link ContentProvider}.
10244 private final String checkContentProviderPermissionLocked(
10245 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10246 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10247 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10248 boolean checkedGrants = false;
10250 // Looking for cross-user grants before enforcing the typical cross-users permissions
10251 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10252 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10253 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10256 checkedGrants = true;
10258 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10259 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10260 if (userId != tmpTargetUserId) {
10261 // When we actually went to determine the final targer user ID, this ended
10262 // up different than our initial check for the authority. This is because
10263 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10264 // SELF. So we need to re-check the grants again.
10265 checkedGrants = false;
10268 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10269 cpi.applicationInfo.uid, cpi.exported)
10270 == PackageManager.PERMISSION_GRANTED) {
10273 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10274 cpi.applicationInfo.uid, cpi.exported)
10275 == PackageManager.PERMISSION_GRANTED) {
10279 PathPermission[] pps = cpi.pathPermissions;
10281 int i = pps.length;
10284 PathPermission pp = pps[i];
10285 String pprperm = pp.getReadPermission();
10286 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10287 cpi.applicationInfo.uid, cpi.exported)
10288 == PackageManager.PERMISSION_GRANTED) {
10291 String ppwperm = pp.getWritePermission();
10292 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10293 cpi.applicationInfo.uid, cpi.exported)
10294 == PackageManager.PERMISSION_GRANTED) {
10299 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10304 if (!cpi.exported) {
10305 msg = "Permission Denial: opening provider " + cpi.name
10306 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10307 + ", uid=" + callingUid + ") that is not exported from uid "
10308 + cpi.applicationInfo.uid;
10310 msg = "Permission Denial: opening provider " + cpi.name
10311 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10312 + ", uid=" + callingUid + ") requires "
10313 + cpi.readPermission + " or " + cpi.writePermission;
10320 * Returns if the ContentProvider has granted a uri to callingUid
10322 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10323 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10324 if (perms != null) {
10325 for (int i=perms.size()-1; i>=0; i--) {
10326 GrantUri grantUri = perms.keyAt(i);
10327 if (grantUri.sourceUserId == userId || !checkUser) {
10328 if (matchesProvider(grantUri.uri, cpi)) {
10338 * Returns true if the uri authority is one of the authorities specified in the provider.
10340 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10341 String uriAuth = uri.getAuthority();
10342 String cpiAuth = cpi.authority;
10343 if (cpiAuth.indexOf(';') == -1) {
10344 return cpiAuth.equals(uriAuth);
10346 String[] cpiAuths = cpiAuth.split(";");
10347 int length = cpiAuths.length;
10348 for (int i = 0; i < length; i++) {
10349 if (cpiAuths[i].equals(uriAuth)) return true;
10354 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10355 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10357 for (int i=0; i<r.conProviders.size(); i++) {
10358 ContentProviderConnection conn = r.conProviders.get(i);
10359 if (conn.provider == cpr) {
10360 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10361 "Adding provider requested by "
10362 + r.processName + " from process "
10363 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10364 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10366 conn.stableCount++;
10367 conn.numStableIncs++;
10369 conn.unstableCount++;
10370 conn.numUnstableIncs++;
10375 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10377 conn.stableCount = 1;
10378 conn.numStableIncs = 1;
10380 conn.unstableCount = 1;
10381 conn.numUnstableIncs = 1;
10383 cpr.connections.add(conn);
10384 r.conProviders.add(conn);
10385 startAssociationLocked(r.uid, r.processName, r.curProcState,
10386 cpr.uid, cpr.name, cpr.info.processName);
10389 cpr.addExternalProcessHandleLocked(externalProcessToken);
10393 boolean decProviderCountLocked(ContentProviderConnection conn,
10394 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10395 if (conn != null) {
10396 cpr = conn.provider;
10397 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10398 "Removing provider requested by "
10399 + conn.client.processName + " from process "
10400 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10401 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10403 conn.stableCount--;
10405 conn.unstableCount--;
10407 if (conn.stableCount == 0 && conn.unstableCount == 0) {
10408 cpr.connections.remove(conn);
10409 conn.client.conProviders.remove(conn);
10410 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10411 // The client is more important than last activity -- note the time this
10412 // is happening, so we keep the old provider process around a bit as last
10413 // activity to avoid thrashing it.
10414 if (cpr.proc != null) {
10415 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10418 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10423 cpr.removeExternalProcessHandleLocked(externalProcessToken);
10427 private void checkTime(long startTime, String where) {
10428 long now = SystemClock.uptimeMillis();
10429 if ((now-startTime) > 50) {
10430 // If we are taking more than 50ms, log about it.
10431 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10435 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10436 String name, IBinder token, boolean stable, int userId) {
10437 ContentProviderRecord cpr;
10438 ContentProviderConnection conn = null;
10439 ProviderInfo cpi = null;
10441 synchronized(this) {
10442 long startTime = SystemClock.uptimeMillis();
10444 ProcessRecord r = null;
10445 if (caller != null) {
10446 r = getRecordForAppLocked(caller);
10448 throw new SecurityException(
10449 "Unable to find app for caller " + caller
10450 + " (pid=" + Binder.getCallingPid()
10451 + ") when getting content provider " + name);
10455 boolean checkCrossUser = true;
10457 checkTime(startTime, "getContentProviderImpl: getProviderByName");
10459 // First check if this content provider has been published...
10460 cpr = mProviderMap.getProviderByName(name, userId);
10461 // If that didn't work, check if it exists for user 0 and then
10462 // verify that it's a singleton provider before using it.
10463 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10464 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10467 if (isSingleton(cpi.processName, cpi.applicationInfo,
10468 cpi.name, cpi.flags)
10469 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10470 userId = UserHandle.USER_SYSTEM;
10471 checkCrossUser = false;
10479 boolean providerRunning = cpr != null;
10480 if (providerRunning) {
10483 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10484 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10486 throw new SecurityException(msg);
10488 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10490 if (r != null && cpr.canRunHere(r)) {
10491 // This provider has been published or is in the process
10492 // of being published... but it is also allowed to run
10493 // in the caller's process, so don't make a connection
10494 // and just let the caller instantiate its own instance.
10495 ContentProviderHolder holder = cpr.newHolder(null);
10496 // don't give caller the provider object, it needs
10497 // to make its own.
10498 holder.provider = null;
10502 final long origId = Binder.clearCallingIdentity();
10504 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10506 // In this case the provider instance already exists, so we can
10507 // return it right away.
10508 conn = incProviderCountLocked(r, cpr, token, stable);
10509 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10510 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10511 // If this is a perceptible app accessing the provider,
10512 // make sure to count it as being accessed and thus
10513 // back up on the LRU list. This is good because
10514 // content providers are often expensive to start.
10515 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10516 updateLruProcessLocked(cpr.proc, false, null);
10517 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10521 if (cpr.proc != null) {
10522 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10523 boolean success = updateOomAdjLocked(cpr.proc);
10524 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10525 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10526 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10527 // NOTE: there is still a race here where a signal could be
10528 // pending on the process even though we managed to update its
10529 // adj level. Not sure what to do about this, but at least
10530 // the race is now smaller.
10532 // Uh oh... it looks like the provider's process
10533 // has been killed on us. We need to wait for a new
10534 // process to be started, and make sure its death
10535 // doesn't kill our process.
10536 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10537 + " is crashing; detaching " + r);
10538 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10539 checkTime(startTime, "getContentProviderImpl: before appDied");
10540 appDiedLocked(cpr.proc);
10541 checkTime(startTime, "getContentProviderImpl: after appDied");
10543 // This wasn't the last ref our process had on
10544 // the provider... we have now been killed, bail.
10547 providerRunning = false;
10552 Binder.restoreCallingIdentity(origId);
10555 if (!providerRunning) {
10557 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10558 cpi = AppGlobals.getPackageManager().
10559 resolveContentProvider(name,
10560 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10561 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10562 } catch (RemoteException ex) {
10567 // If the provider is a singleton AND
10568 // (it's a call within the same user || the provider is a
10570 // Then allow connecting to the singleton provider
10571 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10572 cpi.name, cpi.flags)
10573 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10575 userId = UserHandle.USER_SYSTEM;
10577 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10578 checkTime(startTime, "getContentProviderImpl: got app info for user");
10581 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10582 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10584 throw new SecurityException(msg);
10586 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10588 if (!mProcessesReady
10589 && !cpi.processName.equals("system")) {
10590 // If this content provider does not run in the system
10591 // process, and the system is not yet ready to run other
10592 // processes, then fail fast instead of hanging.
10593 throw new IllegalArgumentException(
10594 "Attempt to launch content provider before system ready");
10597 // Make sure that the user who owns this provider is running. If not,
10598 // we don't want to allow it to run.
10599 if (!mUserController.isUserRunningLocked(userId, 0)) {
10600 Slog.w(TAG, "Unable to launch app "
10601 + cpi.applicationInfo.packageName + "/"
10602 + cpi.applicationInfo.uid + " for provider "
10603 + name + ": user " + userId + " is stopped");
10607 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10608 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10609 cpr = mProviderMap.getProviderByClass(comp, userId);
10610 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10611 final boolean firstClass = cpr == null;
10613 final long ident = Binder.clearCallingIdentity();
10615 // If permissions need a review before any of the app components can run,
10616 // we return no provider and launch a review activity if the calling app
10617 // is in the foreground.
10618 if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10619 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10625 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10626 ApplicationInfo ai =
10627 AppGlobals.getPackageManager().
10628 getApplicationInfo(
10629 cpi.applicationInfo.packageName,
10630 STOCK_PM_FLAGS, userId);
10631 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10633 Slog.w(TAG, "No package info for content provider "
10637 ai = getAppInfoForUser(ai, userId);
10638 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10639 } catch (RemoteException ex) {
10640 // pm is in same process, this will never happen.
10642 Binder.restoreCallingIdentity(ident);
10646 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10648 if (r != null && cpr.canRunHere(r)) {
10649 // If this is a multiprocess provider, then just return its
10650 // info and allow the caller to instantiate it. Only do
10651 // this if the provider is the same user as the caller's
10652 // process, or can run as root (so can be in any process).
10653 return cpr.newHolder(null);
10656 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10657 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10658 + cpr.info.name + " callers=" + Debug.getCallers(6));
10660 // This is single process, and our app is now connecting to it.
10661 // See if we are already in the process of launching this
10663 final int N = mLaunchingProviders.size();
10665 for (i = 0; i < N; i++) {
10666 if (mLaunchingProviders.get(i) == cpr) {
10671 // If the provider is not already being launched, then get it
10674 final long origId = Binder.clearCallingIdentity();
10677 // Content provider is now in use, its package can't be stopped.
10679 checkTime(startTime, "getContentProviderImpl: before set stopped state");
10680 AppGlobals.getPackageManager().setPackageStoppedState(
10681 cpr.appInfo.packageName, false, userId);
10682 checkTime(startTime, "getContentProviderImpl: after set stopped state");
10683 } catch (RemoteException e) {
10684 } catch (IllegalArgumentException e) {
10685 Slog.w(TAG, "Failed trying to unstop package "
10686 + cpr.appInfo.packageName + ": " + e);
10689 // Use existing process if already started
10690 checkTime(startTime, "getContentProviderImpl: looking for process record");
10691 ProcessRecord proc = getProcessRecordLocked(
10692 cpi.processName, cpr.appInfo.uid, false);
10693 if (proc != null && proc.thread != null) {
10694 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10695 "Installing in existing process " + proc);
10696 if (!proc.pubProviders.containsKey(cpi.name)) {
10697 checkTime(startTime, "getContentProviderImpl: scheduling install");
10698 proc.pubProviders.put(cpi.name, cpr);
10700 proc.thread.scheduleInstallProvider(cpi);
10701 } catch (RemoteException e) {
10705 checkTime(startTime, "getContentProviderImpl: before start process");
10706 proc = startProcessLocked(cpi.processName,
10707 cpr.appInfo, false, 0, "content provider",
10708 new ComponentName(cpi.applicationInfo.packageName,
10709 cpi.name), false, false, false);
10710 checkTime(startTime, "getContentProviderImpl: after start process");
10711 if (proc == null) {
10712 Slog.w(TAG, "Unable to launch app "
10713 + cpi.applicationInfo.packageName + "/"
10714 + cpi.applicationInfo.uid + " for provider "
10715 + name + ": process is bad");
10719 cpr.launchingApp = proc;
10720 mLaunchingProviders.add(cpr);
10722 Binder.restoreCallingIdentity(origId);
10726 checkTime(startTime, "getContentProviderImpl: updating data structures");
10728 // Make sure the provider is published (the same provider class
10729 // may be published under multiple names).
10731 mProviderMap.putProviderByClass(comp, cpr);
10734 mProviderMap.putProviderByName(name, cpr);
10735 conn = incProviderCountLocked(r, cpr, token, stable);
10736 if (conn != null) {
10737 conn.waiting = true;
10740 checkTime(startTime, "getContentProviderImpl: done!");
10743 // Wait for the provider to be published...
10744 synchronized (cpr) {
10745 while (cpr.provider == null) {
10746 if (cpr.launchingApp == null) {
10747 Slog.w(TAG, "Unable to launch app "
10748 + cpi.applicationInfo.packageName + "/"
10749 + cpi.applicationInfo.uid + " for provider "
10750 + name + ": launching app became null");
10751 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10752 UserHandle.getUserId(cpi.applicationInfo.uid),
10753 cpi.applicationInfo.packageName,
10754 cpi.applicationInfo.uid, name);
10758 if (DEBUG_MU) Slog.v(TAG_MU,
10759 "Waiting to start provider " + cpr
10760 + " launchingApp=" + cpr.launchingApp);
10761 if (conn != null) {
10762 conn.waiting = true;
10765 } catch (InterruptedException ex) {
10767 if (conn != null) {
10768 conn.waiting = false;
10773 return cpr != null ? cpr.newHolder(conn) : null;
10776 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10777 ProcessRecord r, final int userId) {
10778 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10779 cpi.packageName, userId)) {
10781 final boolean callerForeground = r == null || r.setSchedGroup
10782 != ProcessList.SCHED_GROUP_BACKGROUND;
10784 // Show a permission review UI only for starting from a foreground app
10785 if (!callerForeground) {
10786 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10787 + cpi.packageName + " requires a permissions review");
10791 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10792 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10793 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10794 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10796 if (DEBUG_PERMISSIONS_REVIEW) {
10797 Slog.i(TAG, "u" + userId + " Launching permission review "
10798 + "for package " + cpi.packageName);
10801 final UserHandle userHandle = new UserHandle(userId);
10802 mHandler.post(new Runnable() {
10804 public void run() {
10805 mContext.startActivityAsUser(intent, userHandle);
10815 PackageManagerInternal getPackageManagerInternalLocked() {
10816 if (mPackageManagerInt == null) {
10817 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10819 return mPackageManagerInt;
10823 public final ContentProviderHolder getContentProvider(
10824 IApplicationThread caller, String name, int userId, boolean stable) {
10825 enforceNotIsolatedCaller("getContentProvider");
10826 if (caller == null) {
10827 String msg = "null IApplicationThread when getting content provider "
10830 throw new SecurityException(msg);
10832 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10833 // with cross-user grant.
10834 return getContentProviderImpl(caller, name, null, stable, userId);
10837 public ContentProviderHolder getContentProviderExternal(
10838 String name, int userId, IBinder token) {
10839 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10840 "Do not have permission in call getContentProviderExternal()");
10841 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10842 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10843 return getContentProviderExternalUnchecked(name, token, userId);
10846 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10847 IBinder token, int userId) {
10848 return getContentProviderImpl(null, name, token, true, userId);
10852 * Drop a content provider from a ProcessRecord's bookkeeping
10854 public void removeContentProvider(IBinder connection, boolean stable) {
10855 enforceNotIsolatedCaller("removeContentProvider");
10856 long ident = Binder.clearCallingIdentity();
10858 synchronized (this) {
10859 ContentProviderConnection conn;
10861 conn = (ContentProviderConnection)connection;
10862 } catch (ClassCastException e) {
10863 String msg ="removeContentProvider: " + connection
10864 + " not a ContentProviderConnection";
10866 throw new IllegalArgumentException(msg);
10868 if (conn == null) {
10869 throw new NullPointerException("connection is null");
10871 if (decProviderCountLocked(conn, null, null, stable)) {
10872 updateOomAdjLocked();
10876 Binder.restoreCallingIdentity(ident);
10880 public void removeContentProviderExternal(String name, IBinder token) {
10881 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10882 "Do not have permission in call removeContentProviderExternal()");
10883 int userId = UserHandle.getCallingUserId();
10884 long ident = Binder.clearCallingIdentity();
10886 removeContentProviderExternalUnchecked(name, token, userId);
10888 Binder.restoreCallingIdentity(ident);
10892 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10893 synchronized (this) {
10894 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10896 //remove from mProvidersByClass
10897 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10901 //update content provider record entry info
10902 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10903 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10904 if (localCpr.hasExternalProcessHandles()) {
10905 if (localCpr.removeExternalProcessHandleLocked(token)) {
10906 updateOomAdjLocked();
10908 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10909 + " with no external reference for token: "
10913 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10914 + " with no external references.");
10919 public final void publishContentProviders(IApplicationThread caller,
10920 List<ContentProviderHolder> providers) {
10921 if (providers == null) {
10925 enforceNotIsolatedCaller("publishContentProviders");
10926 synchronized (this) {
10927 final ProcessRecord r = getRecordForAppLocked(caller);
10928 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10930 throw new SecurityException(
10931 "Unable to find app for caller " + caller
10932 + " (pid=" + Binder.getCallingPid()
10933 + ") when publishing content providers");
10936 final long origId = Binder.clearCallingIdentity();
10938 final int N = providers.size();
10939 for (int i = 0; i < N; i++) {
10940 ContentProviderHolder src = providers.get(i);
10941 if (src == null || src.info == null || src.provider == null) {
10944 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10945 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10947 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10948 mProviderMap.putProviderByClass(comp, dst);
10949 String names[] = dst.info.authority.split(";");
10950 for (int j = 0; j < names.length; j++) {
10951 mProviderMap.putProviderByName(names[j], dst);
10954 int launchingCount = mLaunchingProviders.size();
10956 boolean wasInLaunchingProviders = false;
10957 for (j = 0; j < launchingCount; j++) {
10958 if (mLaunchingProviders.get(j) == dst) {
10959 mLaunchingProviders.remove(j);
10960 wasInLaunchingProviders = true;
10965 if (wasInLaunchingProviders) {
10966 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10968 synchronized (dst) {
10969 dst.provider = src.provider;
10973 updateOomAdjLocked(r);
10974 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10975 src.info.authority);
10979 Binder.restoreCallingIdentity(origId);
10983 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10984 ContentProviderConnection conn;
10986 conn = (ContentProviderConnection)connection;
10987 } catch (ClassCastException e) {
10988 String msg ="refContentProvider: " + connection
10989 + " not a ContentProviderConnection";
10991 throw new IllegalArgumentException(msg);
10993 if (conn == null) {
10994 throw new NullPointerException("connection is null");
10997 synchronized (this) {
10999 conn.numStableIncs += stable;
11001 stable = conn.stableCount + stable;
11003 throw new IllegalStateException("stableCount < 0: " + stable);
11006 if (unstable > 0) {
11007 conn.numUnstableIncs += unstable;
11009 unstable = conn.unstableCount + unstable;
11010 if (unstable < 0) {
11011 throw new IllegalStateException("unstableCount < 0: " + unstable);
11014 if ((stable+unstable) <= 0) {
11015 throw new IllegalStateException("ref counts can't go to zero here: stable="
11016 + stable + " unstable=" + unstable);
11018 conn.stableCount = stable;
11019 conn.unstableCount = unstable;
11024 public void unstableProviderDied(IBinder connection) {
11025 ContentProviderConnection conn;
11027 conn = (ContentProviderConnection)connection;
11028 } catch (ClassCastException e) {
11029 String msg ="refContentProvider: " + connection
11030 + " not a ContentProviderConnection";
11032 throw new IllegalArgumentException(msg);
11034 if (conn == null) {
11035 throw new NullPointerException("connection is null");
11038 // Safely retrieve the content provider associated with the connection.
11039 IContentProvider provider;
11040 synchronized (this) {
11041 provider = conn.provider.provider;
11044 if (provider == null) {
11045 // Um, yeah, we're way ahead of you.
11049 // Make sure the caller is being honest with us.
11050 if (provider.asBinder().pingBinder()) {
11051 // Er, no, still looks good to us.
11052 synchronized (this) {
11053 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11054 + " says " + conn + " died, but we don't agree");
11059 // Well look at that! It's dead!
11060 synchronized (this) {
11061 if (conn.provider.provider != provider) {
11062 // But something changed... good enough.
11066 ProcessRecord proc = conn.provider.proc;
11067 if (proc == null || proc.thread == null) {
11068 // Seems like the process is already cleaned up.
11072 // As far as we're concerned, this is just like receiving a
11073 // death notification... just a bit prematurely.
11074 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11075 + ") early provider death");
11076 final long ident = Binder.clearCallingIdentity();
11078 appDiedLocked(proc);
11080 Binder.restoreCallingIdentity(ident);
11086 public void appNotRespondingViaProvider(IBinder connection) {
11087 enforceCallingPermission(
11088 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11090 final ContentProviderConnection conn = (ContentProviderConnection) connection;
11091 if (conn == null) {
11092 Slog.w(TAG, "ContentProviderConnection is null");
11096 final ProcessRecord host = conn.provider.proc;
11097 if (host == null) {
11098 Slog.w(TAG, "Failed to find hosting ProcessRecord");
11102 mHandler.post(new Runnable() {
11104 public void run() {
11105 mAppErrors.appNotResponding(host, null, null, false,
11106 "ContentProvider not responding");
11111 public final void installSystemProviders() {
11112 List<ProviderInfo> providers;
11113 synchronized (this) {
11114 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11115 providers = generateApplicationProvidersLocked(app);
11116 if (providers != null) {
11117 for (int i=providers.size()-1; i>=0; i--) {
11118 ProviderInfo pi = (ProviderInfo)providers.get(i);
11119 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11120 Slog.w(TAG, "Not installing system proc provider " + pi.name
11121 + ": not system .apk");
11122 providers.remove(i);
11127 if (providers != null) {
11128 mSystemThread.installSystemProviders(providers);
11131 mCoreSettingsObserver = new CoreSettingsObserver(this);
11132 mFontScaleSettingObserver = new FontScaleSettingObserver();
11134 //mUsageStatsService.monitorPackages();
11137 private void startPersistentApps(int matchFlags) {
11138 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11140 synchronized (this) {
11142 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11143 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11144 for (ApplicationInfo app : apps) {
11145 if (!"android".equals(app.packageName)) {
11146 addAppLocked(app, false, null /* ABI override */);
11149 } catch (RemoteException ex) {
11155 * When a user is unlocked, we need to install encryption-unaware providers
11156 * belonging to any running apps.
11158 private void installEncryptionUnawareProviders(int userId) {
11159 // We're only interested in providers that are encryption unaware, and
11160 // we don't care about uninstalled apps, since there's no way they're
11161 // running at this point.
11162 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11164 synchronized (this) {
11165 final int NP = mProcessNames.getMap().size();
11166 for (int ip = 0; ip < NP; ip++) {
11167 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11168 final int NA = apps.size();
11169 for (int ia = 0; ia < NA; ia++) {
11170 final ProcessRecord app = apps.valueAt(ia);
11171 if (app.userId != userId || app.thread == null || app.unlocked) continue;
11173 final int NG = app.pkgList.size();
11174 for (int ig = 0; ig < NG; ig++) {
11176 final String pkgName = app.pkgList.keyAt(ig);
11177 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11178 .getPackageInfo(pkgName, matchFlags, userId);
11179 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11180 for (ProviderInfo pi : pkgInfo.providers) {
11181 // TODO: keep in sync with generateApplicationProvidersLocked
11182 final boolean processMatch = Objects.equals(pi.processName,
11183 app.processName) || pi.multiprocess;
11184 final boolean userMatch = isSingleton(pi.processName,
11185 pi.applicationInfo, pi.name, pi.flags)
11186 ? (app.userId == UserHandle.USER_SYSTEM) : true;
11187 if (processMatch && userMatch) {
11188 Log.v(TAG, "Installing " + pi);
11189 app.thread.scheduleInstallProvider(pi);
11191 Log.v(TAG, "Skipping " + pi);
11195 } catch (RemoteException ignored) {
11204 * Allows apps to retrieve the MIME type of a URI.
11205 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11206 * users, then it does not need permission to access the ContentProvider.
11207 * Either, it needs cross-user uri grants.
11209 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11211 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11212 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11214 public String getProviderMimeType(Uri uri, int userId) {
11215 enforceNotIsolatedCaller("getProviderMimeType");
11216 final String name = uri.getAuthority();
11217 int callingUid = Binder.getCallingUid();
11218 int callingPid = Binder.getCallingPid();
11220 boolean clearedIdentity = false;
11221 synchronized (this) {
11222 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11224 if (canClearIdentity(callingPid, callingUid, userId)) {
11225 clearedIdentity = true;
11226 ident = Binder.clearCallingIdentity();
11228 ContentProviderHolder holder = null;
11230 holder = getContentProviderExternalUnchecked(name, null, userId);
11231 if (holder != null) {
11232 return holder.provider.getType(uri);
11234 } catch (RemoteException e) {
11235 Log.w(TAG, "Content provider dead retrieving " + uri, e);
11238 // We need to clear the identity to call removeContentProviderExternalUnchecked
11239 if (!clearedIdentity) {
11240 ident = Binder.clearCallingIdentity();
11243 if (holder != null) {
11244 removeContentProviderExternalUnchecked(name, null, userId);
11247 Binder.restoreCallingIdentity(ident);
11254 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11255 if (UserHandle.getUserId(callingUid) == userId) {
11258 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11259 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11260 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11261 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11267 // =========================================================
11268 // GLOBAL MANAGEMENT
11269 // =========================================================
11271 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11272 boolean isolated, int isolatedUid) {
11273 String proc = customProcess != null ? customProcess : info.processName;
11274 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11275 final int userId = UserHandle.getUserId(info.uid);
11276 int uid = info.uid;
11278 if (isolatedUid == 0) {
11279 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11281 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11282 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11283 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11285 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11286 mNextIsolatedProcessUid++;
11287 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11288 // No process for this uid, use it.
11292 if (stepsLeft <= 0) {
11297 // Special case for startIsolatedProcess (internal only), where
11298 // the uid of the isolated process is specified by the caller.
11302 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11303 if (!mBooted && !mBooting
11304 && userId == UserHandle.USER_SYSTEM
11305 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11306 r.persistent = true;
11308 addProcessNameLocked(r);
11312 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11313 String abiOverride) {
11316 app = getProcessRecordLocked(info.processName, info.uid, true);
11322 app = newProcessRecordLocked(info, null, isolated, 0);
11323 updateLruProcessLocked(app, false, null);
11324 updateOomAdjLocked();
11327 // This package really, really can not be stopped.
11329 AppGlobals.getPackageManager().setPackageStoppedState(
11330 info.packageName, false, UserHandle.getUserId(app.uid));
11331 } catch (RemoteException e) {
11332 } catch (IllegalArgumentException e) {
11333 Slog.w(TAG, "Failed trying to unstop package "
11334 + info.packageName + ": " + e);
11337 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11338 app.persistent = true;
11339 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11341 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11342 mPersistentStartingProcesses.add(app);
11343 startProcessLocked(app, "added application", app.processName, abiOverride,
11344 null /* entryPoint */, null /* entryPointArgs */);
11350 public void unhandledBack() {
11351 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11352 "unhandledBack()");
11354 synchronized(this) {
11355 final long origId = Binder.clearCallingIdentity();
11357 getFocusedStack().unhandledBackLocked();
11359 Binder.restoreCallingIdentity(origId);
11364 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11365 enforceNotIsolatedCaller("openContentUri");
11366 final int userId = UserHandle.getCallingUserId();
11367 String name = uri.getAuthority();
11368 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11369 ParcelFileDescriptor pfd = null;
11371 // We record the binder invoker's uid in thread-local storage before
11372 // going to the content provider to open the file. Later, in the code
11373 // that handles all permissions checks, we look for this uid and use
11374 // that rather than the Activity Manager's own uid. The effect is that
11375 // we do the check against the caller's permissions even though it looks
11376 // to the content provider like the Activity Manager itself is making
11378 Binder token = new Binder();
11379 sCallerIdentity.set(new Identity(
11380 token, Binder.getCallingPid(), Binder.getCallingUid()));
11382 pfd = cph.provider.openFile(null, uri, "r", null, token);
11383 } catch (FileNotFoundException e) {
11384 // do nothing; pfd will be returned null
11386 // Ensure that whatever happens, we clean up the identity state
11387 sCallerIdentity.remove();
11388 // Ensure we're done with the provider.
11389 removeContentProviderExternalUnchecked(name, null, userId);
11392 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11397 // Actually is sleeping or shutting down or whatever else in the future
11398 // is an inactive state.
11399 public boolean isSleepingOrShuttingDown() {
11400 return isSleeping() || mShuttingDown;
11403 public boolean isSleeping() {
11407 void onWakefulnessChanged(int wakefulness) {
11408 synchronized(this) {
11409 mWakefulness = wakefulness;
11410 updateSleepIfNeededLocked();
11414 void finishRunningVoiceLocked() {
11415 if (mRunningVoice != null) {
11416 mRunningVoice = null;
11417 mVoiceWakeLock.release();
11418 updateSleepIfNeededLocked();
11422 void startTimeTrackingFocusedActivityLocked() {
11423 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11424 mCurAppTimeTracker.start(mFocusedActivity.packageName);
11428 void updateSleepIfNeededLocked() {
11429 if (mSleeping && !shouldSleepLocked()) {
11431 startTimeTrackingFocusedActivityLocked();
11432 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11433 mStackSupervisor.comeOutOfSleepIfNeededLocked();
11434 updateOomAdjLocked();
11435 } else if (!mSleeping && shouldSleepLocked()) {
11437 if (mCurAppTimeTracker != null) {
11438 mCurAppTimeTracker.stop();
11440 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11441 mStackSupervisor.goingToSleepLocked();
11442 updateOomAdjLocked();
11444 // Initialize the wake times of all processes.
11445 checkExcessivePowerUsageLocked(false);
11446 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11447 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11448 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11452 private boolean shouldSleepLocked() {
11453 // Resume applications while running a voice interactor.
11454 if (mRunningVoice != null) {
11458 // TODO: Transform the lock screen state into a sleep token instead.
11459 switch (mWakefulness) {
11460 case PowerManagerInternal.WAKEFULNESS_AWAKE:
11461 case PowerManagerInternal.WAKEFULNESS_DREAMING:
11462 case PowerManagerInternal.WAKEFULNESS_DOZING:
11463 // Pause applications whenever the lock screen is shown or any sleep
11464 // tokens have been acquired.
11465 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11466 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11468 // If we're asleep then pause applications unconditionally.
11473 /** Pokes the task persister. */
11474 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11475 mRecentTasks.notifyTaskPersisterLocked(task, flush);
11478 /** Notifies all listeners when the task stack has changed. */
11479 void notifyTaskStackChangedLocked() {
11480 mHandler.sendEmptyMessage(LOG_STACK_STATE);
11481 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11482 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11483 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11486 /** Notifies all listeners when an Activity is pinned. */
11487 void notifyActivityPinnedLocked() {
11488 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11489 mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11493 * Notifies all listeners when an attempt was made to start an an activity that is already
11494 * running in the pinned stack and the activity was not actually started, but the task is
11495 * either brought to the front or a new Intent is delivered to it.
11497 void notifyPinnedActivityRestartAttemptLocked() {
11498 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11499 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11502 /** Notifies all listeners when the pinned stack animation ends. */
11504 public void notifyPinnedStackAnimationEnded() {
11505 synchronized (this) {
11506 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11507 mHandler.obtainMessage(
11508 NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11513 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11514 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11518 public boolean shutdown(int timeout) {
11519 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11520 != PackageManager.PERMISSION_GRANTED) {
11521 throw new SecurityException("Requires permission "
11522 + android.Manifest.permission.SHUTDOWN);
11525 boolean timedout = false;
11527 synchronized(this) {
11528 mShuttingDown = true;
11529 updateEventDispatchingLocked();
11530 timedout = mStackSupervisor.shutdownLocked(timeout);
11533 mAppOpsService.shutdown();
11534 if (mUsageStatsService != null) {
11535 mUsageStatsService.prepareShutdown();
11537 mBatteryStatsService.shutdown();
11538 synchronized (this) {
11539 mProcessStats.shutdownLocked();
11540 notifyTaskPersisterLocked(null, true);
11546 public final void activitySlept(IBinder token) {
11547 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11549 final long origId = Binder.clearCallingIdentity();
11551 synchronized (this) {
11552 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11554 mStackSupervisor.activitySleptLocked(r);
11558 Binder.restoreCallingIdentity(origId);
11561 private String lockScreenShownToString() {
11562 switch (mLockScreenShown) {
11563 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11564 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11565 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11566 default: return "Unknown=" + mLockScreenShown;
11570 void logLockScreen(String msg) {
11571 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11572 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11573 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11574 + " mSleeping=" + mSleeping);
11577 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11578 Slog.d(TAG, "<<< startRunningVoiceLocked()");
11579 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11580 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11581 boolean wasRunningVoice = mRunningVoice != null;
11582 mRunningVoice = session;
11583 if (!wasRunningVoice) {
11584 mVoiceWakeLock.acquire();
11585 updateSleepIfNeededLocked();
11590 private void updateEventDispatchingLocked() {
11591 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11594 public void setLockScreenShown(boolean showing, boolean occluded) {
11595 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11596 != PackageManager.PERMISSION_GRANTED) {
11597 throw new SecurityException("Requires permission "
11598 + android.Manifest.permission.DEVICE_POWER);
11601 synchronized(this) {
11602 long ident = Binder.clearCallingIdentity();
11604 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11605 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11606 if (showing && occluded) {
11607 // The lock screen is currently showing, but is occluded by a window that can
11608 // show on top of the lock screen. In this can we want to dismiss the docked
11609 // stack since it will be complicated/risky to try to put the activity on top
11610 // of the lock screen in the right fullscreen configuration.
11611 mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11612 mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11615 updateSleepIfNeededLocked();
11617 Binder.restoreCallingIdentity(ident);
11623 public void notifyLockedProfile(@UserIdInt int userId) {
11625 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11626 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11628 } catch (RemoteException ex) {
11629 throw new SecurityException("Fail to check is caller a privileged app", ex);
11632 synchronized (this) {
11633 if (mStackSupervisor.isUserLockedProfile(userId)) {
11634 final long ident = Binder.clearCallingIdentity();
11636 final int currentUserId = mUserController.getCurrentUserIdLocked();
11637 if (mUserController.isLockScreenDisabled(currentUserId)) {
11638 // If there is no device lock, we will show the profile's credential page.
11639 mActivityStarter.showConfirmDeviceCredential(userId);
11641 // Showing launcher to avoid user entering credential twice.
11642 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11645 Binder.restoreCallingIdentity(ident);
11652 public void startConfirmDeviceCredentialIntent(Intent intent) {
11653 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11654 synchronized (this) {
11655 final long ident = Binder.clearCallingIdentity();
11657 mActivityStarter.startConfirmCredentialIntent(intent);
11659 Binder.restoreCallingIdentity(ident);
11665 public void stopAppSwitches() {
11666 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11667 != PackageManager.PERMISSION_GRANTED) {
11668 throw new SecurityException("viewquires permission "
11669 + android.Manifest.permission.STOP_APP_SWITCHES);
11672 synchronized(this) {
11673 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11674 + APP_SWITCH_DELAY_TIME;
11675 mDidAppSwitch = false;
11676 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11677 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11678 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11682 public void resumeAppSwitches() {
11683 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11684 != PackageManager.PERMISSION_GRANTED) {
11685 throw new SecurityException("Requires permission "
11686 + android.Manifest.permission.STOP_APP_SWITCHES);
11689 synchronized(this) {
11690 // Note that we don't execute any pending app switches... we will
11691 // let those wait until either the timeout, or the next start
11692 // activity request.
11693 mAppSwitchesAllowedTime = 0;
11697 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11698 int callingPid, int callingUid, String name) {
11699 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11703 int perm = checkComponentPermission(
11704 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11705 sourceUid, -1, true);
11706 if (perm == PackageManager.PERMISSION_GRANTED) {
11710 // If the actual IPC caller is different from the logical source, then
11711 // also see if they are allowed to control app switches.
11712 if (callingUid != -1 && callingUid != sourceUid) {
11713 perm = checkComponentPermission(
11714 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11715 callingUid, -1, true);
11716 if (perm == PackageManager.PERMISSION_GRANTED) {
11721 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11725 public void setDebugApp(String packageName, boolean waitForDebugger,
11726 boolean persistent) {
11727 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11730 long ident = Binder.clearCallingIdentity();
11732 // Note that this is not really thread safe if there are multiple
11733 // callers into it at the same time, but that's not a situation we
11736 final ContentResolver resolver = mContext.getContentResolver();
11737 Settings.Global.putString(
11738 resolver, Settings.Global.DEBUG_APP,
11740 Settings.Global.putInt(
11741 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11742 waitForDebugger ? 1 : 0);
11745 synchronized (this) {
11747 mOrigDebugApp = mDebugApp;
11748 mOrigWaitForDebugger = mWaitForDebugger;
11750 mDebugApp = packageName;
11751 mWaitForDebugger = waitForDebugger;
11752 mDebugTransient = !persistent;
11753 if (packageName != null) {
11754 forceStopPackageLocked(packageName, -1, false, false, true, true,
11755 false, UserHandle.USER_ALL, "set debug app");
11759 Binder.restoreCallingIdentity(ident);
11763 void setTrackAllocationApp(ApplicationInfo app, String processName) {
11764 synchronized (this) {
11765 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11766 if (!isDebuggable) {
11767 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11768 throw new SecurityException("Process not debuggable: " + app.packageName);
11772 mTrackAllocationApp = processName;
11776 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11777 synchronized (this) {
11778 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11779 if (!isDebuggable) {
11780 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11781 throw new SecurityException("Process not debuggable: " + app.packageName);
11784 mProfileApp = processName;
11785 mProfileFile = profilerInfo.profileFile;
11786 if (mProfileFd != null) {
11788 mProfileFd.close();
11789 } catch (IOException e) {
11793 mProfileFd = profilerInfo.profileFd;
11794 mSamplingInterval = profilerInfo.samplingInterval;
11795 mAutoStopProfiler = profilerInfo.autoStopProfiler;
11800 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11801 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11802 if (!isDebuggable) {
11803 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11804 throw new SecurityException("Process not debuggable: " + app.packageName);
11807 mNativeDebuggingApp = processName;
11811 public void setAlwaysFinish(boolean enabled) {
11812 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11813 "setAlwaysFinish()");
11815 long ident = Binder.clearCallingIdentity();
11817 Settings.Global.putInt(
11818 mContext.getContentResolver(),
11819 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11821 synchronized (this) {
11822 mAlwaysFinishActivities = enabled;
11825 Binder.restoreCallingIdentity(ident);
11830 public void setLenientBackgroundCheck(boolean enabled) {
11831 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11832 "setLenientBackgroundCheck()");
11834 long ident = Binder.clearCallingIdentity();
11836 Settings.Global.putInt(
11837 mContext.getContentResolver(),
11838 Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11840 synchronized (this) {
11841 mLenientBackgroundCheck = enabled;
11844 Binder.restoreCallingIdentity(ident);
11849 public void setActivityController(IActivityController controller, boolean imAMonkey) {
11850 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11851 "setActivityController()");
11852 synchronized (this) {
11853 mController = controller;
11854 mControllerIsAMonkey = imAMonkey;
11855 Watchdog.getInstance().setActivityController(controller);
11860 public void setUserIsMonkey(boolean userIsMonkey) {
11861 synchronized (this) {
11862 synchronized (mPidsSelfLocked) {
11863 final int callingPid = Binder.getCallingPid();
11864 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11865 if (precessRecord == null) {
11866 throw new SecurityException("Unknown process: " + callingPid);
11868 if (precessRecord.instrumentationUiAutomationConnection == null) {
11869 throw new SecurityException("Only an instrumentation process "
11870 + "with a UiAutomation can call setUserIsMonkey");
11873 mUserIsMonkey = userIsMonkey;
11878 public boolean isUserAMonkey() {
11879 synchronized (this) {
11880 // If there is a controller also implies the user is a monkey.
11881 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11885 public void requestBugReport(int bugreportType) {
11886 String service = null;
11887 switch (bugreportType) {
11888 case ActivityManager.BUGREPORT_OPTION_FULL:
11889 service = "bugreport";
11891 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11892 service = "bugreportplus";
11894 case ActivityManager.BUGREPORT_OPTION_REMOTE:
11895 service = "bugreportremote";
11898 if (service == null) {
11899 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11902 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11903 SystemProperties.set("ctl.start", service);
11906 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11907 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11910 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11911 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11912 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11914 return KEY_DISPATCHING_TIMEOUT;
11918 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11919 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11920 != PackageManager.PERMISSION_GRANTED) {
11921 throw new SecurityException("Requires permission "
11922 + android.Manifest.permission.FILTER_EVENTS);
11924 ProcessRecord proc;
11926 synchronized (this) {
11927 synchronized (mPidsSelfLocked) {
11928 proc = mPidsSelfLocked.get(pid);
11930 timeout = getInputDispatchingTimeoutLocked(proc);
11933 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11941 * Handle input dispatching timeouts.
11942 * Returns whether input dispatching should be aborted or not.
11944 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11945 final ActivityRecord activity, final ActivityRecord parent,
11946 final boolean aboveSystem, String reason) {
11947 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11948 != PackageManager.PERMISSION_GRANTED) {
11949 throw new SecurityException("Requires permission "
11950 + android.Manifest.permission.FILTER_EVENTS);
11953 final String annotation;
11954 if (reason == null) {
11955 annotation = "Input dispatching timed out";
11957 annotation = "Input dispatching timed out (" + reason + ")";
11960 if (proc != null) {
11961 synchronized (this) {
11962 if (proc.debugging) {
11967 // Give more time since we were dexopting.
11968 mDidDexOpt = false;
11972 if (proc.instrumentationClass != null) {
11973 Bundle info = new Bundle();
11974 info.putString("shortMsg", "keyDispatchingTimedOut");
11975 info.putString("longMsg", annotation);
11976 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11980 mHandler.post(new Runnable() {
11982 public void run() {
11983 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11992 public Bundle getAssistContextExtras(int requestType) {
11993 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11994 null, null, true /* focused */, true /* newSessionId */,
11995 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11999 synchronized (pae) {
12000 while (!pae.haveResult) {
12003 } catch (InterruptedException e) {
12007 synchronized (this) {
12008 buildAssistBundleLocked(pae, pae.result);
12009 mPendingAssistExtras.remove(pae);
12010 mUiHandler.removeCallbacks(pae);
12016 public boolean isAssistDataAllowedOnCurrentActivity() {
12018 synchronized (this) {
12019 userId = mUserController.getCurrentUserIdLocked();
12020 ActivityRecord activity = getFocusedStack().topActivity();
12021 if (activity == null) {
12024 userId = activity.userId;
12026 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12027 Context.DEVICE_POLICY_SERVICE);
12028 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12032 public boolean showAssistFromActivity(IBinder token, Bundle args) {
12033 long ident = Binder.clearCallingIdentity();
12035 synchronized (this) {
12036 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12037 ActivityRecord top = getFocusedStack().topActivity();
12038 if (top != caller) {
12039 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12040 + " is not current top " + top);
12043 if (!top.nowVisible) {
12044 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12045 + " is not visible");
12049 AssistUtils utils = new AssistUtils(mContext);
12050 return utils.showSessionForActiveService(args,
12051 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12053 Binder.restoreCallingIdentity(ident);
12058 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12059 Bundle receiverExtras,
12060 IBinder activityToken, boolean focused, boolean newSessionId) {
12061 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12062 activityToken, focused, newSessionId,
12063 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12067 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12068 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12069 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12070 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12071 "enqueueAssistContext()");
12072 synchronized (this) {
12073 ActivityRecord activity = getFocusedStack().topActivity();
12074 if (activity == null) {
12075 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12078 if (activity.app == null || activity.app.thread == null) {
12079 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12083 if (activityToken != null) {
12084 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12085 if (activity != caller) {
12086 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12087 + " is not current top " + activity);
12092 activity = ActivityRecord.forTokenLocked(activityToken);
12093 if (activity == null) {
12094 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12095 + " couldn't be found");
12100 PendingAssistExtras pae;
12101 Bundle extras = new Bundle();
12102 if (args != null) {
12103 extras.putAll(args);
12105 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12106 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12107 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12109 // Increment the sessionId if necessary
12110 if (newSessionId) {
12114 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12115 requestType, mViSessionId);
12116 mPendingAssistExtras.add(pae);
12117 mUiHandler.postDelayed(pae, timeout);
12118 } catch (RemoteException e) {
12119 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12126 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12127 IResultReceiver receiver;
12128 synchronized (this) {
12129 mPendingAssistExtras.remove(pae);
12130 receiver = pae.receiver;
12132 if (receiver != null) {
12133 // Caller wants result sent back to them.
12134 Bundle sendBundle = new Bundle();
12135 // At least return the receiver extras
12136 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12137 pae.receiverExtras);
12139 pae.receiver.send(0, sendBundle);
12140 } catch (RemoteException e) {
12145 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12146 if (result != null) {
12147 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12149 if (pae.hint != null) {
12150 pae.extras.putBoolean(pae.hint, true);
12154 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12155 AssistContent content, Uri referrer) {
12156 PendingAssistExtras pae = (PendingAssistExtras)token;
12157 synchronized (pae) {
12158 pae.result = extras;
12159 pae.structure = structure;
12160 pae.content = content;
12161 if (referrer != null) {
12162 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12164 pae.haveResult = true;
12166 if (pae.intent == null && pae.receiver == null) {
12167 // Caller is just waiting for the result.
12172 // We are now ready to launch the assist activity.
12173 IResultReceiver sendReceiver = null;
12174 Bundle sendBundle = null;
12175 synchronized (this) {
12176 buildAssistBundleLocked(pae, extras);
12177 boolean exists = mPendingAssistExtras.remove(pae);
12178 mUiHandler.removeCallbacks(pae);
12183 if ((sendReceiver=pae.receiver) != null) {
12184 // Caller wants result sent back to them.
12185 sendBundle = new Bundle();
12186 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12187 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12188 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12189 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12190 pae.receiverExtras);
12193 if (sendReceiver != null) {
12195 sendReceiver.send(0, sendBundle);
12196 } catch (RemoteException e) {
12201 long ident = Binder.clearCallingIdentity();
12203 pae.intent.replaceExtras(pae.extras);
12204 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12205 | Intent.FLAG_ACTIVITY_SINGLE_TOP
12206 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12207 closeSystemDialogs("assist");
12209 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12210 } catch (ActivityNotFoundException e) {
12211 Slog.w(TAG, "No activity to handle assist action.", e);
12214 Binder.restoreCallingIdentity(ident);
12218 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12220 return enqueueAssistContext(requestType, intent, hint, null, null, null,
12221 true /* focused */, true /* newSessionId */,
12222 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12225 public void registerProcessObserver(IProcessObserver observer) {
12226 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12227 "registerProcessObserver()");
12228 synchronized (this) {
12229 mProcessObservers.register(observer);
12234 public void unregisterProcessObserver(IProcessObserver observer) {
12235 synchronized (this) {
12236 mProcessObservers.unregister(observer);
12241 public void registerUidObserver(IUidObserver observer, int which) {
12242 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12243 "registerUidObserver()");
12244 synchronized (this) {
12245 mUidObservers.register(observer, which);
12250 public void unregisterUidObserver(IUidObserver observer) {
12251 synchronized (this) {
12252 mUidObservers.unregister(observer);
12257 public boolean convertFromTranslucent(IBinder token) {
12258 final long origId = Binder.clearCallingIdentity();
12260 synchronized (this) {
12261 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12265 final boolean translucentChanged = r.changeWindowTranslucency(true);
12266 if (translucentChanged) {
12267 r.task.stack.releaseBackgroundResources(r);
12268 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12270 mWindowManager.setAppFullscreen(token, true);
12271 return translucentChanged;
12274 Binder.restoreCallingIdentity(origId);
12279 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12280 final long origId = Binder.clearCallingIdentity();
12282 synchronized (this) {
12283 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12287 int index = r.task.mActivities.lastIndexOf(r);
12289 ActivityRecord under = r.task.mActivities.get(index - 1);
12290 under.returningOptions = options;
12292 final boolean translucentChanged = r.changeWindowTranslucency(false);
12293 if (translucentChanged) {
12294 r.task.stack.convertActivityToTranslucent(r);
12296 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12297 mWindowManager.setAppFullscreen(token, false);
12298 return translucentChanged;
12301 Binder.restoreCallingIdentity(origId);
12306 public boolean requestVisibleBehind(IBinder token, boolean visible) {
12307 final long origId = Binder.clearCallingIdentity();
12309 synchronized (this) {
12310 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12312 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12317 Binder.restoreCallingIdentity(origId);
12322 public boolean isBackgroundVisibleBehind(IBinder token) {
12323 final long origId = Binder.clearCallingIdentity();
12325 synchronized (this) {
12326 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12327 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12328 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12329 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12333 Binder.restoreCallingIdentity(origId);
12338 public ActivityOptions getActivityOptions(IBinder token) {
12339 final long origId = Binder.clearCallingIdentity();
12341 synchronized (this) {
12342 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12344 final ActivityOptions activityOptions = r.pendingOptions;
12345 r.pendingOptions = null;
12346 return activityOptions;
12351 Binder.restoreCallingIdentity(origId);
12356 public void setImmersive(IBinder token, boolean immersive) {
12357 synchronized(this) {
12358 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12360 throw new IllegalArgumentException();
12362 r.immersive = immersive;
12364 // update associated state if we're frontmost
12365 if (r == mFocusedActivity) {
12366 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12367 applyUpdateLockStateLocked(r);
12373 public boolean isImmersive(IBinder token) {
12374 synchronized (this) {
12375 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12377 throw new IllegalArgumentException();
12379 return r.immersive;
12384 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12385 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12386 throw new UnsupportedOperationException("VR mode not supported on this device!");
12389 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12392 synchronized (this) {
12393 r = ActivityRecord.isInStackLocked(token);
12397 throw new IllegalArgumentException();
12401 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12402 VrManagerInternal.NO_ERROR) {
12406 synchronized(this) {
12407 r.requestedVrComponent = (enabled) ? packageName : null;
12409 // Update associated state if this activity is currently focused
12410 if (r == mFocusedActivity) {
12411 applyUpdateVrModeLocked(r);
12418 public boolean isVrModePackageEnabled(ComponentName packageName) {
12419 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12420 throw new UnsupportedOperationException("VR mode not supported on this device!");
12423 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12425 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12426 VrManagerInternal.NO_ERROR;
12429 public boolean isTopActivityImmersive() {
12430 enforceNotIsolatedCaller("startActivity");
12431 synchronized (this) {
12432 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12433 return (r != null) ? r.immersive : false;
12438 public boolean isTopOfTask(IBinder token) {
12439 synchronized (this) {
12440 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12442 throw new IllegalArgumentException();
12444 return r.task.getTopActivity() == r;
12448 public final void enterSafeMode() {
12449 synchronized(this) {
12450 // It only makes sense to do this before the system is ready
12451 // and started launching other packages.
12452 if (!mSystemReady) {
12454 AppGlobals.getPackageManager().enterSafeMode();
12455 } catch (RemoteException e) {
12463 public final void showSafeModeOverlay() {
12464 View v = LayoutInflater.from(mContext).inflate(
12465 com.android.internal.R.layout.safe_mode, null);
12466 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12467 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12468 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12469 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12470 lp.gravity = Gravity.BOTTOM | Gravity.START;
12471 lp.format = v.getBackground().getOpacity();
12472 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12473 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12474 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12475 ((WindowManager)mContext.getSystemService(
12476 Context.WINDOW_SERVICE)).addView(v, lp);
12479 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12480 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12483 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12484 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12485 synchronized (stats) {
12486 if (mBatteryStatsService.isOnBattery()) {
12487 mBatteryStatsService.enforceCallingPermission();
12488 int MY_UID = Binder.getCallingUid();
12490 if (sender == null) {
12493 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12495 BatteryStatsImpl.Uid.Pkg pkg =
12496 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12497 sourcePkg != null ? sourcePkg : rec.key.packageName);
12498 pkg.noteWakeupAlarmLocked(tag);
12503 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12504 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12507 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12508 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12509 synchronized (stats) {
12510 mBatteryStatsService.enforceCallingPermission();
12511 int MY_UID = Binder.getCallingUid();
12513 if (sender == null) {
12516 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12518 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12522 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12523 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12526 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12527 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12528 synchronized (stats) {
12529 mBatteryStatsService.enforceCallingPermission();
12530 int MY_UID = Binder.getCallingUid();
12532 if (sender == null) {
12535 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12537 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12541 public boolean killPids(int[] pids, String pReason, boolean secure) {
12542 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12543 throw new SecurityException("killPids only available to the system");
12545 String reason = (pReason == null) ? "Unknown" : pReason;
12546 // XXX Note: don't acquire main activity lock here, because the window
12547 // manager calls in with its locks held.
12549 boolean killed = false;
12550 synchronized (mPidsSelfLocked) {
12552 for (int i=0; i<pids.length; i++) {
12553 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12554 if (proc != null) {
12555 int type = proc.setAdj;
12556 if (type > worstType) {
12562 // If the worst oom_adj is somewhere in the cached proc LRU range,
12563 // then constrain it so we will kill all cached procs.
12564 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12565 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12566 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12569 // If this is not a secure call, don't let it kill processes that
12571 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12572 worstType = ProcessList.SERVICE_ADJ;
12575 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12576 for (int i=0; i<pids.length; i++) {
12577 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12578 if (proc == null) {
12581 int adj = proc.setAdj;
12582 if (adj >= worstType && !proc.killedByAm) {
12583 proc.kill(reason, true);
12592 public void killUid(int appId, int userId, String reason) {
12593 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12594 synchronized (this) {
12595 final long identity = Binder.clearCallingIdentity();
12597 killPackageProcessesLocked(null, appId, userId,
12598 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12599 reason != null ? reason : "kill uid");
12601 Binder.restoreCallingIdentity(identity);
12607 public boolean killProcessesBelowForeground(String reason) {
12608 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12609 throw new SecurityException("killProcessesBelowForeground() only available to system");
12612 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12615 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12616 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12617 throw new SecurityException("killProcessesBelowAdj() only available to system");
12620 boolean killed = false;
12621 synchronized (mPidsSelfLocked) {
12622 final int size = mPidsSelfLocked.size();
12623 for (int i = 0; i < size; i++) {
12624 final int pid = mPidsSelfLocked.keyAt(i);
12625 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12626 if (proc == null) continue;
12628 final int adj = proc.setAdj;
12629 if (adj > belowAdj && !proc.killedByAm) {
12630 proc.kill(reason, true);
12639 public void hang(final IBinder who, boolean allowRestart) {
12640 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12641 != PackageManager.PERMISSION_GRANTED) {
12642 throw new SecurityException("Requires permission "
12643 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12646 final IBinder.DeathRecipient death = new DeathRecipient() {
12648 public void binderDied() {
12649 synchronized (this) {
12656 who.linkToDeath(death, 0);
12657 } catch (RemoteException e) {
12658 Slog.w(TAG, "hang: given caller IBinder is already dead.");
12662 synchronized (this) {
12663 Watchdog.getInstance().setAllowRestart(allowRestart);
12664 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12665 synchronized (death) {
12666 while (who.isBinderAlive()) {
12669 } catch (InterruptedException e) {
12673 Watchdog.getInstance().setAllowRestart(true);
12678 public void restart() {
12679 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12680 != PackageManager.PERMISSION_GRANTED) {
12681 throw new SecurityException("Requires permission "
12682 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12685 Log.i(TAG, "Sending shutdown broadcast...");
12687 BroadcastReceiver br = new BroadcastReceiver() {
12688 @Override public void onReceive(Context context, Intent intent) {
12689 // Now the broadcast is done, finish up the low-level shutdown.
12690 Log.i(TAG, "Shutting down activity manager...");
12692 Log.i(TAG, "Shutdown complete, restarting!");
12693 Process.killProcess(Process.myPid());
12698 // First send the high-level shut down broadcast.
12699 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12700 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12701 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12702 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12703 mContext.sendOrderedBroadcastAsUser(intent,
12704 UserHandle.ALL, null, br, mHandler, 0, null, null);
12706 br.onReceive(mContext, intent);
12709 private long getLowRamTimeSinceIdle(long now) {
12710 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12714 public void performIdleMaintenance() {
12715 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12716 != PackageManager.PERMISSION_GRANTED) {
12717 throw new SecurityException("Requires permission "
12718 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12721 synchronized (this) {
12722 final long now = SystemClock.uptimeMillis();
12723 final long timeSinceLastIdle = now - mLastIdleTime;
12724 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12725 mLastIdleTime = now;
12726 mLowRamTimeSinceLastIdle = 0;
12727 if (mLowRamStartTime != 0) {
12728 mLowRamStartTime = now;
12731 StringBuilder sb = new StringBuilder(128);
12732 sb.append("Idle maintenance over ");
12733 TimeUtils.formatDuration(timeSinceLastIdle, sb);
12734 sb.append(" low RAM for ");
12735 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12736 Slog.i(TAG, sb.toString());
12738 // If at least 1/3 of our time since the last idle period has been spent
12739 // with RAM low, then we want to kill processes.
12740 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12742 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12743 ProcessRecord proc = mLruProcesses.get(i);
12744 if (proc.notCachedSinceIdle) {
12745 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12746 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12747 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12748 if (doKilling && proc.initialIdlePss != 0
12749 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12750 sb = new StringBuilder(128);
12752 sb.append(proc.processName);
12753 sb.append(" in idle maint: pss=");
12754 sb.append(proc.lastPss);
12755 sb.append(", swapPss=");
12756 sb.append(proc.lastSwapPss);
12757 sb.append(", initialPss=");
12758 sb.append(proc.initialIdlePss);
12759 sb.append(", period=");
12760 TimeUtils.formatDuration(timeSinceLastIdle, sb);
12761 sb.append(", lowRamPeriod=");
12762 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12763 Slog.wtfQuiet(TAG, sb.toString());
12764 proc.kill("idle maint (pss " + proc.lastPss
12765 + " from " + proc.initialIdlePss + ")", true);
12768 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12769 && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12770 proc.notCachedSinceIdle = true;
12771 proc.initialIdlePss = 0;
12772 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12773 mTestPssMode, isSleeping(), now);
12777 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12778 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12783 public void sendIdleJobTrigger() {
12784 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12785 != PackageManager.PERMISSION_GRANTED) {
12786 throw new SecurityException("Requires permission "
12787 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12790 final long ident = Binder.clearCallingIdentity();
12792 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12793 .setPackage("android")
12794 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12795 broadcastIntent(null, intent, null, null, 0, null, null, null,
12796 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12798 Binder.restoreCallingIdentity(ident);
12802 private void retrieveSettings() {
12803 final ContentResolver resolver = mContext.getContentResolver();
12804 final boolean freeformWindowManagement =
12805 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12806 || Settings.Global.getInt(
12807 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12808 final boolean supportsPictureInPicture =
12809 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12811 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12812 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12813 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12814 final boolean alwaysFinishActivities =
12815 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12816 final boolean lenientBackgroundCheck =
12817 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12818 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12819 final boolean forceResizable = Settings.Global.getInt(
12820 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12821 // Transfer any global setting for forcing RTL layout, into a System Property
12822 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12824 final Configuration configuration = new Configuration();
12825 Settings.System.getConfiguration(resolver, configuration);
12827 // This will take care of setting the correct layout direction flags
12828 configuration.setLayoutDirection(configuration.locale);
12831 synchronized (this) {
12832 mDebugApp = mOrigDebugApp = debugApp;
12833 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12834 mAlwaysFinishActivities = alwaysFinishActivities;
12835 mLenientBackgroundCheck = lenientBackgroundCheck;
12836 mForceResizableActivities = forceResizable;
12837 mWindowManager.setForceResizableTasks(mForceResizableActivities);
12838 if (supportsMultiWindow || forceResizable) {
12839 mSupportsMultiWindow = true;
12840 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12841 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12843 mSupportsMultiWindow = false;
12844 mSupportsFreeformWindowManagement = false;
12845 mSupportsPictureInPicture = false;
12847 // This happens before any activities are started, so we can
12848 // change mConfiguration in-place.
12849 updateConfigurationLocked(configuration, null, true);
12850 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12851 "Initial config: " + mConfiguration);
12853 // Load resources only after the current configuration has been set.
12854 final Resources res = mContext.getResources();
12855 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12856 mThumbnailWidth = res.getDimensionPixelSize(
12857 com.android.internal.R.dimen.thumbnail_width);
12858 mThumbnailHeight = res.getDimensionPixelSize(
12859 com.android.internal.R.dimen.thumbnail_height);
12860 mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12861 com.android.internal.R.string.config_defaultPictureInPictureBounds));
12862 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12863 com.android.internal.R.string.config_appsNotReportingCrashes));
12864 if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12865 mFullscreenThumbnailScale = (float) res
12866 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12867 (float) mConfiguration.screenWidthDp;
12869 mFullscreenThumbnailScale = res.getFraction(
12870 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12875 public boolean testIsSystemReady() {
12876 // no need to synchronize(this) just to read & return the value
12877 return mSystemReady;
12880 public void systemReady(final Runnable goingCallback) {
12881 synchronized(this) {
12882 if (mSystemReady) {
12883 // If we're done calling all the receivers, run the next "boot phase" passed in
12884 // by the SystemServer
12885 if (goingCallback != null) {
12886 goingCallback.run();
12891 mLocalDeviceIdleController
12892 = LocalServices.getService(DeviceIdleController.LocalService.class);
12894 // Make sure we have the current profile info, since it is needed for security checks.
12895 mUserController.onSystemReady();
12896 mRecentTasks.onSystemReadyLocked();
12897 mAppOpsService.systemReady();
12898 mSystemReady = true;
12901 ArrayList<ProcessRecord> procsToKill = null;
12902 synchronized(mPidsSelfLocked) {
12903 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12904 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12905 if (!isAllowedWhileBooting(proc.info)){
12906 if (procsToKill == null) {
12907 procsToKill = new ArrayList<ProcessRecord>();
12909 procsToKill.add(proc);
12914 synchronized(this) {
12915 if (procsToKill != null) {
12916 for (int i=procsToKill.size()-1; i>=0; i--) {
12917 ProcessRecord proc = procsToKill.get(i);
12918 Slog.i(TAG, "Removing system update proc: " + proc);
12919 removeProcessLocked(proc, true, false, "system update done");
12923 // Now that we have cleaned up any update processes, we
12924 // are ready to start launching real processes and know that
12925 // we won't trample on them any more.
12926 mProcessesReady = true;
12929 Slog.i(TAG, "System now ready");
12930 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12931 SystemClock.uptimeMillis());
12933 synchronized(this) {
12934 // Make sure we have no pre-ready processes sitting around.
12936 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12937 ResolveInfo ri = mContext.getPackageManager()
12938 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12940 CharSequence errorMsg = null;
12942 ActivityInfo ai = ri.activityInfo;
12943 ApplicationInfo app = ai.applicationInfo;
12944 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12945 mTopAction = Intent.ACTION_FACTORY_TEST;
12947 mTopComponent = new ComponentName(app.packageName,
12950 errorMsg = mContext.getResources().getText(
12951 com.android.internal.R.string.factorytest_not_system);
12954 errorMsg = mContext.getResources().getText(
12955 com.android.internal.R.string.factorytest_no_action);
12957 if (errorMsg != null) {
12960 mTopComponent = null;
12961 Message msg = Message.obtain();
12962 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12963 msg.getData().putCharSequence("msg", errorMsg);
12964 mUiHandler.sendMessage(msg);
12969 retrieveSettings();
12970 final int currentUserId;
12971 synchronized (this) {
12972 currentUserId = mUserController.getCurrentUserIdLocked();
12973 readGrantedUriPermissionsLocked();
12976 if (goingCallback != null) goingCallback.run();
12978 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12979 Integer.toString(currentUserId), currentUserId);
12980 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12981 Integer.toString(currentUserId), currentUserId);
12982 mSystemServiceManager.startUser(currentUserId);
12984 synchronized (this) {
12985 // Only start up encryption-aware persistent apps; once user is
12986 // unlocked we'll come back around and start unaware apps
12987 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12989 // Start up initial activity.
12991 // Enable home activity for system user, so that the system can always boot
12992 if (UserManager.isSplitSystemUser()) {
12993 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12995 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12996 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12997 UserHandle.USER_SYSTEM);
12998 } catch (RemoteException e) {
12999 throw e.rethrowAsRuntimeException();
13002 startHomeActivityLocked(currentUserId, "systemReady");
13005 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13006 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13007 + " data partition or your device will be unstable.");
13008 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13010 } catch (RemoteException e) {
13013 if (!Build.isBuildConsistent()) {
13014 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13015 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13018 long ident = Binder.clearCallingIdentity();
13020 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13021 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13022 | Intent.FLAG_RECEIVER_FOREGROUND);
13023 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13024 broadcastIntentLocked(null, null, intent,
13025 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13026 null, false, false, MY_PID, Process.SYSTEM_UID,
13028 intent = new Intent(Intent.ACTION_USER_STARTING);
13029 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13030 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13031 broadcastIntentLocked(null, null, intent,
13032 null, new IIntentReceiver.Stub() {
13034 public void performReceive(Intent intent, int resultCode, String data,
13035 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13036 throws RemoteException {
13039 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13040 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13041 } catch (Throwable t) {
13042 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13044 Binder.restoreCallingIdentity(ident);
13046 mStackSupervisor.resumeFocusedStackTopActivityLocked();
13047 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13051 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13052 synchronized (this) {
13053 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13057 void skipCurrentReceiverLocked(ProcessRecord app) {
13058 for (BroadcastQueue queue : mBroadcastQueues) {
13059 queue.skipCurrentReceiverLocked(app);
13064 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13065 * The application process will exit immediately after this call returns.
13066 * @param app object of the crashing app, null for the system server
13067 * @param crashInfo describing the exception
13069 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13070 ProcessRecord r = findAppProcess(app, "Crash");
13071 final String processName = app == null ? "system_server"
13072 : (r == null ? "unknown" : r.processName);
13074 handleApplicationCrashInner("crash", r, processName, crashInfo);
13077 /* Native crash reporting uses this inner version because it needs to be somewhat
13078 * decoupled from the AM-managed cleanup lifecycle
13080 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13081 ApplicationErrorReport.CrashInfo crashInfo) {
13082 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13083 UserHandle.getUserId(Binder.getCallingUid()), processName,
13084 r == null ? -1 : r.info.flags,
13085 crashInfo.exceptionClassName,
13086 crashInfo.exceptionMessage,
13087 crashInfo.throwFileName,
13088 crashInfo.throwLineNumber);
13090 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13092 mAppErrors.crashApplication(r, crashInfo);
13095 public void handleApplicationStrictModeViolation(
13098 StrictMode.ViolationInfo info) {
13099 ProcessRecord r = findAppProcess(app, "StrictMode");
13104 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13105 Integer stackFingerprint = info.hashCode();
13106 boolean logIt = true;
13107 synchronized (mAlreadyLoggedViolatedStacks) {
13108 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13110 // TODO: sub-sample into EventLog for these, with
13111 // the info.durationMillis? Then we'd get
13112 // the relative pain numbers, without logging all
13113 // the stack traces repeatedly. We'd want to do
13114 // likewise in the client code, which also does
13115 // dup suppression, before the Binder call.
13117 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13118 mAlreadyLoggedViolatedStacks.clear();
13120 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13124 logStrictModeViolationToDropBox(r, info);
13128 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13129 AppErrorResult result = new AppErrorResult();
13130 synchronized (this) {
13131 final long origId = Binder.clearCallingIdentity();
13133 Message msg = Message.obtain();
13134 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13135 HashMap<String, Object> data = new HashMap<String, Object>();
13136 data.put("result", result);
13137 data.put("app", r);
13138 data.put("violationMask", violationMask);
13139 data.put("info", info);
13141 mUiHandler.sendMessage(msg);
13143 Binder.restoreCallingIdentity(origId);
13145 int res = result.get();
13146 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13150 // Depending on the policy in effect, there could be a bunch of
13151 // these in quick succession so we try to batch these together to
13152 // minimize disk writes, number of dropbox entries, and maximize
13153 // compression, by having more fewer, larger records.
13154 private void logStrictModeViolationToDropBox(
13155 ProcessRecord process,
13156 StrictMode.ViolationInfo info) {
13157 if (info == null) {
13160 final boolean isSystemApp = process == null ||
13161 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13162 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13163 final String processName = process == null ? "unknown" : process.processName;
13164 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13165 final DropBoxManager dbox = (DropBoxManager)
13166 mContext.getSystemService(Context.DROPBOX_SERVICE);
13168 // Exit early if the dropbox isn't configured to accept this report type.
13169 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13171 boolean bufferWasEmpty;
13172 boolean needsFlush;
13173 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13174 synchronized (sb) {
13175 bufferWasEmpty = sb.length() == 0;
13176 appendDropBoxProcessHeaders(process, processName, sb);
13177 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13178 sb.append("System-App: ").append(isSystemApp).append("\n");
13179 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13180 if (info.violationNumThisLoop != 0) {
13181 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13183 if (info.numAnimationsRunning != 0) {
13184 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13186 if (info.broadcastIntentAction != null) {
13187 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13189 if (info.durationMillis != -1) {
13190 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13192 if (info.numInstances != -1) {
13193 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13195 if (info.tags != null) {
13196 for (String tag : info.tags) {
13197 sb.append("Span-Tag: ").append(tag).append("\n");
13201 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13202 sb.append(info.crashInfo.stackTrace);
13205 if (info.message != null) {
13206 sb.append(info.message);
13210 // Only buffer up to ~64k. Various logging bits truncate
13212 needsFlush = (sb.length() > 64 * 1024);
13215 // Flush immediately if the buffer's grown too large, or this
13216 // is a non-system app. Non-system apps are isolated with a
13217 // different tag & policy and not batched.
13219 // Batching is useful during internal testing with
13220 // StrictMode settings turned up high. Without batching,
13221 // thousands of separate files could be created on boot.
13222 if (!isSystemApp || needsFlush) {
13223 new Thread("Error dump: " + dropboxTag) {
13225 public void run() {
13227 synchronized (sb) {
13228 report = sb.toString();
13229 sb.delete(0, sb.length());
13232 if (report.length() != 0) {
13233 dbox.addText(dropboxTag, report);
13240 // System app batching:
13241 if (!bufferWasEmpty) {
13242 // An existing dropbox-writing thread is outstanding, so
13243 // we don't need to start it up. The existing thread will
13244 // catch the buffer appends we just did.
13248 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13249 // (After this point, we shouldn't access AMS internal data structures.)
13250 new Thread("Error dump: " + dropboxTag) {
13252 public void run() {
13253 // 5 second sleep to let stacks arrive and be batched together
13255 Thread.sleep(5000); // 5 seconds
13256 } catch (InterruptedException e) {}
13258 String errorReport;
13259 synchronized (mStrictModeBuffer) {
13260 errorReport = mStrictModeBuffer.toString();
13261 if (errorReport.length() == 0) {
13264 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13265 mStrictModeBuffer.trimToSize();
13267 dbox.addText(dropboxTag, errorReport);
13273 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13274 * @param app object of the crashing app, null for the system server
13275 * @param tag reported by the caller
13276 * @param system whether this wtf is coming from the system
13277 * @param crashInfo describing the context of the error
13278 * @return true if the process should exit immediately (WTF is fatal)
13280 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13281 final ApplicationErrorReport.CrashInfo crashInfo) {
13282 final int callingUid = Binder.getCallingUid();
13283 final int callingPid = Binder.getCallingPid();
13286 // If this is coming from the system, we could very well have low-level
13287 // system locks held, so we want to do this all asynchronously. And we
13288 // never want this to become fatal, so there is that too.
13289 mHandler.post(new Runnable() {
13290 @Override public void run() {
13291 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13297 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13300 if (r != null && r.pid != Process.myPid() &&
13301 Settings.Global.getInt(mContext.getContentResolver(),
13302 Settings.Global.WTF_IS_FATAL, 0) != 0) {
13303 mAppErrors.crashApplication(r, crashInfo);
13310 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13311 final ApplicationErrorReport.CrashInfo crashInfo) {
13312 final ProcessRecord r = findAppProcess(app, "WTF");
13313 final String processName = app == null ? "system_server"
13314 : (r == null ? "unknown" : r.processName);
13316 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13317 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13319 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13325 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13326 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13328 private ProcessRecord findAppProcess(IBinder app, String reason) {
13333 synchronized (this) {
13334 final int NP = mProcessNames.getMap().size();
13335 for (int ip=0; ip<NP; ip++) {
13336 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13337 final int NA = apps.size();
13338 for (int ia=0; ia<NA; ia++) {
13339 ProcessRecord p = apps.valueAt(ia);
13340 if (p.thread != null && p.thread.asBinder() == app) {
13346 Slog.w(TAG, "Can't find mystery application for " + reason
13347 + " from pid=" + Binder.getCallingPid()
13348 + " uid=" + Binder.getCallingUid() + ": " + app);
13354 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13355 * to append various headers to the dropbox log text.
13357 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13358 StringBuilder sb) {
13359 // Watchdog thread ends up invoking this function (with
13360 // a null ProcessRecord) to add the stack file to dropbox.
13361 // Do not acquire a lock on this (am) in such cases, as it
13362 // could cause a potential deadlock, if and when watchdog
13363 // is invoked due to unavailability of lock on am and it
13364 // would prevent watchdog from killing system_server.
13365 if (process == null) {
13366 sb.append("Process: ").append(processName).append("\n");
13369 // Note: ProcessRecord 'process' is guarded by the service
13370 // instance. (notably process.pkgList, which could otherwise change
13371 // concurrently during execution of this method)
13372 synchronized (this) {
13373 sb.append("Process: ").append(processName).append("\n");
13374 int flags = process.info.flags;
13375 IPackageManager pm = AppGlobals.getPackageManager();
13376 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13377 for (int ip=0; ip<process.pkgList.size(); ip++) {
13378 String pkg = process.pkgList.keyAt(ip);
13379 sb.append("Package: ").append(pkg);
13381 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13383 sb.append(" v").append(pi.versionCode);
13384 if (pi.versionName != null) {
13385 sb.append(" (").append(pi.versionName).append(")");
13388 } catch (RemoteException e) {
13389 Slog.e(TAG, "Error getting package info: " + pkg, e);
13396 private static String processClass(ProcessRecord process) {
13397 if (process == null || process.pid == MY_PID) {
13398 return "system_server";
13399 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13400 return "system_app";
13406 private volatile long mWtfClusterStart;
13407 private volatile int mWtfClusterCount;
13410 * Write a description of an error (crash, WTF, ANR) to the drop box.
13411 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13412 * @param process which caused the error, null means the system server
13413 * @param activity which triggered the error, null if unknown
13414 * @param parent activity related to the error, null if unknown
13415 * @param subject line related to the error, null if absent
13416 * @param report in long form describing the error, null if absent
13417 * @param logFile to include in the report, null if none
13418 * @param crashInfo giving an application stack trace, null if absent
13420 public void addErrorToDropBox(String eventType,
13421 ProcessRecord process, String processName, ActivityRecord activity,
13422 ActivityRecord parent, String subject,
13423 final String report, final File logFile,
13424 final ApplicationErrorReport.CrashInfo crashInfo) {
13425 // NOTE -- this must never acquire the ActivityManagerService lock,
13426 // otherwise the watchdog may be prevented from resetting the system.
13428 final String dropboxTag = processClass(process) + "_" + eventType;
13429 final DropBoxManager dbox = (DropBoxManager)
13430 mContext.getSystemService(Context.DROPBOX_SERVICE);
13432 // Exit early if the dropbox isn't configured to accept this report type.
13433 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13435 // Rate-limit how often we're willing to do the heavy lifting below to
13436 // collect and record logs; currently 5 logs per 10 second period.
13437 final long now = SystemClock.elapsedRealtime();
13438 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13439 mWtfClusterStart = now;
13440 mWtfClusterCount = 1;
13442 if (mWtfClusterCount++ >= 5) return;
13445 final StringBuilder sb = new StringBuilder(1024);
13446 appendDropBoxProcessHeaders(process, processName, sb);
13447 if (process != null) {
13448 sb.append("Foreground: ")
13449 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13452 if (activity != null) {
13453 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13455 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13456 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13458 if (parent != null && parent != activity) {
13459 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13461 if (subject != null) {
13462 sb.append("Subject: ").append(subject).append("\n");
13464 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13465 if (Debug.isDebuggerConnected()) {
13466 sb.append("Debugger: Connected\n");
13470 // Do the rest in a worker thread to avoid blocking the caller on I/O
13471 // (After this point, we shouldn't access AMS internal data structures.)
13472 Thread worker = new Thread("Error dump: " + dropboxTag) {
13474 public void run() {
13475 if (report != null) {
13478 if (logFile != null) {
13480 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13481 "\n\n[[TRUNCATED]]"));
13482 } catch (IOException e) {
13483 Slog.e(TAG, "Error reading " + logFile, e);
13486 if (crashInfo != null && crashInfo.stackTrace != null) {
13487 sb.append(crashInfo.stackTrace);
13490 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13491 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13495 // Merge several logcat streams, and take the last N lines
13496 InputStreamReader input = null;
13498 java.lang.Process logcat = new ProcessBuilder(
13499 "/system/bin/timeout", "-k", "15s", "10s",
13500 "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13501 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13502 .redirectErrorStream(true).start();
13504 try { logcat.getOutputStream().close(); } catch (IOException e) {}
13505 try { logcat.getErrorStream().close(); } catch (IOException e) {}
13506 input = new InputStreamReader(logcat.getInputStream());
13509 char[] buf = new char[8192];
13510 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13511 } catch (IOException e) {
13512 Slog.e(TAG, "Error running logcat", e);
13514 if (input != null) try { input.close(); } catch (IOException e) {}
13518 dbox.addText(dropboxTag, sb.toString());
13522 if (process == null) {
13523 // If process is null, we are being called from some internal code
13524 // and may be about to die -- run this synchronously.
13532 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13533 enforceNotIsolatedCaller("getProcessesInErrorState");
13534 // assume our apps are happy - lazy create the list
13535 List<ActivityManager.ProcessErrorStateInfo> errList = null;
13537 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13538 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13539 int userId = UserHandle.getUserId(Binder.getCallingUid());
13541 synchronized (this) {
13543 // iterate across all processes
13544 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13545 ProcessRecord app = mLruProcesses.get(i);
13546 if (!allUsers && app.userId != userId) {
13549 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13550 // This one's in trouble, so we'll generate a report for it
13551 // crashes are higher priority (in case there's a crash *and* an anr)
13552 ActivityManager.ProcessErrorStateInfo report = null;
13553 if (app.crashing) {
13554 report = app.crashingReport;
13555 } else if (app.notResponding) {
13556 report = app.notRespondingReport;
13559 if (report != null) {
13560 if (errList == null) {
13561 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13563 errList.add(report);
13565 Slog.w(TAG, "Missing app error report, app = " + app.processName +
13566 " crashing = " + app.crashing +
13567 " notResponding = " + app.notResponding);
13576 static int procStateToImportance(int procState, int memAdj,
13577 ActivityManager.RunningAppProcessInfo currApp) {
13578 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13579 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13580 currApp.lru = memAdj;
13587 private void fillInProcMemInfo(ProcessRecord app,
13588 ActivityManager.RunningAppProcessInfo outInfo) {
13589 outInfo.pid = app.pid;
13590 outInfo.uid = app.info.uid;
13591 if (mHeavyWeightProcess == app) {
13592 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13594 if (app.persistent) {
13595 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13597 if (app.activities.size() > 0) {
13598 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13600 outInfo.lastTrimLevel = app.trimMemoryLevel;
13601 int adj = app.curAdj;
13602 int procState = app.curProcState;
13603 outInfo.importance = procStateToImportance(procState, adj, outInfo);
13604 outInfo.importanceReasonCode = app.adjTypeCode;
13605 outInfo.processState = app.curProcState;
13609 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13610 enforceNotIsolatedCaller("getRunningAppProcesses");
13612 final int callingUid = Binder.getCallingUid();
13614 // Lazy instantiation of list
13615 List<ActivityManager.RunningAppProcessInfo> runList = null;
13616 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13617 callingUid) == PackageManager.PERMISSION_GRANTED;
13618 final int userId = UserHandle.getUserId(callingUid);
13619 final boolean allUids = isGetTasksAllowed(
13620 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13622 synchronized (this) {
13623 // Iterate across all processes
13624 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13625 ProcessRecord app = mLruProcesses.get(i);
13626 if ((!allUsers && app.userId != userId)
13627 || (!allUids && app.uid != callingUid)) {
13630 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13631 // Generate process state info for running application
13632 ActivityManager.RunningAppProcessInfo currApp =
13633 new ActivityManager.RunningAppProcessInfo(app.processName,
13634 app.pid, app.getPackageList());
13635 fillInProcMemInfo(app, currApp);
13636 if (app.adjSource instanceof ProcessRecord) {
13637 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13638 currApp.importanceReasonImportance =
13639 ActivityManager.RunningAppProcessInfo.procStateToImportance(
13640 app.adjSourceProcState);
13641 } else if (app.adjSource instanceof ActivityRecord) {
13642 ActivityRecord r = (ActivityRecord)app.adjSource;
13643 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13645 if (app.adjTarget instanceof ComponentName) {
13646 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13648 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13649 // + " lru=" + currApp.lru);
13650 if (runList == null) {
13651 runList = new ArrayList<>();
13653 runList.add(currApp);
13661 public List<ApplicationInfo> getRunningExternalApplications() {
13662 enforceNotIsolatedCaller("getRunningExternalApplications");
13663 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13664 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13665 if (runningApps != null && runningApps.size() > 0) {
13666 Set<String> extList = new HashSet<String>();
13667 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13668 if (app.pkgList != null) {
13669 for (String pkg : app.pkgList) {
13674 IPackageManager pm = AppGlobals.getPackageManager();
13675 for (String pkg : extList) {
13677 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13678 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13681 } catch (RemoteException e) {
13689 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13690 enforceNotIsolatedCaller("getMyMemoryState");
13691 synchronized (this) {
13692 ProcessRecord proc;
13693 synchronized (mPidsSelfLocked) {
13694 proc = mPidsSelfLocked.get(Binder.getCallingPid());
13696 fillInProcMemInfo(proc, outInfo);
13701 public int getMemoryTrimLevel() {
13702 enforceNotIsolatedCaller("getMyMemoryState");
13703 synchronized (this) {
13704 return mLastMemoryLevel;
13709 public void onShellCommand(FileDescriptor in, FileDescriptor out,
13710 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13711 (new ActivityManagerShellCommand(this, false)).exec(
13712 this, in, out, err, args, resultReceiver);
13716 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13717 if (checkCallingPermission(android.Manifest.permission.DUMP)
13718 != PackageManager.PERMISSION_GRANTED) {
13719 pw.println("Permission Denial: can't dump ActivityManager from from pid="
13720 + Binder.getCallingPid()
13721 + ", uid=" + Binder.getCallingUid()
13722 + " without permission "
13723 + android.Manifest.permission.DUMP);
13727 boolean dumpAll = false;
13728 boolean dumpClient = false;
13729 String dumpPackage = null;
13732 while (opti < args.length) {
13733 String opt = args[opti];
13734 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13738 if ("-a".equals(opt)) {
13740 } else if ("-c".equals(opt)) {
13742 } else if ("-p".equals(opt)) {
13743 if (opti < args.length) {
13744 dumpPackage = args[opti];
13747 pw.println("Error: -p option requires package argument");
13751 } else if ("-h".equals(opt)) {
13752 ActivityManagerShellCommand.dumpHelp(pw, true);
13755 pw.println("Unknown argument: " + opt + "; use -h for help");
13759 long origId = Binder.clearCallingIdentity();
13760 boolean more = false;
13761 // Is the caller requesting to dump a particular piece of data?
13762 if (opti < args.length) {
13763 String cmd = args[opti];
13765 if ("activities".equals(cmd) || "a".equals(cmd)) {
13766 synchronized (this) {
13767 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13769 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13770 synchronized (this) {
13771 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13773 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13776 if (opti >= args.length) {
13778 newArgs = EMPTY_STRING_ARRAY;
13780 dumpPackage = args[opti];
13782 newArgs = new String[args.length - opti];
13783 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13784 args.length - opti);
13786 synchronized (this) {
13787 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13789 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13792 if (opti >= args.length) {
13794 newArgs = EMPTY_STRING_ARRAY;
13796 dumpPackage = args[opti];
13798 newArgs = new String[args.length - opti];
13799 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13800 args.length - opti);
13802 synchronized (this) {
13803 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13805 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13808 if (opti >= args.length) {
13810 newArgs = EMPTY_STRING_ARRAY;
13812 dumpPackage = args[opti];
13814 newArgs = new String[args.length - opti];
13815 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13816 args.length - opti);
13818 synchronized (this) {
13819 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13821 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13822 synchronized (this) {
13823 dumpOomLocked(fd, pw, args, opti, true);
13825 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13826 synchronized (this) {
13827 dumpPermissionsLocked(fd, pw, args, opti, true, null);
13829 } else if ("provider".equals(cmd)) {
13832 if (opti >= args.length) {
13834 newArgs = EMPTY_STRING_ARRAY;
13838 newArgs = new String[args.length - opti];
13839 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13841 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13842 pw.println("No providers match: " + name);
13843 pw.println("Use -h for help.");
13845 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13846 synchronized (this) {
13847 dumpProvidersLocked(fd, pw, args, opti, true, null);
13849 } else if ("service".equals(cmd)) {
13852 if (opti >= args.length) {
13854 newArgs = EMPTY_STRING_ARRAY;
13858 newArgs = new String[args.length - opti];
13859 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13860 args.length - opti);
13862 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13863 pw.println("No services match: " + name);
13864 pw.println("Use -h for help.");
13866 } else if ("package".equals(cmd)) {
13868 if (opti >= args.length) {
13869 pw.println("package: no package name specified");
13870 pw.println("Use -h for help.");
13872 dumpPackage = args[opti];
13874 newArgs = new String[args.length - opti];
13875 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13876 args.length - opti);
13881 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13882 synchronized (this) {
13883 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13885 } else if ("services".equals(cmd) || "s".equals(cmd)) {
13887 ActiveServices.ServiceDumper dumper;
13888 synchronized (this) {
13889 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13892 dumper.dumpWithClient();
13894 synchronized (this) {
13895 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13896 dumpPackage).dumpLocked();
13899 } else if ("locks".equals(cmd)) {
13900 LockGuard.dump(fd, pw, args);
13902 // Dumping a single activity?
13903 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13904 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13905 int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13907 pw.println("Bad activity command, or no activities match: " + cmd);
13908 pw.println("Use -h for help.");
13913 Binder.restoreCallingIdentity(origId);
13918 // No piece of data specified, dump everything.
13920 ActiveServices.ServiceDumper sdumper;
13921 synchronized (this) {
13922 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13925 pw.println("-------------------------------------------------------------------------------");
13927 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13930 pw.println("-------------------------------------------------------------------------------");
13932 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13935 pw.println("-------------------------------------------------------------------------------");
13937 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13940 pw.println("-------------------------------------------------------------------------------");
13942 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13945 sdumper.dumpWithClient();
13947 synchronized (this) {
13949 pw.println("-------------------------------------------------------------------------------");
13951 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13954 pw.println("-------------------------------------------------------------------------------");
13956 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13957 if (mAssociations.size() > 0) {
13960 pw.println("-------------------------------------------------------------------------------");
13962 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13966 pw.println("-------------------------------------------------------------------------------");
13968 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13972 synchronized (this) {
13973 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13976 pw.println("-------------------------------------------------------------------------------");
13978 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13981 pw.println("-------------------------------------------------------------------------------");
13983 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13986 pw.println("-------------------------------------------------------------------------------");
13988 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13991 pw.println("-------------------------------------------------------------------------------");
13993 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
13997 pw.println("-------------------------------------------------------------------------------");
13999 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14002 pw.println("-------------------------------------------------------------------------------");
14004 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14005 if (mAssociations.size() > 0) {
14008 pw.println("-------------------------------------------------------------------------------");
14010 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14014 pw.println("-------------------------------------------------------------------------------");
14016 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14019 Binder.restoreCallingIdentity(origId);
14022 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14023 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14024 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14026 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14028 boolean needSep = printedAnything;
14030 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14031 dumpPackage, needSep, " mFocusedActivity: ");
14033 printedAnything = true;
14037 if (dumpPackage == null) {
14042 printedAnything = true;
14043 mStackSupervisor.dump(pw, " ");
14046 if (!printedAnything) {
14047 pw.println(" (nothing)");
14051 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14052 int opti, boolean dumpAll, String dumpPackage) {
14053 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14055 boolean printedAnything = false;
14057 if (mRecentTasks != null && mRecentTasks.size() > 0) {
14058 boolean printedHeader = false;
14060 final int N = mRecentTasks.size();
14061 for (int i=0; i<N; i++) {
14062 TaskRecord tr = mRecentTasks.get(i);
14063 if (dumpPackage != null) {
14064 if (tr.realActivity == null ||
14065 !dumpPackage.equals(tr.realActivity)) {
14069 if (!printedHeader) {
14070 pw.println(" Recent tasks:");
14071 printedHeader = true;
14072 printedAnything = true;
14074 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
14077 mRecentTasks.get(i).dump(pw, " ");
14082 if (!printedAnything) {
14083 pw.println(" (nothing)");
14087 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14088 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14089 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14092 if (dumpPackage != null) {
14093 IPackageManager pm = AppGlobals.getPackageManager();
14095 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14096 } catch (RemoteException e) {
14100 boolean printedAnything = false;
14102 final long now = SystemClock.uptimeMillis();
14104 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14105 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14106 = mAssociations.valueAt(i1);
14107 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14108 SparseArray<ArrayMap<String, Association>> sourceUids
14109 = targetComponents.valueAt(i2);
14110 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14111 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14112 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14113 Association ass = sourceProcesses.valueAt(i4);
14114 if (dumpPackage != null) {
14115 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14116 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14120 printedAnything = true;
14122 pw.print(ass.mTargetProcess);
14124 UserHandle.formatUid(pw, ass.mTargetUid);
14126 pw.print(ass.mSourceProcess);
14128 UserHandle.formatUid(pw, ass.mSourceUid);
14131 pw.print(ass.mTargetComponent.flattenToShortString());
14134 long dur = ass.mTime;
14135 if (ass.mNesting > 0) {
14136 dur += now - ass.mStartTime;
14138 TimeUtils.formatDuration(dur, pw);
14140 pw.print(ass.mCount);
14141 pw.print(" times)");
14143 for (int i=0; i<ass.mStateTimes.length; i++) {
14144 long amt = ass.mStateTimes[i];
14145 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14146 amt += now - ass.mLastStateUptime;
14150 pw.print(ProcessList.makeProcStateString(
14151 i + ActivityManager.MIN_PROCESS_STATE));
14153 TimeUtils.formatDuration(amt, pw);
14154 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14160 if (ass.mNesting > 0) {
14161 pw.print(" Currently active: ");
14162 TimeUtils.formatDuration(now - ass.mStartTime, pw);
14171 if (!printedAnything) {
14172 pw.println(" (nothing)");
14176 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14177 String header, boolean needSep) {
14178 boolean printed = false;
14179 int whichAppId = -1;
14180 if (dumpPackage != null) {
14182 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14184 whichAppId = UserHandle.getAppId(info.uid);
14185 } catch (NameNotFoundException e) {
14186 e.printStackTrace();
14189 for (int i=0; i<uids.size(); i++) {
14190 UidRecord uidRec = uids.valueAt(i);
14191 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14200 pw.println(header);
14203 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
14204 pw.print(": "); pw.println(uidRec);
14209 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14210 int opti, boolean dumpAll, String dumpPackage) {
14211 boolean needSep = false;
14212 boolean printedAnything = false;
14215 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14218 final int NP = mProcessNames.getMap().size();
14219 for (int ip=0; ip<NP; ip++) {
14220 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14221 final int NA = procs.size();
14222 for (int ia=0; ia<NA; ia++) {
14223 ProcessRecord r = procs.valueAt(ia);
14224 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14228 pw.println(" All known processes:");
14230 printedAnything = true;
14232 pw.print(r.persistent ? " *PERS*" : " *APP*");
14233 pw.print(" UID "); pw.print(procs.keyAt(ia));
14234 pw.print(" "); pw.println(r);
14236 if (r.persistent) {
14243 if (mIsolatedProcesses.size() > 0) {
14244 boolean printed = false;
14245 for (int i=0; i<mIsolatedProcesses.size(); i++) {
14246 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14247 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14254 pw.println(" Isolated process list (sorted by uid):");
14255 printedAnything = true;
14259 pw.println(String.format("%sIsolated #%2d: %s",
14260 " ", i, r.toString()));
14264 if (mActiveUids.size() > 0) {
14265 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14266 printedAnything = needSep = true;
14269 if (mValidateUids.size() > 0) {
14270 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14271 printedAnything = needSep = true;
14275 if (mLruProcesses.size() > 0) {
14279 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14280 pw.print(" total, non-act at ");
14281 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14282 pw.print(", non-svc at ");
14283 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14285 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
14287 printedAnything = true;
14290 if (dumpAll || dumpPackage != null) {
14291 synchronized (mPidsSelfLocked) {
14292 boolean printed = false;
14293 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14294 ProcessRecord r = mPidsSelfLocked.valueAt(i);
14295 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14299 if (needSep) pw.println();
14301 pw.println(" PID mappings:");
14303 printedAnything = true;
14305 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14306 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14311 if (mForegroundProcesses.size() > 0) {
14312 synchronized (mPidsSelfLocked) {
14313 boolean printed = false;
14314 for (int i=0; i<mForegroundProcesses.size(); i++) {
14315 ProcessRecord r = mPidsSelfLocked.get(
14316 mForegroundProcesses.valueAt(i).pid);
14317 if (dumpPackage != null && (r == null
14318 || !r.pkgList.containsKey(dumpPackage))) {
14322 if (needSep) pw.println();
14324 pw.println(" Foreground Processes:");
14326 printedAnything = true;
14328 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
14329 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14334 if (mPersistentStartingProcesses.size() > 0) {
14335 if (needSep) pw.println();
14337 printedAnything = true;
14338 pw.println(" Persisent processes that are starting:");
14339 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
14340 "Starting Norm", "Restarting PERS", dumpPackage);
14343 if (mRemovedProcesses.size() > 0) {
14344 if (needSep) pw.println();
14346 printedAnything = true;
14347 pw.println(" Processes that are being removed:");
14348 dumpProcessList(pw, this, mRemovedProcesses, " ",
14349 "Removed Norm", "Removed PERS", dumpPackage);
14352 if (mProcessesOnHold.size() > 0) {
14353 if (needSep) pw.println();
14355 printedAnything = true;
14356 pw.println(" Processes that are on old until the system is ready:");
14357 dumpProcessList(pw, this, mProcessesOnHold, " ",
14358 "OnHold Norm", "OnHold PERS", dumpPackage);
14361 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14363 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14365 printedAnything = true;
14368 if (dumpPackage == null) {
14371 mUserController.dump(pw, dumpAll);
14373 if (mHomeProcess != null && (dumpPackage == null
14374 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14379 pw.println(" mHomeProcess: " + mHomeProcess);
14381 if (mPreviousProcess != null && (dumpPackage == null
14382 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14387 pw.println(" mPreviousProcess: " + mPreviousProcess);
14390 StringBuilder sb = new StringBuilder(128);
14391 sb.append(" mPreviousProcessVisibleTime: ");
14392 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14395 if (mHeavyWeightProcess != null && (dumpPackage == null
14396 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14401 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14403 if (dumpPackage == null) {
14404 pw.println(" mConfiguration: " + mConfiguration);
14407 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14408 if (mCompatModePackages.getPackages().size() > 0) {
14409 boolean printed = false;
14410 for (Map.Entry<String, Integer> entry
14411 : mCompatModePackages.getPackages().entrySet()) {
14412 String pkg = entry.getKey();
14413 int mode = entry.getValue();
14414 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14418 pw.println(" mScreenCompatPackages:");
14421 pw.print(" "); pw.print(pkg); pw.print(": ");
14422 pw.print(mode); pw.println();
14426 if (dumpPackage == null) {
14427 pw.println(" mWakefulness="
14428 + PowerManagerInternal.wakefulnessToString(mWakefulness));
14429 pw.println(" mSleepTokens=" + mSleepTokens);
14430 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
14431 + lockScreenShownToString());
14432 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14433 if (mRunningVoice != null) {
14434 pw.println(" mRunningVoice=" + mRunningVoice);
14435 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
14438 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14439 || mOrigWaitForDebugger) {
14440 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14441 || dumpPackage.equals(mOrigDebugApp)) {
14446 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14447 + " mDebugTransient=" + mDebugTransient
14448 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14451 if (mCurAppTimeTracker != null) {
14452 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
14454 if (mMemWatchProcesses.getMap().size() > 0) {
14455 pw.println(" Mem watch processes:");
14456 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14457 = mMemWatchProcesses.getMap();
14458 for (int i=0; i<procs.size(); i++) {
14459 final String proc = procs.keyAt(i);
14460 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14461 for (int j=0; j<uids.size(); j++) {
14466 StringBuilder sb = new StringBuilder();
14467 sb.append(" ").append(proc).append('/');
14468 UserHandle.formatUid(sb, uids.keyAt(j));
14469 Pair<Long, String> val = uids.valueAt(j);
14470 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14471 if (val.second != null) {
14472 sb.append(", report to ").append(val.second);
14474 pw.println(sb.toString());
14477 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14478 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14479 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14480 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14482 if (mTrackAllocationApp != null) {
14483 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14488 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
14491 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14492 || mProfileFd != null) {
14493 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14498 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14499 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14500 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14501 + mAutoStopProfiler);
14502 pw.println(" mProfileType=" + mProfileType);
14505 if (mNativeDebuggingApp != null) {
14506 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14511 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
14514 if (dumpPackage == null) {
14515 if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14516 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
14517 + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14519 if (mController != null) {
14520 pw.println(" mController=" + mController
14521 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14524 pw.println(" Total persistent processes: " + numPers);
14525 pw.println(" mProcessesReady=" + mProcessesReady
14526 + " mSystemReady=" + mSystemReady
14527 + " mBooted=" + mBooted
14528 + " mFactoryTest=" + mFactoryTest);
14529 pw.println(" mBooting=" + mBooting
14530 + " mCallFinishBooting=" + mCallFinishBooting
14531 + " mBootAnimationComplete=" + mBootAnimationComplete);
14532 pw.print(" mLastPowerCheckRealtime=");
14533 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14535 pw.print(" mLastPowerCheckUptime=");
14536 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14538 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14539 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14540 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14541 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
14542 + " (" + mLruProcesses.size() + " total)"
14543 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14544 + " mNumServiceProcs=" + mNumServiceProcs
14545 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14546 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
14547 + " mLastMemoryLevel=" + mLastMemoryLevel
14548 + " mLastNumProcesses=" + mLastNumProcesses);
14549 long now = SystemClock.uptimeMillis();
14550 pw.print(" mLastIdleTime=");
14551 TimeUtils.formatDuration(now, mLastIdleTime, pw);
14552 pw.print(" mLowRamSinceLastIdle=");
14553 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14558 if (!printedAnything) {
14559 pw.println(" (nothing)");
14563 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14564 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14565 if (mProcessesToGc.size() > 0) {
14566 boolean printed = false;
14567 long now = SystemClock.uptimeMillis();
14568 for (int i=0; i<mProcessesToGc.size(); i++) {
14569 ProcessRecord proc = mProcessesToGc.get(i);
14570 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14574 if (needSep) pw.println();
14576 pw.println(" Processes that are waiting to GC:");
14579 pw.print(" Process "); pw.println(proc);
14580 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
14581 pw.print(", last gced=");
14582 pw.print(now-proc.lastRequestedGc);
14583 pw.print(" ms ago, last lowMem=");
14584 pw.print(now-proc.lastLowMemory);
14585 pw.println(" ms ago");
14592 void printOomLevel(PrintWriter pw, String name, int adj) {
14596 if (adj < 10) pw.print(' ');
14598 if (adj > -10) pw.print(' ');
14604 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14608 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14609 int opti, boolean dumpAll) {
14610 boolean needSep = false;
14612 if (mLruProcesses.size() > 0) {
14613 if (needSep) pw.println();
14615 pw.println(" OOM levels:");
14616 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14617 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14618 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14619 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14620 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14621 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14622 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14623 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14624 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14625 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14626 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14627 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14628 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14629 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14631 if (needSep) pw.println();
14632 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
14633 pw.print(" total, non-act at ");
14634 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14635 pw.print(", non-svc at ");
14636 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14638 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
14642 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14645 pw.println(" mHomeProcess: " + mHomeProcess);
14646 pw.println(" mPreviousProcess: " + mPreviousProcess);
14647 if (mHeavyWeightProcess != null) {
14648 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14655 * There are three ways to call this:
14656 * - no provider specified: dump all the providers
14657 * - a flattened component name that matched an existing provider was specified as the
14658 * first arg: dump that one provider
14659 * - the first arg isn't the flattened component name of an existing provider:
14660 * dump all providers whose component contains the first arg as a substring
14662 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14663 int opti, boolean dumpAll) {
14664 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14667 static class ItemMatcher {
14668 ArrayList<ComponentName> components;
14669 ArrayList<String> strings;
14670 ArrayList<Integer> objects;
14677 void build(String name) {
14678 ComponentName componentName = ComponentName.unflattenFromString(name);
14679 if (componentName != null) {
14680 if (components == null) {
14681 components = new ArrayList<ComponentName>();
14683 components.add(componentName);
14687 // Not a '/' separated full component name; maybe an object ID?
14689 objectId = Integer.parseInt(name, 16);
14690 if (objects == null) {
14691 objects = new ArrayList<Integer>();
14693 objects.add(objectId);
14695 } catch (RuntimeException e) {
14696 // Not an integer; just do string match.
14697 if (strings == null) {
14698 strings = new ArrayList<String>();
14706 int build(String[] args, int opti) {
14707 for (; opti<args.length; opti++) {
14708 String name = args[opti];
14709 if ("--".equals(name)) {
14717 boolean match(Object object, ComponentName comp) {
14721 if (components != null) {
14722 for (int i=0; i<components.size(); i++) {
14723 if (components.get(i).equals(comp)) {
14728 if (objects != null) {
14729 for (int i=0; i<objects.size(); i++) {
14730 if (System.identityHashCode(object) == objects.get(i)) {
14735 if (strings != null) {
14736 String flat = comp.flattenToString();
14737 for (int i=0; i<strings.size(); i++) {
14738 if (flat.contains(strings.get(i))) {
14748 * There are three things that cmd can be:
14749 * - a flattened component name that matches an existing activity
14750 * - the cmd arg isn't the flattened component name of an existing activity:
14751 * dump all activity whose component contains the cmd as a substring
14752 * - A hex number of the ActivityRecord object instance.
14754 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14755 int opti, boolean dumpAll) {
14756 ArrayList<ActivityRecord> activities;
14758 synchronized (this) {
14759 activities = mStackSupervisor.getDumpActivitiesLocked(name);
14762 if (activities.size() <= 0) {
14766 String[] newArgs = new String[args.length - opti];
14767 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14769 TaskRecord lastTask = null;
14770 boolean needSep = false;
14771 for (int i=activities.size()-1; i>=0; i--) {
14772 ActivityRecord r = activities.get(i);
14777 synchronized (this) {
14778 if (lastTask != r.task) {
14780 pw.print("TASK "); pw.print(lastTask.affinity);
14781 pw.print(" id="); pw.println(lastTask.taskId);
14783 lastTask.dump(pw, " ");
14787 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
14793 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14794 * there is a thread associated with the activity.
14796 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14797 final ActivityRecord r, String[] args, boolean dumpAll) {
14798 String innerPrefix = prefix + " ";
14799 synchronized (this) {
14800 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14801 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14803 if (r.app != null) pw.println(r.app.pid);
14804 else pw.println("(not running)");
14806 r.dump(pw, innerPrefix);
14809 if (r.app != null && r.app.thread != null) {
14810 // flush anything that is already in the PrintWriter since the thread is going
14811 // to write to the file descriptor directly
14814 TransferPipe tp = new TransferPipe();
14816 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14817 r.appToken, innerPrefix, args);
14822 } catch (IOException e) {
14823 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14824 } catch (RemoteException e) {
14825 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14830 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14831 int opti, boolean dumpAll, String dumpPackage) {
14832 boolean needSep = false;
14833 boolean onlyHistory = false;
14834 boolean printedAnything = false;
14836 if ("history".equals(dumpPackage)) {
14837 if (opti < args.length && "-s".equals(args[opti])) {
14840 onlyHistory = true;
14841 dumpPackage = null;
14844 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14845 if (!onlyHistory && dumpAll) {
14846 if (mRegisteredReceivers.size() > 0) {
14847 boolean printed = false;
14848 Iterator it = mRegisteredReceivers.values().iterator();
14849 while (it.hasNext()) {
14850 ReceiverList r = (ReceiverList)it.next();
14851 if (dumpPackage != null && (r.app == null ||
14852 !dumpPackage.equals(r.app.info.packageName))) {
14856 pw.println(" Registered Receivers:");
14859 printedAnything = true;
14861 pw.print(" * "); pw.println(r);
14866 if (mReceiverResolver.dump(pw, needSep ?
14867 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
14868 " ", dumpPackage, false, false)) {
14870 printedAnything = true;
14874 for (BroadcastQueue q : mBroadcastQueues) {
14875 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14876 printedAnything |= needSep;
14881 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14882 for (int user=0; user<mStickyBroadcasts.size(); user++) {
14887 printedAnything = true;
14888 pw.print(" Sticky broadcasts for user ");
14889 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14890 StringBuilder sb = new StringBuilder(128);
14891 for (Map.Entry<String, ArrayList<Intent>> ent
14892 : mStickyBroadcasts.valueAt(user).entrySet()) {
14893 pw.print(" * Sticky action "); pw.print(ent.getKey());
14896 ArrayList<Intent> intents = ent.getValue();
14897 final int N = intents.size();
14898 for (int i=0; i<N; i++) {
14900 sb.append(" Intent: ");
14901 intents.get(i).toShortString(sb, false, true, false, false);
14902 pw.println(sb.toString());
14903 Bundle bundle = intents.get(i).getExtras();
14904 if (bundle != null) {
14906 pw.println(bundle.toString());
14916 if (!onlyHistory && dumpAll) {
14918 for (BroadcastQueue queue : mBroadcastQueues) {
14919 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
14920 + queue.mBroadcastsScheduled);
14922 pw.println(" mHandler:");
14923 mHandler.dump(new PrintWriterPrinter(pw), " ");
14925 printedAnything = true;
14928 if (!printedAnything) {
14929 pw.println(" (nothing)");
14933 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14934 int opti, boolean dumpAll, String dumpPackage) {
14936 boolean printedAnything = false;
14938 ItemMatcher matcher = new ItemMatcher();
14939 matcher.build(args, opti);
14941 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14943 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14944 printedAnything |= needSep;
14946 if (mLaunchingProviders.size() > 0) {
14947 boolean printed = false;
14948 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14949 ContentProviderRecord r = mLaunchingProviders.get(i);
14950 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14954 if (needSep) pw.println();
14956 pw.println(" Launching content providers:");
14958 printedAnything = true;
14960 pw.print(" Launching #"); pw.print(i); pw.print(": ");
14965 if (!printedAnything) {
14966 pw.println(" (nothing)");
14970 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14971 int opti, boolean dumpAll, String dumpPackage) {
14972 boolean needSep = false;
14973 boolean printedAnything = false;
14975 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14977 if (mGrantedUriPermissions.size() > 0) {
14978 boolean printed = false;
14980 if (dumpPackage != null) {
14982 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14983 MATCH_UNINSTALLED_PACKAGES, 0);
14984 } catch (NameNotFoundException e) {
14988 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14989 int uid = mGrantedUriPermissions.keyAt(i);
14990 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14993 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14995 if (needSep) pw.println();
14997 pw.println(" Granted Uri Permissions:");
14999 printedAnything = true;
15001 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
15002 for (UriPermission perm : perms.values()) {
15003 pw.print(" "); pw.println(perm);
15005 perm.dump(pw, " ");
15011 if (!printedAnything) {
15012 pw.println(" (nothing)");
15016 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15017 int opti, boolean dumpAll, String dumpPackage) {
15018 boolean printed = false;
15020 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15022 if (mIntentSenderRecords.size() > 0) {
15023 Iterator<WeakReference<PendingIntentRecord>> it
15024 = mIntentSenderRecords.values().iterator();
15025 while (it.hasNext()) {
15026 WeakReference<PendingIntentRecord> ref = it.next();
15027 PendingIntentRecord rec = ref != null ? ref.get(): null;
15028 if (dumpPackage != null && (rec == null
15029 || !dumpPackage.equals(rec.key.packageName))) {
15034 pw.print(" * "); pw.println(rec);
15039 pw.print(" * "); pw.println(ref);
15045 pw.println(" (nothing)");
15049 private static final int dumpProcessList(PrintWriter pw,
15050 ActivityManagerService service, List list,
15051 String prefix, String normalLabel, String persistentLabel,
15052 String dumpPackage) {
15054 final int N = list.size()-1;
15055 for (int i=N; i>=0; i--) {
15056 ProcessRecord r = (ProcessRecord)list.get(i);
15057 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15060 pw.println(String.format("%s%s #%2d: %s",
15061 prefix, (r.persistent ? persistentLabel : normalLabel),
15063 if (r.persistent) {
15070 private static final boolean dumpProcessOomList(PrintWriter pw,
15071 ActivityManagerService service, List<ProcessRecord> origList,
15072 String prefix, String normalLabel, String persistentLabel,
15073 boolean inclDetails, String dumpPackage) {
15075 ArrayList<Pair<ProcessRecord, Integer>> list
15076 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15077 for (int i=0; i<origList.size(); i++) {
15078 ProcessRecord r = origList.get(i);
15079 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15082 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15085 if (list.size() <= 0) {
15089 Comparator<Pair<ProcessRecord, Integer>> comparator
15090 = new Comparator<Pair<ProcessRecord, Integer>>() {
15092 public int compare(Pair<ProcessRecord, Integer> object1,
15093 Pair<ProcessRecord, Integer> object2) {
15094 if (object1.first.setAdj != object2.first.setAdj) {
15095 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15097 if (object1.first.setProcState != object2.first.setProcState) {
15098 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15100 if (object1.second.intValue() != object2.second.intValue()) {
15101 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15107 Collections.sort(list, comparator);
15109 final long curRealtime = SystemClock.elapsedRealtime();
15110 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15111 final long curUptime = SystemClock.uptimeMillis();
15112 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15114 for (int i=list.size()-1; i>=0; i--) {
15115 ProcessRecord r = list.get(i).first;
15116 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15118 switch (r.setSchedGroup) {
15119 case ProcessList.SCHED_GROUP_BACKGROUND:
15122 case ProcessList.SCHED_GROUP_DEFAULT:
15125 case ProcessList.SCHED_GROUP_TOP_APP:
15133 if (r.foregroundActivities) {
15135 } else if (r.foregroundServices) {
15140 String procState = ProcessList.makeProcStateString(r.curProcState);
15142 pw.print(r.persistent ? persistentLabel : normalLabel);
15144 int num = (origList.size()-1)-list.get(i).second;
15145 if (num < 10) pw.print(' ');
15150 pw.print(schedGroup);
15152 pw.print(foreground);
15154 pw.print(procState);
15156 if (r.trimMemoryLevel < 10) pw.print(' ');
15157 pw.print(r.trimMemoryLevel);
15159 pw.print(r.toShortString());
15161 pw.print(r.adjType);
15163 if (r.adjSource != null || r.adjTarget != null) {
15166 if (r.adjTarget instanceof ComponentName) {
15167 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15168 } else if (r.adjTarget != null) {
15169 pw.print(r.adjTarget.toString());
15171 pw.print("{null}");
15174 if (r.adjSource instanceof ProcessRecord) {
15176 pw.print(((ProcessRecord)r.adjSource).toShortString());
15178 } else if (r.adjSource != null) {
15179 pw.println(r.adjSource.toString());
15181 pw.println("{null}");
15187 pw.print("oom: max="); pw.print(r.maxAdj);
15188 pw.print(" curRaw="); pw.print(r.curRawAdj);
15189 pw.print(" setRaw="); pw.print(r.setRawAdj);
15190 pw.print(" cur="); pw.print(r.curAdj);
15191 pw.print(" set="); pw.println(r.setAdj);
15194 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15195 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15196 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15197 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15198 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15202 pw.print("cached="); pw.print(r.cached);
15203 pw.print(" empty="); pw.print(r.empty);
15204 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15206 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15207 if (r.lastWakeTime != 0) {
15209 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15210 synchronized (stats) {
15211 wtime = stats.getProcessWakeTime(r.info.uid,
15212 r.pid, curRealtime);
15214 long timeUsed = wtime - r.lastWakeTime;
15217 pw.print("keep awake over ");
15218 TimeUtils.formatDuration(realtimeSince, pw);
15219 pw.print(" used ");
15220 TimeUtils.formatDuration(timeUsed, pw);
15222 pw.print((timeUsed*100)/realtimeSince);
15225 if (r.lastCpuTime != 0) {
15226 long timeUsed = r.curCpuTime - r.lastCpuTime;
15229 pw.print("run cpu over ");
15230 TimeUtils.formatDuration(uptimeSince, pw);
15231 pw.print(" used ");
15232 TimeUtils.formatDuration(timeUsed, pw);
15234 pw.print((timeUsed*100)/uptimeSince);
15243 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15245 ArrayList<ProcessRecord> procs;
15246 synchronized (this) {
15247 if (args != null && args.length > start
15248 && args[start].charAt(0) != '-') {
15249 procs = new ArrayList<ProcessRecord>();
15252 pid = Integer.parseInt(args[start]);
15253 } catch (NumberFormatException e) {
15255 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15256 ProcessRecord proc = mLruProcesses.get(i);
15257 if (proc.pid == pid) {
15259 } else if (allPkgs && proc.pkgList != null
15260 && proc.pkgList.containsKey(args[start])) {
15262 } else if (proc.processName.equals(args[start])) {
15266 if (procs.size() <= 0) {
15270 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15276 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15277 PrintWriter pw, String[] args) {
15278 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15279 if (procs == null) {
15280 pw.println("No process found for: " + args[0]);
15284 long uptime = SystemClock.uptimeMillis();
15285 long realtime = SystemClock.elapsedRealtime();
15286 pw.println("Applications Graphics Acceleration Info:");
15287 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15289 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15290 ProcessRecord r = procs.get(i);
15291 if (r.thread != null) {
15292 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15295 TransferPipe tp = new TransferPipe();
15297 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15302 } catch (IOException e) {
15303 pw.println("Failure while dumping the app: " + r);
15305 } catch (RemoteException e) {
15306 pw.println("Got a RemoteException while dumping the app " + r);
15313 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15314 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15315 if (procs == null) {
15316 pw.println("No process found for: " + args[0]);
15320 pw.println("Applications Database Info:");
15322 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15323 ProcessRecord r = procs.get(i);
15324 if (r.thread != null) {
15325 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15328 TransferPipe tp = new TransferPipe();
15330 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15335 } catch (IOException e) {
15336 pw.println("Failure while dumping the app: " + r);
15338 } catch (RemoteException e) {
15339 pw.println("Got a RemoteException while dumping the app " + r);
15346 final static class MemItem {
15347 final boolean isProc;
15348 final String label;
15349 final String shortLabel;
15351 final long swapPss;
15353 final boolean hasActivities;
15354 ArrayList<MemItem> subitems;
15356 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15357 boolean _hasActivities) {
15360 shortLabel = _shortLabel;
15362 swapPss = _swapPss;
15364 hasActivities = _hasActivities;
15367 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15370 shortLabel = _shortLabel;
15372 swapPss = _swapPss;
15374 hasActivities = false;
15378 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15379 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15380 if (sort && !isCompact) {
15381 Collections.sort(items, new Comparator<MemItem>() {
15383 public int compare(MemItem lhs, MemItem rhs) {
15384 if (lhs.pss < rhs.pss) {
15386 } else if (lhs.pss > rhs.pss) {
15394 for (int i=0; i<items.size(); i++) {
15395 MemItem mi = items.get(i);
15398 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15399 mi.label, stringifyKBSize(mi.swapPss));
15401 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15403 } else if (mi.isProc) {
15404 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15405 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15406 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15407 pw.println(mi.hasActivities ? ",a" : ",e");
15409 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15410 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15412 if (mi.subitems != null) {
15413 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
15414 true, isCompact, dumpSwapPss);
15419 // These are in KB.
15420 static final long[] DUMP_MEM_BUCKETS = new long[] {
15421 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15422 120*1024, 160*1024, 200*1024,
15423 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15424 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15427 static final void appendMemBucket(StringBuilder out, long memKB, String label,
15428 boolean stackLike) {
15429 int start = label.lastIndexOf('.');
15430 if (start >= 0) start++;
15432 int end = label.length();
15433 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15434 if (DUMP_MEM_BUCKETS[i] >= memKB) {
15435 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15436 out.append(bucket);
15437 out.append(stackLike ? "MB." : "MB ");
15438 out.append(label, start, end);
15442 out.append(memKB/1024);
15443 out.append(stackLike ? "MB." : "MB ");
15444 out.append(label, start, end);
15447 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15448 ProcessList.NATIVE_ADJ,
15449 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15450 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15451 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15452 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15453 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15454 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15456 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15458 "System", "Persistent", "Persistent Service", "Foreground",
15459 "Visible", "Perceptible",
15460 "Heavy Weight", "Backup",
15461 "A Services", "Home",
15462 "Previous", "B Services", "Cached"
15464 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15466 "sys", "pers", "persvc", "fore",
15469 "servicea", "home",
15470 "prev", "serviceb", "cached"
15473 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15474 long realtime, boolean isCheckinRequest, boolean isCompact) {
15476 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15478 if (isCheckinRequest || isCompact) {
15479 // short checkin version
15480 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15482 pw.println("Applications Memory Usage (in Kilobytes):");
15483 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15487 private static final int KSM_SHARED = 0;
15488 private static final int KSM_SHARING = 1;
15489 private static final int KSM_UNSHARED = 2;
15490 private static final int KSM_VOLATILE = 3;
15492 private final long[] getKsmInfo() {
15493 long[] longOut = new long[4];
15494 final int[] SINGLE_LONG_FORMAT = new int[] {
15495 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15497 long[] longTmp = new long[1];
15498 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15499 SINGLE_LONG_FORMAT, null, longTmp, null);
15500 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15502 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15503 SINGLE_LONG_FORMAT, null, longTmp, null);
15504 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15506 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15507 SINGLE_LONG_FORMAT, null, longTmp, null);
15508 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15510 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15511 SINGLE_LONG_FORMAT, null, longTmp, null);
15512 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15516 private static String stringifySize(long size, int order) {
15517 Locale locale = Locale.US;
15520 return String.format(locale, "%,13d", size);
15522 return String.format(locale, "%,9dK", size / 1024);
15524 return String.format(locale, "%,5dM", size / 1024 / 1024);
15525 case 1024 * 1024 * 1024:
15526 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15528 throw new IllegalArgumentException("Invalid size order");
15532 private static String stringifyKBSize(long size) {
15533 return stringifySize(size * 1024, 1024);
15536 // Update this version number in case you change the 'compact' format
15537 private static final int MEMINFO_COMPACT_VERSION = 1;
15539 final void dumpApplicationMemoryUsage(FileDescriptor fd,
15540 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15541 boolean dumpDetails = false;
15542 boolean dumpFullDetails = false;
15543 boolean dumpDalvik = false;
15544 boolean dumpSummaryOnly = false;
15545 boolean dumpUnreachable = false;
15546 boolean oomOnly = false;
15547 boolean isCompact = false;
15548 boolean localOnly = false;
15549 boolean packages = false;
15550 boolean isCheckinRequest = false;
15551 boolean dumpSwapPss = false;
15554 while (opti < args.length) {
15555 String opt = args[opti];
15556 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15560 if ("-a".equals(opt)) {
15561 dumpDetails = true;
15562 dumpFullDetails = true;
15564 dumpSwapPss = true;
15565 } else if ("-d".equals(opt)) {
15567 } else if ("-c".equals(opt)) {
15569 } else if ("-s".equals(opt)) {
15570 dumpDetails = true;
15571 dumpSummaryOnly = true;
15572 } else if ("-S".equals(opt)) {
15573 dumpSwapPss = true;
15574 } else if ("--unreachable".equals(opt)) {
15575 dumpUnreachable = true;
15576 } else if ("--oom".equals(opt)) {
15578 } else if ("--local".equals(opt)) {
15580 } else if ("--package".equals(opt)) {
15582 } else if ("--checkin".equals(opt)) {
15583 isCheckinRequest = true;
15585 } else if ("-h".equals(opt)) {
15586 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15587 pw.println(" -a: include all available information for each process.");
15588 pw.println(" -d: include dalvik details.");
15589 pw.println(" -c: dump in a compact machine-parseable representation.");
15590 pw.println(" -s: dump only summary of application memory usage.");
15591 pw.println(" -S: dump also SwapPss.");
15592 pw.println(" --oom: only show processes organized by oom adj.");
15593 pw.println(" --local: only collect details locally, don't call process.");
15594 pw.println(" --package: interpret process arg as package, dumping all");
15595 pw.println(" processes that have loaded that package.");
15596 pw.println(" --checkin: dump data for a checkin");
15597 pw.println("If [process] is specified it can be the name or ");
15598 pw.println("pid of a specific process to dump.");
15601 pw.println("Unknown argument: " + opt + "; use -h for help");
15605 long uptime = SystemClock.uptimeMillis();
15606 long realtime = SystemClock.elapsedRealtime();
15607 final long[] tmpLong = new long[1];
15609 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15610 if (procs == null) {
15611 // No Java processes. Maybe they want to print a native process.
15612 if (args != null && args.length > opti
15613 && args[opti].charAt(0) != '-') {
15614 ArrayList<ProcessCpuTracker.Stats> nativeProcs
15615 = new ArrayList<ProcessCpuTracker.Stats>();
15616 updateCpuStatsNow();
15619 findPid = Integer.parseInt(args[opti]);
15620 } catch (NumberFormatException e) {
15622 synchronized (mProcessCpuTracker) {
15623 final int N = mProcessCpuTracker.countStats();
15624 for (int i=0; i<N; i++) {
15625 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15626 if (st.pid == findPid || (st.baseName != null
15627 && st.baseName.equals(args[opti]))) {
15628 nativeProcs.add(st);
15632 if (nativeProcs.size() > 0) {
15633 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15635 Debug.MemoryInfo mi = null;
15636 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15637 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15638 final int pid = r.pid;
15639 if (!isCheckinRequest && dumpDetails) {
15640 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15643 mi = new Debug.MemoryInfo();
15645 if (dumpDetails || (!brief && !oomOnly)) {
15646 Debug.getMemoryInfo(pid, mi);
15648 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15649 mi.dalvikPrivateDirty = (int)tmpLong[0];
15651 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15652 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15653 if (isCheckinRequest) {
15660 pw.println("No process found for: " + args[opti]);
15664 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15665 dumpDetails = true;
15668 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15670 String[] innerArgs = new String[args.length-opti];
15671 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15673 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15674 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15675 long nativePss = 0;
15676 long nativeSwapPss = 0;
15677 long dalvikPss = 0;
15678 long dalvikSwapPss = 0;
15679 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15681 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15684 long otherSwapPss = 0;
15685 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15686 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15688 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15689 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15690 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15691 new ArrayList[DUMP_MEM_OOM_LABEL.length];
15694 long totalSwapPss = 0;
15695 long cachedPss = 0;
15696 long cachedSwapPss = 0;
15697 boolean hasSwapPss = false;
15699 Debug.MemoryInfo mi = null;
15700 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15701 final ProcessRecord r = procs.get(i);
15702 final IApplicationThread thread;
15705 final boolean hasActivities;
15706 synchronized (this) {
15709 oomAdj = r.getSetAdjWithServices();
15710 hasActivities = r.activities.size() > 0;
15712 if (thread != null) {
15713 if (!isCheckinRequest && dumpDetails) {
15714 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15717 mi = new Debug.MemoryInfo();
15719 if (dumpDetails || (!brief && !oomOnly)) {
15720 Debug.getMemoryInfo(pid, mi);
15721 hasSwapPss = mi.hasSwappedOutPss;
15723 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15724 mi.dalvikPrivateDirty = (int)tmpLong[0];
15728 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15729 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15730 if (isCheckinRequest) {
15736 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15737 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15738 } catch (RemoteException e) {
15739 if (!isCheckinRequest) {
15740 pw.println("Got RemoteException!");
15747 final long myTotalPss = mi.getTotalPss();
15748 final long myTotalUss = mi.getTotalUss();
15749 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15751 synchronized (this) {
15752 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15753 // Record this for posterity if the process has been stable.
15754 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15758 if (!isCheckinRequest && mi != null) {
15759 totalPss += myTotalPss;
15760 totalSwapPss += myTotalSwapPss;
15761 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15762 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15763 myTotalSwapPss, pid, hasActivities);
15764 procMems.add(pssItem);
15765 procMemsMap.put(pid, pssItem);
15767 nativePss += mi.nativePss;
15768 nativeSwapPss += mi.nativeSwappedOutPss;
15769 dalvikPss += mi.dalvikPss;
15770 dalvikSwapPss += mi.dalvikSwappedOutPss;
15771 for (int j=0; j<dalvikSubitemPss.length; j++) {
15772 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15773 dalvikSubitemSwapPss[j] +=
15774 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15776 otherPss += mi.otherPss;
15777 otherSwapPss += mi.otherSwappedOutPss;
15778 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15779 long mem = mi.getOtherPss(j);
15782 mem = mi.getOtherSwappedOutPss(j);
15783 miscSwapPss[j] += mem;
15784 otherSwapPss -= mem;
15787 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15788 cachedPss += myTotalPss;
15789 cachedSwapPss += myTotalSwapPss;
15792 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15793 if (oomIndex == (oomPss.length - 1)
15794 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15795 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15796 oomPss[oomIndex] += myTotalPss;
15797 oomSwapPss[oomIndex] += myTotalSwapPss;
15798 if (oomProcs[oomIndex] == null) {
15799 oomProcs[oomIndex] = new ArrayList<MemItem>();
15801 oomProcs[oomIndex].add(pssItem);
15809 long nativeProcTotalPss = 0;
15811 if (!isCheckinRequest && procs.size() > 1 && !packages) {
15812 // If we are showing aggregations, also look for native processes to
15813 // include so that our aggregations are more accurate.
15814 updateCpuStatsNow();
15816 synchronized (mProcessCpuTracker) {
15817 final int N = mProcessCpuTracker.countStats();
15818 for (int i=0; i<N; i++) {
15819 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15820 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15822 mi = new Debug.MemoryInfo();
15824 if (!brief && !oomOnly) {
15825 Debug.getMemoryInfo(st.pid, mi);
15827 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15828 mi.nativePrivateDirty = (int)tmpLong[0];
15831 final long myTotalPss = mi.getTotalPss();
15832 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15833 totalPss += myTotalPss;
15834 nativeProcTotalPss += myTotalPss;
15836 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15837 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15838 procMems.add(pssItem);
15840 nativePss += mi.nativePss;
15841 nativeSwapPss += mi.nativeSwappedOutPss;
15842 dalvikPss += mi.dalvikPss;
15843 dalvikSwapPss += mi.dalvikSwappedOutPss;
15844 for (int j=0; j<dalvikSubitemPss.length; j++) {
15845 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15846 dalvikSubitemSwapPss[j] +=
15847 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15849 otherPss += mi.otherPss;
15850 otherSwapPss += mi.otherSwappedOutPss;
15851 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15852 long mem = mi.getOtherPss(j);
15855 mem = mi.getOtherSwappedOutPss(j);
15856 miscSwapPss[j] += mem;
15857 otherSwapPss -= mem;
15859 oomPss[0] += myTotalPss;
15860 oomSwapPss[0] += myTotalSwapPss;
15861 if (oomProcs[0] == null) {
15862 oomProcs[0] = new ArrayList<MemItem>();
15864 oomProcs[0].add(pssItem);
15869 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15871 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15872 final MemItem dalvikItem =
15873 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15874 if (dalvikSubitemPss.length > 0) {
15875 dalvikItem.subitems = new ArrayList<MemItem>();
15876 for (int j=0; j<dalvikSubitemPss.length; j++) {
15877 final String name = Debug.MemoryInfo.getOtherLabel(
15878 Debug.MemoryInfo.NUM_OTHER_STATS + j);
15879 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15880 dalvikSubitemSwapPss[j], j));
15883 catMems.add(dalvikItem);
15884 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15885 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15886 String label = Debug.MemoryInfo.getOtherLabel(j);
15887 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15890 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15891 for (int j=0; j<oomPss.length; j++) {
15892 if (oomPss[j] != 0) {
15893 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15894 : DUMP_MEM_OOM_LABEL[j];
15895 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15896 DUMP_MEM_OOM_ADJ[j]);
15897 item.subitems = oomProcs[j];
15902 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15903 if (!brief && !oomOnly && !isCompact) {
15905 pw.println("Total PSS by process:");
15906 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
15910 pw.println("Total PSS by OOM adjustment:");
15912 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
15913 if (!brief && !oomOnly) {
15914 PrintWriter out = categoryPw != null ? categoryPw : pw;
15917 out.println("Total PSS by category:");
15919 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
15924 MemInfoReader memInfo = new MemInfoReader();
15925 memInfo.readMemInfo();
15926 if (nativeProcTotalPss > 0) {
15927 synchronized (this) {
15928 final long cachedKb = memInfo.getCachedSizeKb();
15929 final long freeKb = memInfo.getFreeSizeKb();
15930 final long zramKb = memInfo.getZramTotalSizeKb();
15931 final long kernelKb = memInfo.getKernelUsedSizeKb();
15932 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15933 kernelKb*1024, nativeProcTotalPss*1024);
15934 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15935 nativeProcTotalPss);
15940 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15941 pw.print(" (status ");
15942 switch (mLastMemoryLevel) {
15943 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15944 pw.println("normal)");
15946 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15947 pw.println("moderate)");
15949 case ProcessStats.ADJ_MEM_FACTOR_LOW:
15950 pw.println("low)");
15952 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15953 pw.println("critical)");
15956 pw.print(mLastMemoryLevel);
15960 pw.print(" Free RAM: ");
15961 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15962 + memInfo.getFreeSizeKb()));
15964 pw.print(stringifyKBSize(cachedPss));
15965 pw.print(" cached pss + ");
15966 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15967 pw.print(" cached kernel + ");
15968 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15969 pw.println(" free)");
15971 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15972 pw.print(cachedPss + memInfo.getCachedSizeKb()
15973 + memInfo.getFreeSizeKb()); pw.print(",");
15974 pw.println(totalPss - cachedPss);
15977 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
15978 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15979 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15981 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15982 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15983 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15984 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15985 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15987 pw.print("lostram,"); pw.println(lostRAM);
15990 if (memInfo.getZramTotalSizeKb() != 0) {
15992 pw.print(" ZRAM: ");
15993 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15994 pw.print(" physical used for ");
15995 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15996 - memInfo.getSwapFreeSizeKb()));
15997 pw.print(" in swap (");
15998 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15999 pw.println(" total swap)");
16001 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16002 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16003 pw.println(memInfo.getSwapFreeSizeKb());
16006 final long[] ksm = getKsmInfo();
16008 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16009 || ksm[KSM_VOLATILE] != 0) {
16010 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16011 pw.print(" saved from shared ");
16012 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16013 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16014 pw.print(" unshared; ");
16015 pw.print(stringifyKBSize(
16016 ksm[KSM_VOLATILE])); pw.println(" volatile");
16018 pw.print(" Tuning: ");
16019 pw.print(ActivityManager.staticGetMemoryClass());
16020 pw.print(" (large ");
16021 pw.print(ActivityManager.staticGetLargeMemoryClass());
16022 pw.print("), oom ");
16023 pw.print(stringifySize(
16024 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16025 pw.print(", restore limit ");
16026 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16027 if (ActivityManager.isLowRamDeviceStatic()) {
16028 pw.print(" (low-ram)");
16030 if (ActivityManager.isHighEndGfx()) {
16031 pw.print(" (high-end-gfx)");
16035 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16036 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16037 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16038 pw.print("tuning,");
16039 pw.print(ActivityManager.staticGetMemoryClass());
16041 pw.print(ActivityManager.staticGetLargeMemoryClass());
16043 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16044 if (ActivityManager.isLowRamDeviceStatic()) {
16045 pw.print(",low-ram");
16047 if (ActivityManager.isHighEndGfx()) {
16048 pw.print(",high-end-gfx");
16056 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16057 long memtrack, String name) {
16059 sb.append(ProcessList.makeOomAdjString(oomAdj));
16061 sb.append(ProcessList.makeProcStateString(procState));
16063 ProcessList.appendRamKb(sb, pss);
16066 if (memtrack > 0) {
16068 sb.append(stringifyKBSize(memtrack));
16069 sb.append(" memtrack)");
16073 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16074 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16075 sb.append(" (pid ");
16078 sb.append(mi.adjType);
16080 if (mi.adjReason != null) {
16082 sb.append(mi.adjReason);
16087 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16088 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16089 for (int i=0, N=memInfos.size(); i<N; i++) {
16090 ProcessMemInfo mi = memInfos.get(i);
16091 infoMap.put(mi.pid, mi);
16093 updateCpuStatsNow();
16094 long[] memtrackTmp = new long[1];
16095 synchronized (mProcessCpuTracker) {
16096 final int N = mProcessCpuTracker.countStats();
16097 for (int i=0; i<N; i++) {
16098 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16099 if (st.vsize > 0) {
16100 long pss = Debug.getPss(st.pid, null, memtrackTmp);
16102 if (infoMap.indexOfKey(st.pid) < 0) {
16103 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16104 ProcessList.NATIVE_ADJ, -1, "native", null);
16106 mi.memtrack = memtrackTmp[0];
16115 long totalMemtrack = 0;
16116 for (int i=0, N=memInfos.size(); i<N; i++) {
16117 ProcessMemInfo mi = memInfos.get(i);
16119 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16120 mi.memtrack = memtrackTmp[0];
16122 totalPss += mi.pss;
16123 totalMemtrack += mi.memtrack;
16125 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16126 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16127 if (lhs.oomAdj != rhs.oomAdj) {
16128 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16130 if (lhs.pss != rhs.pss) {
16131 return lhs.pss < rhs.pss ? 1 : -1;
16137 StringBuilder tag = new StringBuilder(128);
16138 StringBuilder stack = new StringBuilder(128);
16139 tag.append("Low on memory -- ");
16140 appendMemBucket(tag, totalPss, "total", false);
16141 appendMemBucket(stack, totalPss, "total", true);
16143 StringBuilder fullNativeBuilder = new StringBuilder(1024);
16144 StringBuilder shortNativeBuilder = new StringBuilder(1024);
16145 StringBuilder fullJavaBuilder = new StringBuilder(1024);
16147 boolean firstLine = true;
16148 int lastOomAdj = Integer.MIN_VALUE;
16149 long extraNativeRam = 0;
16150 long extraNativeMemtrack = 0;
16151 long cachedPss = 0;
16152 for (int i=0, N=memInfos.size(); i<N; i++) {
16153 ProcessMemInfo mi = memInfos.get(i);
16155 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16156 cachedPss += mi.pss;
16159 if (mi.oomAdj != ProcessList.NATIVE_ADJ
16160 && (mi.oomAdj < ProcessList.SERVICE_ADJ
16161 || mi.oomAdj == ProcessList.HOME_APP_ADJ
16162 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16163 if (lastOomAdj != mi.oomAdj) {
16164 lastOomAdj = mi.oomAdj;
16165 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16168 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16173 stack.append("\n\t at ");
16181 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16182 appendMemBucket(tag, mi.pss, mi.name, false);
16184 appendMemBucket(stack, mi.pss, mi.name, true);
16185 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16186 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16188 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16189 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16190 stack.append(DUMP_MEM_OOM_LABEL[k]);
16192 stack.append(DUMP_MEM_OOM_ADJ[k]);
16199 appendMemInfo(fullNativeBuilder, mi);
16200 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16201 // The short form only has native processes that are >= 512K.
16202 if (mi.pss >= 512) {
16203 appendMemInfo(shortNativeBuilder, mi);
16205 extraNativeRam += mi.pss;
16206 extraNativeMemtrack += mi.memtrack;
16209 // Short form has all other details, but if we have collected RAM
16210 // from smaller native processes let's dump a summary of that.
16211 if (extraNativeRam > 0) {
16212 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16213 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16214 shortNativeBuilder.append('\n');
16215 extraNativeRam = 0;
16217 appendMemInfo(fullJavaBuilder, mi);
16221 fullJavaBuilder.append(" ");
16222 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16223 fullJavaBuilder.append(": TOTAL");
16224 if (totalMemtrack > 0) {
16225 fullJavaBuilder.append(" (");
16226 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16227 fullJavaBuilder.append(" memtrack)");
16230 fullJavaBuilder.append("\n");
16232 MemInfoReader memInfo = new MemInfoReader();
16233 memInfo.readMemInfo();
16234 final long[] infos = memInfo.getRawInfo();
16236 StringBuilder memInfoBuilder = new StringBuilder(1024);
16237 Debug.getMemInfo(infos);
16238 memInfoBuilder.append(" MemInfo: ");
16239 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16240 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16241 memInfoBuilder.append(stringifyKBSize(
16242 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16243 memInfoBuilder.append(stringifyKBSize(
16244 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16245 memInfoBuilder.append(stringifyKBSize(
16246 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16247 memInfoBuilder.append(" ");
16248 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16249 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16250 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16251 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16252 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16253 memInfoBuilder.append(" ZRAM: ");
16254 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16255 memInfoBuilder.append(" RAM, ");
16256 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16257 memInfoBuilder.append(" swap total, ");
16258 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16259 memInfoBuilder.append(" swap free\n");
16261 final long[] ksm = getKsmInfo();
16262 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16263 || ksm[KSM_VOLATILE] != 0) {
16264 memInfoBuilder.append(" KSM: ");
16265 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16266 memInfoBuilder.append(" saved from shared ");
16267 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16268 memInfoBuilder.append("\n ");
16269 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16270 memInfoBuilder.append(" unshared; ");
16271 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16272 memInfoBuilder.append(" volatile\n");
16274 memInfoBuilder.append(" Free RAM: ");
16275 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16276 + memInfo.getFreeSizeKb()));
16277 memInfoBuilder.append("\n");
16278 memInfoBuilder.append(" Used RAM: ");
16279 memInfoBuilder.append(stringifyKBSize(
16280 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16281 memInfoBuilder.append("\n");
16282 memInfoBuilder.append(" Lost RAM: ");
16283 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16284 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16285 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16286 memInfoBuilder.append("\n");
16287 Slog.i(TAG, "Low on memory:");
16288 Slog.i(TAG, shortNativeBuilder.toString());
16289 Slog.i(TAG, fullJavaBuilder.toString());
16290 Slog.i(TAG, memInfoBuilder.toString());
16292 StringBuilder dropBuilder = new StringBuilder(1024);
16294 StringWriter oomSw = new StringWriter();
16295 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16296 StringWriter catSw = new StringWriter();
16297 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16298 String[] emptyArgs = new String[] { };
16299 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
16301 String oomString = oomSw.toString();
16303 dropBuilder.append("Low on memory:");
16304 dropBuilder.append(stack);
16305 dropBuilder.append('\n');
16306 dropBuilder.append(fullNativeBuilder);
16307 dropBuilder.append(fullJavaBuilder);
16308 dropBuilder.append('\n');
16309 dropBuilder.append(memInfoBuilder);
16310 dropBuilder.append('\n');
16312 dropBuilder.append(oomString);
16313 dropBuilder.append('\n');
16315 StringWriter catSw = new StringWriter();
16316 synchronized (ActivityManagerService.this) {
16317 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16318 String[] emptyArgs = new String[] { };
16320 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16322 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16323 false, null).dumpLocked();
16325 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16328 dropBuilder.append(catSw.toString());
16329 addErrorToDropBox("lowmem", null, "system_server", null,
16330 null, tag.toString(), dropBuilder.toString(), null, null);
16331 //Slog.i(TAG, "Sent to dropbox:");
16332 //Slog.i(TAG, dropBuilder.toString());
16333 synchronized (ActivityManagerService.this) {
16334 long now = SystemClock.uptimeMillis();
16335 if (mLastMemUsageReportTime < now) {
16336 mLastMemUsageReportTime = now;
16342 * Searches array of arguments for the specified string
16343 * @param args array of argument strings
16344 * @param value value to search for
16345 * @return true if the value is contained in the array
16347 private static boolean scanArgs(String[] args, String value) {
16348 if (args != null) {
16349 for (String arg : args) {
16350 if (value.equals(arg)) {
16358 private final boolean removeDyingProviderLocked(ProcessRecord proc,
16359 ContentProviderRecord cpr, boolean always) {
16360 final boolean inLaunching = mLaunchingProviders.contains(cpr);
16362 if (!inLaunching || always) {
16363 synchronized (cpr) {
16364 cpr.launchingApp = null;
16367 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16368 String names[] = cpr.info.authority.split(";");
16369 for (int j = 0; j < names.length; j++) {
16370 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16374 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16375 ContentProviderConnection conn = cpr.connections.get(i);
16376 if (conn.waiting) {
16377 // If this connection is waiting for the provider, then we don't
16378 // need to mess with its process unless we are always removing
16379 // or for some reason the provider is not currently launching.
16380 if (inLaunching && !always) {
16384 ProcessRecord capp = conn.client;
16386 if (conn.stableCount > 0) {
16387 if (!capp.persistent && capp.thread != null
16389 && capp.pid != MY_PID) {
16390 capp.kill("depends on provider "
16391 + cpr.name.flattenToShortString()
16392 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16394 } else if (capp.thread != null && conn.provider.provider != null) {
16396 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16397 } catch (RemoteException e) {
16399 // In the protocol here, we don't expect the client to correctly
16400 // clean up this connection, we'll just remove it.
16401 cpr.connections.remove(i);
16402 if (conn.client.conProviders.remove(conn)) {
16403 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16408 if (inLaunching && always) {
16409 mLaunchingProviders.remove(cpr);
16411 return inLaunching;
16415 * Main code for cleaning up a process when it has gone away. This is
16416 * called both as a result of the process dying, or directly when stopping
16417 * a process when running in single process mode.
16419 * @return Returns true if the given process has been restarted, so the
16420 * app that was passed in must remain on the process lists.
16422 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16423 boolean restarting, boolean allowRestart, int index) {
16425 removeLruProcessLocked(app);
16426 ProcessList.remove(app.pid);
16429 mProcessesToGc.remove(app);
16430 mPendingPssProcesses.remove(app);
16432 // Dismiss any open dialogs.
16433 if (app.crashDialog != null && !app.forceCrashReport) {
16434 app.crashDialog.dismiss();
16435 app.crashDialog = null;
16437 if (app.anrDialog != null) {
16438 app.anrDialog.dismiss();
16439 app.anrDialog = null;
16441 if (app.waitDialog != null) {
16442 app.waitDialog.dismiss();
16443 app.waitDialog = null;
16446 app.crashing = false;
16447 app.notResponding = false;
16449 app.resetPackageList(mProcessStats);
16450 app.unlinkDeathRecipient();
16451 app.makeInactive(mProcessStats);
16452 app.waitingToKill = null;
16453 app.forcingToForeground = null;
16454 updateProcessForegroundLocked(app, false, false);
16455 app.foregroundActivities = false;
16456 app.hasShownUi = false;
16457 app.treatLikeActivity = false;
16458 app.hasAboveClient = false;
16459 app.hasClientActivities = false;
16461 mServices.killServicesLocked(app, allowRestart);
16463 boolean restart = false;
16465 // Remove published content providers.
16466 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16467 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16468 final boolean always = app.bad || !allowRestart;
16469 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16470 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16471 // We left the provider in the launching list, need to
16476 cpr.provider = null;
16479 app.pubProviders.clear();
16481 // Take care of any launching providers waiting for this process.
16482 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16486 // Unregister from connected content providers.
16487 if (!app.conProviders.isEmpty()) {
16488 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16489 ContentProviderConnection conn = app.conProviders.get(i);
16490 conn.provider.connections.remove(conn);
16491 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16492 conn.provider.name);
16494 app.conProviders.clear();
16497 // At this point there may be remaining entries in mLaunchingProviders
16498 // where we were the only one waiting, so they are no longer of use.
16499 // Look for these and clean up if found.
16500 // XXX Commented out for now. Trying to figure out a way to reproduce
16501 // the actual situation to identify what is actually going on.
16503 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16504 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16505 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16506 synchronized (cpr) {
16507 cpr.launchingApp = null;
16514 skipCurrentReceiverLocked(app);
16516 // Unregister any receivers.
16517 for (int i = app.receivers.size() - 1; i >= 0; i--) {
16518 removeReceiverLocked(app.receivers.valueAt(i));
16520 app.receivers.clear();
16522 // If the app is undergoing backup, tell the backup manager about it
16523 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16524 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16525 + mBackupTarget.appInfo + " died during backup");
16527 IBackupManager bm = IBackupManager.Stub.asInterface(
16528 ServiceManager.getService(Context.BACKUP_SERVICE));
16529 bm.agentDisconnected(app.info.packageName);
16530 } catch (RemoteException e) {
16531 // can't happen; backup manager is local
16535 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16536 ProcessChangeItem item = mPendingProcessChanges.get(i);
16537 if (item.pid == app.pid) {
16538 mPendingProcessChanges.remove(i);
16539 mAvailProcessChanges.add(item);
16542 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16543 null).sendToTarget();
16545 // If the caller is restarting this app, then leave it in its
16546 // current lists and let the caller take care of it.
16551 if (!app.persistent || app.isolated) {
16552 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16553 "Removing non-persistent process during cleanup: " + app);
16554 removeProcessNameLocked(app.processName, app.uid);
16555 if (mHeavyWeightProcess == app) {
16556 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16557 mHeavyWeightProcess.userId, 0));
16558 mHeavyWeightProcess = null;
16560 } else if (!app.removed) {
16561 // This app is persistent, so we need to keep its record around.
16562 // If it is not already on the pending app list, add it there
16563 // and start a new process for it.
16564 if (mPersistentStartingProcesses.indexOf(app) < 0) {
16565 mPersistentStartingProcesses.add(app);
16569 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16570 TAG_CLEANUP, "Clean-up removing on hold: " + app);
16571 mProcessesOnHold.remove(app);
16573 if (app == mHomeProcess) {
16574 mHomeProcess = null;
16576 if (app == mPreviousProcess) {
16577 mPreviousProcess = null;
16580 if (restart && !app.isolated) {
16581 // We have components that still need to be running in the
16582 // process, so re-launch it.
16584 ProcessList.remove(app.pid);
16586 addProcessNameLocked(app);
16587 startProcessLocked(app, "restart", app.processName);
16589 } else if (app.pid > 0 && app.pid != MY_PID) {
16592 synchronized (mPidsSelfLocked) {
16593 mPidsSelfLocked.remove(app.pid);
16594 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16596 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16597 if (app.isolated) {
16598 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16605 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16606 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16607 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16608 if (cpr.launchingApp == app) {
16615 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16616 // Look through the content providers we are waiting to have launched,
16617 // and if any run in this process then either schedule a restart of
16618 // the process or kill the client waiting for it if this process has
16620 boolean restart = false;
16621 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16622 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16623 if (cpr.launchingApp == app) {
16624 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16627 removeDyingProviderLocked(app, cpr, true);
16634 // =========================================================
16636 // =========================================================
16639 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16641 enforceNotIsolatedCaller("getServices");
16642 synchronized (this) {
16643 return mServices.getRunningServiceInfoLocked(maxNum, flags);
16648 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16649 enforceNotIsolatedCaller("getRunningServiceControlPanel");
16650 synchronized (this) {
16651 return mServices.getRunningServiceControlPanelLocked(name);
16656 public ComponentName startService(IApplicationThread caller, Intent service,
16657 String resolvedType, String callingPackage, int userId)
16658 throws TransactionTooLargeException {
16659 enforceNotIsolatedCaller("startService");
16660 // Refuse possible leaked file descriptors
16661 if (service != null && service.hasFileDescriptors() == true) {
16662 throw new IllegalArgumentException("File descriptors passed in Intent");
16665 if (callingPackage == null) {
16666 throw new IllegalArgumentException("callingPackage cannot be null");
16669 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16670 "startService: " + service + " type=" + resolvedType);
16671 synchronized(this) {
16672 final int callingPid = Binder.getCallingPid();
16673 final int callingUid = Binder.getCallingUid();
16674 final long origId = Binder.clearCallingIdentity();
16675 ComponentName res = mServices.startServiceLocked(caller, service,
16676 resolvedType, callingPid, callingUid, callingPackage, userId);
16677 Binder.restoreCallingIdentity(origId);
16682 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16683 String callingPackage, int userId)
16684 throws TransactionTooLargeException {
16685 synchronized(this) {
16686 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16687 "startServiceInPackage: " + service + " type=" + resolvedType);
16688 final long origId = Binder.clearCallingIdentity();
16689 ComponentName res = mServices.startServiceLocked(null, service,
16690 resolvedType, -1, uid, callingPackage, userId);
16691 Binder.restoreCallingIdentity(origId);
16697 public int stopService(IApplicationThread caller, Intent service,
16698 String resolvedType, int userId) {
16699 enforceNotIsolatedCaller("stopService");
16700 // Refuse possible leaked file descriptors
16701 if (service != null && service.hasFileDescriptors() == true) {
16702 throw new IllegalArgumentException("File descriptors passed in Intent");
16705 synchronized(this) {
16706 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16711 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16712 enforceNotIsolatedCaller("peekService");
16713 // Refuse possible leaked file descriptors
16714 if (service != null && service.hasFileDescriptors() == true) {
16715 throw new IllegalArgumentException("File descriptors passed in Intent");
16718 if (callingPackage == null) {
16719 throw new IllegalArgumentException("callingPackage cannot be null");
16722 synchronized(this) {
16723 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16728 public boolean stopServiceToken(ComponentName className, IBinder token,
16730 synchronized(this) {
16731 return mServices.stopServiceTokenLocked(className, token, startId);
16736 public void setServiceForeground(ComponentName className, IBinder token,
16737 int id, Notification notification, int flags) {
16738 synchronized(this) {
16739 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16744 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16745 boolean requireFull, String name, String callerPackage) {
16746 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16747 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16750 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16751 String className, int flags) {
16752 boolean result = false;
16753 // For apps that don't have pre-defined UIDs, check for permission
16754 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16755 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16756 if (ActivityManager.checkUidPermission(
16757 INTERACT_ACROSS_USERS,
16758 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16759 ComponentName comp = new ComponentName(aInfo.packageName, className);
16760 String msg = "Permission Denial: Component " + comp.flattenToShortString()
16761 + " requests FLAG_SINGLE_USER, but app does not hold "
16762 + INTERACT_ACROSS_USERS;
16764 throw new SecurityException(msg);
16766 // Permission passed
16769 } else if ("system".equals(componentProcessName)) {
16771 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16772 // Phone app and persistent apps are allowed to export singleuser providers.
16773 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16774 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16776 if (DEBUG_MU) Slog.v(TAG_MU,
16777 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16778 + Integer.toHexString(flags) + ") = " + result);
16783 * Checks to see if the caller is in the same app as the singleton
16784 * component, or the component is in a special app. It allows special apps
16785 * to export singleton components but prevents exporting singleton
16786 * components for regular apps.
16788 boolean isValidSingletonCall(int callingUid, int componentUid) {
16789 int componentAppId = UserHandle.getAppId(componentUid);
16790 return UserHandle.isSameApp(callingUid, componentUid)
16791 || componentAppId == Process.SYSTEM_UID
16792 || componentAppId == Process.PHONE_UID
16793 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16794 == PackageManager.PERMISSION_GRANTED;
16797 public int bindService(IApplicationThread caller, IBinder token, Intent service,
16798 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16799 int userId) throws TransactionTooLargeException {
16800 enforceNotIsolatedCaller("bindService");
16802 // Refuse possible leaked file descriptors
16803 if (service != null && service.hasFileDescriptors() == true) {
16804 throw new IllegalArgumentException("File descriptors passed in Intent");
16807 if (callingPackage == null) {
16808 throw new IllegalArgumentException("callingPackage cannot be null");
16811 synchronized(this) {
16812 return mServices.bindServiceLocked(caller, token, service,
16813 resolvedType, connection, flags, callingPackage, userId);
16817 public boolean unbindService(IServiceConnection connection) {
16818 synchronized (this) {
16819 return mServices.unbindServiceLocked(connection);
16823 public void publishService(IBinder token, Intent intent, IBinder service) {
16824 // Refuse possible leaked file descriptors
16825 if (intent != null && intent.hasFileDescriptors() == true) {
16826 throw new IllegalArgumentException("File descriptors passed in Intent");
16829 synchronized(this) {
16830 if (!(token instanceof ServiceRecord)) {
16831 throw new IllegalArgumentException("Invalid service token");
16833 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16837 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16838 // Refuse possible leaked file descriptors
16839 if (intent != null && intent.hasFileDescriptors() == true) {
16840 throw new IllegalArgumentException("File descriptors passed in Intent");
16843 synchronized(this) {
16844 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16848 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16849 synchronized(this) {
16850 if (!(token instanceof ServiceRecord)) {
16851 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16852 throw new IllegalArgumentException("Invalid service token");
16854 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16858 // =========================================================
16859 // BACKUP AND RESTORE
16860 // =========================================================
16862 // Cause the target app to be launched if necessary and its backup agent
16863 // instantiated. The backup agent will invoke backupAgentCreated() on the
16864 // activity manager to announce its creation.
16865 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16866 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16867 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16868 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16870 synchronized(this) {
16871 // !!! TODO: currently no check here that we're already bound
16872 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16873 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16874 synchronized (stats) {
16875 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16878 // Backup agent is now in use, its package can't be stopped.
16880 AppGlobals.getPackageManager().setPackageStoppedState(
16881 app.packageName, false, UserHandle.getUserId(app.uid));
16882 } catch (RemoteException e) {
16883 } catch (IllegalArgumentException e) {
16884 Slog.w(TAG, "Failed trying to unstop package "
16885 + app.packageName + ": " + e);
16888 BackupRecord r = new BackupRecord(ss, app, backupMode);
16889 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16890 ? new ComponentName(app.packageName, app.backupAgentName)
16891 : new ComponentName("android", "FullBackupAgent");
16892 // startProcessLocked() returns existing proc's record if it's already running
16893 ProcessRecord proc = startProcessLocked(app.processName, app,
16894 false, 0, "backup", hostingName, false, false, false);
16895 if (proc == null) {
16896 Slog.e(TAG, "Unable to start backup agent process " + r);
16900 // If the app is a regular app (uid >= 10000) and not the system server or phone
16901 // process, etc, then mark it as being in full backup so that certain calls to the
16902 // process can be blocked. This is not reset to false anywhere because we kill the
16903 // process after the full backup is done and the ProcessRecord will vaporize anyway.
16904 if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
16905 proc.inFullBackup = true;
16909 mBackupAppName = app.packageName;
16911 // Try not to kill the process during backup
16912 updateOomAdjLocked(proc);
16914 // If the process is already attached, schedule the creation of the backup agent now.
16915 // If it is not yet live, this will be done when it attaches to the framework.
16916 if (proc.thread != null) {
16917 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16919 proc.thread.scheduleCreateBackupAgent(app,
16920 compatibilityInfoForPackageLocked(app), backupMode);
16921 } catch (RemoteException e) {
16922 // Will time out on the backup manager side
16925 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16927 // Invariants: at this point, the target app process exists and the application
16928 // is either already running or in the process of coming up. mBackupTarget and
16929 // mBackupAppName describe the app, so that when it binds back to the AM we
16930 // know that it's scheduled for a backup-agent operation.
16937 public void clearPendingBackup() {
16938 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16939 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16941 synchronized (this) {
16942 mBackupTarget = null;
16943 mBackupAppName = null;
16947 // A backup agent has just come up
16948 public void backupAgentCreated(String agentPackageName, IBinder agent) {
16949 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16952 synchronized(this) {
16953 if (!agentPackageName.equals(mBackupAppName)) {
16954 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16959 long oldIdent = Binder.clearCallingIdentity();
16961 IBackupManager bm = IBackupManager.Stub.asInterface(
16962 ServiceManager.getService(Context.BACKUP_SERVICE));
16963 bm.agentConnected(agentPackageName, agent);
16964 } catch (RemoteException e) {
16965 // can't happen; the backup manager service is local
16966 } catch (Exception e) {
16967 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16968 e.printStackTrace();
16970 Binder.restoreCallingIdentity(oldIdent);
16974 // done with this agent
16975 public void unbindBackupAgent(ApplicationInfo appInfo) {
16976 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16977 if (appInfo == null) {
16978 Slog.w(TAG, "unbind backup agent for null app");
16982 synchronized(this) {
16984 if (mBackupAppName == null) {
16985 Slog.w(TAG, "Unbinding backup agent with no active backup");
16989 if (!mBackupAppName.equals(appInfo.packageName)) {
16990 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16994 // Not backing this app up any more; reset its OOM adjustment
16995 final ProcessRecord proc = mBackupTarget.app;
16996 updateOomAdjLocked(proc);
16998 // If the app crashed during backup, 'thread' will be null here
16999 if (proc.thread != null) {
17001 proc.thread.scheduleDestroyBackupAgent(appInfo,
17002 compatibilityInfoForPackageLocked(appInfo));
17003 } catch (Exception e) {
17004 Slog.e(TAG, "Exception when unbinding backup agent:");
17005 e.printStackTrace();
17009 mBackupTarget = null;
17010 mBackupAppName = null;
17014 // =========================================================
17016 // =========================================================
17018 boolean isPendingBroadcastProcessLocked(int pid) {
17019 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17020 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17023 void skipPendingBroadcastLocked(int pid) {
17024 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17025 for (BroadcastQueue queue : mBroadcastQueues) {
17026 queue.skipPendingBroadcastLocked(pid);
17030 // The app just attached; send any pending broadcasts that it should receive
17031 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17032 boolean didSomething = false;
17033 for (BroadcastQueue queue : mBroadcastQueues) {
17034 didSomething |= queue.sendPendingBroadcastsLocked(app);
17036 return didSomething;
17039 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17040 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17041 enforceNotIsolatedCaller("registerReceiver");
17042 ArrayList<Intent> stickyIntents = null;
17043 ProcessRecord callerApp = null;
17046 synchronized(this) {
17047 if (caller != null) {
17048 callerApp = getRecordForAppLocked(caller);
17049 if (callerApp == null) {
17050 throw new SecurityException(
17051 "Unable to find app for caller " + caller
17052 + " (pid=" + Binder.getCallingPid()
17053 + ") when registering receiver " + receiver);
17055 if (callerApp.info.uid != Process.SYSTEM_UID &&
17056 !callerApp.pkgList.containsKey(callerPackage) &&
17057 !"android".equals(callerPackage)) {
17058 throw new SecurityException("Given caller package " + callerPackage
17059 + " is not running in process " + callerApp);
17061 callingUid = callerApp.info.uid;
17062 callingPid = callerApp.pid;
17064 callerPackage = null;
17065 callingUid = Binder.getCallingUid();
17066 callingPid = Binder.getCallingPid();
17069 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17070 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17072 Iterator<String> actions = filter.actionsIterator();
17073 if (actions == null) {
17074 ArrayList<String> noAction = new ArrayList<String>(1);
17075 noAction.add(null);
17076 actions = noAction.iterator();
17079 // Collect stickies of users
17080 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17081 while (actions.hasNext()) {
17082 String action = actions.next();
17083 for (int id : userIds) {
17084 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17085 if (stickies != null) {
17086 ArrayList<Intent> intents = stickies.get(action);
17087 if (intents != null) {
17088 if (stickyIntents == null) {
17089 stickyIntents = new ArrayList<Intent>();
17091 stickyIntents.addAll(intents);
17098 ArrayList<Intent> allSticky = null;
17099 if (stickyIntents != null) {
17100 final ContentResolver resolver = mContext.getContentResolver();
17101 // Look for any matching sticky broadcasts...
17102 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17103 Intent intent = stickyIntents.get(i);
17104 // If intent has scheme "content", it will need to acccess
17105 // provider that needs to lock mProviderMap in ActivityThread
17106 // and also it may need to wait application response, so we
17107 // cannot lock ActivityManagerService here.
17108 if (filter.match(resolver, intent, true, TAG) >= 0) {
17109 if (allSticky == null) {
17110 allSticky = new ArrayList<Intent>();
17112 allSticky.add(intent);
17117 // The first sticky in the list is returned directly back to the client.
17118 Intent sticky = allSticky != null ? allSticky.get(0) : null;
17119 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17120 if (receiver == null) {
17124 synchronized (this) {
17125 if (callerApp != null && (callerApp.thread == null
17126 || callerApp.thread.asBinder() != caller.asBinder())) {
17127 // Original caller already died
17130 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17132 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17134 if (rl.app != null) {
17135 rl.app.receivers.add(rl);
17138 receiver.asBinder().linkToDeath(rl, 0);
17139 } catch (RemoteException e) {
17142 rl.linkedToDeath = true;
17144 mRegisteredReceivers.put(receiver.asBinder(), rl);
17145 } else if (rl.uid != callingUid) {
17146 throw new IllegalArgumentException(
17147 "Receiver requested to register for uid " + callingUid
17148 + " was previously registered for uid " + rl.uid);
17149 } else if (rl.pid != callingPid) {
17150 throw new IllegalArgumentException(
17151 "Receiver requested to register for pid " + callingPid
17152 + " was previously registered for pid " + rl.pid);
17153 } else if (rl.userId != userId) {
17154 throw new IllegalArgumentException(
17155 "Receiver requested to register for user " + userId
17156 + " was previously registered for user " + rl.userId);
17158 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17159 permission, callingUid, userId);
17161 if (!bf.debugCheck()) {
17162 Slog.w(TAG, "==> For Dynamic broadcast");
17164 mReceiverResolver.addFilter(bf);
17166 // Enqueue broadcasts for all existing stickies that match
17168 if (allSticky != null) {
17169 ArrayList receivers = new ArrayList();
17172 final int stickyCount = allSticky.size();
17173 for (int i = 0; i < stickyCount; i++) {
17174 Intent intent = allSticky.get(i);
17175 BroadcastQueue queue = broadcastQueueForIntent(intent);
17176 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17177 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17178 null, 0, null, null, false, true, true, -1);
17179 queue.enqueueParallelBroadcastLocked(r);
17180 queue.scheduleBroadcastsLocked();
17188 public void unregisterReceiver(IIntentReceiver receiver) {
17189 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17191 final long origId = Binder.clearCallingIdentity();
17193 boolean doTrim = false;
17195 synchronized(this) {
17196 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17198 final BroadcastRecord r = rl.curBroadcast;
17199 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17200 final boolean doNext = r.queue.finishReceiverLocked(
17201 r, r.resultCode, r.resultData, r.resultExtras,
17202 r.resultAbort, false);
17205 r.queue.processNextBroadcast(false);
17209 if (rl.app != null) {
17210 rl.app.receivers.remove(rl);
17212 removeReceiverLocked(rl);
17213 if (rl.linkedToDeath) {
17214 rl.linkedToDeath = false;
17215 rl.receiver.asBinder().unlinkToDeath(rl, 0);
17220 // If we actually concluded any broadcasts, we might now be able
17221 // to trim the recipients' apps from our working set
17223 trimApplications();
17228 Binder.restoreCallingIdentity(origId);
17232 void removeReceiverLocked(ReceiverList rl) {
17233 mRegisteredReceivers.remove(rl.receiver.asBinder());
17234 for (int i = rl.size() - 1; i >= 0; i--) {
17235 mReceiverResolver.removeFilter(rl.get(i));
17239 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17240 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17241 ProcessRecord r = mLruProcesses.get(i);
17242 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17244 r.thread.dispatchPackageBroadcast(cmd, packages);
17245 } catch (RemoteException ex) {
17251 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17252 int callingUid, int[] users) {
17253 // TODO: come back and remove this assumption to triage all broadcasts
17254 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17256 List<ResolveInfo> receivers = null;
17258 HashSet<ComponentName> singleUserReceivers = null;
17259 boolean scannedFirstReceivers = false;
17260 for (int user : users) {
17261 // Skip users that have Shell restrictions, with exception of always permitted
17262 // Shell broadcasts
17263 if (callingUid == Process.SHELL_UID
17264 && mUserController.hasUserRestriction(
17265 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17266 && !isPermittedShellBroadcast(intent)) {
17269 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17270 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17271 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17272 // If this is not the system user, we need to check for
17273 // any receivers that should be filtered out.
17274 for (int i=0; i<newReceivers.size(); i++) {
17275 ResolveInfo ri = newReceivers.get(i);
17276 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17277 newReceivers.remove(i);
17282 if (newReceivers != null && newReceivers.size() == 0) {
17283 newReceivers = null;
17285 if (receivers == null) {
17286 receivers = newReceivers;
17287 } else if (newReceivers != null) {
17288 // We need to concatenate the additional receivers
17289 // found with what we have do far. This would be easy,
17290 // but we also need to de-dup any receivers that are
17292 if (!scannedFirstReceivers) {
17293 // Collect any single user receivers we had already retrieved.
17294 scannedFirstReceivers = true;
17295 for (int i=0; i<receivers.size(); i++) {
17296 ResolveInfo ri = receivers.get(i);
17297 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17298 ComponentName cn = new ComponentName(
17299 ri.activityInfo.packageName, ri.activityInfo.name);
17300 if (singleUserReceivers == null) {
17301 singleUserReceivers = new HashSet<ComponentName>();
17303 singleUserReceivers.add(cn);
17307 // Add the new results to the existing results, tracking
17308 // and de-dupping single user receivers.
17309 for (int i=0; i<newReceivers.size(); i++) {
17310 ResolveInfo ri = newReceivers.get(i);
17311 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17312 ComponentName cn = new ComponentName(
17313 ri.activityInfo.packageName, ri.activityInfo.name);
17314 if (singleUserReceivers == null) {
17315 singleUserReceivers = new HashSet<ComponentName>();
17317 if (!singleUserReceivers.contains(cn)) {
17318 singleUserReceivers.add(cn);
17327 } catch (RemoteException ex) {
17328 // pm is in same process, this will never happen.
17333 private boolean isPermittedShellBroadcast(Intent intent) {
17334 // remote bugreport should always be allowed to be taken
17335 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17338 final int broadcastIntentLocked(ProcessRecord callerApp,
17339 String callerPackage, Intent intent, String resolvedType,
17340 IIntentReceiver resultTo, int resultCode, String resultData,
17341 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17342 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17343 intent = new Intent(intent);
17345 // By default broadcasts do not go to stopped apps.
17346 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17348 // If we have not finished booting, don't allow this to launch new processes.
17349 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17350 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17353 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17354 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17355 + " ordered=" + ordered + " userid=" + userId);
17356 if ((resultTo != null) && !ordered) {
17357 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17360 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17361 ALLOW_NON_FULL, "broadcast", callerPackage);
17363 // Make sure that the user who is receiving this broadcast is running.
17364 // If not, we will just skip it. Make an exception for shutdown broadcasts
17365 // and upgrade steps.
17367 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17368 if ((callingUid != Process.SYSTEM_UID
17369 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17370 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17371 Slog.w(TAG, "Skipping broadcast of " + intent
17372 + ": user " + userId + " is stopped");
17373 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17377 BroadcastOptions brOptions = null;
17378 if (bOptions != null) {
17379 brOptions = new BroadcastOptions(bOptions);
17380 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17381 // See if the caller is allowed to do this. Note we are checking against
17382 // the actual real caller (not whoever provided the operation as say a
17383 // PendingIntent), because that who is actually supplied the arguments.
17384 if (checkComponentPermission(
17385 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17386 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17387 != PackageManager.PERMISSION_GRANTED) {
17388 String msg = "Permission Denial: " + intent.getAction()
17389 + " broadcast from " + callerPackage + " (pid=" + callingPid
17390 + ", uid=" + callingUid + ")"
17392 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17394 throw new SecurityException(msg);
17399 // Verify that protected broadcasts are only being sent by system code,
17400 // and that system code is only sending protected broadcasts.
17401 final String action = intent.getAction();
17402 final boolean isProtectedBroadcast;
17404 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17405 } catch (RemoteException e) {
17406 Slog.w(TAG, "Remote exception", e);
17407 return ActivityManager.BROADCAST_SUCCESS;
17410 final boolean isCallerSystem;
17411 switch (UserHandle.getAppId(callingUid)) {
17412 case Process.ROOT_UID:
17413 case Process.SYSTEM_UID:
17414 case Process.PHONE_UID:
17415 case Process.BLUETOOTH_UID:
17416 case Process.NFC_UID:
17417 isCallerSystem = true;
17420 isCallerSystem = (callerApp != null) && callerApp.persistent;
17424 if (isCallerSystem) {
17425 if (isProtectedBroadcast
17426 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17427 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17428 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17429 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17430 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17431 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17432 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17433 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17434 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17435 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17436 // Broadcast is either protected, or it's a public action that
17437 // we've relaxed, so it's fine for system internals to send.
17439 // The vast majority of broadcasts sent from system internals
17440 // should be protected to avoid security holes, so yell loudly
17441 // to ensure we examine these cases.
17442 if (callerApp != null) {
17443 Log.wtf(TAG, "Sending non-protected broadcast " + action
17444 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17447 Log.wtf(TAG, "Sending non-protected broadcast " + action
17448 + " from system uid " + UserHandle.formatUid(callingUid)
17449 + " pkg " + callerPackage,
17455 if (isProtectedBroadcast) {
17456 String msg = "Permission Denial: not allowed to send broadcast "
17457 + action + " from pid="
17458 + callingPid + ", uid=" + callingUid;
17460 throw new SecurityException(msg);
17462 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17463 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17464 // Special case for compatibility: we don't want apps to send this,
17465 // but historically it has not been protected and apps may be using it
17466 // to poke their own app widget. So, instead of making it protected,
17467 // just limit it to the caller.
17468 if (callerPackage == null) {
17469 String msg = "Permission Denial: not allowed to send broadcast "
17470 + action + " from unknown caller.";
17472 throw new SecurityException(msg);
17473 } else if (intent.getComponent() != null) {
17474 // They are good enough to send to an explicit component... verify
17475 // it is being sent to the calling app.
17476 if (!intent.getComponent().getPackageName().equals(
17478 String msg = "Permission Denial: not allowed to send broadcast "
17480 + intent.getComponent().getPackageName() + " from "
17483 throw new SecurityException(msg);
17486 // Limit broadcast to their own package.
17487 intent.setPackage(callerPackage);
17492 if (action != null) {
17494 case Intent.ACTION_UID_REMOVED:
17495 case Intent.ACTION_PACKAGE_REMOVED:
17496 case Intent.ACTION_PACKAGE_CHANGED:
17497 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17498 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17499 case Intent.ACTION_PACKAGES_SUSPENDED:
17500 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17501 // Handle special intents: if this broadcast is from the package
17502 // manager about a package being removed, we need to remove all of
17503 // its activities from the history stack.
17504 if (checkComponentPermission(
17505 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17506 callingPid, callingUid, -1, true)
17507 != PackageManager.PERMISSION_GRANTED) {
17508 String msg = "Permission Denial: " + intent.getAction()
17509 + " broadcast from " + callerPackage + " (pid=" + callingPid
17510 + ", uid=" + callingUid + ")"
17512 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17514 throw new SecurityException(msg);
17517 case Intent.ACTION_UID_REMOVED:
17518 final Bundle intentExtras = intent.getExtras();
17519 final int uid = intentExtras != null
17520 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17522 mBatteryStatsService.removeUid(uid);
17523 mAppOpsService.uidRemoved(uid);
17526 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17527 // If resources are unavailable just force stop all those packages
17528 // and flush the attribute cache as well.
17530 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17531 if (list != null && list.length > 0) {
17532 for (int i = 0; i < list.length; i++) {
17533 forceStopPackageLocked(list[i], -1, false, true, true,
17534 false, false, userId, "storage unmount");
17536 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17537 sendPackageBroadcastLocked(
17538 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17542 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17543 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17545 case Intent.ACTION_PACKAGE_REMOVED:
17546 case Intent.ACTION_PACKAGE_CHANGED:
17547 Uri data = intent.getData();
17549 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17550 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17551 final boolean replacing =
17552 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17553 final boolean killProcess =
17554 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17555 final boolean fullUninstall = removed && !replacing;
17558 forceStopPackageLocked(ssp, UserHandle.getAppId(
17559 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17560 false, true, true, false, fullUninstall, userId,
17561 removed ? "pkg removed" : "pkg changed");
17563 final int cmd = killProcess
17564 ? IApplicationThread.PACKAGE_REMOVED
17565 : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17566 sendPackageBroadcastLocked(cmd,
17567 new String[] {ssp}, userId);
17568 if (fullUninstall) {
17569 mAppOpsService.packageRemoved(
17570 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17572 // Remove all permissions granted from/to this package
17573 removeUriPermissionsForPackageLocked(ssp, userId, true);
17575 removeTasksByPackageNameLocked(ssp, userId);
17576 mBatteryStatsService.notePackageUninstalled(ssp);
17580 killPackageProcessesLocked(ssp, UserHandle.getAppId(
17581 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17582 userId, ProcessList.INVALID_ADJ,
17583 false, true, true, false, "change " + ssp);
17585 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17586 intent.getStringArrayExtra(
17587 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17591 case Intent.ACTION_PACKAGES_SUSPENDED:
17592 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17593 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17594 intent.getAction());
17595 final String[] packageNames = intent.getStringArrayExtra(
17596 Intent.EXTRA_CHANGED_PACKAGE_LIST);
17597 final int userHandle = intent.getIntExtra(
17598 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17600 synchronized(ActivityManagerService.this) {
17601 mRecentTasks.onPackagesSuspendedChanged(
17602 packageNames, suspended, userHandle);
17607 case Intent.ACTION_PACKAGE_REPLACED:
17609 final Uri data = intent.getData();
17611 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17612 final ApplicationInfo aInfo =
17613 getPackageManagerInternalLocked().getApplicationInfo(
17616 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17617 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17618 new String[] {ssp}, userId);
17622 case Intent.ACTION_PACKAGE_ADDED:
17624 // Special case for adding a package: by default turn on compatibility mode.
17625 Uri data = intent.getData();
17627 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17628 final boolean replacing =
17629 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17630 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17633 ApplicationInfo ai = AppGlobals.getPackageManager().
17634 getApplicationInfo(ssp, 0, 0);
17635 mBatteryStatsService.notePackageInstalled(ssp,
17636 ai != null ? ai.versionCode : 0);
17637 } catch (RemoteException e) {
17642 case Intent.ACTION_TIMEZONE_CHANGED:
17643 // If this is the time zone changed action, queue up a message that will reset
17644 // the timezone of all currently running processes. This message will get
17645 // queued up before the broadcast happens.
17646 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17648 case Intent.ACTION_TIME_CHANGED:
17649 // If the user set the time, let all running processes know.
17650 final int is24Hour =
17651 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17653 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17654 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17655 synchronized (stats) {
17656 stats.noteCurrentTimeChangedLocked();
17659 case Intent.ACTION_CLEAR_DNS_CACHE:
17660 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17662 case Proxy.PROXY_CHANGE_ACTION:
17663 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17664 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17666 case android.hardware.Camera.ACTION_NEW_PICTURE:
17667 case android.hardware.Camera.ACTION_NEW_VIDEO:
17668 // These broadcasts are no longer allowed by the system, since they can
17669 // cause significant thrashing at a crictical point (using the camera).
17670 // Apps should use JobScehduler to monitor for media provider changes.
17671 Slog.w(TAG, action + " no longer allowed; dropping from "
17672 + UserHandle.formatUid(callingUid));
17673 // Lie; we don't want to crash the app.
17674 return ActivityManager.BROADCAST_SUCCESS;
17678 // Add to the sticky list if requested.
17680 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17681 callingPid, callingUid)
17682 != PackageManager.PERMISSION_GRANTED) {
17683 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17684 + callingPid + ", uid=" + callingUid
17685 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17687 throw new SecurityException(msg);
17689 if (requiredPermissions != null && requiredPermissions.length > 0) {
17690 Slog.w(TAG, "Can't broadcast sticky intent " + intent
17691 + " and enforce permissions " + Arrays.toString(requiredPermissions));
17692 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17694 if (intent.getComponent() != null) {
17695 throw new SecurityException(
17696 "Sticky broadcasts can't target a specific component");
17698 // We use userId directly here, since the "all" target is maintained
17699 // as a separate set of sticky broadcasts.
17700 if (userId != UserHandle.USER_ALL) {
17701 // But first, if this is not a broadcast to all users, then
17702 // make sure it doesn't conflict with an existing broadcast to
17704 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17705 UserHandle.USER_ALL);
17706 if (stickies != null) {
17707 ArrayList<Intent> list = stickies.get(intent.getAction());
17708 if (list != null) {
17709 int N = list.size();
17711 for (i=0; i<N; i++) {
17712 if (intent.filterEquals(list.get(i))) {
17713 throw new IllegalArgumentException(
17714 "Sticky broadcast " + intent + " for user "
17715 + userId + " conflicts with existing global broadcast");
17721 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17722 if (stickies == null) {
17723 stickies = new ArrayMap<>();
17724 mStickyBroadcasts.put(userId, stickies);
17726 ArrayList<Intent> list = stickies.get(intent.getAction());
17727 if (list == null) {
17728 list = new ArrayList<>();
17729 stickies.put(intent.getAction(), list);
17731 final int stickiesCount = list.size();
17733 for (i = 0; i < stickiesCount; i++) {
17734 if (intent.filterEquals(list.get(i))) {
17735 // This sticky already exists, replace it.
17736 list.set(i, new Intent(intent));
17740 if (i >= stickiesCount) {
17741 list.add(new Intent(intent));
17746 if (userId == UserHandle.USER_ALL) {
17747 // Caller wants broadcast to go to all started users.
17748 users = mUserController.getStartedUserArrayLocked();
17750 // Caller wants broadcast to go to one specific user.
17751 users = new int[] {userId};
17754 // Figure out who all will receive this broadcast.
17755 List receivers = null;
17756 List<BroadcastFilter> registeredReceivers = null;
17757 // Need to resolve the intent to interested receivers...
17758 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17760 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17762 if (intent.getComponent() == null) {
17763 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17764 // Query one target user at a time, excluding shell-restricted users
17765 for (int i = 0; i < users.length; i++) {
17766 if (mUserController.hasUserRestriction(
17767 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17770 List<BroadcastFilter> registeredReceiversForUser =
17771 mReceiverResolver.queryIntent(intent,
17772 resolvedType, false, users[i]);
17773 if (registeredReceivers == null) {
17774 registeredReceivers = registeredReceiversForUser;
17775 } else if (registeredReceiversForUser != null) {
17776 registeredReceivers.addAll(registeredReceiversForUser);
17780 registeredReceivers = mReceiverResolver.queryIntent(intent,
17781 resolvedType, false, userId);
17785 final boolean replacePending =
17786 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17788 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17789 + " replacePending=" + replacePending);
17791 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17792 if (!ordered && NR > 0) {
17793 // If we are not serializing this broadcast, then send the
17794 // registered receivers separately so they don't wait for the
17795 // components to be launched.
17796 final BroadcastQueue queue = broadcastQueueForIntent(intent);
17797 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17798 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17799 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17800 resultExtras, ordered, sticky, false, userId);
17801 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17802 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17804 queue.enqueueParallelBroadcastLocked(r);
17805 queue.scheduleBroadcastsLocked();
17807 registeredReceivers = null;
17811 // Merge into one list.
17813 if (receivers != null) {
17814 // A special case for PACKAGE_ADDED: do not allow the package
17815 // being added to see this broadcast. This prevents them from
17816 // using this as a back door to get run as soon as they are
17817 // installed. Maybe in the future we want to have a special install
17818 // broadcast or such for apps, but we'd like to deliberately make
17820 String skipPackages[] = null;
17821 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17822 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17823 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17824 Uri data = intent.getData();
17825 if (data != null) {
17826 String pkgName = data.getSchemeSpecificPart();
17827 if (pkgName != null) {
17828 skipPackages = new String[] { pkgName };
17831 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17832 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17834 if (skipPackages != null && (skipPackages.length > 0)) {
17835 for (String skipPackage : skipPackages) {
17836 if (skipPackage != null) {
17837 int NT = receivers.size();
17838 for (int it=0; it<NT; it++) {
17839 ResolveInfo curt = (ResolveInfo)receivers.get(it);
17840 if (curt.activityInfo.packageName.equals(skipPackage)) {
17841 receivers.remove(it);
17850 int NT = receivers != null ? receivers.size() : 0;
17852 ResolveInfo curt = null;
17853 BroadcastFilter curr = null;
17854 while (it < NT && ir < NR) {
17855 if (curt == null) {
17856 curt = (ResolveInfo)receivers.get(it);
17858 if (curr == null) {
17859 curr = registeredReceivers.get(ir);
17861 if (curr.getPriority() >= curt.priority) {
17862 // Insert this broadcast record into the final list.
17863 receivers.add(it, curr);
17869 // Skip to the next ResolveInfo in the final list.
17876 if (receivers == null) {
17877 receivers = new ArrayList();
17879 receivers.add(registeredReceivers.get(ir));
17883 if ((receivers != null && receivers.size() > 0)
17884 || resultTo != null) {
17885 BroadcastQueue queue = broadcastQueueForIntent(intent);
17886 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17887 callerPackage, callingPid, callingUid, resolvedType,
17888 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17889 resultData, resultExtras, ordered, sticky, false, userId);
17891 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17892 + ": prev had " + queue.mOrderedBroadcasts.size());
17893 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17894 "Enqueueing broadcast " + r.intent.getAction());
17896 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17898 queue.enqueueOrderedBroadcastLocked(r);
17899 queue.scheduleBroadcastsLocked();
17903 return ActivityManager.BROADCAST_SUCCESS;
17906 final Intent verifyBroadcastLocked(Intent intent) {
17907 // Refuse possible leaked file descriptors
17908 if (intent != null && intent.hasFileDescriptors() == true) {
17909 throw new IllegalArgumentException("File descriptors passed in Intent");
17912 int flags = intent.getFlags();
17914 if (!mProcessesReady) {
17915 // if the caller really truly claims to know what they're doing, go
17916 // ahead and allow the broadcast without launching any receivers
17917 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17918 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17919 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17920 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17921 + " before boot completion");
17922 throw new IllegalStateException("Cannot broadcast before boot completed");
17926 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17927 throw new IllegalArgumentException(
17928 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17934 public final int broadcastIntent(IApplicationThread caller,
17935 Intent intent, String resolvedType, IIntentReceiver resultTo,
17936 int resultCode, String resultData, Bundle resultExtras,
17937 String[] requiredPermissions, int appOp, Bundle bOptions,
17938 boolean serialized, boolean sticky, int userId) {
17939 enforceNotIsolatedCaller("broadcastIntent");
17940 synchronized(this) {
17941 intent = verifyBroadcastLocked(intent);
17943 final ProcessRecord callerApp = getRecordForAppLocked(caller);
17944 final int callingPid = Binder.getCallingPid();
17945 final int callingUid = Binder.getCallingUid();
17946 final long origId = Binder.clearCallingIdentity();
17947 int res = broadcastIntentLocked(callerApp,
17948 callerApp != null ? callerApp.info.packageName : null,
17949 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17950 requiredPermissions, appOp, bOptions, serialized, sticky,
17951 callingPid, callingUid, userId);
17952 Binder.restoreCallingIdentity(origId);
17958 int broadcastIntentInPackage(String packageName, int uid,
17959 Intent intent, String resolvedType, IIntentReceiver resultTo,
17960 int resultCode, String resultData, Bundle resultExtras,
17961 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17963 synchronized(this) {
17964 intent = verifyBroadcastLocked(intent);
17966 final long origId = Binder.clearCallingIdentity();
17967 String[] requiredPermissions = requiredPermission == null ? null
17968 : new String[] {requiredPermission};
17969 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17970 resultTo, resultCode, resultData, resultExtras,
17971 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17972 sticky, -1, uid, userId);
17973 Binder.restoreCallingIdentity(origId);
17978 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17979 // Refuse possible leaked file descriptors
17980 if (intent != null && intent.hasFileDescriptors() == true) {
17981 throw new IllegalArgumentException("File descriptors passed in Intent");
17984 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17985 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17987 synchronized(this) {
17988 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17989 != PackageManager.PERMISSION_GRANTED) {
17990 String msg = "Permission Denial: unbroadcastIntent() from pid="
17991 + Binder.getCallingPid()
17992 + ", uid=" + Binder.getCallingUid()
17993 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17995 throw new SecurityException(msg);
17997 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17998 if (stickies != null) {
17999 ArrayList<Intent> list = stickies.get(intent.getAction());
18000 if (list != null) {
18001 int N = list.size();
18003 for (i=0; i<N; i++) {
18004 if (intent.filterEquals(list.get(i))) {
18009 if (list.size() <= 0) {
18010 stickies.remove(intent.getAction());
18013 if (stickies.size() <= 0) {
18014 mStickyBroadcasts.remove(userId);
18020 void backgroundServicesFinishedLocked(int userId) {
18021 for (BroadcastQueue queue : mBroadcastQueues) {
18022 queue.backgroundServicesFinishedLocked(userId);
18026 public void finishReceiver(IBinder who, int resultCode, String resultData,
18027 Bundle resultExtras, boolean resultAbort, int flags) {
18028 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18030 // Refuse possible leaked file descriptors
18031 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18032 throw new IllegalArgumentException("File descriptors passed in Bundle");
18035 final long origId = Binder.clearCallingIdentity();
18037 boolean doNext = false;
18040 synchronized(this) {
18041 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18042 ? mFgBroadcastQueue : mBgBroadcastQueue;
18043 r = queue.getMatchingOrderedReceiver(who);
18045 doNext = r.queue.finishReceiverLocked(r, resultCode,
18046 resultData, resultExtras, resultAbort, true);
18051 r.queue.processNextBroadcast(false);
18053 trimApplications();
18055 Binder.restoreCallingIdentity(origId);
18059 // =========================================================
18061 // =========================================================
18063 public boolean startInstrumentation(ComponentName className,
18064 String profileFile, int flags, Bundle arguments,
18065 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18066 int userId, String abiOverride) {
18067 enforceNotIsolatedCaller("startInstrumentation");
18068 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18069 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18070 // Refuse possible leaked file descriptors
18071 if (arguments != null && arguments.hasFileDescriptors()) {
18072 throw new IllegalArgumentException("File descriptors passed in Bundle");
18075 synchronized(this) {
18076 InstrumentationInfo ii = null;
18077 ApplicationInfo ai = null;
18079 ii = mContext.getPackageManager().getInstrumentationInfo(
18080 className, STOCK_PM_FLAGS);
18081 ai = AppGlobals.getPackageManager().getApplicationInfo(
18082 ii.targetPackage, STOCK_PM_FLAGS, userId);
18083 } catch (PackageManager.NameNotFoundException e) {
18084 } catch (RemoteException e) {
18087 reportStartInstrumentationFailureLocked(watcher, className,
18088 "Unable to find instrumentation info for: " + className);
18092 reportStartInstrumentationFailureLocked(watcher, className,
18093 "Unable to find instrumentation target package: " + ii.targetPackage);
18096 if (!ai.hasCode()) {
18097 reportStartInstrumentationFailureLocked(watcher, className,
18098 "Instrumentation target has no code: " + ii.targetPackage);
18102 int match = mContext.getPackageManager().checkSignatures(
18103 ii.targetPackage, ii.packageName);
18104 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18105 String msg = "Permission Denial: starting instrumentation "
18106 + className + " from pid="
18107 + Binder.getCallingPid()
18108 + ", uid=" + Binder.getCallingPid()
18109 + " not allowed because package " + ii.packageName
18110 + " does not have a signature matching the target "
18111 + ii.targetPackage;
18112 reportStartInstrumentationFailureLocked(watcher, className, msg);
18113 throw new SecurityException(msg);
18116 final long origId = Binder.clearCallingIdentity();
18117 // Instrumentation can kill and relaunch even persistent processes
18118 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18120 ProcessRecord app = addAppLocked(ai, false, abiOverride);
18121 app.instrumentationClass = className;
18122 app.instrumentationInfo = ai;
18123 app.instrumentationProfileFile = profileFile;
18124 app.instrumentationArguments = arguments;
18125 app.instrumentationWatcher = watcher;
18126 app.instrumentationUiAutomationConnection = uiAutomationConnection;
18127 app.instrumentationResultClass = className;
18128 Binder.restoreCallingIdentity(origId);
18135 * Report errors that occur while attempting to start Instrumentation. Always writes the
18136 * error to the logs, but if somebody is watching, send the report there too. This enables
18137 * the "am" command to report errors with more information.
18139 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
18140 * @param cn The component name of the instrumentation.
18141 * @param report The error report.
18143 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18144 ComponentName cn, String report) {
18145 Slog.w(TAG, report);
18146 if (watcher != null) {
18147 Bundle results = new Bundle();
18148 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18149 results.putString("Error", report);
18150 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18154 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18155 if (app.instrumentationWatcher != null) {
18156 mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18157 app.instrumentationClass, resultCode, results);
18160 // Can't call out of the system process with a lock held, so post a message.
18161 if (app.instrumentationUiAutomationConnection != null) {
18162 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18163 app.instrumentationUiAutomationConnection).sendToTarget();
18166 app.instrumentationWatcher = null;
18167 app.instrumentationUiAutomationConnection = null;
18168 app.instrumentationClass = null;
18169 app.instrumentationInfo = null;
18170 app.instrumentationProfileFile = null;
18171 app.instrumentationArguments = null;
18173 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18177 public void finishInstrumentation(IApplicationThread target,
18178 int resultCode, Bundle results) {
18179 int userId = UserHandle.getCallingUserId();
18180 // Refuse possible leaked file descriptors
18181 if (results != null && results.hasFileDescriptors()) {
18182 throw new IllegalArgumentException("File descriptors passed in Intent");
18185 synchronized(this) {
18186 ProcessRecord app = getRecordForAppLocked(target);
18188 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18191 final long origId = Binder.clearCallingIdentity();
18192 finishInstrumentationLocked(app, resultCode, results);
18193 Binder.restoreCallingIdentity(origId);
18197 // =========================================================
18199 // =========================================================
18201 public ConfigurationInfo getDeviceConfigurationInfo() {
18202 ConfigurationInfo config = new ConfigurationInfo();
18203 synchronized (this) {
18204 config.reqTouchScreen = mConfiguration.touchscreen;
18205 config.reqKeyboardType = mConfiguration.keyboard;
18206 config.reqNavigation = mConfiguration.navigation;
18207 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18208 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18209 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18211 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18212 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18213 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18215 config.reqGlEsVersion = GL_ES_VERSION;
18220 ActivityStack getFocusedStack() {
18221 return mStackSupervisor.getFocusedStack();
18225 public int getFocusedStackId() throws RemoteException {
18226 ActivityStack focusedStack = getFocusedStack();
18227 if (focusedStack != null) {
18228 return focusedStack.getStackId();
18233 public Configuration getConfiguration() {
18235 synchronized(this) {
18236 ci = new Configuration(mConfiguration);
18237 ci.userSetLocale = false;
18243 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18244 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18245 synchronized (this) {
18246 mSuppressResizeConfigChanges = suppress;
18251 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18252 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18253 if (fromStackId == HOME_STACK_ID) {
18254 throw new IllegalArgumentException("You can't move tasks from the home stack.");
18256 synchronized (this) {
18257 final long origId = Binder.clearCallingIdentity();
18259 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18261 Binder.restoreCallingIdentity(origId);
18267 public void updatePersistentConfiguration(Configuration values) {
18268 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18269 "updateConfiguration()");
18270 enforceWriteSettingsPermission("updateConfiguration()");
18271 if (values == null) {
18272 throw new NullPointerException("Configuration must not be null");
18275 int userId = UserHandle.getCallingUserId();
18277 synchronized(this) {
18278 final long origId = Binder.clearCallingIdentity();
18279 updateConfigurationLocked(values, null, false, true, userId);
18280 Binder.restoreCallingIdentity(origId);
18284 private void updateFontScaleIfNeeded() {
18285 final int currentUserId;
18286 synchronized(this) {
18287 currentUserId = mUserController.getCurrentUserIdLocked();
18289 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18290 FONT_SCALE, 1.0f, currentUserId);
18291 if (mConfiguration.fontScale != scaleFactor) {
18292 final Configuration configuration = mWindowManager.computeNewConfiguration();
18293 configuration.fontScale = scaleFactor;
18294 updatePersistentConfiguration(configuration);
18298 private void enforceWriteSettingsPermission(String func) {
18299 int uid = Binder.getCallingUid();
18300 if (uid == Process.ROOT_UID) {
18304 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18305 Settings.getPackageNameForUid(mContext, uid), false)) {
18309 String msg = "Permission Denial: " + func + " from pid="
18310 + Binder.getCallingPid()
18312 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18314 throw new SecurityException(msg);
18317 public void updateConfiguration(Configuration values) {
18318 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18319 "updateConfiguration()");
18321 synchronized(this) {
18322 if (values == null && mWindowManager != null) {
18323 // sentinel: fetch the current configuration from the window manager
18324 values = mWindowManager.computeNewConfiguration();
18327 if (mWindowManager != null) {
18328 mProcessList.applyDisplaySize(mWindowManager);
18331 final long origId = Binder.clearCallingIdentity();
18332 if (values != null) {
18333 Settings.System.clearConfiguration(values);
18335 updateConfigurationLocked(values, null, false);
18336 Binder.restoreCallingIdentity(origId);
18340 void updateUserConfigurationLocked() {
18341 Configuration configuration = new Configuration(mConfiguration);
18342 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18343 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18344 updateConfigurationLocked(configuration, null, false);
18347 boolean updateConfigurationLocked(Configuration values,
18348 ActivityRecord starting, boolean initLocale) {
18349 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18350 return updateConfigurationLocked(values, starting, initLocale, false,
18351 UserHandle.USER_NULL);
18354 // To cache the list of supported system locales
18355 private String[] mSupportedSystemLocales = null;
18358 * Do either or both things: (1) change the current configuration, and (2)
18359 * make sure the given activity is running with the (now) current
18360 * configuration. Returns true if the activity has been left running, or
18361 * false if <var>starting</var> is being destroyed to match the new
18364 * @param userId is only used when persistent parameter is set to true to persist configuration
18365 * for that particular user
18367 private boolean updateConfigurationLocked(Configuration values,
18368 ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18371 if (mWindowManager != null) {
18372 mWindowManager.deferSurfaceLayout();
18374 if (values != null) {
18375 Configuration newConfig = new Configuration(mConfiguration);
18376 changes = newConfig.updateFrom(values);
18377 if (changes != 0) {
18378 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18379 "Updating configuration to: " + values);
18381 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18383 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18384 final LocaleList locales = values.getLocales();
18385 int bestLocaleIndex = 0;
18386 if (locales.size() > 1) {
18387 if (mSupportedSystemLocales == null) {
18388 mSupportedSystemLocales =
18389 Resources.getSystem().getAssets().getLocales();
18391 bestLocaleIndex = Math.max(0,
18392 locales.getFirstMatchIndex(mSupportedSystemLocales));
18394 SystemProperties.set("persist.sys.locale",
18395 locales.get(bestLocaleIndex).toLanguageTag());
18396 LocaleList.setDefault(locales, bestLocaleIndex);
18397 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18398 locales.get(bestLocaleIndex)));
18401 mConfigurationSeq++;
18402 if (mConfigurationSeq <= 0) {
18403 mConfigurationSeq = 1;
18405 newConfig.seq = mConfigurationSeq;
18406 mConfiguration = newConfig;
18407 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18408 mUsageStatsService.reportConfigurationChange(newConfig,
18409 mUserController.getCurrentUserIdLocked());
18410 //mUsageStatsService.noteStartConfig(newConfig);
18412 final Configuration configCopy = new Configuration(mConfiguration);
18414 // TODO: If our config changes, should we auto dismiss any currently
18415 // showing dialogs?
18416 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18418 AttributeCache ac = AttributeCache.instance();
18420 ac.updateConfiguration(configCopy);
18423 // Make sure all resources in our process are updated
18424 // right now, so that anyone who is going to retrieve
18425 // resource values after we return will be sure to get
18426 // the new ones. This is especially important during
18427 // boot, where the first config change needs to guarantee
18428 // all resources have that config before following boot
18429 // code is executed.
18430 mSystemThread.applyConfigurationToResources(configCopy);
18432 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18433 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18434 msg.obj = new Configuration(configCopy);
18436 mHandler.sendMessage(msg);
18439 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18440 if (isDensityChange) {
18441 killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18442 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18445 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18446 ProcessRecord app = mLruProcesses.get(i);
18448 if (app.thread != null) {
18449 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18450 + app.processName + " new config " + mConfiguration);
18451 app.thread.scheduleConfigurationChanged(configCopy);
18453 } catch (Exception e) {
18456 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18457 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18458 | Intent.FLAG_RECEIVER_REPLACE_PENDING
18459 | Intent.FLAG_RECEIVER_FOREGROUND);
18460 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18461 null, AppOpsManager.OP_NONE, null, false, false,
18462 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18463 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18464 // Tell the shortcut manager that the system locale changed. It needs to know
18465 // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18466 // we "push" from here, rather than having the service listen to the broadcast.
18467 final ShortcutServiceInternal shortcutService =
18468 LocalServices.getService(ShortcutServiceInternal.class);
18469 if (shortcutService != null) {
18470 shortcutService.onSystemLocaleChangedNoLock();
18473 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18474 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18475 if (!mProcessesReady) {
18476 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18478 broadcastIntentLocked(null, null, intent,
18479 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18480 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18483 // Update the configuration with WM first and check if any of the stacks need to be
18484 // resized due to the configuration change. If so, resize the stacks now and do any
18485 // relaunches if necessary. This way we don't need to relaunch again below in
18486 // ensureActivityConfigurationLocked().
18487 if (mWindowManager != null) {
18488 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18489 if (resizedStacks != null) {
18490 for (int stackId : resizedStacks) {
18491 final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18492 mStackSupervisor.resizeStackLocked(
18493 stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18499 boolean kept = true;
18500 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18501 // mainStack is null during startup.
18502 if (mainStack != null) {
18503 if (changes != 0 && starting == null) {
18504 // If the configuration changed, and the caller is not already
18505 // in the process of starting an activity, then find the top
18506 // activity to check if its configuration needs to change.
18507 starting = mainStack.topRunningActivityLocked();
18510 if (starting != null) {
18511 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18512 // And we need to make sure at this point that all other activities
18513 // are made visible with the correct configuration.
18514 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18515 !PRESERVE_WINDOWS);
18518 if (mWindowManager != null) {
18519 mWindowManager.continueSurfaceLayout();
18525 * Decide based on the configuration whether we should shouw the ANR,
18526 * crash, etc dialogs. The idea is that if there is no affordnace to
18527 * press the on-screen buttons, we shouldn't show the dialog.
18529 * A thought: SystemUI might also want to get told about this, the Power
18530 * dialog / global actions also might want different behaviors.
18532 private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18533 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18534 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18535 && config.navigation == Configuration.NAVIGATION_NONAV);
18536 final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18537 == Configuration.UI_MODE_TYPE_CAR);
18538 return inputMethodExists && uiIsNotCarType && !inVrMode;
18542 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18543 synchronized (this) {
18544 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18545 if (srec != null) {
18546 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18552 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18553 Intent resultData) {
18555 synchronized (this) {
18556 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18558 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18564 public int getLaunchedFromUid(IBinder activityToken) {
18565 ActivityRecord srec;
18566 synchronized (this) {
18567 srec = ActivityRecord.forTokenLocked(activityToken);
18569 if (srec == null) {
18572 return srec.launchedFromUid;
18575 public String getLaunchedFromPackage(IBinder activityToken) {
18576 ActivityRecord srec;
18577 synchronized (this) {
18578 srec = ActivityRecord.forTokenLocked(activityToken);
18580 if (srec == null) {
18583 return srec.launchedFromPackage;
18586 // =========================================================
18587 // LIFETIME MANAGEMENT
18588 // =========================================================
18590 // Returns which broadcast queue the app is the current [or imminent] receiver
18591 // on, or 'null' if the app is not an active broadcast recipient.
18592 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18593 BroadcastRecord r = app.curReceiver;
18598 // It's not the current receiver, but it might be starting up to become one
18599 synchronized (this) {
18600 for (BroadcastQueue queue : mBroadcastQueues) {
18601 r = queue.mPendingBroadcast;
18602 if (r != null && r.curApp == app) {
18603 // found it; report which queue it's in
18612 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18613 int targetUid, ComponentName targetComponent, String targetProcess) {
18614 if (!mTrackingAssociations) {
18617 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18618 = mAssociations.get(targetUid);
18619 if (components == null) {
18620 components = new ArrayMap<>();
18621 mAssociations.put(targetUid, components);
18623 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18624 if (sourceUids == null) {
18625 sourceUids = new SparseArray<>();
18626 components.put(targetComponent, sourceUids);
18628 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18629 if (sourceProcesses == null) {
18630 sourceProcesses = new ArrayMap<>();
18631 sourceUids.put(sourceUid, sourceProcesses);
18633 Association ass = sourceProcesses.get(sourceProcess);
18635 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18637 sourceProcesses.put(sourceProcess, ass);
18641 if (ass.mNesting == 1) {
18642 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18643 ass.mLastState = sourceState;
18648 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18649 ComponentName targetComponent) {
18650 if (!mTrackingAssociations) {
18653 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18654 = mAssociations.get(targetUid);
18655 if (components == null) {
18658 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18659 if (sourceUids == null) {
18662 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18663 if (sourceProcesses == null) {
18666 Association ass = sourceProcesses.get(sourceProcess);
18667 if (ass == null || ass.mNesting <= 0) {
18671 if (ass.mNesting == 0) {
18672 long uptime = SystemClock.uptimeMillis();
18673 ass.mTime += uptime - ass.mStartTime;
18674 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18675 += uptime - ass.mLastStateUptime;
18676 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18680 private void noteUidProcessState(final int uid, final int state) {
18681 mBatteryStatsService.noteUidProcessState(uid, state);
18682 if (mTrackingAssociations) {
18683 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18684 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18685 = mAssociations.valueAt(i1);
18686 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18687 SparseArray<ArrayMap<String, Association>> sourceUids
18688 = targetComponents.valueAt(i2);
18689 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18690 if (sourceProcesses != null) {
18691 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18692 Association ass = sourceProcesses.valueAt(i4);
18693 if (ass.mNesting >= 1) {
18694 // currently associated
18695 long uptime = SystemClock.uptimeMillis();
18696 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18697 += uptime - ass.mLastStateUptime;
18698 ass.mLastState = state;
18699 ass.mLastStateUptime = uptime;
18708 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18709 boolean doingAll, long now) {
18710 if (mAdjSeq == app.adjSeq) {
18711 // This adjustment has already been computed.
18712 return app.curRawAdj;
18715 if (app.thread == null) {
18716 app.adjSeq = mAdjSeq;
18717 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18718 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18719 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18722 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18723 app.adjSource = null;
18724 app.adjTarget = null;
18726 app.cached = false;
18728 final int activitiesSize = app.activities.size();
18730 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18731 // The max adjustment doesn't allow this app to be anything
18732 // below foreground, so it is not worth doing work for it.
18733 app.adjType = "fixed";
18734 app.adjSeq = mAdjSeq;
18735 app.curRawAdj = app.maxAdj;
18736 app.foregroundActivities = false;
18737 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18738 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18739 // System processes can do UI, and when they do we want to have
18740 // them trim their memory after the user leaves the UI. To
18741 // facilitate this, here we need to determine whether or not it
18742 // is currently showing UI.
18743 app.systemNoUi = true;
18744 if (app == TOP_APP) {
18745 app.systemNoUi = false;
18746 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18747 app.adjType = "pers-top-activity";
18748 } else if (activitiesSize > 0) {
18749 for (int j = 0; j < activitiesSize; j++) {
18750 final ActivityRecord r = app.activities.get(j);
18752 app.systemNoUi = false;
18756 if (!app.systemNoUi) {
18757 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18759 return (app.curAdj=app.maxAdj);
18762 app.systemNoUi = false;
18764 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18766 // Determine the importance of the process, starting with most
18767 // important to least, and assign an appropriate OOM adjustment.
18771 boolean foregroundActivities = false;
18772 BroadcastQueue queue;
18773 if (app == TOP_APP) {
18774 // The last app on the list is the foreground app.
18775 adj = ProcessList.FOREGROUND_APP_ADJ;
18776 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18777 app.adjType = "top-activity";
18778 foregroundActivities = true;
18779 procState = PROCESS_STATE_CUR_TOP;
18780 } else if (app.instrumentationClass != null) {
18781 // Don't want to kill running instrumentation.
18782 adj = ProcessList.FOREGROUND_APP_ADJ;
18783 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18784 app.adjType = "instrumentation";
18785 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18786 } else if ((queue = isReceivingBroadcast(app)) != null) {
18787 // An app that is currently receiving a broadcast also
18788 // counts as being in the foreground for OOM killer purposes.
18789 // It's placed in a sched group based on the nature of the
18790 // broadcast as reflected by which queue it's active in.
18791 adj = ProcessList.FOREGROUND_APP_ADJ;
18792 schedGroup = (queue == mFgBroadcastQueue)
18793 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18794 app.adjType = "broadcast";
18795 procState = ActivityManager.PROCESS_STATE_RECEIVER;
18796 } else if (app.executingServices.size() > 0) {
18797 // An app that is currently executing a service callback also
18798 // counts as being in the foreground.
18799 adj = ProcessList.FOREGROUND_APP_ADJ;
18800 schedGroup = app.execServicesFg ?
18801 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18802 app.adjType = "exec-service";
18803 procState = ActivityManager.PROCESS_STATE_SERVICE;
18804 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18806 // As far as we know the process is empty. We may change our mind later.
18807 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18808 // At this point we don't actually know the adjustment. Use the cached adj
18809 // value that the caller wants us to.
18811 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18814 app.adjType = "cch-empty";
18817 // Examine all activities if not already foreground.
18818 if (!foregroundActivities && activitiesSize > 0) {
18819 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18820 for (int j = 0; j < activitiesSize; j++) {
18821 final ActivityRecord r = app.activities.get(j);
18822 if (r.app != app) {
18823 Log.wtf(TAG, "Found activity " + r + " in proc activity list using " + r.app
18824 + " instead of expected " + app);
18825 if (r.app == null || (r.app.uid == app.uid)) {
18826 // Only fix things up when they look sane
18833 // App has a visible activity; only upgrade adjustment.
18834 if (adj > ProcessList.VISIBLE_APP_ADJ) {
18835 adj = ProcessList.VISIBLE_APP_ADJ;
18836 app.adjType = "visible";
18838 if (procState > PROCESS_STATE_CUR_TOP) {
18839 procState = PROCESS_STATE_CUR_TOP;
18841 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18842 app.cached = false;
18844 foregroundActivities = true;
18845 if (r.task != null && minLayer > 0) {
18846 final int layer = r.task.mLayerRank;
18847 if (layer >= 0 && minLayer > layer) {
18852 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18853 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18854 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18855 app.adjType = "pausing";
18857 if (procState > PROCESS_STATE_CUR_TOP) {
18858 procState = PROCESS_STATE_CUR_TOP;
18860 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18861 app.cached = false;
18863 foregroundActivities = true;
18864 } else if (r.state == ActivityState.STOPPING) {
18865 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18866 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18867 app.adjType = "stopping";
18869 // For the process state, we will at this point consider the
18870 // process to be cached. It will be cached either as an activity
18871 // or empty depending on whether the activity is finishing. We do
18872 // this so that we can treat the process as cached for purposes of
18873 // memory trimming (determing current memory level, trim command to
18874 // send to process) since there can be an arbitrary number of stopping
18875 // processes and they should soon all go into the cached state.
18876 if (!r.finishing) {
18877 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18878 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18881 app.cached = false;
18883 foregroundActivities = true;
18885 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18886 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18887 app.adjType = "cch-act";
18891 if (adj == ProcessList.VISIBLE_APP_ADJ) {
18896 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18897 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18898 if (app.foregroundServices) {
18899 // The user is aware of this app, so make it visible.
18900 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18901 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18902 app.cached = false;
18903 app.adjType = "fg-service";
18904 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18905 } else if (app.forcingToForeground != null) {
18906 // The user is aware of this app, so make it visible.
18907 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18908 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18909 app.cached = false;
18910 app.adjType = "force-fg";
18911 app.adjSource = app.forcingToForeground;
18912 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18916 if (app == mHeavyWeightProcess) {
18917 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18918 // We don't want to kill the current heavy-weight process.
18919 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18920 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18921 app.cached = false;
18922 app.adjType = "heavy";
18924 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18925 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18929 if (app == mHomeProcess) {
18930 if (adj > ProcessList.HOME_APP_ADJ) {
18931 // This process is hosting what we currently consider to be the
18932 // home app, so we don't want to let it go into the background.
18933 adj = ProcessList.HOME_APP_ADJ;
18934 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18935 app.cached = false;
18936 app.adjType = "home";
18938 if (procState > ActivityManager.PROCESS_STATE_HOME) {
18939 procState = ActivityManager.PROCESS_STATE_HOME;
18943 if (app == mPreviousProcess && app.activities.size() > 0) {
18944 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18945 // This was the previous process that showed UI to the user.
18946 // We want to try to keep it around more aggressively, to give
18947 // a good experience around switching between two apps.
18948 adj = ProcessList.PREVIOUS_APP_ADJ;
18949 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18950 app.cached = false;
18951 app.adjType = "previous";
18953 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18954 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18958 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18959 + " reason=" + app.adjType);
18961 // By default, we use the computed adjustment. It may be changed if
18962 // there are applications dependent on our services or providers, but
18963 // this gives us a baseline and makes sure we don't get into an
18964 // infinite recursion.
18965 app.adjSeq = mAdjSeq;
18966 app.curRawAdj = adj;
18967 app.hasStartedServices = false;
18969 if (mBackupTarget != null && app == mBackupTarget.app) {
18970 // If possible we want to avoid killing apps while they're being backed up
18971 if (adj > ProcessList.BACKUP_APP_ADJ) {
18972 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18973 adj = ProcessList.BACKUP_APP_ADJ;
18974 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18975 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18977 app.adjType = "backup";
18978 app.cached = false;
18980 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18981 procState = ActivityManager.PROCESS_STATE_BACKUP;
18985 boolean mayBeTop = false;
18987 for (int is = app.services.size()-1;
18988 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18989 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18990 || procState > ActivityManager.PROCESS_STATE_TOP);
18992 ServiceRecord s = app.services.valueAt(is);
18993 if (s.startRequested) {
18994 app.hasStartedServices = true;
18995 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18996 procState = ActivityManager.PROCESS_STATE_SERVICE;
18998 if (app.hasShownUi && app != mHomeProcess) {
18999 // If this process has shown some UI, let it immediately
19000 // go to the LRU list because it may be pretty heavy with
19001 // UI stuff. We'll tag it with a label just to help
19002 // debug and understand what is going on.
19003 if (adj > ProcessList.SERVICE_ADJ) {
19004 app.adjType = "cch-started-ui-services";
19007 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19008 // This service has seen some activity within
19009 // recent memory, so we will keep its process ahead
19010 // of the background processes.
19011 if (adj > ProcessList.SERVICE_ADJ) {
19012 adj = ProcessList.SERVICE_ADJ;
19013 app.adjType = "started-services";
19014 app.cached = false;
19017 // If we have let the service slide into the background
19018 // state, still have some text describing what it is doing
19019 // even though the service no longer has an impact.
19020 if (adj > ProcessList.SERVICE_ADJ) {
19021 app.adjType = "cch-started-services";
19025 for (int conni = s.connections.size()-1;
19026 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19027 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19028 || procState > ActivityManager.PROCESS_STATE_TOP);
19030 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19032 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19033 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19034 || procState > ActivityManager.PROCESS_STATE_TOP);
19036 // XXX should compute this based on the max of
19037 // all connected clients.
19038 ConnectionRecord cr = clist.get(i);
19039 if (cr.binding.client == app) {
19040 // Binding to ourself is not interesting.
19043 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19044 ProcessRecord client = cr.binding.client;
19045 int clientAdj = computeOomAdjLocked(client, cachedAdj,
19046 TOP_APP, doingAll, now);
19047 int clientProcState = client.curProcState;
19048 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19049 // If the other app is cached for any reason, for purposes here
19050 // we are going to consider it empty. The specific cached state
19051 // doesn't propagate except under certain conditions.
19052 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19054 String adjType = null;
19055 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19056 // Not doing bind OOM management, so treat
19057 // this guy more like a started service.
19058 if (app.hasShownUi && app != mHomeProcess) {
19059 // If this process has shown some UI, let it immediately
19060 // go to the LRU list because it may be pretty heavy with
19061 // UI stuff. We'll tag it with a label just to help
19062 // debug and understand what is going on.
19063 if (adj > clientAdj) {
19064 adjType = "cch-bound-ui-services";
19066 app.cached = false;
19068 clientProcState = procState;
19070 if (now >= (s.lastActivity
19071 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19072 // This service has not seen activity within
19073 // recent memory, so allow it to drop to the
19074 // LRU list if there is no other reason to keep
19075 // it around. We'll also tag it with a label just
19076 // to help debug and undertand what is going on.
19077 if (adj > clientAdj) {
19078 adjType = "cch-bound-services";
19084 if (adj > clientAdj) {
19085 // If this process has recently shown UI, and
19086 // the process that is binding to it is less
19087 // important than being visible, then we don't
19088 // care about the binding as much as we care
19089 // about letting this process get into the LRU
19090 // list to be killed and restarted if needed for
19092 if (app.hasShownUi && app != mHomeProcess
19093 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19094 adjType = "cch-bound-ui-services";
19096 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19097 |Context.BIND_IMPORTANT)) != 0) {
19098 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19099 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19100 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19101 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19102 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19103 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19104 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19107 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19108 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19111 if (!client.cached) {
19112 app.cached = false;
19114 adjType = "service";
19117 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19118 // This will treat important bound services identically to
19119 // the top app, which may behave differently than generic
19120 // foreground work.
19121 if (client.curSchedGroup > schedGroup) {
19122 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19123 schedGroup = client.curSchedGroup;
19125 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19128 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19129 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19130 // Special handling of clients who are in the top state.
19131 // We *may* want to consider this process to be in the
19132 // top state as well, but only if there is not another
19133 // reason for it to be running. Being on the top is a
19134 // special state, meaning you are specifically running
19135 // for the current top app. If the process is already
19136 // running in the background for some other reason, it
19137 // is more important to continue considering it to be
19138 // in the background state.
19140 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19142 // Special handling for above-top states (persistent
19143 // processes). These should not bring the current process
19144 // into the top state, since they are not on top. Instead
19145 // give them the best state after that.
19146 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19148 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19149 } else if (mWakefulness
19150 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19151 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19154 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19157 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19162 if (clientProcState <
19163 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19165 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19168 if (procState > clientProcState) {
19169 procState = clientProcState;
19171 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19172 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19173 app.pendingUiClean = true;
19175 if (adjType != null) {
19176 app.adjType = adjType;
19177 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19178 .REASON_SERVICE_IN_USE;
19179 app.adjSource = cr.binding.client;
19180 app.adjSourceProcState = clientProcState;
19181 app.adjTarget = s.name;
19184 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19185 app.treatLikeActivity = true;
19187 final ActivityRecord a = cr.activity;
19188 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19189 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19190 (a.visible || a.state == ActivityState.RESUMED ||
19191 a.state == ActivityState.PAUSING)) {
19192 adj = ProcessList.FOREGROUND_APP_ADJ;
19193 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19194 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19195 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19197 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19200 app.cached = false;
19201 app.adjType = "service";
19202 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19203 .REASON_SERVICE_IN_USE;
19205 app.adjSourceProcState = procState;
19206 app.adjTarget = s.name;
19213 for (int provi = app.pubProviders.size()-1;
19214 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19215 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19216 || procState > ActivityManager.PROCESS_STATE_TOP);
19218 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19219 for (int i = cpr.connections.size()-1;
19220 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19221 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19222 || procState > ActivityManager.PROCESS_STATE_TOP);
19224 ContentProviderConnection conn = cpr.connections.get(i);
19225 ProcessRecord client = conn.client;
19226 if (client == app) {
19227 // Being our own client is not interesting.
19230 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19231 int clientProcState = client.curProcState;
19232 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19233 // If the other app is cached for any reason, for purposes here
19234 // we are going to consider it empty.
19235 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19237 if (adj > clientAdj) {
19238 if (app.hasShownUi && app != mHomeProcess
19239 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19240 app.adjType = "cch-ui-provider";
19242 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19243 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19244 app.adjType = "provider";
19246 app.cached &= client.cached;
19247 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19248 .REASON_PROVIDER_IN_USE;
19249 app.adjSource = client;
19250 app.adjSourceProcState = clientProcState;
19251 app.adjTarget = cpr.name;
19253 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19254 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19255 // Special handling of clients who are in the top state.
19256 // We *may* want to consider this process to be in the
19257 // top state as well, but only if there is not another
19258 // reason for it to be running. Being on the top is a
19259 // special state, meaning you are specifically running
19260 // for the current top app. If the process is already
19261 // running in the background for some other reason, it
19262 // is more important to continue considering it to be
19263 // in the background state.
19265 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19267 // Special handling for above-top states (persistent
19268 // processes). These should not bring the current process
19269 // into the top state, since they are not on top. Instead
19270 // give them the best state after that.
19272 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19275 if (procState > clientProcState) {
19276 procState = clientProcState;
19278 if (client.curSchedGroup > schedGroup) {
19279 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19282 // If the provider has external (non-framework) process
19283 // dependencies, ensure that its adjustment is at least
19284 // FOREGROUND_APP_ADJ.
19285 if (cpr.hasExternalProcessHandles()) {
19286 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19287 adj = ProcessList.FOREGROUND_APP_ADJ;
19288 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19289 app.cached = false;
19290 app.adjType = "provider";
19291 app.adjTarget = cpr.name;
19293 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19294 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19299 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19300 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19301 adj = ProcessList.PREVIOUS_APP_ADJ;
19302 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19303 app.cached = false;
19304 app.adjType = "provider";
19306 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19307 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19311 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19312 // A client of one of our services or providers is in the top state. We
19313 // *may* want to be in the top state, but not if we are already running in
19314 // the background for some other reason. For the decision here, we are going
19315 // to pick out a few specific states that we want to remain in when a client
19316 // is top (states that tend to be longer-term) and otherwise allow it to go
19317 // to the top state.
19318 switch (procState) {
19319 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19320 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19321 case ActivityManager.PROCESS_STATE_SERVICE:
19322 // These all are longer-term states, so pull them up to the top
19323 // of the background states, but not all the way to the top state.
19324 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19327 // Otherwise, top is a better choice, so take it.
19328 procState = ActivityManager.PROCESS_STATE_TOP;
19333 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19334 if (app.hasClientActivities) {
19335 // This is a cached process, but with client activities. Mark it so.
19336 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19337 app.adjType = "cch-client-act";
19338 } else if (app.treatLikeActivity) {
19339 // This is a cached process, but somebody wants us to treat it like it has
19340 // an activity, okay!
19341 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19342 app.adjType = "cch-as-act";
19346 if (adj == ProcessList.SERVICE_ADJ) {
19348 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19349 mNewNumServiceProcs++;
19350 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19351 if (!app.serviceb) {
19352 // This service isn't far enough down on the LRU list to
19353 // normally be a B service, but if we are low on RAM and it
19354 // is large we want to force it down since we would prefer to
19355 // keep launcher over it.
19356 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19357 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19358 app.serviceHighRam = true;
19359 app.serviceb = true;
19360 //Slog.i(TAG, "ADJ " + app + " high ram!");
19362 mNewNumAServiceProcs++;
19363 //Slog.i(TAG, "ADJ " + app + " not high ram!");
19366 app.serviceHighRam = false;
19369 if (app.serviceb) {
19370 adj = ProcessList.SERVICE_B_ADJ;
19374 app.curRawAdj = adj;
19376 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19377 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19378 if (adj > app.maxAdj) {
19380 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19381 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19385 // Do final modification to adj. Everything we do between here and applying
19386 // the final setAdj must be done in this function, because we will also use
19387 // it when computing the final cached adj later. Note that we don't need to
19388 // worry about this for max adj above, since max adj will always be used to
19389 // keep it out of the cached vaues.
19390 app.curAdj = app.modifyRawOomAdj(adj);
19391 app.curSchedGroup = schedGroup;
19392 app.curProcState = procState;
19393 app.foregroundActivities = foregroundActivities;
19395 return app.curRawAdj;
19399 * Record new PSS sample for a process.
19401 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19403 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19405 proc.lastPssTime = now;
19406 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19407 if (DEBUG_PSS) Slog.d(TAG_PSS,
19408 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19409 + " state=" + ProcessList.makeProcStateString(procState));
19410 if (proc.initialIdlePss == 0) {
19411 proc.initialIdlePss = pss;
19413 proc.lastPss = pss;
19414 proc.lastSwapPss = swapPss;
19415 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19416 proc.lastCachedPss = pss;
19417 proc.lastCachedSwapPss = swapPss;
19420 final SparseArray<Pair<Long, String>> watchUids
19421 = mMemWatchProcesses.getMap().get(proc.processName);
19423 if (watchUids != null) {
19424 Pair<Long, String> val = watchUids.get(proc.uid);
19426 val = watchUids.get(0);
19432 if (check != null) {
19433 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19434 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19435 if (!isDebuggable) {
19436 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19437 isDebuggable = true;
19440 if (isDebuggable) {
19441 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19442 final ProcessRecord myProc = proc;
19443 final File heapdumpFile = DumpHeapProvider.getJavaFile();
19444 mMemWatchDumpProcName = proc.processName;
19445 mMemWatchDumpFile = heapdumpFile.toString();
19446 mMemWatchDumpPid = proc.pid;
19447 mMemWatchDumpUid = proc.uid;
19448 BackgroundThread.getHandler().post(new Runnable() {
19450 public void run() {
19451 revokeUriPermission(ActivityThread.currentActivityThread()
19452 .getApplicationThread(),
19453 DumpHeapActivity.JAVA_URI,
19454 Intent.FLAG_GRANT_READ_URI_PERMISSION
19455 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19456 UserHandle.myUserId());
19457 ParcelFileDescriptor fd = null;
19459 heapdumpFile.delete();
19460 fd = ParcelFileDescriptor.open(heapdumpFile,
19461 ParcelFileDescriptor.MODE_CREATE |
19462 ParcelFileDescriptor.MODE_TRUNCATE |
19463 ParcelFileDescriptor.MODE_WRITE_ONLY |
19464 ParcelFileDescriptor.MODE_APPEND);
19465 IApplicationThread thread = myProc.thread;
19466 if (thread != null) {
19468 if (DEBUG_PSS) Slog.d(TAG_PSS,
19469 "Requesting dump heap from "
19470 + myProc + " to " + heapdumpFile);
19471 thread.dumpHeap(true, heapdumpFile.toString(), fd);
19472 } catch (RemoteException e) {
19475 } catch (FileNotFoundException e) {
19476 e.printStackTrace();
19481 } catch (IOException e) {
19488 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19489 + ", but debugging not enabled");
19496 * Schedule PSS collection of a process.
19498 void requestPssLocked(ProcessRecord proc, int procState) {
19499 if (mPendingPssProcesses.contains(proc)) {
19502 if (mPendingPssProcesses.size() == 0) {
19503 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19505 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19506 proc.pssProcState = procState;
19507 mPendingPssProcesses.add(proc);
19511 * Schedule PSS collection of all processes.
19513 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19515 if (now < (mLastFullPssTime +
19516 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19520 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
19521 mLastFullPssTime = now;
19522 mFullPssPending = true;
19523 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19524 mPendingPssProcesses.clear();
19525 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19526 ProcessRecord app = mLruProcesses.get(i);
19527 if (app.thread == null
19528 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19531 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19532 app.pssProcState = app.setProcState;
19533 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19534 mTestPssMode, isSleeping(), now);
19535 mPendingPssProcesses.add(app);
19538 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19541 public void setTestPssMode(boolean enabled) {
19542 synchronized (this) {
19543 mTestPssMode = enabled;
19545 // Whenever we enable the mode, we want to take a snapshot all of current
19546 // process mem use.
19547 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19553 * Ask a given process to GC right now.
19555 final void performAppGcLocked(ProcessRecord app) {
19557 app.lastRequestedGc = SystemClock.uptimeMillis();
19558 if (app.thread != null) {
19559 if (app.reportLowMemory) {
19560 app.reportLowMemory = false;
19561 app.thread.scheduleLowMemory();
19563 app.thread.processInBackground();
19566 } catch (Exception e) {
19572 * Returns true if things are idle enough to perform GCs.
19574 private final boolean canGcNowLocked() {
19575 boolean processingBroadcasts = false;
19576 for (BroadcastQueue q : mBroadcastQueues) {
19577 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19578 processingBroadcasts = true;
19581 return !processingBroadcasts
19582 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19586 * Perform GCs on all processes that are waiting for it, but only
19587 * if things are idle.
19589 final void performAppGcsLocked() {
19590 final int N = mProcessesToGc.size();
19594 if (canGcNowLocked()) {
19595 while (mProcessesToGc.size() > 0) {
19596 ProcessRecord proc = mProcessesToGc.remove(0);
19597 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19598 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19599 <= SystemClock.uptimeMillis()) {
19600 // To avoid spamming the system, we will GC processes one
19601 // at a time, waiting a few seconds between each.
19602 performAppGcLocked(proc);
19603 scheduleAppGcsLocked();
19606 // It hasn't been long enough since we last GCed this
19607 // process... put it in the list to wait for its time.
19608 addProcessToGcListLocked(proc);
19614 scheduleAppGcsLocked();
19619 * If all looks good, perform GCs on all processes waiting for them.
19621 final void performAppGcsIfAppropriateLocked() {
19622 if (canGcNowLocked()) {
19623 performAppGcsLocked();
19626 // Still not idle, wait some more.
19627 scheduleAppGcsLocked();
19631 * Schedule the execution of all pending app GCs.
19633 final void scheduleAppGcsLocked() {
19634 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19636 if (mProcessesToGc.size() > 0) {
19637 // Schedule a GC for the time to the next process.
19638 ProcessRecord proc = mProcessesToGc.get(0);
19639 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19641 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19642 long now = SystemClock.uptimeMillis();
19643 if (when < (now+GC_TIMEOUT)) {
19644 when = now + GC_TIMEOUT;
19646 mHandler.sendMessageAtTime(msg, when);
19651 * Add a process to the array of processes waiting to be GCed. Keeps the
19652 * list in sorted order by the last GC time. The process can't already be
19655 final void addProcessToGcListLocked(ProcessRecord proc) {
19656 boolean added = false;
19657 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19658 if (mProcessesToGc.get(i).lastRequestedGc <
19659 proc.lastRequestedGc) {
19661 mProcessesToGc.add(i+1, proc);
19666 mProcessesToGc.add(0, proc);
19671 * Set up to ask a process to GC itself. This will either do it
19672 * immediately, or put it on the list of processes to gc the next
19673 * time things are idle.
19675 final void scheduleAppGcLocked(ProcessRecord app) {
19676 long now = SystemClock.uptimeMillis();
19677 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19680 if (!mProcessesToGc.contains(app)) {
19681 addProcessToGcListLocked(app);
19682 scheduleAppGcsLocked();
19686 final void checkExcessivePowerUsageLocked(boolean doKills) {
19687 updateCpuStatsNow();
19689 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19690 boolean doWakeKills = doKills;
19691 boolean doCpuKills = doKills;
19692 if (mLastPowerCheckRealtime == 0) {
19693 doWakeKills = false;
19695 if (mLastPowerCheckUptime == 0) {
19696 doCpuKills = false;
19698 if (stats.isScreenOn()) {
19699 doWakeKills = false;
19701 final long curRealtime = SystemClock.elapsedRealtime();
19702 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19703 final long curUptime = SystemClock.uptimeMillis();
19704 final long uptimeSince = curUptime - mLastPowerCheckUptime;
19705 mLastPowerCheckRealtime = curRealtime;
19706 mLastPowerCheckUptime = curUptime;
19707 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19708 doWakeKills = false;
19710 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19711 doCpuKills = false;
19713 int i = mLruProcesses.size();
19716 ProcessRecord app = mLruProcesses.get(i);
19717 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19719 synchronized (stats) {
19720 wtime = stats.getProcessWakeTime(app.info.uid,
19721 app.pid, curRealtime);
19723 long wtimeUsed = wtime - app.lastWakeTime;
19724 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19726 StringBuilder sb = new StringBuilder(128);
19727 sb.append("Wake for ");
19728 app.toShortString(sb);
19729 sb.append(": over ");
19730 TimeUtils.formatDuration(realtimeSince, sb);
19731 sb.append(" used ");
19732 TimeUtils.formatDuration(wtimeUsed, sb);
19734 sb.append((wtimeUsed*100)/realtimeSince);
19736 Slog.i(TAG_POWER, sb.toString());
19738 sb.append("CPU for ");
19739 app.toShortString(sb);
19740 sb.append(": over ");
19741 TimeUtils.formatDuration(uptimeSince, sb);
19742 sb.append(" used ");
19743 TimeUtils.formatDuration(cputimeUsed, sb);
19745 sb.append((cputimeUsed*100)/uptimeSince);
19747 Slog.i(TAG_POWER, sb.toString());
19749 // If a process has held a wake lock for more
19750 // than 50% of the time during this period,
19751 // that sounds bad. Kill!
19752 if (doWakeKills && realtimeSince > 0
19753 && ((wtimeUsed*100)/realtimeSince) >= 50) {
19754 synchronized (stats) {
19755 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19756 realtimeSince, wtimeUsed);
19758 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19759 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19760 } else if (doCpuKills && uptimeSince > 0
19761 && ((cputimeUsed*100)/uptimeSince) >= 25) {
19762 synchronized (stats) {
19763 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19764 uptimeSince, cputimeUsed);
19766 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19767 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19769 app.lastWakeTime = wtime;
19770 app.lastCpuTime = app.curCpuTime;
19776 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19778 boolean success = true;
19780 if (app.curRawAdj != app.setRawAdj) {
19781 app.setRawAdj = app.curRawAdj;
19786 if (app.curAdj != app.setAdj) {
19787 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19788 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19789 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19791 app.setAdj = app.curAdj;
19794 if (app.setSchedGroup != app.curSchedGroup) {
19795 app.setSchedGroup = app.curSchedGroup;
19796 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19797 "Setting sched group of " + app.processName
19798 + " to " + app.curSchedGroup);
19799 if (app.waitingToKill != null && app.curReceiver == null
19800 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19801 app.kill(app.waitingToKill, true);
19805 switch (app.curSchedGroup) {
19806 case ProcessList.SCHED_GROUP_BACKGROUND:
19807 processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19809 case ProcessList.SCHED_GROUP_TOP_APP:
19810 processGroup = Process.THREAD_GROUP_TOP_APP;
19813 processGroup = Process.THREAD_GROUP_DEFAULT;
19817 long oldId = Binder.clearCallingIdentity();
19819 Process.setProcessGroup(app.pid, processGroup);
19820 } catch (Exception e) {
19821 Slog.w(TAG, "Failed setting process group of " + app.pid
19822 + " to " + app.curSchedGroup);
19823 e.printStackTrace();
19825 Binder.restoreCallingIdentity(oldId);
19828 if (app.thread != null) {
19830 app.thread.setSchedulingGroup(processGroup);
19831 } catch (RemoteException e) {
19837 if (app.repForegroundActivities != app.foregroundActivities) {
19838 app.repForegroundActivities = app.foregroundActivities;
19839 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19841 if (app.repProcState != app.curProcState) {
19842 app.repProcState = app.curProcState;
19843 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19844 if (app.thread != null) {
19847 //RuntimeException h = new RuntimeException("here");
19848 Slog.i(TAG, "Sending new process state " + app.repProcState
19849 + " to " + app /*, h*/);
19851 app.thread.setProcessState(app.repProcState);
19852 } catch (RemoteException e) {
19856 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19857 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19858 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19859 // Experimental code to more aggressively collect pss while
19860 // running test... the problem is that this tends to collect
19861 // the data right when a process is transitioning between process
19862 // states, which well tend to give noisy data.
19863 long start = SystemClock.uptimeMillis();
19864 long pss = Debug.getPss(app.pid, mTmpLong, null);
19865 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19866 mPendingPssProcesses.remove(app);
19867 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19868 + " to " + app.curProcState + ": "
19869 + (SystemClock.uptimeMillis()-start) + "ms");
19871 app.lastStateTime = now;
19872 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19873 mTestPssMode, isSleeping(), now);
19874 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19875 + ProcessList.makeProcStateString(app.setProcState) + " to "
19876 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19877 + (app.nextPssTime-now) + ": " + app);
19879 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19880 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19882 requestPssLocked(app, app.setProcState);
19883 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19884 mTestPssMode, isSleeping(), now);
19885 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19886 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19888 if (app.setProcState != app.curProcState) {
19889 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19890 "Proc state change of " + app.processName
19891 + " to " + app.curProcState);
19892 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19893 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19894 if (setImportant && !curImportant) {
19895 // This app is no longer something we consider important enough to allow to
19896 // use arbitrary amounts of battery power. Note
19897 // its current wake lock time to later know to kill it if
19898 // it is not behaving well.
19899 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19900 synchronized (stats) {
19901 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19902 app.pid, nowElapsed);
19904 app.lastCpuTime = app.curCpuTime;
19907 // Inform UsageStats of important process state change
19908 // Must be called before updating setProcState
19909 maybeUpdateUsageStatsLocked(app, nowElapsed);
19911 app.setProcState = app.curProcState;
19912 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19913 app.notCachedSinceIdle = false;
19916 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19918 app.procStateChanged = true;
19920 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19921 > USAGE_STATS_INTERACTION_INTERVAL) {
19922 // For apps that sit around for a long time in the interactive state, we need
19923 // to report this at least once a day so they don't go idle.
19924 maybeUpdateUsageStatsLocked(app, nowElapsed);
19927 if (changes != 0) {
19928 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19929 "Changes in " + app + ": " + changes);
19930 int i = mPendingProcessChanges.size()-1;
19931 ProcessChangeItem item = null;
19933 item = mPendingProcessChanges.get(i);
19934 if (item.pid == app.pid) {
19935 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19936 "Re-using existing item: " + item);
19942 // No existing item in pending changes; need a new one.
19943 final int NA = mAvailProcessChanges.size();
19945 item = mAvailProcessChanges.remove(NA-1);
19946 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19947 "Retrieving available item: " + item);
19949 item = new ProcessChangeItem();
19950 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19951 "Allocating new item: " + item);
19954 item.pid = app.pid;
19955 item.uid = app.info.uid;
19956 if (mPendingProcessChanges.size() == 0) {
19957 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19958 "*** Enqueueing dispatch processes changed!");
19959 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19961 mPendingProcessChanges.add(item);
19963 item.changes |= changes;
19964 item.processState = app.repProcState;
19965 item.foregroundActivities = app.repForegroundActivities;
19966 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19967 "Item " + Integer.toHexString(System.identityHashCode(item))
19968 + " " + app.toShortString() + ": changes=" + item.changes
19969 + " procState=" + item.processState
19970 + " foreground=" + item.foregroundActivities
19971 + " type=" + app.adjType + " source=" + app.adjSource
19972 + " target=" + app.adjTarget);
19978 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19979 final UidRecord.ChangeItem pendingChange;
19980 if (uidRec == null || uidRec.pendingChange == null) {
19981 if (mPendingUidChanges.size() == 0) {
19982 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19983 "*** Enqueueing dispatch uid changed!");
19984 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19986 final int NA = mAvailUidChanges.size();
19988 pendingChange = mAvailUidChanges.remove(NA-1);
19989 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19990 "Retrieving available item: " + pendingChange);
19992 pendingChange = new UidRecord.ChangeItem();
19993 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19994 "Allocating new item: " + pendingChange);
19996 if (uidRec != null) {
19997 uidRec.pendingChange = pendingChange;
19998 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19999 // If this uid is going away, and we haven't yet reported it is gone,
20001 change = UidRecord.CHANGE_GONE_IDLE;
20003 } else if (uid < 0) {
20004 throw new IllegalArgumentException("No UidRecord or uid");
20006 pendingChange.uidRecord = uidRec;
20007 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20008 mPendingUidChanges.add(pendingChange);
20010 pendingChange = uidRec.pendingChange;
20011 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20012 change = UidRecord.CHANGE_GONE_IDLE;
20015 pendingChange.change = change;
20016 pendingChange.processState = uidRec != null
20017 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20020 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20021 String authority) {
20022 if (app == null) return;
20023 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20024 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20025 if (userState == null) return;
20026 final long now = SystemClock.elapsedRealtime();
20027 Long lastReported = userState.mProviderLastReportedFg.get(authority);
20028 if (lastReported == null || lastReported < now - 60 * 1000L) {
20029 mUsageStatsService.reportContentProviderUsage(
20030 authority, providerPkgName, app.userId);
20031 userState.mProviderLastReportedFg.put(authority, now);
20036 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20037 if (DEBUG_USAGE_STATS) {
20038 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20039 + "] state changes: old = " + app.setProcState + ", new = "
20040 + app.curProcState);
20042 if (mUsageStatsService == null) {
20045 boolean isInteraction;
20046 // To avoid some abuse patterns, we are going to be careful about what we consider
20047 // to be an app interaction. Being the top activity doesn't count while the display
20048 // is sleeping, nor do short foreground services.
20049 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20050 isInteraction = true;
20051 app.fgInteractionTime = 0;
20052 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20053 if (app.fgInteractionTime == 0) {
20054 app.fgInteractionTime = nowElapsed;
20055 isInteraction = false;
20057 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20060 isInteraction = app.curProcState
20061 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20062 app.fgInteractionTime = 0;
20064 if (isInteraction && (!app.reportedInteraction
20065 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20066 app.interactionEventTime = nowElapsed;
20067 String[] packages = app.getPackageList();
20068 if (packages != null) {
20069 for (int i = 0; i < packages.length; i++) {
20070 mUsageStatsService.reportEvent(packages[i], app.userId,
20071 UsageEvents.Event.SYSTEM_INTERACTION);
20075 app.reportedInteraction = isInteraction;
20076 if (!isInteraction) {
20077 app.interactionEventTime = 0;
20081 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20082 if (proc.thread != null) {
20083 if (proc.baseProcessTracker != null) {
20084 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20089 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20090 ProcessRecord TOP_APP, boolean doingAll, long now) {
20091 if (app.thread == null) {
20095 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20097 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20100 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20102 if (isForeground != proc.foregroundServices) {
20103 proc.foregroundServices = isForeground;
20104 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20106 if (isForeground) {
20107 if (curProcs == null) {
20108 curProcs = new ArrayList<ProcessRecord>();
20109 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20111 if (!curProcs.contains(proc)) {
20112 curProcs.add(proc);
20113 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20114 proc.info.packageName, proc.info.uid);
20117 if (curProcs != null) {
20118 if (curProcs.remove(proc)) {
20119 mBatteryStatsService.noteEvent(
20120 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20121 proc.info.packageName, proc.info.uid);
20122 if (curProcs.size() <= 0) {
20123 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20129 updateOomAdjLocked();
20134 private final ActivityRecord resumedAppLocked() {
20135 ActivityRecord act = mStackSupervisor.resumedAppLocked();
20139 pkg = act.packageName;
20140 uid = act.info.applicationInfo.uid;
20145 // Has the UID or resumed package name changed?
20146 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20147 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20148 if (mCurResumedPackage != null) {
20149 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20150 mCurResumedPackage, mCurResumedUid);
20152 mCurResumedPackage = pkg;
20153 mCurResumedUid = uid;
20154 if (mCurResumedPackage != null) {
20155 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20156 mCurResumedPackage, mCurResumedUid);
20162 final boolean updateOomAdjLocked(ProcessRecord app) {
20163 final ActivityRecord TOP_ACT = resumedAppLocked();
20164 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20165 final boolean wasCached = app.cached;
20169 // This is the desired cached adjusment we want to tell it to use.
20170 // If our app is currently cached, we know it, and that is it. Otherwise,
20171 // we don't know it yet, and it needs to now be cached we will then
20172 // need to do a complete oom adj.
20173 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20174 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20175 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20176 SystemClock.uptimeMillis());
20177 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20178 // Changed to/from cached state, so apps after it in the LRU
20179 // list may also be changed.
20180 updateOomAdjLocked();
20185 final void updateOomAdjLocked() {
20186 final ActivityRecord TOP_ACT = resumedAppLocked();
20187 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20188 final long now = SystemClock.uptimeMillis();
20189 final long nowElapsed = SystemClock.elapsedRealtime();
20190 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20191 final int N = mLruProcesses.size();
20194 RuntimeException e = new RuntimeException();
20195 e.fillInStackTrace();
20196 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20199 // Reset state in all uid records.
20200 for (int i=mActiveUids.size()-1; i>=0; i--) {
20201 final UidRecord uidRec = mActiveUids.valueAt(i);
20202 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20203 "Starting update of " + uidRec);
20207 mStackSupervisor.rankTaskLayersIfNeeded();
20210 mNewNumServiceProcs = 0;
20211 mNewNumAServiceProcs = 0;
20213 final int emptyProcessLimit;
20214 final int cachedProcessLimit;
20215 if (mProcessLimit <= 0) {
20216 emptyProcessLimit = cachedProcessLimit = 0;
20217 } else if (mProcessLimit == 1) {
20218 emptyProcessLimit = 1;
20219 cachedProcessLimit = 0;
20221 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20222 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20225 // Let's determine how many processes we have running vs.
20226 // how many slots we have for background processes; we may want
20227 // to put multiple processes in a slot of there are enough of
20229 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20230 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20231 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20232 if (numEmptyProcs > cachedProcessLimit) {
20233 // If there are more empty processes than our limit on cached
20234 // processes, then use the cached process limit for the factor.
20235 // This ensures that the really old empty processes get pushed
20236 // down to the bottom, so if we are running low on memory we will
20237 // have a better chance at keeping around more cached processes
20238 // instead of a gazillion empty processes.
20239 numEmptyProcs = cachedProcessLimit;
20241 int emptyFactor = numEmptyProcs/numSlots;
20242 if (emptyFactor < 1) emptyFactor = 1;
20243 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20244 if (cachedFactor < 1) cachedFactor = 1;
20245 int stepCached = 0;
20249 int numTrimming = 0;
20251 mNumNonCachedProcs = 0;
20252 mNumCachedHiddenProcs = 0;
20254 // First update the OOM adjustment for each of the
20255 // application processes based on their current state.
20256 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20257 int nextCachedAdj = curCachedAdj+1;
20258 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20259 int nextEmptyAdj = curEmptyAdj+2;
20260 for (int i=N-1; i>=0; i--) {
20261 ProcessRecord app = mLruProcesses.get(i);
20262 if (!app.killedByAm && app.thread != null) {
20263 app.procStateChanged = false;
20264 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20266 // If we haven't yet assigned the final cached adj
20267 // to the process, do that now.
20268 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20269 switch (app.curProcState) {
20270 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20271 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20272 // This process is a cached process holding activities...
20273 // assign it the next cached value for that type, and then
20274 // step that cached level.
20275 app.curRawAdj = curCachedAdj;
20276 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20277 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20278 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20280 if (curCachedAdj != nextCachedAdj) {
20282 if (stepCached >= cachedFactor) {
20284 curCachedAdj = nextCachedAdj;
20285 nextCachedAdj += 2;
20286 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20287 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20293 // For everything else, assign next empty cached process
20294 // level and bump that up. Note that this means that
20295 // long-running services that have dropped down to the
20296 // cached level will be treated as empty (since their process
20297 // state is still as a service), which is what we want.
20298 app.curRawAdj = curEmptyAdj;
20299 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20300 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20301 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20303 if (curEmptyAdj != nextEmptyAdj) {
20305 if (stepEmpty >= emptyFactor) {
20307 curEmptyAdj = nextEmptyAdj;
20309 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20310 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20318 applyOomAdjLocked(app, true, now, nowElapsed);
20320 // Count the number of process types.
20321 switch (app.curProcState) {
20322 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20323 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20324 mNumCachedHiddenProcs++;
20326 if (numCached > cachedProcessLimit) {
20327 app.kill("cached #" + numCached, true);
20330 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20331 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20332 && app.lastActivityTime < oldTime) {
20333 app.kill("empty for "
20334 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20335 / 1000) + "s", true);
20338 if (numEmpty > emptyProcessLimit) {
20339 app.kill("empty #" + numEmpty, true);
20344 mNumNonCachedProcs++;
20348 if (app.isolated && app.services.size() <= 0) {
20349 // If this is an isolated process, and there are no
20350 // services running in it, then the process is no longer
20351 // needed. We agressively kill these because we can by
20352 // definition not re-use the same process again, and it is
20353 // good to avoid having whatever code was running in them
20354 // left sitting around after no longer needed.
20355 app.kill("isolated not needed", true);
20357 // Keeping this process, update its uid.
20358 final UidRecord uidRec = app.uidRecord;
20359 if (uidRec != null && uidRec.curProcState > app.curProcState) {
20360 uidRec.curProcState = app.curProcState;
20364 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20365 && !app.killedByAm) {
20371 mNumServiceProcs = mNewNumServiceProcs;
20373 // Now determine the memory trimming level of background processes.
20374 // Unfortunately we need to start at the back of the list to do this
20375 // properly. We only do this if the number of background apps we
20376 // are managing to keep around is less than half the maximum we desire;
20377 // if we are keeping a good number around, we'll let them use whatever
20378 // memory they want.
20379 final int numCachedAndEmpty = numCached + numEmpty;
20381 if (numCached <= ProcessList.TRIM_CACHED_APPS
20382 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20383 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20384 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20385 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20386 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20388 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20391 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20393 // We always allow the memory level to go up (better). We only allow it to go
20394 // down if we are in a state where that is allowed, *and* the total number of processes
20395 // has gone down since last time.
20396 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20397 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20398 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20399 if (memFactor > mLastMemoryLevel) {
20400 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20401 memFactor = mLastMemoryLevel;
20402 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20405 if (memFactor != mLastMemoryLevel) {
20406 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20408 mLastMemoryLevel = memFactor;
20409 mLastNumProcesses = mLruProcesses.size();
20410 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20411 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20412 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20413 if (mLowRamStartTime == 0) {
20414 mLowRamStartTime = now;
20418 switch (memFactor) {
20419 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20420 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20422 case ProcessStats.ADJ_MEM_FACTOR_LOW:
20423 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20426 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20429 int factor = numTrimming/3;
20431 if (mHomeProcess != null) minFactor++;
20432 if (mPreviousProcess != null) minFactor++;
20433 if (factor < minFactor) factor = minFactor;
20434 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20435 for (int i=N-1; i>=0; i--) {
20436 ProcessRecord app = mLruProcesses.get(i);
20437 if (allChanged || app.procStateChanged) {
20438 setProcessTrackerStateLocked(app, trackerMemFactor, now);
20439 app.procStateChanged = false;
20441 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20442 && !app.killedByAm) {
20443 if (app.trimMemoryLevel < curLevel && app.thread != null) {
20445 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20446 "Trimming memory of " + app.processName + " to " + curLevel);
20447 app.thread.scheduleTrimMemory(curLevel);
20448 } catch (RemoteException e) {
20451 // For now we won't do this; our memory trimming seems
20452 // to be good enough at this point that destroying
20453 // activities causes more harm than good.
20454 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20455 && app != mHomeProcess && app != mPreviousProcess) {
20456 // Need to do this on its own message because the stack may not
20457 // be in a consistent state at this point.
20458 // For these apps we will also finish their activities
20459 // to help them free memory.
20460 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20464 app.trimMemoryLevel = curLevel;
20466 if (step >= factor) {
20468 switch (curLevel) {
20469 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20470 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20472 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20473 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20477 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20478 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20479 && app.thread != null) {
20481 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20482 "Trimming memory of heavy-weight " + app.processName
20483 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20484 app.thread.scheduleTrimMemory(
20485 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20486 } catch (RemoteException e) {
20489 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20491 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20492 || app.systemNoUi) && app.pendingUiClean) {
20493 // If this application is now in the background and it
20494 // had done UI, then give it the special trim level to
20495 // have it free UI resources.
20496 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20497 if (app.trimMemoryLevel < level && app.thread != null) {
20499 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20500 "Trimming memory of bg-ui " + app.processName
20502 app.thread.scheduleTrimMemory(level);
20503 } catch (RemoteException e) {
20506 app.pendingUiClean = false;
20508 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20510 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20511 "Trimming memory of fg " + app.processName
20512 + " to " + fgTrimLevel);
20513 app.thread.scheduleTrimMemory(fgTrimLevel);
20514 } catch (RemoteException e) {
20517 app.trimMemoryLevel = fgTrimLevel;
20521 if (mLowRamStartTime != 0) {
20522 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20523 mLowRamStartTime = 0;
20525 for (int i=N-1; i>=0; i--) {
20526 ProcessRecord app = mLruProcesses.get(i);
20527 if (allChanged || app.procStateChanged) {
20528 setProcessTrackerStateLocked(app, trackerMemFactor, now);
20529 app.procStateChanged = false;
20531 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20532 || app.systemNoUi) && app.pendingUiClean) {
20533 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20534 && app.thread != null) {
20536 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20537 "Trimming memory of ui hidden " + app.processName
20538 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20539 app.thread.scheduleTrimMemory(
20540 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20541 } catch (RemoteException e) {
20544 app.pendingUiClean = false;
20546 app.trimMemoryLevel = 0;
20550 if (mAlwaysFinishActivities) {
20551 // Need to do this on its own message because the stack may not
20552 // be in a consistent state at this point.
20553 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20557 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20560 // Update from any uid changes.
20561 for (int i=mActiveUids.size()-1; i>=0; i--) {
20562 final UidRecord uidRec = mActiveUids.valueAt(i);
20563 int uidChange = UidRecord.CHANGE_PROCSTATE;
20564 if (uidRec.setProcState != uidRec.curProcState) {
20565 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20566 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20567 + " to " + uidRec.curProcState);
20568 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20569 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20570 uidRec.lastBackgroundTime = nowElapsed;
20571 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20572 // Note: the background settle time is in elapsed realtime, while
20573 // the handler time base is uptime. All this means is that we may
20574 // stop background uids later than we had intended, but that only
20575 // happens because the device was sleeping so we are okay anyway.
20576 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20581 uidChange = UidRecord.CHANGE_ACTIVE;
20582 uidRec.idle = false;
20584 uidRec.lastBackgroundTime = 0;
20586 uidRec.setProcState = uidRec.curProcState;
20587 enqueueUidChangeLocked(uidRec, -1, uidChange);
20588 noteUidProcessState(uidRec.uid, uidRec.curProcState);
20592 if (mProcessStats.shouldWriteNowLocked(now)) {
20593 mHandler.post(new Runnable() {
20594 @Override public void run() {
20595 synchronized (ActivityManagerService.this) {
20596 mProcessStats.writeStateAsyncLocked();
20602 if (DEBUG_OOM_ADJ) {
20603 final long duration = SystemClock.uptimeMillis() - now;
20605 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20606 new RuntimeException("here").fillInStackTrace());
20608 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20613 final void idleUids() {
20614 synchronized (this) {
20615 final long nowElapsed = SystemClock.elapsedRealtime();
20616 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20618 for (int i=mActiveUids.size()-1; i>=0; i--) {
20619 final UidRecord uidRec = mActiveUids.valueAt(i);
20620 final long bgTime = uidRec.lastBackgroundTime;
20621 if (bgTime > 0 && !uidRec.idle) {
20622 if (bgTime <= maxBgTime) {
20623 uidRec.idle = true;
20624 doStopUidLocked(uidRec.uid, uidRec);
20626 if (nextTime == 0 || nextTime > bgTime) {
20632 if (nextTime > 0) {
20633 mHandler.removeMessages(IDLE_UIDS_MSG);
20634 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20635 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20640 final void runInBackgroundDisabled(int uid) {
20641 synchronized (this) {
20642 UidRecord uidRec = mActiveUids.get(uid);
20643 if (uidRec != null) {
20644 // This uid is actually running... should it be considered background now?
20646 doStopUidLocked(uidRec.uid, uidRec);
20649 // This uid isn't actually running... still send a report about it being "stopped".
20650 doStopUidLocked(uid, null);
20655 final void doStopUidLocked(int uid, final UidRecord uidRec) {
20656 mServices.stopInBackgroundLocked(uid);
20657 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20660 final void trimApplications() {
20661 synchronized (this) {
20664 // First remove any unused application processes whose package
20665 // has been removed.
20666 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20667 final ProcessRecord app = mRemovedProcesses.get(i);
20668 if (app.activities.size() == 0
20669 && app.curReceiver == null && app.services.size() == 0) {
20671 TAG, "Exiting empty application process "
20672 + app.toShortString() + " ("
20673 + (app.thread != null ? app.thread.asBinder() : null)
20675 if (app.pid > 0 && app.pid != MY_PID) {
20676 app.kill("empty", false);
20679 app.thread.scheduleExit();
20680 } catch (Exception e) {
20681 // Ignore exceptions.
20684 cleanUpApplicationRecordLocked(app, false, true, -1);
20685 mRemovedProcesses.remove(i);
20687 if (app.persistent) {
20688 addAppLocked(app.info, false, null /* ABI override */);
20693 // Now update the oom adj for all processes.
20694 updateOomAdjLocked();
20698 /** This method sends the specified signal to each of the persistent apps */
20699 public void signalPersistentProcesses(int sig) throws RemoteException {
20700 if (sig != Process.SIGNAL_USR1) {
20701 throw new SecurityException("Only SIGNAL_USR1 is allowed");
20704 synchronized (this) {
20705 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20706 != PackageManager.PERMISSION_GRANTED) {
20707 throw new SecurityException("Requires permission "
20708 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20711 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20712 ProcessRecord r = mLruProcesses.get(i);
20713 if (r.thread != null && r.persistent) {
20714 Process.sendSignal(r.pid, sig);
20720 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20721 if (proc == null || proc == mProfileProc) {
20722 proc = mProfileProc;
20723 profileType = mProfileType;
20724 clearProfilerLocked();
20726 if (proc == null) {
20730 proc.thread.profilerControl(false, null, profileType);
20731 } catch (RemoteException e) {
20732 throw new IllegalStateException("Process disappeared");
20736 private void clearProfilerLocked() {
20737 if (mProfileFd != null) {
20739 mProfileFd.close();
20740 } catch (IOException e) {
20743 mProfileApp = null;
20744 mProfileProc = null;
20745 mProfileFile = null;
20747 mAutoStopProfiler = false;
20748 mSamplingInterval = 0;
20751 public boolean profileControl(String process, int userId, boolean start,
20752 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20755 synchronized (this) {
20756 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20757 // its own permission.
20758 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20759 != PackageManager.PERMISSION_GRANTED) {
20760 throw new SecurityException("Requires permission "
20761 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20764 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20765 throw new IllegalArgumentException("null profile info or fd");
20768 ProcessRecord proc = null;
20769 if (process != null) {
20770 proc = findProcessLocked(process, userId, "profileControl");
20773 if (start && (proc == null || proc.thread == null)) {
20774 throw new IllegalArgumentException("Unknown process: " + process);
20778 stopProfilerLocked(null, 0);
20779 setProfileApp(proc.info, proc.processName, profilerInfo);
20780 mProfileProc = proc;
20781 mProfileType = profileType;
20782 ParcelFileDescriptor fd = profilerInfo.profileFd;
20785 } catch (IOException e) {
20788 profilerInfo.profileFd = fd;
20789 proc.thread.profilerControl(start, profilerInfo, profileType);
20793 stopProfilerLocked(proc, profileType);
20794 if (profilerInfo != null && profilerInfo.profileFd != null) {
20796 profilerInfo.profileFd.close();
20797 } catch (IOException e) {
20804 } catch (RemoteException e) {
20805 throw new IllegalStateException("Process disappeared");
20807 if (profilerInfo != null && profilerInfo.profileFd != null) {
20809 profilerInfo.profileFd.close();
20810 } catch (IOException e) {
20816 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20817 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20818 userId, true, ALLOW_FULL_ONLY, callName, null);
20819 ProcessRecord proc = null;
20821 int pid = Integer.parseInt(process);
20822 synchronized (mPidsSelfLocked) {
20823 proc = mPidsSelfLocked.get(pid);
20825 } catch (NumberFormatException e) {
20828 if (proc == null) {
20829 ArrayMap<String, SparseArray<ProcessRecord>> all
20830 = mProcessNames.getMap();
20831 SparseArray<ProcessRecord> procs = all.get(process);
20832 if (procs != null && procs.size() > 0) {
20833 proc = procs.valueAt(0);
20834 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20835 for (int i=1; i<procs.size(); i++) {
20836 ProcessRecord thisProc = procs.valueAt(i);
20837 if (thisProc.userId == userId) {
20849 public boolean dumpHeap(String process, int userId, boolean managed,
20850 String path, ParcelFileDescriptor fd) throws RemoteException {
20853 synchronized (this) {
20854 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20855 // its own permission (same as profileControl).
20856 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20857 != PackageManager.PERMISSION_GRANTED) {
20858 throw new SecurityException("Requires permission "
20859 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20863 throw new IllegalArgumentException("null fd");
20866 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20867 if (proc == null || proc.thread == null) {
20868 throw new IllegalArgumentException("Unknown process: " + process);
20871 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20872 if (!isDebuggable) {
20873 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20874 throw new SecurityException("Process not debuggable: " + proc);
20878 proc.thread.dumpHeap(managed, path, fd);
20882 } catch (RemoteException e) {
20883 throw new IllegalStateException("Process disappeared");
20888 } catch (IOException e) {
20895 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20896 String reportPackage) {
20897 if (processName != null) {
20898 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20899 "setDumpHeapDebugLimit()");
20901 synchronized (mPidsSelfLocked) {
20902 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20903 if (proc == null) {
20904 throw new SecurityException("No process found for calling pid "
20905 + Binder.getCallingPid());
20907 if (!Build.IS_DEBUGGABLE
20908 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20909 throw new SecurityException("Not running a debuggable build");
20911 processName = proc.processName;
20913 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20914 throw new SecurityException("Package " + reportPackage + " is not running in "
20919 synchronized (this) {
20920 if (maxMemSize > 0) {
20921 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20924 mMemWatchProcesses.remove(processName, uid);
20926 mMemWatchProcesses.getMap().remove(processName);
20933 public void dumpHeapFinished(String path) {
20934 synchronized (this) {
20935 if (Binder.getCallingPid() != mMemWatchDumpPid) {
20936 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20937 + " does not match last pid " + mMemWatchDumpPid);
20940 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20941 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20942 + " does not match last path " + mMemWatchDumpFile);
20945 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20946 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20950 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20951 public void monitor() {
20952 synchronized (this) { }
20955 void onCoreSettingsChange(Bundle settings) {
20956 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20957 ProcessRecord processRecord = mLruProcesses.get(i);
20959 if (processRecord.thread != null) {
20960 processRecord.thread.setCoreSettings(settings);
20962 } catch (RemoteException re) {
20968 // Multi-user methods
20971 * Start user, if its not already running, but don't bring it to foreground.
20974 public boolean startUserInBackground(final int userId) {
20975 return mUserController.startUser(userId, /* foreground */ false);
20979 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
20980 return mUserController.unlockUser(userId, token, secret, listener);
20984 public boolean switchUser(final int targetUserId) {
20985 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20986 UserInfo currentUserInfo;
20987 UserInfo targetUserInfo;
20988 synchronized (this) {
20989 int currentUserId = mUserController.getCurrentUserIdLocked();
20990 currentUserInfo = mUserController.getUserInfo(currentUserId);
20991 targetUserInfo = mUserController.getUserInfo(targetUserId);
20992 if (targetUserInfo == null) {
20993 Slog.w(TAG, "No user info for user #" + targetUserId);
20996 if (!targetUserInfo.supportsSwitchTo()) {
20997 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21000 if (targetUserInfo.isManagedProfile()) {
21001 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21004 mUserController.setTargetUserIdLocked(targetUserId);
21006 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21007 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21008 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21012 void scheduleStartProfilesLocked() {
21013 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21014 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21015 DateUtils.SECOND_IN_MILLIS);
21020 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21021 return mUserController.stopUser(userId, force, callback);
21025 public UserInfo getCurrentUser() {
21026 return mUserController.getCurrentUser();
21030 public boolean isUserRunning(int userId, int flags) {
21031 if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21032 INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21033 String msg = "Permission Denial: isUserRunning() from pid="
21034 + Binder.getCallingPid()
21035 + ", uid=" + Binder.getCallingUid()
21036 + " requires " + INTERACT_ACROSS_USERS;
21038 throw new SecurityException(msg);
21040 synchronized (this) {
21041 return mUserController.isUserRunningLocked(userId, flags);
21046 public int[] getRunningUserIds() {
21047 if (checkCallingPermission(INTERACT_ACROSS_USERS)
21048 != PackageManager.PERMISSION_GRANTED) {
21049 String msg = "Permission Denial: isUserRunning() from pid="
21050 + Binder.getCallingPid()
21051 + ", uid=" + Binder.getCallingUid()
21052 + " requires " + INTERACT_ACROSS_USERS;
21054 throw new SecurityException(msg);
21056 synchronized (this) {
21057 return mUserController.getStartedUserArrayLocked();
21062 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21063 mUserController.registerUserSwitchObserver(observer);
21067 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21068 mUserController.unregisterUserSwitchObserver(observer);
21071 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21072 if (info == null) return null;
21073 ApplicationInfo newInfo = new ApplicationInfo(info);
21074 newInfo.initForUser(userId);
21078 public boolean isUserStopped(int userId) {
21079 synchronized (this) {
21080 return mUserController.getStartedUserStateLocked(userId) == null;
21084 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21086 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21090 ActivityInfo info = new ActivityInfo(aInfo);
21091 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21095 private boolean processSanityChecksLocked(ProcessRecord process) {
21096 if (process == null || process.thread == null) {
21100 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21101 if (!isDebuggable) {
21102 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21110 public boolean startBinderTracking() throws RemoteException {
21111 synchronized (this) {
21112 mBinderTransactionTrackingEnabled = true;
21113 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21114 // permission (same as profileControl).
21115 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21116 != PackageManager.PERMISSION_GRANTED) {
21117 throw new SecurityException("Requires permission "
21118 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21121 for (int i = 0; i < mLruProcesses.size(); i++) {
21122 ProcessRecord process = mLruProcesses.get(i);
21123 if (!processSanityChecksLocked(process)) {
21127 process.thread.startBinderTracking();
21128 } catch (RemoteException e) {
21129 Log.v(TAG, "Process disappared");
21136 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21138 synchronized (this) {
21139 mBinderTransactionTrackingEnabled = false;
21140 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21141 // permission (same as profileControl).
21142 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21143 != PackageManager.PERMISSION_GRANTED) {
21144 throw new SecurityException("Requires permission "
21145 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21149 throw new IllegalArgumentException("null fd");
21152 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21153 pw.println("Binder transaction traces for all processes.\n");
21154 for (ProcessRecord process : mLruProcesses) {
21155 if (!processSanityChecksLocked(process)) {
21159 pw.println("Traces for process: " + process.processName);
21162 TransferPipe tp = new TransferPipe();
21164 process.thread.stopBinderTrackingAndDump(
21165 tp.getWriteFd().getFileDescriptor());
21166 tp.go(fd.getFileDescriptor());
21170 } catch (IOException e) {
21171 pw.println("Failure while dumping IPC traces from " + process +
21172 ". Exception: " + e);
21174 } catch (RemoteException e) {
21175 pw.println("Got a RemoteException while dumping IPC traces from " +
21176 process + ". Exception: " + e);
21187 } catch (IOException e) {
21193 private final class LocalService extends ActivityManagerInternal {
21195 public void onWakefulnessChanged(int wakefulness) {
21196 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21200 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21201 String processName, String abiOverride, int uid, Runnable crashHandler) {
21202 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21203 processName, abiOverride, uid, crashHandler);
21207 public SleepToken acquireSleepToken(String tag) {
21208 Preconditions.checkNotNull(tag);
21210 synchronized (ActivityManagerService.this) {
21211 SleepTokenImpl token = new SleepTokenImpl(tag);
21212 mSleepTokens.add(token);
21213 updateSleepIfNeededLocked();
21214 applyVrModeIfNeededLocked(mFocusedActivity, false);
21220 public ComponentName getHomeActivityForUser(int userId) {
21221 synchronized (ActivityManagerService.this) {
21222 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21223 return homeActivity == null ? null : homeActivity.realActivity;
21228 public void onUserRemoved(int userId) {
21229 synchronized (ActivityManagerService.this) {
21230 ActivityManagerService.this.onUserStoppedLocked(userId);
21235 public void onLocalVoiceInteractionStarted(IBinder activity,
21236 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21237 synchronized (ActivityManagerService.this) {
21238 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21239 voiceSession, voiceInteractor);
21244 public void notifyStartingWindowDrawn() {
21245 synchronized (ActivityManagerService.this) {
21246 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21251 public void notifyAppTransitionStarting(int reason) {
21252 synchronized (ActivityManagerService.this) {
21253 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21258 public void notifyAppTransitionFinished() {
21259 synchronized (ActivityManagerService.this) {
21260 mStackSupervisor.notifyAppTransitionDone();
21265 public void notifyAppTransitionCancelled() {
21266 synchronized (ActivityManagerService.this) {
21267 mStackSupervisor.notifyAppTransitionDone();
21272 public List<IBinder> getTopVisibleActivities() {
21273 synchronized (ActivityManagerService.this) {
21274 return mStackSupervisor.getTopVisibleActivities();
21279 public void notifyDockedStackMinimizedChanged(boolean minimized) {
21280 synchronized (ActivityManagerService.this) {
21281 mStackSupervisor.setDockedStackMinimized(minimized);
21286 public void killForegroundAppsForUser(int userHandle) {
21287 synchronized (ActivityManagerService.this) {
21288 final ArrayList<ProcessRecord> procs = new ArrayList<>();
21289 final int NP = mProcessNames.getMap().size();
21290 for (int ip = 0; ip < NP; ip++) {
21291 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21292 final int NA = apps.size();
21293 for (int ia = 0; ia < NA; ia++) {
21294 final ProcessRecord app = apps.valueAt(ia);
21295 if (app.persistent) {
21296 // We don't kill persistent processes.
21301 } else if (app.userId == userHandle && app.foregroundActivities) {
21302 app.removed = true;
21308 final int N = procs.size();
21309 for (int i = 0; i < N; i++) {
21310 removeProcessLocked(procs.get(i), false, true, "kill all fg");
21316 private final class SleepTokenImpl extends SleepToken {
21317 private final String mTag;
21318 private final long mAcquireTime;
21320 public SleepTokenImpl(String tag) {
21322 mAcquireTime = SystemClock.uptimeMillis();
21326 public void release() {
21327 synchronized (ActivityManagerService.this) {
21328 if (mSleepTokens.remove(this)) {
21329 updateSleepIfNeededLocked();
21335 public String toString() {
21336 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21341 * An implementation of IAppTask, that allows an app to manage its own tasks via
21342 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
21343 * only the process that calls getAppTasks() can call the AppTask methods.
21345 class AppTaskImpl extends IAppTask.Stub {
21346 private int mTaskId;
21347 private int mCallingUid;
21349 public AppTaskImpl(int taskId, int callingUid) {
21351 mCallingUid = callingUid;
21354 private void checkCaller() {
21355 if (mCallingUid != Binder.getCallingUid()) {
21356 throw new SecurityException("Caller " + mCallingUid
21357 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21362 public void finishAndRemoveTask() {
21365 synchronized (ActivityManagerService.this) {
21366 long origId = Binder.clearCallingIdentity();
21368 // We remove the task from recents to preserve backwards
21369 if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21370 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21373 Binder.restoreCallingIdentity(origId);
21379 public ActivityManager.RecentTaskInfo getTaskInfo() {
21382 synchronized (ActivityManagerService.this) {
21383 long origId = Binder.clearCallingIdentity();
21385 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21387 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21389 return createRecentTaskInfoFromTaskRecord(tr);
21391 Binder.restoreCallingIdentity(origId);
21397 public void moveToFront() {
21399 // Will bring task to front if it already has a root activity.
21400 final long origId = Binder.clearCallingIdentity();
21402 synchronized (this) {
21403 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21406 Binder.restoreCallingIdentity(origId);
21411 public int startActivity(IBinder whoThread, String callingPackage,
21412 Intent intent, String resolvedType, Bundle bOptions) {
21415 int callingUser = UserHandle.getCallingUserId();
21417 IApplicationThread appThread;
21418 synchronized (ActivityManagerService.this) {
21419 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21421 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21423 appThread = ApplicationThreadNative.asInterface(whoThread);
21424 if (appThread == null) {
21425 throw new IllegalArgumentException("Bad app thread " + appThread);
21428 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21429 resolvedType, null, null, null, null, 0, 0, null, null,
21430 null, bOptions, false, callingUser, null, tr);
21434 public void setExcludeFromRecents(boolean exclude) {
21437 synchronized (ActivityManagerService.this) {
21438 long origId = Binder.clearCallingIdentity();
21440 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21442 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21444 Intent intent = tr.getBaseIntent();
21446 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21448 intent.setFlags(intent.getFlags()
21449 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21452 Binder.restoreCallingIdentity(origId);
21459 * Kill processes for the user with id userId and that depend on the package named packageName
21462 public void killPackageDependents(String packageName, int userId) {
21463 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21464 if (packageName == null) {
21465 throw new NullPointerException(
21466 "Cannot kill the dependents of a package without its name.");
21469 long callingId = Binder.clearCallingIdentity();
21470 IPackageManager pm = AppGlobals.getPackageManager();
21473 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21474 } catch (RemoteException e) {
21476 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21477 throw new IllegalArgumentException(
21478 "Cannot kill dependents of non-existing package " + packageName);
21481 synchronized(this) {
21482 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21483 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21484 "dep: " + packageName);
21487 Binder.restoreCallingIdentity(callingId);