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 static android.Manifest.permission.INTERACT_ACROSS_USERS;
20 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24 import static com.android.internal.util.XmlUtils.readIntAttribute;
25 import static com.android.internal.util.XmlUtils.readLongAttribute;
26 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27 import static com.android.internal.util.XmlUtils.writeIntAttribute;
28 import static com.android.internal.util.XmlUtils.writeLongAttribute;
29 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30 import static com.android.server.am.ActivityManagerDebugConfig.*;
31 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
32 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
33 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
34 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
35 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
36 import static org.xmlpull.v1.XmlPullParser.START_TAG;
38 import com.google.android.collect.Lists;
39 import com.google.android.collect.Maps;
41 import android.Manifest;
42 import android.app.AppOpsManager;
43 import android.app.ApplicationThreadNative;
44 import android.app.BroadcastOptions;
45 import android.app.IActivityContainer;
46 import android.app.IActivityContainerCallback;
47 import android.app.IAppTask;
48 import android.app.ITaskStackListener;
49 import android.app.ProfilerInfo;
50 import android.app.assist.AssistContent;
51 import android.app.assist.AssistStructure;
52 import android.app.usage.UsageEvents;
53 import android.app.usage.UsageStatsManagerInternal;
54 import android.appwidget.AppWidgetManager;
55 import android.content.pm.PackageManagerInternal;
56 import android.content.pm.PermissionInfo;
57 import android.content.res.Resources;
58 import android.graphics.Bitmap;
59 import android.graphics.Point;
60 import android.graphics.Rect;
61 import android.os.BatteryStats;
62 import android.os.PersistableBundle;
63 import android.os.PowerManager;
64 import android.os.Trace;
65 import android.os.TransactionTooLargeException;
66 import android.os.WorkSource;
67 import android.os.storage.IMountService;
68 import android.os.storage.MountServiceInternal;
69 import android.os.storage.StorageManager;
70 import android.service.voice.IVoiceInteractionSession;
71 import android.service.voice.VoiceInteractionSession;
72 import android.util.ArrayMap;
73 import android.util.ArraySet;
74 import android.util.DebugUtils;
75 import android.util.SparseIntArray;
76 import android.view.Display;
78 import com.android.internal.R;
79 import com.android.internal.annotations.GuardedBy;
80 import com.android.internal.app.AssistUtils;
81 import com.android.internal.app.DumpHeapActivity;
82 import com.android.internal.app.IAppOpsCallback;
83 import com.android.internal.app.IAppOpsService;
84 import com.android.internal.app.IVoiceInteractor;
85 import com.android.internal.app.ProcessMap;
86 import com.android.internal.app.ProcessStats;
87 import com.android.internal.app.SystemUserHomeActivity;
88 import com.android.internal.os.BackgroundThread;
89 import com.android.internal.os.BatteryStatsImpl;
90 import com.android.internal.os.IResultReceiver;
91 import com.android.internal.os.ProcessCpuTracker;
92 import com.android.internal.os.TransferPipe;
93 import com.android.internal.os.Zygote;
94 import com.android.internal.util.ArrayUtils;
95 import com.android.internal.util.FastPrintWriter;
96 import com.android.internal.util.FastXmlSerializer;
97 import com.android.internal.util.MemInfoReader;
98 import com.android.internal.util.Preconditions;
99 import com.android.server.AppOpsService;
100 import com.android.server.AttributeCache;
101 import com.android.server.DeviceIdleController;
102 import com.android.server.IntentResolver;
103 import com.android.server.LocalServices;
104 import com.android.server.ServiceThread;
105 import com.android.server.SystemService;
106 import com.android.server.SystemServiceManager;
107 import com.android.server.Watchdog;
108 import com.android.server.am.ActivityStack.ActivityState;
109 import com.android.server.firewall.IntentFirewall;
110 import com.android.server.pm.Installer;
111 import com.android.server.statusbar.StatusBarManagerInternal;
112 import com.android.server.wm.AppTransition;
113 import com.android.server.wm.WindowManagerService;
115 import org.xmlpull.v1.XmlPullParser;
116 import org.xmlpull.v1.XmlPullParserException;
117 import org.xmlpull.v1.XmlSerializer;
119 import android.Manifest;
120 import android.app.Activity;
121 import android.app.ActivityManager;
122 import android.app.ActivityManager.RunningTaskInfo;
123 import android.app.ActivityManager.StackId;
124 import android.app.ActivityManager.StackInfo;
125 import android.app.ActivityManager.TaskThumbnailInfo;
126 import android.app.ActivityManagerInternal;
127 import android.app.ActivityManagerInternal.SleepToken;
128 import android.app.ActivityManagerNative;
129 import android.app.ActivityOptions;
130 import android.app.ActivityThread;
131 import android.app.AlertDialog;
132 import android.app.AppGlobals;
133 import android.app.AppOpsManager;
134 import android.app.ApplicationErrorReport;
135 import android.app.ApplicationThreadNative;
136 import android.app.BroadcastOptions;
137 import android.app.Dialog;
138 import android.app.IActivityContainer;
139 import android.app.IActivityContainerCallback;
140 import android.app.IActivityController;
141 import android.app.IAppTask;
142 import android.app.IApplicationThread;
143 import android.app.IInstrumentationWatcher;
144 import android.app.INotificationManager;
145 import android.app.IProcessObserver;
146 import android.app.IServiceConnection;
147 import android.app.IStopUserCallback;
148 import android.app.ITaskStackListener;
149 import android.app.IUiAutomationConnection;
150 import android.app.IUidObserver;
151 import android.app.IUserSwitchObserver;
152 import android.app.Instrumentation;
153 import android.app.Notification;
154 import android.app.NotificationManager;
155 import android.app.PendingIntent;
156 import android.app.ProfilerInfo;
157 import android.app.admin.DevicePolicyManager;
158 import android.app.assist.AssistContent;
159 import android.app.assist.AssistStructure;
160 import android.app.backup.IBackupManager;
161 import android.app.usage.UsageEvents;
162 import android.app.usage.UsageStatsManagerInternal;
163 import android.appwidget.AppWidgetManager;
164 import android.content.ActivityNotFoundException;
165 import android.content.BroadcastReceiver;
166 import android.content.ClipData;
167 import android.content.ComponentCallbacks2;
168 import android.content.ComponentName;
169 import android.content.ContentProvider;
170 import android.content.ContentResolver;
171 import android.content.Context;
172 import android.content.DialogInterface;
173 import android.content.IContentProvider;
174 import android.content.IIntentReceiver;
175 import android.content.IIntentSender;
176 import android.content.Intent;
177 import android.content.IntentFilter;
178 import android.content.IntentSender;
179 import android.content.pm.ActivityInfo;
180 import android.content.pm.ApplicationInfo;
181 import android.content.pm.ConfigurationInfo;
182 import android.content.pm.IPackageDataObserver;
183 import android.content.pm.IPackageManager;
184 import android.content.pm.InstrumentationInfo;
185 import android.content.pm.PackageInfo;
186 import android.content.pm.PackageManager;
187 import android.content.pm.PackageManager.NameNotFoundException;
188 import android.content.pm.ParceledListSlice;
189 import android.content.pm.PathPermission;
190 import android.content.pm.PermissionInfo;
191 import android.content.pm.ProviderInfo;
192 import android.content.pm.ResolveInfo;
193 import android.content.pm.ServiceInfo;
194 import android.content.pm.UserInfo;
195 import android.content.res.CompatibilityInfo;
196 import android.content.res.Configuration;
197 import android.content.res.Resources;
198 import android.graphics.Bitmap;
199 import android.graphics.Point;
200 import android.graphics.Rect;
201 import android.net.Proxy;
202 import android.net.ProxyInfo;
203 import android.net.Uri;
204 import android.os.BatteryStats;
205 import android.os.Binder;
206 import android.os.Build;
207 import android.os.Bundle;
208 import android.os.Debug;
209 import android.os.DropBoxManager;
210 import android.os.Environment;
211 import android.os.FactoryTest;
212 import android.os.FileObserver;
213 import android.os.FileUtils;
214 import android.os.Handler;
215 import android.os.IBinder;
216 import android.os.IPermissionController;
217 import android.os.IProcessInfoService;
218 import android.os.Looper;
219 import android.os.Message;
220 import android.os.Parcel;
221 import android.os.ParcelFileDescriptor;
222 import android.os.PersistableBundle;
223 import android.os.PowerManager;
224 import android.os.PowerManagerInternal;
225 import android.os.Process;
226 import android.os.RemoteCallbackList;
227 import android.os.RemoteException;
228 import android.os.ResultReceiver;
229 import android.os.ServiceManager;
230 import android.os.StrictMode;
231 import android.os.SystemClock;
232 import android.os.SystemProperties;
233 import android.os.Trace;
234 import android.os.TransactionTooLargeException;
235 import android.os.UpdateLock;
236 import android.os.UserHandle;
237 import android.os.UserManager;
238 import android.os.WorkSource;
239 import android.os.storage.IMountService;
240 import android.os.storage.MountServiceInternal;
241 import android.os.storage.StorageManager;
242 import android.provider.Settings;
243 import android.service.voice.IVoiceInteractionSession;
244 import android.service.voice.VoiceInteractionSession;
245 import android.text.format.DateUtils;
246 import android.text.format.Time;
247 import android.util.ArrayMap;
248 import android.util.ArraySet;
249 import android.util.AtomicFile;
250 import android.util.DebugUtils;
251 import android.util.EventLog;
252 import android.util.LocaleList;
253 import android.util.Log;
254 import android.util.Pair;
255 import android.util.PrintWriterPrinter;
256 import android.util.Slog;
257 import android.util.SparseArray;
258 import android.util.TimeUtils;
259 import android.util.Xml;
260 import android.view.Display;
261 import android.view.Gravity;
262 import android.view.LayoutInflater;
263 import android.view.View;
264 import android.view.WindowManager;
266 import java.io.BufferedInputStream;
267 import java.io.BufferedOutputStream;
268 import java.io.DataInputStream;
269 import java.io.DataOutputStream;
271 import java.io.FileDescriptor;
272 import java.io.FileInputStream;
273 import java.io.FileNotFoundException;
274 import java.io.FileOutputStream;
275 import java.io.IOException;
276 import java.io.InputStreamReader;
277 import java.io.PrintWriter;
278 import java.io.StringWriter;
279 import java.lang.ref.WeakReference;
280 import java.nio.charset.StandardCharsets;
281 import java.util.ArrayList;
282 import java.util.Arrays;
283 import java.util.Collections;
284 import java.util.Comparator;
285 import java.util.HashMap;
286 import java.util.HashSet;
287 import java.util.Iterator;
288 import java.util.List;
289 import java.util.Locale;
290 import java.util.Map;
291 import java.util.Set;
292 import java.util.concurrent.atomic.AtomicBoolean;
293 import java.util.concurrent.atomic.AtomicLong;
295 import dalvik.system.VMRuntime;
296 import libcore.io.IoUtils;
297 import libcore.util.EmptyArray;
299 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
300 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
301 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
302 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
303 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
304 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
305 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
306 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
307 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
308 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
309 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
310 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
311 import static android.provider.Settings.Global.DEBUG_APP;
312 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
313 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
314 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
315 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
316 import static com.android.internal.util.XmlUtils.readIntAttribute;
317 import static com.android.internal.util.XmlUtils.readLongAttribute;
318 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
319 import static com.android.internal.util.XmlUtils.writeIntAttribute;
320 import static com.android.internal.util.XmlUtils.writeLongAttribute;
321 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
328 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
329 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
330 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
331 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
332 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
333 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
334 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
335 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
336 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
337 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
338 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
339 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
340 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
341 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
342 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
343 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
344 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
345 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
346 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
347 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
348 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
349 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
350 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
351 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
352 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
353 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
354 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
355 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
356 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
357 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
358 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
359 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
360 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
361 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
362 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
363 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
364 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
365 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
366 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
367 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
368 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
369 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
370 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
371 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
372 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
373 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
374 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
375 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
376 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
377 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
378 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
379 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
380 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
381 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
382 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
383 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
384 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
385 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
386 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
387 import static org.xmlpull.v1.XmlPullParser.START_TAG;
389 public final class ActivityManagerService extends ActivityManagerNative
390 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
392 // File that stores last updated system version and called preboot receivers
393 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
395 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
396 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
397 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
398 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
399 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
400 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
401 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
402 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
403 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
404 private static final String TAG_LRU = TAG + POSTFIX_LRU;
405 private static final String TAG_MU = TAG + POSTFIX_MU;
406 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
407 private static final String TAG_POWER = TAG + POSTFIX_POWER;
408 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
409 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
410 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
411 private static final String TAG_PSS = TAG + POSTFIX_PSS;
412 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
413 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
414 private static final String TAG_STACK = TAG + POSTFIX_STACK;
415 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
416 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
417 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
418 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
419 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
421 /** Control over CPU and battery monitoring */
422 // write battery stats every 30 minutes.
423 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
424 static final boolean MONITOR_CPU_USAGE = true;
425 // don't sample cpu less than every 5 seconds.
426 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
427 // wait possibly forever for next cpu sample.
428 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
429 static final boolean MONITOR_THREAD_CPU_USAGE = false;
431 // The flags that are set for all calls we make to the package manager.
432 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
434 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
436 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
438 // Amount of time after a call to stopAppSwitches() during which we will
439 // prevent further untrusted switches from happening.
440 static final long APP_SWITCH_DELAY_TIME = 5*1000;
442 // How long we wait for a launched process to attach to the activity manager
443 // before we decide it's never going to come up for real.
444 static final int PROC_START_TIMEOUT = 10*1000;
445 // How long we wait for an attached process to publish its content providers
446 // before we decide it must be hung.
447 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
449 // How long we will retain processes hosting content providers in the "last activity"
450 // state before allowing them to drop down to the regular cached LRU list. This is
451 // to avoid thrashing of provider processes under low memory situations.
452 static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
454 // How long we wait for a launched process to attach to the activity manager
455 // before we decide it's never going to come up for real, when the process was
456 // started with a wrapper for instrumentation (such as Valgrind) because it
457 // could take much longer than usual.
458 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
460 // How long to wait after going idle before forcing apps to GC.
461 static final int GC_TIMEOUT = 5*1000;
463 // The minimum amount of time between successive GC requests for a process.
464 static final int GC_MIN_INTERVAL = 60*1000;
466 // The minimum amount of time between successive PSS requests for a process.
467 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
469 // The minimum amount of time between successive PSS requests for a process
470 // when the request is due to the memory state being lowered.
471 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
473 // The rate at which we check for apps using excessive power -- 15 mins.
474 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
476 // The minimum sample duration we will allow before deciding we have
477 // enough data on wake locks to start killing things.
478 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
480 // The minimum sample duration we will allow before deciding we have
481 // enough data on CPU usage to start killing things.
482 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
484 // How long we allow a receiver to run before giving up on it.
485 static final int BROADCAST_FG_TIMEOUT = 10*1000;
486 static final int BROADCAST_BG_TIMEOUT = 60*1000;
488 // How long we wait until we timeout on key dispatching.
489 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
491 // How long we wait until we timeout on key dispatching during instrumentation.
492 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
494 // This is the amount of time an app needs to be running a foreground service before
495 // we will consider it to be doing interaction for usage stats.
496 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
498 // Maximum amount of time we will allow to elapse before re-reporting usage stats
499 // interaction with foreground processes.
500 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
502 // Maximum number of users we allow to be running at a time.
503 static final int MAX_RUNNING_USERS = 3;
505 // This is the amount of time we allow an app to settle after it goes into the background,
506 // before we start restricting what it can do.
507 static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
509 // How long to wait in getAssistContextExtras for the activity and foreground services
510 // to respond with the result.
511 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
513 // How long top wait when going through the modern assist (which doesn't need to block
514 // on getting this result before starting to launch its UI).
515 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
517 // Maximum number of persisted Uri grants a package is allowed
518 static final int MAX_PERSISTED_URI_GRANTS = 128;
520 static final int MY_PID = Process.myPid();
522 static final String[] EMPTY_STRING_ARRAY = new String[0];
524 // How many bytes to write into the dropbox log before truncating
525 static final int DROPBOX_MAX_SIZE = 256 * 1024;
527 // Access modes for handleIncomingUser.
528 static final int ALLOW_NON_FULL = 0;
529 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
530 static final int ALLOW_FULL_ONLY = 2;
532 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
534 // Delay in notifying task stack change listeners (in millis)
535 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
537 // Necessary ApplicationInfo flags to mark an app as persistent
538 private static final int PERSISTENT_MASK =
539 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
542 // Delay to disable app launch boost
543 static final int APP_BOOST_MESSAGE_DELAY = 3000;
544 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
545 static final int APP_BOOST_TIMEOUT = 2500;
547 // Used to indicate that a task is removed it should also be removed from recents.
548 private static final boolean REMOVE_FROM_RECENTS = true;
550 private static native int nativeMigrateToBoost();
551 private static native int nativeMigrateFromBoost();
552 private boolean mIsBoosted = false;
553 private long mBoostStartTime = 0;
555 /** All system services */
556 SystemServiceManager mSystemServiceManager;
558 private Installer mInstaller;
560 /** Run all ActivityStacks through this */
561 ActivityStackSupervisor mStackSupervisor;
563 /** Task stack change listeners. */
564 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
565 new RemoteCallbackList<ITaskStackListener>();
567 public IntentFirewall mIntentFirewall;
569 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
570 // default actuion automatically. Important for devices without direct input
572 private boolean mShowDialogs = true;
574 BroadcastQueue mFgBroadcastQueue;
575 BroadcastQueue mBgBroadcastQueue;
576 // Convenient for easy iteration over the queues. Foreground is first
577 // so that dispatch of foreground broadcasts gets precedence.
578 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
580 BroadcastQueue broadcastQueueForIntent(Intent intent) {
581 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
582 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
583 "Broadcast intent " + intent + " on "
584 + (isFg ? "foreground" : "background") + " queue");
585 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
589 * Activity we have told the window manager to have key focus.
591 ActivityRecord mFocusedActivity = null;
594 * User id of the last activity mFocusedActivity was set to.
596 private int mLastFocusedUserId;
599 * If non-null, we are tracking the time the user spends in the currently focused app.
601 private AppTimeTracker mCurAppTimeTracker;
604 * List of intents that were used to start the most recent tasks.
606 private final RecentTasks mRecentTasks;
609 * For addAppTask: cached of the last activity component that was added.
611 ComponentName mLastAddedTaskComponent;
614 * For addAppTask: cached of the last activity uid that was added.
616 int mLastAddedTaskUid;
619 * For addAppTask: cached of the last ActivityInfo that was added.
621 ActivityInfo mLastAddedTaskActivity;
624 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
626 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
629 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
631 String mDeviceOwnerName;
633 final UserController mUserController;
635 public class PendingAssistExtras extends Binder implements Runnable {
636 public final ActivityRecord activity;
637 public final Bundle extras;
638 public final Intent intent;
639 public final String hint;
640 public final IResultReceiver receiver;
641 public final int userHandle;
642 public boolean haveResult = false;
643 public Bundle result = null;
644 public AssistStructure structure = null;
645 public AssistContent content = null;
646 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
647 String _hint, IResultReceiver _receiver, int _userHandle) {
648 activity = _activity;
652 receiver = _receiver;
653 userHandle = _userHandle;
657 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
658 synchronized (this) {
662 pendingAssistExtrasTimedOut(this);
666 final ArrayList<PendingAssistExtras> mPendingAssistExtras
667 = new ArrayList<PendingAssistExtras>();
670 * Process management.
672 final ProcessList mProcessList = new ProcessList();
675 * All of the applications we currently have running organized by name.
676 * The keys are strings of the application package name (as
677 * returned by the package manager), and the keys are ApplicationRecord
680 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
683 * Tracking long-term execution of processes to look for abuse and other
686 final ProcessStatsService mProcessStats;
689 * The currently running isolated processes.
691 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
694 * Counter for assigning isolated process uids, to avoid frequently reusing the
697 int mNextIsolatedProcessUid = 0;
700 * The currently running heavy-weight process, if any.
702 ProcessRecord mHeavyWeightProcess = null;
705 * The last time that various processes have crashed.
707 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
710 * Information about a process that is currently marked as bad.
712 static final class BadProcessInfo {
713 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
715 this.shortMsg = shortMsg;
716 this.longMsg = longMsg;
721 final String shortMsg;
722 final String longMsg;
727 * Set of applications that we consider to be bad, and will reject
728 * incoming broadcasts from (which the user has no control over).
729 * Processes are added to this set when they have crashed twice within
730 * a minimum amount of time; they are removed from it when they are
731 * later restarted (hopefully due to some user action). The value is the
732 * time it was added to the list.
734 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
737 * All of the processes we currently have running organized by pid.
738 * The keys are the pid running the application.
740 * <p>NOTE: This object is protected by its own lock, NOT the global
741 * activity manager lock!
743 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
746 * All of the processes that have been forced to be foreground. The key
747 * is the pid of the caller who requested it (we hold a death
750 abstract class ForegroundToken implements IBinder.DeathRecipient {
754 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
757 * List of records for processes that someone had tried to start before the
758 * system was ready. We don't start them at that point, but ensure they
759 * are started by the time booting is complete.
761 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
764 * List of persistent applications that are in the process
767 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
770 * Processes that are being forcibly torn down.
772 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
775 * List of running applications, sorted by recent usage.
776 * The first entry in the list is the least recently used.
778 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
781 * Where in mLruProcesses that the processes hosting activities start.
783 int mLruProcessActivityStart = 0;
786 * Where in mLruProcesses that the processes hosting services start.
787 * This is after (lower index) than mLruProcessesActivityStart.
789 int mLruProcessServiceStart = 0;
792 * List of processes that should gc as soon as things are idle.
794 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
797 * Processes we want to collect PSS data from.
799 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
801 private boolean mBinderTransactionTrackingEnabled = false;
804 * Last time we requested PSS data of all processes.
806 long mLastFullPssTime = SystemClock.uptimeMillis();
809 * If set, the next time we collect PSS data we should do a full collection
810 * with data from native processes and the kernel.
812 boolean mFullPssPending = false;
815 * This is the process holding what we currently consider to be
816 * the "home" activity.
818 ProcessRecord mHomeProcess;
821 * This is the process holding the activity the user last visited that
822 * is in a different process from the one they are currently in.
824 ProcessRecord mPreviousProcess;
827 * The time at which the previous process was last visible.
829 long mPreviousProcessVisibleTime;
832 * Track all uids that have actively running processes.
834 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
837 * This is for verifying the UID report flow.
839 static final boolean VALIDATE_UID_STATES = true;
840 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
843 * Packages that the user has asked to have run in screen size
844 * compatibility mode instead of filling the screen.
846 final CompatModePackages mCompatModePackages;
849 * Set of IntentSenderRecord objects that are currently active.
851 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
852 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
855 * Fingerprints (hashCode()) of stack traces that we've
856 * already logged DropBox entries for. Guarded by itself. If
857 * something (rogue user app) forces this over
858 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
860 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
861 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
864 * Strict Mode background batched logging state.
866 * The string buffer is guarded by itself, and its lock is also
867 * used to determine if another batched write is already
870 private final StringBuilder mStrictModeBuffer = new StringBuilder();
873 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
874 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
876 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
879 * Resolver for broadcast intents to registered receivers.
880 * Holds BroadcastFilter (subclass of IntentFilter).
882 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
883 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
885 protected boolean allowFilterResult(
886 BroadcastFilter filter, List<BroadcastFilter> dest) {
887 IBinder target = filter.receiverList.receiver.asBinder();
888 for (int i = dest.size() - 1; i >= 0; i--) {
889 if (dest.get(i).receiverList.receiver.asBinder() == target) {
897 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
898 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
899 || userId == filter.owningUserId) {
900 return super.newResult(filter, match, userId);
906 protected BroadcastFilter[] newArray(int size) {
907 return new BroadcastFilter[size];
911 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
912 return packageName.equals(filter.packageName);
917 * State of all active sticky broadcasts per user. Keys are the action of the
918 * sticky Intent, values are an ArrayList of all broadcasted intents with
919 * that action (which should usually be one). The SparseArray is keyed
920 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
921 * for stickies that are sent to all users.
923 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
924 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
926 final ActiveServices mServices;
928 final static class Association {
929 final int mSourceUid;
930 final String mSourceProcess;
931 final int mTargetUid;
932 final ComponentName mTargetComponent;
933 final String mTargetProcess;
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;
1055 * Thread-local storage used to carry caller permissions over through
1056 * indirect content-provider access.
1058 private class Identity {
1059 public final IBinder token;
1060 public final int pid;
1061 public final int uid;
1063 Identity(IBinder _token, int _pid, int _uid) {
1070 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1073 * All information we have collected about the runtime performance of
1074 * any user id that can impact battery performance.
1076 final BatteryStatsService mBatteryStatsService;
1079 * Information about component usage
1081 UsageStatsManagerInternal mUsageStatsService;
1084 * Access to DeviceIdleController service.
1086 DeviceIdleController.LocalService mLocalDeviceIdleController;
1089 * Information about and control over application operations
1091 final AppOpsService mAppOpsService;
1094 * Save recent tasks information across reboots.
1096 final TaskPersister mTaskPersister;
1099 * Current configuration information. HistoryRecord objects are given
1100 * a reference to this object to indicate which configuration they are
1101 * currently running in, so this object must be kept immutable.
1103 Configuration mConfiguration = new Configuration();
1106 * Current sequencing integer of the configuration, for skipping old
1109 int mConfigurationSeq = 0;
1111 boolean mSuppressResizeConfigChanges = false;
1114 * Hardware-reported OpenGLES version.
1116 final int GL_ES_VERSION;
1119 * List of initialization arguments to pass to all processes when binding applications to them.
1120 * For example, references to the commonly used services.
1122 HashMap<String, IBinder> mAppBindArgs;
1125 * Temporary to avoid allocations. Protected by main lock.
1127 final StringBuilder mStringBuilder = new StringBuilder(256);
1130 * Used to control how we initialize the service.
1132 ComponentName mTopComponent;
1133 String mTopAction = Intent.ACTION_MAIN;
1135 boolean mProcessesReady = false;
1136 boolean mSystemReady = false;
1137 boolean mBooting = false;
1138 boolean mCallFinishBooting = false;
1139 boolean mBootAnimationComplete = false;
1140 boolean mWaitingUpdate = false;
1141 boolean mDidUpdate = false;
1142 boolean mOnBattery = false;
1143 boolean mLaunchWarningShown = false;
1149 boolean mCheckedForSetup;
1152 * The time at which we will allow normal application switches again,
1153 * after a call to {@link #stopAppSwitches()}.
1155 long mAppSwitchesAllowedTime;
1158 * This is set to true after the first switch after mAppSwitchesAllowedTime
1159 * is set; any switches after that will clear the time.
1161 boolean mDidAppSwitch;
1164 * Last time (in realtime) at which we checked for power usage.
1166 long mLastPowerCheckRealtime;
1169 * Last time (in uptime) at which we checked for power usage.
1171 long mLastPowerCheckUptime;
1174 * Set while we are wanting to sleep, to prevent any
1175 * activities from being started/resumed.
1177 private boolean mSleeping = false;
1180 * The process state used for processes that are running the top activities.
1181 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1183 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1186 * Set while we are running a voice interaction. This overrides
1187 * sleeping while it is active.
1189 private IVoiceInteractionSession mRunningVoice;
1192 * For some direct access we need to power manager.
1194 PowerManagerInternal mLocalPowerManager;
1197 * We want to hold a wake lock while running a voice interaction session, since
1198 * this may happen with the screen off and we need to keep the CPU running to
1199 * be able to continue to interact with the user.
1201 PowerManager.WakeLock mVoiceWakeLock;
1204 * State of external calls telling us if the device is awake or asleep.
1206 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1209 * A list of tokens that cause the top activity to be put to sleep.
1210 * They are used by components that may hide and block interaction with underlying
1213 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1215 static final int LOCK_SCREEN_HIDDEN = 0;
1216 static final int LOCK_SCREEN_LEAVING = 1;
1217 static final int LOCK_SCREEN_SHOWN = 2;
1219 * State of external call telling us if the lock screen is shown.
1221 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1224 * Set if we are shutting down the system, similar to sleeping.
1226 boolean mShuttingDown = false;
1229 * Current sequence id for oom_adj computation traversal.
1234 * Current sequence id for process LRU updating.
1239 * Keep track of the non-cached/empty process we last found, to help
1240 * determine how to distribute cached/empty processes next time.
1242 int mNumNonCachedProcs = 0;
1245 * Keep track of the number of cached hidden procs, to balance oom adj
1246 * distribution between those and empty procs.
1248 int mNumCachedHiddenProcs = 0;
1251 * Keep track of the number of service processes we last found, to
1252 * determine on the next iteration which should be B services.
1254 int mNumServiceProcs = 0;
1255 int mNewNumAServiceProcs = 0;
1256 int mNewNumServiceProcs = 0;
1259 * Allow the current computed overall memory level of the system to go down?
1260 * This is set to false when we are killing processes for reasons other than
1261 * memory management, so that the now smaller process list will not be taken as
1262 * an indication that memory is tighter.
1264 boolean mAllowLowerMemLevel = false;
1267 * The last computed memory level, for holding when we are in a state that
1268 * processes are going away for other reasons.
1270 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1273 * The last total number of process we have, to determine if changes actually look
1274 * like a shrinking number of process due to lower RAM.
1276 int mLastNumProcesses;
1279 * The uptime of the last time we performed idle maintenance.
1281 long mLastIdleTime = SystemClock.uptimeMillis();
1284 * Total time spent with RAM that has been added in the past since the last idle time.
1286 long mLowRamTimeSinceLastIdle = 0;
1289 * If RAM is currently low, when that horrible situation started.
1291 long mLowRamStartTime = 0;
1294 * For reporting to battery stats the current top application.
1296 private String mCurResumedPackage = null;
1297 private int mCurResumedUid = -1;
1300 * For reporting to battery stats the apps currently running foreground
1301 * service. The ProcessMap is package/uid tuples; each of these contain
1302 * an array of the currently foreground processes.
1304 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1305 = new ProcessMap<ArrayList<ProcessRecord>>();
1308 * This is set if we had to do a delayed dexopt of an app before launching
1309 * it, to increase the ANR timeouts in that case.
1314 * Set if the systemServer made a call to enterSafeMode.
1319 * If true, we are running under a test environment so will sample PSS from processes
1320 * much more rapidly to try to collect better data when the tests are rapidly
1321 * running through apps.
1323 boolean mTestPssMode = false;
1325 String mDebugApp = null;
1326 boolean mWaitForDebugger = false;
1327 boolean mDebugTransient = false;
1328 String mOrigDebugApp = null;
1329 boolean mOrigWaitForDebugger = false;
1330 boolean mAlwaysFinishActivities = false;
1331 boolean mForceResizableActivities;
1332 boolean mSupportsFreeformWindowManagement;
1333 boolean mTakeFullscreenScreenshots;
1334 IActivityController mController = null;
1335 String mProfileApp = null;
1336 ProcessRecord mProfileProc = null;
1337 String mProfileFile;
1338 ParcelFileDescriptor mProfileFd;
1339 int mSamplingInterval = 0;
1340 boolean mAutoStopProfiler = false;
1341 int mProfileType = 0;
1342 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1343 String mMemWatchDumpProcName;
1344 String mMemWatchDumpFile;
1345 int mMemWatchDumpPid;
1346 int mMemWatchDumpUid;
1347 String mTrackAllocationApp = null;
1349 final long[] mTmpLong = new long[1];
1351 static final class ProcessChangeItem {
1352 static final int CHANGE_ACTIVITIES = 1<<0;
1353 static final int CHANGE_PROCESS_STATE = 1<<1;
1358 boolean foregroundActivities;
1361 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1362 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1364 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1365 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1367 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1368 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1370 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1371 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1373 ArraySet<String> mAppsNotReportingCrashes;
1376 * Runtime CPU use collection thread. This object's lock is used to
1377 * perform synchronization with the thread (notifying it to run).
1379 final Thread mProcessCpuThread;
1382 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1383 * Must acquire this object's lock when accessing it.
1384 * NOTE: this lock will be held while doing long operations (trawling
1385 * through all processes in /proc), so it should never be acquired by
1386 * any critical paths such as when holding the main activity manager lock.
1388 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1389 MONITOR_THREAD_CPU_USAGE);
1390 final AtomicLong mLastCpuTime = new AtomicLong(0);
1391 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1393 long mLastWriteTime = 0;
1396 * Used to retain an update lock when the foreground activity is in
1399 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1402 * Set to true after the system has finished booting.
1404 boolean mBooted = false;
1406 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1407 int mProcessLimitOverride = -1;
1409 WindowManagerService mWindowManager;
1411 final ActivityThread mSystemThread;
1413 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1414 final ProcessRecord mApp;
1416 final IApplicationThread mAppThread;
1418 AppDeathRecipient(ProcessRecord app, int pid,
1419 IApplicationThread thread) {
1420 if (DEBUG_ALL) Slog.v(
1421 TAG, "New death recipient " + this
1422 + " for thread " + thread.asBinder());
1425 mAppThread = thread;
1429 public void binderDied() {
1430 if (DEBUG_ALL) Slog.v(
1431 TAG, "Death received in " + this
1432 + " for thread " + mAppThread.asBinder());
1433 synchronized(ActivityManagerService.this) {
1434 appDiedLocked(mApp, mPid, mAppThread, true);
1439 static final int SHOW_ERROR_UI_MSG = 1;
1440 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1441 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1442 static final int UPDATE_CONFIGURATION_MSG = 4;
1443 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1444 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1445 static final int SERVICE_TIMEOUT_MSG = 12;
1446 static final int UPDATE_TIME_ZONE = 13;
1447 static final int SHOW_UID_ERROR_UI_MSG = 14;
1448 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1449 static final int PROC_START_TIMEOUT_MSG = 20;
1450 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1451 static final int KILL_APPLICATION_MSG = 22;
1452 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1453 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1454 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1455 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1456 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1457 static final int CLEAR_DNS_CACHE_MSG = 28;
1458 static final int UPDATE_HTTP_PROXY_MSG = 29;
1459 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1460 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1461 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1462 static final int REPORT_MEM_USAGE_MSG = 33;
1463 static final int REPORT_USER_SWITCH_MSG = 34;
1464 static final int CONTINUE_USER_SWITCH_MSG = 35;
1465 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1466 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1467 static final int PERSIST_URI_GRANTS_MSG = 38;
1468 static final int REQUEST_ALL_PSS_MSG = 39;
1469 static final int START_PROFILES_MSG = 40;
1470 static final int UPDATE_TIME = 41;
1471 static final int SYSTEM_USER_START_MSG = 42;
1472 static final int SYSTEM_USER_CURRENT_MSG = 43;
1473 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1474 static final int FINISH_BOOTING_MSG = 45;
1475 static final int START_USER_SWITCH_UI_MSG = 46;
1476 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1477 static final int DISMISS_DIALOG_UI_MSG = 48;
1478 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1479 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1480 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1481 static final int DELETE_DUMPHEAP_MSG = 52;
1482 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1483 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1484 static final int REPORT_TIME_TRACKER_MSG = 55;
1485 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1486 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1487 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1488 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1489 static final int IDLE_UIDS_MSG = 60;
1491 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1492 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1493 static final int FIRST_COMPAT_MODE_MSG = 300;
1494 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1496 CompatModeDialog mCompatModeDialog;
1497 long mLastMemUsageReportTime = 0;
1500 * Flag whether the current user is a "monkey", i.e. whether
1501 * the UI is driven by a UI automation tool.
1503 private boolean mUserIsMonkey;
1505 /** Flag whether the device has a Recents UI */
1506 boolean mHasRecents;
1508 /** The dimensions of the thumbnails in the Recents UI. */
1509 int mThumbnailWidth;
1510 int mThumbnailHeight;
1512 final ServiceThread mHandlerThread;
1513 final MainHandler mHandler;
1514 final UiHandler mUiHandler;
1516 PackageManagerInternal mPackageManagerInt;
1518 final class UiHandler extends Handler {
1519 public UiHandler() {
1520 super(com.android.server.UiThread.get().getLooper(), null, true);
1524 public void handleMessage(Message msg) {
1526 case SHOW_ERROR_UI_MSG: {
1527 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1528 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1529 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1530 synchronized (ActivityManagerService.this) {
1531 ProcessRecord proc = (ProcessRecord)data.get("app");
1532 AppErrorResult res = (AppErrorResult) data.get("result");
1533 if (proc != null && proc.crashDialog != null) {
1534 Slog.e(TAG, "App already has crash dialog: " + proc);
1540 boolean isBackground = (UserHandle.getAppId(proc.uid)
1541 >= Process.FIRST_APPLICATION_UID
1542 && proc.pid != MY_PID);
1543 for (int userId : mUserController.getCurrentProfileIdsLocked()) {
1544 isBackground &= (proc.userId != userId);
1546 if (isBackground && !showBackground) {
1547 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1553 final boolean crashSilenced = mAppsNotReportingCrashes != null &&
1554 mAppsNotReportingCrashes.contains(proc.info.packageName);
1555 if (mShowDialogs && !mSleeping && !mShuttingDown && !crashSilenced) {
1556 Dialog d = new AppErrorDialog(mContext,
1557 ActivityManagerService.this, res, proc);
1559 proc.crashDialog = d;
1561 // The device is asleep, so just pretend that the user
1562 // saw a crash dialog and hit "force quit".
1569 ensureBootCompleted();
1571 case SHOW_NOT_RESPONDING_UI_MSG: {
1572 synchronized (ActivityManagerService.this) {
1573 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1574 ProcessRecord proc = (ProcessRecord)data.get("app");
1575 if (proc != null && proc.anrDialog != null) {
1576 Slog.e(TAG, "App already has anr dialog: " + proc);
1580 Intent intent = new Intent("android.intent.action.ANR");
1581 if (!mProcessesReady) {
1582 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1583 | Intent.FLAG_RECEIVER_FOREGROUND);
1585 broadcastIntentLocked(null, null, intent,
1586 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1587 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1590 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1591 mContext, proc, (ActivityRecord)data.get("activity"),
1596 // Just kill the app if there is no dialog to be shown.
1597 killAppAtUsersRequest(proc, null);
1601 ensureBootCompleted();
1603 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1604 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1605 synchronized (ActivityManagerService.this) {
1606 ProcessRecord proc = (ProcessRecord) data.get("app");
1608 Slog.e(TAG, "App not found when showing strict mode dialog.");
1611 if (proc.crashDialog != null) {
1612 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1615 AppErrorResult res = (AppErrorResult) data.get("result");
1616 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1617 Dialog d = new StrictModeViolationDialog(mContext,
1618 ActivityManagerService.this, res, proc);
1620 proc.crashDialog = d;
1622 // The device is asleep, so just pretend that the user
1623 // saw a crash dialog and hit "force quit".
1627 ensureBootCompleted();
1629 case SHOW_FACTORY_ERROR_UI_MSG: {
1630 Dialog d = new FactoryErrorDialog(
1631 mContext, msg.getData().getCharSequence("msg"));
1633 ensureBootCompleted();
1635 case WAIT_FOR_DEBUGGER_UI_MSG: {
1636 synchronized (ActivityManagerService.this) {
1637 ProcessRecord app = (ProcessRecord)msg.obj;
1638 if (msg.arg1 != 0) {
1639 if (!app.waitedForDebugger) {
1640 Dialog d = new AppWaitingForDebuggerDialog(
1641 ActivityManagerService.this,
1644 app.waitedForDebugger = true;
1648 if (app.waitDialog != null) {
1649 app.waitDialog.dismiss();
1650 app.waitDialog = null;
1655 case SHOW_UID_ERROR_UI_MSG: {
1657 AlertDialog d = new BaseErrorDialog(mContext);
1658 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1659 d.setCancelable(false);
1660 d.setTitle(mContext.getText(R.string.android_system_label));
1661 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1662 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1663 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1667 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1669 AlertDialog d = new BaseErrorDialog(mContext);
1670 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1671 d.setCancelable(false);
1672 d.setTitle(mContext.getText(R.string.android_system_label));
1673 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1674 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1675 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1679 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1680 synchronized (ActivityManagerService.this) {
1681 ActivityRecord ar = (ActivityRecord) msg.obj;
1682 if (mCompatModeDialog != null) {
1683 if (mCompatModeDialog.mAppInfo.packageName.equals(
1684 ar.info.applicationInfo.packageName)) {
1687 mCompatModeDialog.dismiss();
1688 mCompatModeDialog = null;
1690 if (ar != null && false) {
1691 if (mCompatModePackages.getPackageAskCompatModeLocked(
1693 int mode = mCompatModePackages.computeCompatModeLocked(
1694 ar.info.applicationInfo);
1695 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1696 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1697 mCompatModeDialog = new CompatModeDialog(
1698 ActivityManagerService.this, mContext,
1699 ar.info.applicationInfo);
1700 mCompatModeDialog.show();
1707 case START_USER_SWITCH_UI_MSG: {
1708 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1711 case DISMISS_DIALOG_UI_MSG: {
1712 final Dialog d = (Dialog) msg.obj;
1716 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1717 dispatchProcessesChanged();
1720 case DISPATCH_PROCESS_DIED_UI_MSG: {
1721 final int pid = msg.arg1;
1722 final int uid = msg.arg2;
1723 dispatchProcessDied(pid, uid);
1726 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1727 dispatchUidsChanged();
1733 final class MainHandler extends Handler {
1734 public MainHandler(Looper looper) {
1735 super(looper, null, true);
1739 public void handleMessage(Message msg) {
1741 case UPDATE_CONFIGURATION_MSG: {
1742 final ContentResolver resolver = mContext.getContentResolver();
1743 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1746 case GC_BACKGROUND_PROCESSES_MSG: {
1747 synchronized (ActivityManagerService.this) {
1748 performAppGcsIfAppropriateLocked();
1751 case SERVICE_TIMEOUT_MSG: {
1754 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1756 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1759 mServices.serviceTimeout((ProcessRecord)msg.obj);
1761 case UPDATE_TIME_ZONE: {
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.updateTimeZone();
1768 } catch (RemoteException ex) {
1769 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1775 case CLEAR_DNS_CACHE_MSG: {
1776 synchronized (ActivityManagerService.this) {
1777 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1778 ProcessRecord r = mLruProcesses.get(i);
1779 if (r.thread != null) {
1781 r.thread.clearDnsCache();
1782 } catch (RemoteException ex) {
1783 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1789 case UPDATE_HTTP_PROXY_MSG: {
1790 ProxyInfo proxy = (ProxyInfo)msg.obj;
1793 String exclList = "";
1794 Uri pacFileUrl = Uri.EMPTY;
1795 if (proxy != null) {
1796 host = proxy.getHost();
1797 port = Integer.toString(proxy.getPort());
1798 exclList = proxy.getExclusionListAsString();
1799 pacFileUrl = proxy.getPacFileUrl();
1801 synchronized (ActivityManagerService.this) {
1802 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1803 ProcessRecord r = mLruProcesses.get(i);
1804 if (r.thread != null) {
1806 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1807 } catch (RemoteException ex) {
1808 Slog.w(TAG, "Failed to update http proxy for: " +
1809 r.info.processName);
1815 case PROC_START_TIMEOUT_MSG: {
1818 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1820 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1823 ProcessRecord app = (ProcessRecord)msg.obj;
1824 synchronized (ActivityManagerService.this) {
1825 processStartTimedOutLocked(app);
1828 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1829 ProcessRecord app = (ProcessRecord)msg.obj;
1830 synchronized (ActivityManagerService.this) {
1831 processContentProviderPublishTimedOutLocked(app);
1834 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1835 synchronized (ActivityManagerService.this) {
1836 mStackSupervisor.doPendingActivityLaunchesLocked(true);
1839 case KILL_APPLICATION_MSG: {
1840 synchronized (ActivityManagerService.this) {
1841 int appid = msg.arg1;
1842 boolean restart = (msg.arg2 == 1);
1843 Bundle bundle = (Bundle)msg.obj;
1844 String pkg = bundle.getString("pkg");
1845 String reason = bundle.getString("reason");
1846 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1847 false, UserHandle.USER_ALL, reason);
1850 case FINALIZE_PENDING_INTENT_MSG: {
1851 ((PendingIntentRecord)msg.obj).completeFinalize();
1853 case POST_HEAVY_NOTIFICATION_MSG: {
1854 INotificationManager inm = NotificationManager.getService();
1859 ActivityRecord root = (ActivityRecord)msg.obj;
1860 ProcessRecord process = root.app;
1861 if (process == null) {
1866 Context context = mContext.createPackageContext(process.info.packageName, 0);
1867 String text = mContext.getString(R.string.heavy_weight_notification,
1868 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1869 Notification notification = new Notification.Builder(context)
1870 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1874 .setColor(mContext.getColor(
1875 com.android.internal.R.color.system_notification_accent_color))
1876 .setContentTitle(text)
1878 mContext.getText(R.string.heavy_weight_notification_detail))
1879 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1880 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1881 new UserHandle(root.userId)))
1884 int[] outId = new int[1];
1885 inm.enqueueNotificationWithTag("android", "android", null,
1886 R.string.heavy_weight_notification,
1887 notification, outId, root.userId);
1888 } catch (RuntimeException e) {
1889 Slog.w(ActivityManagerService.TAG,
1890 "Error showing notification for heavy-weight app", e);
1891 } catch (RemoteException e) {
1893 } catch (NameNotFoundException e) {
1894 Slog.w(TAG, "Unable to create context for heavy notification", e);
1897 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1898 INotificationManager inm = NotificationManager.getService();
1903 inm.cancelNotificationWithTag("android", null,
1904 R.string.heavy_weight_notification, msg.arg1);
1905 } catch (RuntimeException e) {
1906 Slog.w(ActivityManagerService.TAG,
1907 "Error canceling notification for service", e);
1908 } catch (RemoteException e) {
1911 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1912 synchronized (ActivityManagerService.this) {
1913 checkExcessivePowerUsageLocked(true);
1914 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1915 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1916 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1919 case REPORT_MEM_USAGE_MSG: {
1920 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1921 Thread thread = new Thread() {
1922 @Override public void run() {
1923 reportMemUsage(memInfos);
1929 case REPORT_USER_SWITCH_MSG: {
1930 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1933 case CONTINUE_USER_SWITCH_MSG: {
1934 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1937 case USER_SWITCH_TIMEOUT_MSG: {
1938 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1941 case IMMERSIVE_MODE_LOCK_MSG: {
1942 final boolean nextState = (msg.arg1 != 0);
1943 if (mUpdateLock.isHeld() != nextState) {
1944 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1945 "Applying new update lock state '" + nextState
1946 + "' for " + (ActivityRecord)msg.obj);
1948 mUpdateLock.acquire();
1950 mUpdateLock.release();
1955 case PERSIST_URI_GRANTS_MSG: {
1956 writeGrantedUriPermissions();
1959 case REQUEST_ALL_PSS_MSG: {
1960 synchronized (ActivityManagerService.this) {
1961 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1965 case START_PROFILES_MSG: {
1966 synchronized (ActivityManagerService.this) {
1967 mUserController.startProfilesLocked();
1972 synchronized (ActivityManagerService.this) {
1973 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1974 ProcessRecord r = mLruProcesses.get(i);
1975 if (r.thread != null) {
1977 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1978 } catch (RemoteException ex) {
1979 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1986 case SYSTEM_USER_START_MSG: {
1987 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1988 Integer.toString(msg.arg1), msg.arg1);
1989 mSystemServiceManager.startUser(msg.arg1);
1992 case SYSTEM_USER_CURRENT_MSG: {
1993 mBatteryStatsService.noteEvent(
1994 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1995 Integer.toString(msg.arg2), msg.arg2);
1996 mBatteryStatsService.noteEvent(
1997 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1998 Integer.toString(msg.arg1), msg.arg1);
1999 mSystemServiceManager.switchUser(msg.arg1);
2002 case ENTER_ANIMATION_COMPLETE_MSG: {
2003 synchronized (ActivityManagerService.this) {
2004 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2005 if (r != null && r.app != null && r.app.thread != null) {
2007 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2008 } catch (RemoteException e) {
2014 case FINISH_BOOTING_MSG: {
2015 if (msg.arg1 != 0) {
2016 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2018 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2020 if (msg.arg2 != 0) {
2021 enableScreenAfterBoot();
2025 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2027 Locale l = (Locale) msg.obj;
2028 IBinder service = ServiceManager.getService("mount");
2029 IMountService mountService = IMountService.Stub.asInterface(service);
2030 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2031 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2032 } catch (RemoteException e) {
2033 Log.e(TAG, "Error storing locale for decryption UI", e);
2037 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2038 synchronized (ActivityManagerService.this) {
2039 int i = mTaskStackListeners.beginBroadcast();
2043 // Make a one-way callback to the listener
2044 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2045 } catch (RemoteException e){
2046 // Handled by the RemoteCallbackList
2049 mTaskStackListeners.finishBroadcast();
2053 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2054 final int uid = msg.arg1;
2055 final byte[] firstPacket = (byte[]) msg.obj;
2057 synchronized (mPidsSelfLocked) {
2058 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2059 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2062 p.thread.notifyCleartextNetwork(firstPacket);
2063 } catch (RemoteException ignored) {
2070 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2071 final String procName;
2073 final long memLimit;
2074 final String reportPackage;
2075 synchronized (ActivityManagerService.this) {
2076 procName = mMemWatchDumpProcName;
2077 uid = mMemWatchDumpUid;
2078 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2080 val = mMemWatchProcesses.get(procName, 0);
2083 memLimit = val.first;
2084 reportPackage = val.second;
2087 reportPackage = null;
2090 if (procName == null) {
2094 if (DEBUG_PSS) Slog.d(TAG_PSS,
2095 "Showing dump heap notification from " + procName + "/" + uid);
2097 INotificationManager inm = NotificationManager.getService();
2102 String text = mContext.getString(R.string.dump_heap_notification, procName);
2105 Intent deleteIntent = new Intent();
2106 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2107 Intent intent = new Intent();
2108 intent.setClassName("android", DumpHeapActivity.class.getName());
2109 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2110 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2111 if (reportPackage != null) {
2112 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2114 int userId = UserHandle.getUserId(uid);
2115 Notification notification = new Notification.Builder(mContext)
2116 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2119 .setAutoCancel(true)
2121 .setColor(mContext.getColor(
2122 com.android.internal.R.color.system_notification_accent_color))
2123 .setContentTitle(text)
2125 mContext.getText(R.string.dump_heap_notification_detail))
2126 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2127 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2128 new UserHandle(userId)))
2129 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2130 deleteIntent, 0, UserHandle.SYSTEM))
2134 int[] outId = new int[1];
2135 inm.enqueueNotificationWithTag("android", "android", null,
2136 R.string.dump_heap_notification,
2137 notification, outId, userId);
2138 } catch (RuntimeException e) {
2139 Slog.w(ActivityManagerService.TAG,
2140 "Error showing notification for dump heap", e);
2141 } catch (RemoteException e) {
2144 case DELETE_DUMPHEAP_MSG: {
2145 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2146 DumpHeapActivity.JAVA_URI,
2147 Intent.FLAG_GRANT_READ_URI_PERMISSION
2148 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2149 UserHandle.myUserId());
2150 synchronized (ActivityManagerService.this) {
2151 mMemWatchDumpFile = null;
2152 mMemWatchDumpProcName = null;
2153 mMemWatchDumpPid = -1;
2154 mMemWatchDumpUid = -1;
2157 case FOREGROUND_PROFILE_CHANGED_MSG: {
2158 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2160 case REPORT_TIME_TRACKER_MSG: {
2161 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2162 tracker.deliverResult(mContext);
2164 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2165 mUserController.dispatchUserSwitchComplete(msg.arg1);
2167 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2168 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2170 connection.shutdown();
2171 } catch (RemoteException e) {
2172 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2174 // Only a UiAutomation can set this flag and now that
2175 // it is finished we make sure it is reset to its default.
2176 mUserIsMonkey = false;
2178 case APP_BOOST_DEACTIVATE_MSG: {
2179 synchronized(ActivityManagerService.this) {
2181 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2182 nativeMigrateFromBoost();
2184 mBoostStartTime = 0;
2186 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2187 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2192 case IDLE_UIDS_MSG: {
2199 static final int COLLECT_PSS_BG_MSG = 1;
2201 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2203 public void handleMessage(Message msg) {
2205 case COLLECT_PSS_BG_MSG: {
2206 long start = SystemClock.uptimeMillis();
2207 MemInfoReader memInfo = null;
2208 synchronized (ActivityManagerService.this) {
2209 if (mFullPssPending) {
2210 mFullPssPending = false;
2211 memInfo = new MemInfoReader();
2214 if (memInfo != null) {
2215 updateCpuStatsNow();
2216 long nativeTotalPss = 0;
2217 synchronized (mProcessCpuTracker) {
2218 final int N = mProcessCpuTracker.countStats();
2219 for (int j=0; j<N; j++) {
2220 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2221 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2222 // This is definitely an application process; skip it.
2225 synchronized (mPidsSelfLocked) {
2226 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2227 // This is one of our own processes; skip it.
2231 nativeTotalPss += Debug.getPss(st.pid, null, null);
2234 memInfo.readMemInfo();
2235 synchronized (ActivityManagerService.this) {
2236 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2237 + (SystemClock.uptimeMillis()-start) + "ms");
2238 final long cachedKb = memInfo.getCachedSizeKb();
2239 final long freeKb = memInfo.getFreeSizeKb();
2240 final long zramKb = memInfo.getZramTotalSizeKb();
2241 final long kernelKb = memInfo.getKernelUsedSizeKb();
2242 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2243 kernelKb*1024, nativeTotalPss*1024);
2244 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2250 long[] tmp = new long[1];
2256 synchronized (ActivityManagerService.this) {
2257 if (mPendingPssProcesses.size() <= 0) {
2258 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2259 "Collected PSS of " + num + " processes in "
2260 + (SystemClock.uptimeMillis() - start) + "ms");
2261 mPendingPssProcesses.clear();
2264 proc = mPendingPssProcesses.remove(0);
2265 procState = proc.pssProcState;
2266 lastPssTime = proc.lastPssTime;
2267 if (proc.thread != null && procState == proc.setProcState
2268 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2269 < SystemClock.uptimeMillis()) {
2277 long pss = Debug.getPss(pid, tmp, null);
2278 synchronized (ActivityManagerService.this) {
2279 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2280 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2282 recordPssSampleLocked(proc, procState, pss, tmp[0],
2283 SystemClock.uptimeMillis());
2293 public void setSystemProcess() {
2295 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2296 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2297 ServiceManager.addService("meminfo", new MemBinder(this));
2298 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2299 ServiceManager.addService("dbinfo", new DbBinder(this));
2300 if (MONITOR_CPU_USAGE) {
2301 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2303 ServiceManager.addService("permission", new PermissionController(this));
2304 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2306 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2307 "android", STOCK_PM_FLAGS);
2308 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2310 synchronized (this) {
2311 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2312 app.persistent = true;
2314 app.maxAdj = ProcessList.SYSTEM_ADJ;
2315 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2316 synchronized (mPidsSelfLocked) {
2317 mPidsSelfLocked.put(app.pid, app);
2319 updateLruProcessLocked(app, false, null);
2320 updateOomAdjLocked();
2322 } catch (PackageManager.NameNotFoundException e) {
2323 throw new RuntimeException(
2324 "Unable to find android system package", e);
2328 public void setWindowManager(WindowManagerService wm) {
2329 mWindowManager = wm;
2330 mStackSupervisor.setWindowManager(wm);
2333 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2334 mUsageStatsService = usageStatsManager;
2337 public void startObservingNativeCrashes() {
2338 final NativeCrashListener ncl = new NativeCrashListener(this);
2342 public IAppOpsService getAppOpsService() {
2343 return mAppOpsService;
2346 static class MemBinder extends Binder {
2347 ActivityManagerService mActivityManagerService;
2348 MemBinder(ActivityManagerService activityManagerService) {
2349 mActivityManagerService = activityManagerService;
2353 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2354 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2355 != PackageManager.PERMISSION_GRANTED) {
2356 pw.println("Permission Denial: can't dump meminfo from from pid="
2357 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2358 + " without permission " + android.Manifest.permission.DUMP);
2362 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2366 static class GraphicsBinder extends Binder {
2367 ActivityManagerService mActivityManagerService;
2368 GraphicsBinder(ActivityManagerService activityManagerService) {
2369 mActivityManagerService = activityManagerService;
2373 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2374 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2375 != PackageManager.PERMISSION_GRANTED) {
2376 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2377 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2378 + " without permission " + android.Manifest.permission.DUMP);
2382 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2386 static class DbBinder extends Binder {
2387 ActivityManagerService mActivityManagerService;
2388 DbBinder(ActivityManagerService activityManagerService) {
2389 mActivityManagerService = activityManagerService;
2393 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2394 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2395 != PackageManager.PERMISSION_GRANTED) {
2396 pw.println("Permission Denial: can't dump dbinfo from from pid="
2397 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2398 + " without permission " + android.Manifest.permission.DUMP);
2402 mActivityManagerService.dumpDbInfo(fd, pw, args);
2406 static class CpuBinder extends Binder {
2407 ActivityManagerService mActivityManagerService;
2408 CpuBinder(ActivityManagerService activityManagerService) {
2409 mActivityManagerService = activityManagerService;
2413 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2414 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2415 != PackageManager.PERMISSION_GRANTED) {
2416 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2417 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2418 + " without permission " + android.Manifest.permission.DUMP);
2422 synchronized (mActivityManagerService.mProcessCpuTracker) {
2423 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2424 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2425 SystemClock.uptimeMillis()));
2430 public static final class Lifecycle extends SystemService {
2431 private final ActivityManagerService mService;
2433 public Lifecycle(Context context) {
2435 mService = new ActivityManagerService(context);
2439 public void onStart() {
2443 public ActivityManagerService getService() {
2448 // Note: This method is invoked on the main thread but may need to attach various
2449 // handlers to other threads. So take care to be explicit about the looper.
2450 public ActivityManagerService(Context systemContext) {
2451 mContext = systemContext;
2452 mFactoryTest = FactoryTest.getMode();
2453 mSystemThread = ActivityThread.currentActivityThread();
2455 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2457 mHandlerThread = new ServiceThread(TAG,
2458 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2459 mHandlerThread.start();
2460 mHandler = new MainHandler(mHandlerThread.getLooper());
2461 mUiHandler = new UiHandler();
2463 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2464 "foreground", BROADCAST_FG_TIMEOUT, false);
2465 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2466 "background", BROADCAST_BG_TIMEOUT, true);
2467 mBroadcastQueues[0] = mFgBroadcastQueue;
2468 mBroadcastQueues[1] = mBgBroadcastQueue;
2470 mServices = new ActiveServices(this);
2471 mProviderMap = new ProviderMap(this);
2473 // TODO: Move creation of battery stats service outside of activity manager service.
2474 File dataDir = Environment.getDataDirectory();
2475 File systemDir = new File(dataDir, "system");
2477 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2478 mBatteryStatsService.getActiveStatistics().readLocked();
2479 mBatteryStatsService.scheduleWriteToDisk();
2480 mOnBattery = DEBUG_POWER ? true
2481 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2482 mBatteryStatsService.getActiveStatistics().setCallback(this);
2484 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2486 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2487 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2488 new IAppOpsCallback.Stub() {
2489 @Override public void opChanged(int op, int uid, String packageName) {
2490 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2491 if (mAppOpsService.checkOperation(op, uid, packageName)
2492 != AppOpsManager.MODE_ALLOWED) {
2493 runInBackgroundDisabled(uid);
2499 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2501 mUserController = new UserController(this);
2503 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2504 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2506 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2508 mConfiguration.setToDefaults();
2509 mConfiguration.setLocales(LocaleList.getDefault());
2511 mConfigurationSeq = mConfiguration.seq = 1;
2512 mProcessCpuTracker.init();
2514 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2515 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2516 mRecentTasks = new RecentTasks(this);
2517 mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2518 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2520 mProcessCpuThread = new Thread("CpuTracker") {
2526 synchronized(this) {
2527 final long now = SystemClock.uptimeMillis();
2528 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2529 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2530 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2531 // + ", write delay=" + nextWriteDelay);
2532 if (nextWriteDelay < nextCpuDelay) {
2533 nextCpuDelay = nextWriteDelay;
2535 if (nextCpuDelay > 0) {
2536 mProcessCpuMutexFree.set(true);
2537 this.wait(nextCpuDelay);
2540 } catch (InterruptedException e) {
2542 updateCpuStatsNow();
2543 } catch (Exception e) {
2544 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2550 Watchdog.getInstance().addMonitor(this);
2551 Watchdog.getInstance().addThread(mHandler);
2554 public void setSystemServiceManager(SystemServiceManager mgr) {
2555 mSystemServiceManager = mgr;
2558 public void setInstaller(Installer installer) {
2559 mInstaller = installer;
2562 private void start() {
2563 Process.removeAllProcessGroups();
2564 mProcessCpuThread.start();
2566 mBatteryStatsService.publish(mContext);
2567 mAppOpsService.publish(mContext);
2568 Slog.d("AppOps", "AppOpsService published");
2569 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2572 public void initPowerManagement() {
2573 mStackSupervisor.initPowerManagement();
2574 mBatteryStatsService.initPowerManagement();
2575 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2576 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2577 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2578 mVoiceWakeLock.setReferenceCounted(false);
2582 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2583 throws RemoteException {
2584 if (code == SYSPROPS_TRANSACTION) {
2585 // We need to tell all apps about the system property change.
2586 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2587 synchronized(this) {
2588 final int NP = mProcessNames.getMap().size();
2589 for (int ip=0; ip<NP; ip++) {
2590 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2591 final int NA = apps.size();
2592 for (int ia=0; ia<NA; ia++) {
2593 ProcessRecord app = apps.valueAt(ia);
2594 if (app.thread != null) {
2595 procs.add(app.thread.asBinder());
2601 int N = procs.size();
2602 for (int i=0; i<N; i++) {
2603 Parcel data2 = Parcel.obtain();
2605 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2606 } catch (RemoteException e) {
2612 return super.onTransact(code, data, reply, flags);
2613 } catch (RuntimeException e) {
2614 // The activity manager only throws security exceptions, so let's
2616 if (!(e instanceof SecurityException)) {
2617 Slog.wtf(TAG, "Activity Manager Crash", e);
2623 void updateCpuStats() {
2624 final long now = SystemClock.uptimeMillis();
2625 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2628 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2629 synchronized (mProcessCpuThread) {
2630 mProcessCpuThread.notify();
2635 void updateCpuStatsNow() {
2636 synchronized (mProcessCpuTracker) {
2637 mProcessCpuMutexFree.set(false);
2638 final long now = SystemClock.uptimeMillis();
2639 boolean haveNewCpuStats = false;
2641 if (MONITOR_CPU_USAGE &&
2642 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2643 mLastCpuTime.set(now);
2644 mProcessCpuTracker.update();
2645 if (mProcessCpuTracker.hasGoodLastStats()) {
2646 haveNewCpuStats = true;
2647 //Slog.i(TAG, mProcessCpu.printCurrentState());
2648 //Slog.i(TAG, "Total CPU usage: "
2649 // + mProcessCpu.getTotalCpuPercent() + "%");
2651 // Slog the cpu usage if the property is set.
2652 if ("true".equals(SystemProperties.get("events.cpu"))) {
2653 int user = mProcessCpuTracker.getLastUserTime();
2654 int system = mProcessCpuTracker.getLastSystemTime();
2655 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2656 int irq = mProcessCpuTracker.getLastIrqTime();
2657 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2658 int idle = mProcessCpuTracker.getLastIdleTime();
2660 int total = user + system + iowait + irq + softIrq + idle;
2661 if (total == 0) total = 1;
2663 EventLog.writeEvent(EventLogTags.CPU,
2664 ((user+system+iowait+irq+softIrq) * 100) / total,
2665 (user * 100) / total,
2666 (system * 100) / total,
2667 (iowait * 100) / total,
2668 (irq * 100) / total,
2669 (softIrq * 100) / total);
2674 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2675 synchronized(bstats) {
2676 synchronized(mPidsSelfLocked) {
2677 if (haveNewCpuStats) {
2678 if (bstats.startAddingCpuLocked()) {
2681 final int N = mProcessCpuTracker.countStats();
2682 for (int i=0; i<N; i++) {
2683 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2687 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2688 totalUTime += st.rel_utime;
2689 totalSTime += st.rel_stime;
2691 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2692 if (ps == null || !ps.isActive()) {
2693 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2694 pr.info.uid, pr.processName);
2696 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2697 pr.curCpuTime += st.rel_utime + st.rel_stime;
2699 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2700 if (ps == null || !ps.isActive()) {
2701 st.batteryStats = ps = bstats.getProcessStatsLocked(
2702 bstats.mapUid(st.uid), st.name);
2704 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2707 final int userTime = mProcessCpuTracker.getLastUserTime();
2708 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2709 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2710 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2711 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2712 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2713 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2714 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2719 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2720 mLastWriteTime = now;
2721 mBatteryStatsService.scheduleWriteToDisk();
2728 public void batteryNeedsCpuUpdate() {
2729 updateCpuStatsNow();
2733 public void batteryPowerChanged(boolean onBattery) {
2734 // When plugging in, update the CPU stats first before changing
2736 updateCpuStatsNow();
2737 synchronized (this) {
2738 synchronized(mPidsSelfLocked) {
2739 mOnBattery = DEBUG_POWER ? true : onBattery;
2745 public void batterySendBroadcast(Intent intent) {
2746 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2747 AppOpsManager.OP_NONE, null, false, false,
2748 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2752 * Initialize the application bind args. These are passed to each
2753 * process when the bindApplication() IPC is sent to the process. They're
2754 * lazily setup to make sure the services are running when they're asked for.
2756 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2757 if (mAppBindArgs == null) {
2758 mAppBindArgs = new HashMap<>();
2760 // Isolated processes won't get this optimization, so that we don't
2761 // violate the rules about which services they have access to.
2763 // Setup the application init args
2764 mAppBindArgs.put("package", ServiceManager.getService("package"));
2765 mAppBindArgs.put("window", ServiceManager.getService("window"));
2766 mAppBindArgs.put(Context.ALARM_SERVICE,
2767 ServiceManager.getService(Context.ALARM_SERVICE));
2770 return mAppBindArgs;
2773 final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2774 if (r == null || mFocusedActivity == r) {
2778 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2779 final ActivityRecord last = mFocusedActivity;
2780 mFocusedActivity = r;
2781 if (r.task.isApplicationTask()) {
2782 if (mCurAppTimeTracker != r.appTimeTracker) {
2783 // We are switching app tracking. Complete the current one.
2784 if (mCurAppTimeTracker != null) {
2785 mCurAppTimeTracker.stop();
2786 mHandler.obtainMessage(
2787 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2788 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2789 mCurAppTimeTracker = null;
2791 if (r.appTimeTracker != null) {
2792 mCurAppTimeTracker = r.appTimeTracker;
2793 startTimeTrackingFocusedActivityLocked();
2796 startTimeTrackingFocusedActivityLocked();
2799 r.appTimeTracker = null;
2801 if (r.task.voiceInteractor != null) {
2802 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2804 finishRunningVoiceLocked();
2805 if (last != null && last.task.voiceSession != null) {
2806 // We had been in a voice interaction session, but now focused has
2807 // move to something different. Just finish the session, we can't
2808 // return to it and retain the proper state and synchronization with
2809 // the voice interaction service.
2810 finishVoiceTask(last.task.voiceSession);
2813 if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2814 mWindowManager.setFocusedApp(r.appToken, true);
2816 applyUpdateLockStateLocked(r);
2817 if (mFocusedActivity.userId != mLastFocusedUserId) {
2818 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2819 mHandler.obtainMessage(
2820 FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2821 mLastFocusedUserId = mFocusedActivity.userId;
2824 EventLogTags.writeAmFocusedActivity(
2825 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2826 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2830 final void clearFocusedActivity(ActivityRecord r) {
2831 if (mFocusedActivity == r) {
2832 ActivityStack stack = mStackSupervisor.getFocusedStack();
2833 if (stack != null) {
2834 ActivityRecord top = stack.topActivity();
2835 if (top != null && top.userId != mLastFocusedUserId) {
2836 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2837 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2839 mLastFocusedUserId = top.userId;
2842 mFocusedActivity = null;
2843 EventLogTags.writeAmFocusedActivity(-1, "NULL", "clearFocusedActivity");
2848 public void setFocusedStack(int stackId) {
2849 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2850 synchronized (ActivityManagerService.this) {
2851 ActivityStack stack = mStackSupervisor.getStack(stackId);
2852 if (stack != null) {
2853 ActivityRecord r = stack.topRunningActivityLocked();
2855 setFocusedActivityLocked(r, "setFocusedStack");
2856 mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2863 public void setFocusedTask(int taskId) {
2864 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2865 long callingId = Binder.clearCallingIdentity();
2867 synchronized (ActivityManagerService.this) {
2868 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2870 ActivityRecord r = task.topRunningActivityLocked();
2872 setFocusedActivityLocked(r, "setFocusedTask");
2873 mStackSupervisor.resumeTopActivitiesLocked(task.stack, null, null);
2878 Binder.restoreCallingIdentity(callingId);
2882 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2884 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2885 synchronized (ActivityManagerService.this) {
2886 if (listener != null) {
2887 mTaskStackListeners.register(listener);
2893 public void notifyActivityDrawn(IBinder token) {
2894 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2895 synchronized (this) {
2896 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2898 r.task.stack.notifyActivityDrawnLocked(r);
2903 final void applyUpdateLockStateLocked(ActivityRecord r) {
2904 // Modifications to the UpdateLock state are done on our handler, outside
2905 // the activity manager's locks. The new state is determined based on the
2906 // state *now* of the relevant activity record. The object is passed to
2907 // the handler solely for logging detail, not to be consulted/modified.
2908 final boolean nextState = r != null && r.immersive;
2909 mHandler.sendMessage(
2910 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2913 final void showAskCompatModeDialogLocked(ActivityRecord r) {
2914 Message msg = Message.obtain();
2915 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2916 msg.obj = r.task.askedCompatMode ? null : r;
2917 mUiHandler.sendMessage(msg);
2920 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2921 String what, Object obj, ProcessRecord srcApp) {
2922 app.lastActivityTime = now;
2924 if (app.activities.size() > 0) {
2925 // Don't want to touch dependent processes that are hosting activities.
2929 int lrui = mLruProcesses.lastIndexOf(app);
2931 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2932 + what + " " + obj + " from " + srcApp);
2936 if (lrui >= index) {
2937 // Don't want to cause this to move dependent processes *back* in the
2938 // list as if they were less frequently used.
2942 if (lrui >= mLruProcessActivityStart) {
2943 // Don't want to touch dependent processes that are hosting activities.
2947 mLruProcesses.remove(lrui);
2951 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2952 + " in LRU list: " + app);
2953 mLruProcesses.add(index, app);
2957 private static void killProcessGroup(int uid, int pid) {
2958 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2959 Process.killProcessGroup(uid, pid);
2960 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2963 final void removeLruProcessLocked(ProcessRecord app) {
2964 int lrui = mLruProcesses.lastIndexOf(app);
2967 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2968 Process.killProcessQuiet(app.pid);
2969 killProcessGroup(app.info.uid, app.pid);
2971 if (lrui <= mLruProcessActivityStart) {
2972 mLruProcessActivityStart--;
2974 if (lrui <= mLruProcessServiceStart) {
2975 mLruProcessServiceStart--;
2977 mLruProcesses.remove(lrui);
2981 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2982 ProcessRecord client) {
2983 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2984 || app.treatLikeActivity;
2985 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2986 if (!activityChange && hasActivity) {
2987 // The process has activities, so we are only allowing activity-based adjustments
2988 // to move it. It should be kept in the front of the list with other
2989 // processes that have activities, and we don't want those to change their
2990 // order except due to activity operations.
2995 final long now = SystemClock.uptimeMillis();
2996 app.lastActivityTime = now;
2998 // First a quick reject: if the app is already at the position we will
2999 // put it, then there is nothing to do.
3001 final int N = mLruProcesses.size();
3002 if (N > 0 && mLruProcesses.get(N-1) == app) {
3003 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3007 if (mLruProcessServiceStart > 0
3008 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3009 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3014 int lrui = mLruProcesses.lastIndexOf(app);
3016 if (app.persistent && lrui >= 0) {
3017 // We don't care about the position of persistent processes, as long as
3018 // they are in the list.
3019 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3023 /* In progress: compute new position first, so we can avoid doing work
3024 if the process is not actually going to move. Not yet working.
3027 boolean inActivity = false, inService = false;
3029 // Process has activities, put it at the very tipsy-top.
3030 addIndex = mLruProcesses.size();
3031 nextIndex = mLruProcessServiceStart;
3033 } else if (hasService) {
3034 // Process has services, put it at the top of the service list.
3035 addIndex = mLruProcessActivityStart;
3036 nextIndex = mLruProcessServiceStart;
3040 // Process not otherwise of interest, it goes to the top of the non-service area.
3041 addIndex = mLruProcessServiceStart;
3042 if (client != null) {
3043 int clientIndex = mLruProcesses.lastIndexOf(client);
3044 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3046 if (clientIndex >= 0 && addIndex > clientIndex) {
3047 addIndex = clientIndex;
3050 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3053 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3054 + mLruProcessActivityStart + "): " + app);
3058 if (lrui < mLruProcessActivityStart) {
3059 mLruProcessActivityStart--;
3061 if (lrui < mLruProcessServiceStart) {
3062 mLruProcessServiceStart--;
3065 if (addIndex > lrui) {
3068 if (nextIndex > lrui) {
3072 mLruProcesses.remove(lrui);
3076 mLruProcesses.add(addIndex, app);
3078 mLruProcessActivityStart++;
3081 mLruProcessActivityStart++;
3087 final int N = mLruProcesses.size();
3088 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3089 // Process doesn't have activities, but has clients with
3090 // activities... move it up, but one below the top (the top
3091 // should always have a real activity).
3092 if (DEBUG_LRU) Slog.d(TAG_LRU,
3093 "Adding to second-top of LRU activity list: " + app);
3094 mLruProcesses.add(N - 1, app);
3095 // To keep it from spamming the LRU list (by making a bunch of clients),
3096 // we will push down any other entries owned by the app.
3097 final int uid = app.info.uid;
3098 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3099 ProcessRecord subProc = mLruProcesses.get(i);
3100 if (subProc.info.uid == uid) {
3101 // We want to push this one down the list. If the process after
3102 // it is for the same uid, however, don't do so, because we don't
3103 // want them internally to be re-ordered.
3104 if (mLruProcesses.get(i - 1).info.uid != uid) {
3105 if (DEBUG_LRU) Slog.d(TAG_LRU,
3106 "Pushing uid " + uid + " swapping at " + i + ": "
3107 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3108 ProcessRecord tmp = mLruProcesses.get(i);
3109 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3110 mLruProcesses.set(i - 1, tmp);
3114 // A gap, we can stop here.
3119 // Process has activities, put it at the very tipsy-top.
3120 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3121 mLruProcesses.add(app);
3123 nextIndex = mLruProcessServiceStart;
3124 } else if (hasService) {
3125 // Process has services, put it at the top of the service list.
3126 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3127 mLruProcesses.add(mLruProcessActivityStart, app);
3128 nextIndex = mLruProcessServiceStart;
3129 mLruProcessActivityStart++;
3131 // Process not otherwise of interest, it goes to the top of the non-service area.
3132 int index = mLruProcessServiceStart;
3133 if (client != null) {
3134 // If there is a client, don't allow the process to be moved up higher
3135 // in the list than that client.
3136 int clientIndex = mLruProcesses.lastIndexOf(client);
3137 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3138 + " when updating " + app);
3139 if (clientIndex <= lrui) {
3140 // Don't allow the client index restriction to push it down farther in the
3141 // list than it already is.
3144 if (clientIndex >= 0 && index > clientIndex) {
3145 index = clientIndex;
3148 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3149 mLruProcesses.add(index, app);
3150 nextIndex = index-1;
3151 mLruProcessActivityStart++;
3152 mLruProcessServiceStart++;
3155 // If the app is currently using a content provider or service,
3156 // bump those processes as well.
3157 for (int j=app.connections.size()-1; j>=0; j--) {
3158 ConnectionRecord cr = app.connections.valueAt(j);
3159 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3160 && cr.binding.service.app != null
3161 && cr.binding.service.app.lruSeq != mLruSeq
3162 && !cr.binding.service.app.persistent) {
3163 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3164 "service connection", cr, app);
3167 for (int j=app.conProviders.size()-1; j>=0; j--) {
3168 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3169 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3170 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3171 "provider reference", cpr, app);
3176 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3177 if (uid == Process.SYSTEM_UID) {
3178 // The system gets to run in any process. If there are multiple
3179 // processes with the same uid, just pick the first (this
3180 // should never happen).
3181 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3182 if (procs == null) return null;
3183 final int procCount = procs.size();
3184 for (int i = 0; i < procCount; i++) {
3185 final int procUid = procs.keyAt(i);
3186 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3187 // Don't use an app process or different user process for system component.
3190 return procs.valueAt(i);
3193 ProcessRecord proc = mProcessNames.get(processName, uid);
3194 if (false && proc != null && !keepIfLarge
3195 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3196 && proc.lastCachedPss >= 4000) {
3197 // Turn this condition on to cause killing to happen regularly, for testing.
3198 if (proc.baseProcessTracker != null) {
3199 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3201 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3202 } else if (proc != null && !keepIfLarge
3203 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3204 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3205 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3206 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3207 if (proc.baseProcessTracker != null) {
3208 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3210 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3216 void notifyPackageUse(String packageName) {
3217 IPackageManager pm = AppGlobals.getPackageManager();
3219 pm.notifyPackageUse(packageName);
3220 } catch (RemoteException e) {
3224 boolean isNextTransitionForward() {
3225 int transit = mWindowManager.getPendingAppTransition();
3226 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3227 || transit == AppTransition.TRANSIT_TASK_OPEN
3228 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3231 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3232 String processName, String abiOverride, int uid, Runnable crashHandler) {
3233 synchronized(this) {
3234 ApplicationInfo info = new ApplicationInfo();
3235 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3236 // For isolated processes, the former contains the parent's uid and the latter the
3237 // actual uid of the isolated process.
3238 // In the special case introduced by this method (which is, starting an isolated
3239 // process directly from the SystemServer without an actual parent app process) the
3240 // closest thing to a parent's uid is SYSTEM_UID.
3241 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3242 // the |isolated| logic in the ProcessRecord constructor.
3243 info.uid = Process.SYSTEM_UID;
3244 info.processName = processName;
3245 info.className = entryPoint;
3246 info.packageName = "android";
3247 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3248 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3249 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3250 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3252 return proc != null ? proc.pid : 0;
3256 final ProcessRecord startProcessLocked(String processName,
3257 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3258 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3259 boolean isolated, boolean keepIfLarge) {
3260 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3261 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3262 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3263 null /* crashHandler */);
3266 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3267 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3268 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3269 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3270 long startTime = SystemClock.elapsedRealtime();
3273 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3274 checkTime(startTime, "startProcess: after getProcessRecord");
3276 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3277 // If we are in the background, then check to see if this process
3278 // is bad. If so, we will just silently fail.
3279 if (mBadProcesses.get(info.processName, info.uid) != null) {
3280 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3281 + "/" + info.processName);
3285 // When the user is explicitly starting a process, then clear its
3286 // crash count so that we won't make it bad until they see at
3287 // least one crash dialog again, and make the process good again
3288 // if it had been bad.
3289 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3290 + "/" + info.processName);
3291 mProcessCrashTimes.remove(info.processName, info.uid);
3292 if (mBadProcesses.get(info.processName, info.uid) != null) {
3293 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3294 UserHandle.getUserId(info.uid), info.uid,
3296 mBadProcesses.remove(info.processName, info.uid);
3303 // If this is an isolated process, it can't re-use an existing process.
3307 // app launch boost for big.little configurations
3308 // use cpusets to migrate freshly launched tasks to big cores
3309 synchronized(ActivityManagerService.this) {
3310 nativeMigrateToBoost();
3312 mBoostStartTime = SystemClock.uptimeMillis();
3313 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3314 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3317 // We don't have to do anything more if:
3318 // (1) There is an existing application record; and
3319 // (2) The caller doesn't think it is dead, OR there is no thread
3320 // object attached to it so we know it couldn't have crashed; and
3321 // (3) There is a pid assigned to it, so it is either starting or
3323 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3324 + " app=" + app + " knownToBeDead=" + knownToBeDead
3325 + " thread=" + (app != null ? app.thread : null)
3326 + " pid=" + (app != null ? app.pid : -1));
3327 if (app != null && app.pid > 0) {
3328 if (!knownToBeDead || app.thread == null) {
3329 // We already have the app running, or are waiting for it to
3330 // come up (we have a pid but not yet its thread), so keep it.
3331 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3332 // If this is a new package in the process, add the package to the list
3333 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3334 checkTime(startTime, "startProcess: done, added package to proc");
3338 // An application record is attached to a previous process,
3340 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3341 checkTime(startTime, "startProcess: bad proc running, killing");
3342 killProcessGroup(app.info.uid, app.pid);
3343 handleAppDiedLocked(app, true, true);
3344 checkTime(startTime, "startProcess: done killing old proc");
3347 String hostingNameStr = hostingName != null
3348 ? hostingName.flattenToShortString() : null;
3351 checkTime(startTime, "startProcess: creating new process record");
3352 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3354 Slog.w(TAG, "Failed making new process record for "
3355 + processName + "/" + info.uid + " isolated=" + isolated);
3358 app.crashHandler = crashHandler;
3359 checkTime(startTime, "startProcess: done creating new process record");
3361 // If this is a new package in the process, add the package to the list
3362 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3363 checkTime(startTime, "startProcess: added package to existing proc");
3366 // If the system is not ready yet, then hold off on starting this
3367 // process until it is.
3368 if (!mProcessesReady
3369 && !isAllowedWhileBooting(info)
3370 && !allowWhileBooting) {
3371 if (!mProcessesOnHold.contains(app)) {
3372 mProcessesOnHold.add(app);
3374 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3375 "System not ready, putting on hold: " + app);
3376 checkTime(startTime, "startProcess: returning with proc on hold");
3380 checkTime(startTime, "startProcess: stepping in to startProcess");
3382 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3383 checkTime(startTime, "startProcess: done starting proc!");
3384 return (app.pid != 0) ? app : null;
3387 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3388 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3391 private final void startProcessLocked(ProcessRecord app,
3392 String hostingType, String hostingNameStr) {
3393 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3394 null /* entryPoint */, null /* entryPointArgs */);
3397 private final void startProcessLocked(ProcessRecord app, String hostingType,
3398 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3399 long startTime = SystemClock.elapsedRealtime();
3400 if (app.pid > 0 && app.pid != MY_PID) {
3401 checkTime(startTime, "startProcess: removing from pids map");
3402 synchronized (mPidsSelfLocked) {
3403 mPidsSelfLocked.remove(app.pid);
3404 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3406 checkTime(startTime, "startProcess: done removing from pids map");
3410 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3411 "startProcessLocked removing on hold: " + app);
3412 mProcessesOnHold.remove(app);
3414 checkTime(startTime, "startProcess: starting to update cpu stats");
3416 checkTime(startTime, "startProcess: done updating cpu stats");
3420 final int userId = UserHandle.getUserId(app.uid);
3421 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3422 } catch (RemoteException e) {
3423 throw e.rethrowAsRuntimeException();
3428 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3429 if (!app.isolated) {
3430 int[] permGids = null;
3432 checkTime(startTime, "startProcess: getting gids from package manager");
3433 final IPackageManager pm = AppGlobals.getPackageManager();
3434 permGids = pm.getPackageGids(app.info.packageName, app.userId);
3435 MountServiceInternal mountServiceInternal = LocalServices.getService(
3436 MountServiceInternal.class);
3437 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3438 app.info.packageName);
3439 } catch (RemoteException e) {
3440 throw e.rethrowAsRuntimeException();
3444 * Add shared application and profile GIDs so applications can share some
3445 * resources like shared libraries and access user-wide resources
3447 if (ArrayUtils.isEmpty(permGids)) {
3450 gids = new int[permGids.length + 2];
3451 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3453 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3454 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3456 checkTime(startTime, "startProcess: building args");
3457 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3458 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3459 && mTopComponent != null
3460 && app.processName.equals(mTopComponent.getPackageName())) {
3463 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3464 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3469 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3470 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3471 // Also turn on CheckJNI for debuggable apps. It's quite
3472 // awkward to turn on otherwise.
3473 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3475 // Run the app in safe mode if its manifest requests so or the
3476 // system is booted in safe mode.
3477 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3478 mSafeMode == true) {
3479 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3481 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3482 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3484 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3485 if ("true".equals(genDebugInfoProperty)) {
3486 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3488 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3489 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3491 if ("1".equals(SystemProperties.get("debug.assert"))) {
3492 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3495 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3496 if (requiredAbi == null) {
3497 requiredAbi = Build.SUPPORTED_ABIS[0];
3500 String instructionSet = null;
3501 if (app.info.primaryCpuAbi != null) {
3502 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3506 app.requiredAbi = requiredAbi;
3507 app.instructionSet = instructionSet;
3509 // Start the process. It will either succeed and return a result containing
3510 // the PID of the new process, or else throw a RuntimeException.
3511 boolean isActivityProcess = (entryPoint == null);
3512 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3513 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3515 checkTime(startTime, "startProcess: asking zygote to start proc");
3516 Process.ProcessStartResult startResult = Process.start(entryPoint,
3517 app.processName, uid, uid, gids, debugFlags, mountExternal,
3518 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3519 app.info.dataDir, entryPointArgs);
3520 checkTime(startTime, "startProcess: returned from zygote!");
3521 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3524 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3526 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3527 checkTime(startTime, "startProcess: done updating battery stats");
3529 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3530 UserHandle.getUserId(uid), startResult.pid, uid,
3531 app.processName, hostingType,
3532 hostingNameStr != null ? hostingNameStr : "");
3534 if (app.persistent) {
3535 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3538 checkTime(startTime, "startProcess: building log message");
3539 StringBuilder buf = mStringBuilder;
3541 buf.append("Start proc ");
3542 buf.append(startResult.pid);
3544 buf.append(app.processName);
3546 UserHandle.formatUid(buf, uid);
3547 if (!isActivityProcess) {
3549 buf.append(entryPoint);
3552 buf.append(" for ");
3553 buf.append(hostingType);
3554 if (hostingNameStr != null) {
3556 buf.append(hostingNameStr);
3558 Slog.i(TAG, buf.toString());
3559 app.setPid(startResult.pid);
3560 app.usingWrapper = startResult.usingWrapper;
3561 app.removed = false;
3563 app.killedByAm = false;
3564 checkTime(startTime, "startProcess: starting to update pids map");
3565 synchronized (mPidsSelfLocked) {
3566 this.mPidsSelfLocked.put(startResult.pid, app);
3567 if (isActivityProcess) {
3568 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3570 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3571 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3574 checkTime(startTime, "startProcess: done updating pids map");
3575 } catch (RuntimeException e) {
3576 // XXX do better error recovery.
3578 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3580 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3582 Slog.e(TAG, "Failure starting process " + app.processName, e);
3586 void updateUsageStats(ActivityRecord component, boolean resumed) {
3587 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3588 "updateUsageStats: comp=" + component + "res=" + resumed);
3589 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3591 if (mUsageStatsService != null) {
3592 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3593 UsageEvents.Event.MOVE_TO_FOREGROUND);
3595 synchronized (stats) {
3596 stats.noteActivityResumedLocked(component.app.uid);
3599 if (mUsageStatsService != null) {
3600 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3601 UsageEvents.Event.MOVE_TO_BACKGROUND);
3603 synchronized (stats) {
3604 stats.noteActivityPausedLocked(component.app.uid);
3609 Intent getHomeIntent() {
3610 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3611 intent.setComponent(mTopComponent);
3612 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3613 intent.addCategory(Intent.CATEGORY_HOME);
3618 boolean startHomeActivityLocked(int userId, String reason) {
3619 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3620 && mTopAction == null) {
3621 // We are running in factory test mode, but unable to find
3622 // the factory test app, so just sit around displaying the
3623 // error message and don't try to start anything.
3626 Intent intent = getHomeIntent();
3627 ActivityInfo aInfo =
3628 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3629 if (aInfo != null) {
3630 intent.setComponent(new ComponentName(
3631 aInfo.applicationInfo.packageName, aInfo.name));
3632 // Don't do this if the home app is currently being
3634 aInfo = new ActivityInfo(aInfo);
3635 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3636 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3637 aInfo.applicationInfo.uid, true);
3638 if (app == null || app.instrumentationClass == null) {
3639 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3640 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3647 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3648 ActivityInfo ai = null;
3649 ComponentName comp = intent.getComponent();
3653 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3655 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3657 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3661 ai = info.activityInfo;
3664 } catch (RemoteException e) {
3672 * Starts the "new version setup screen" if appropriate.
3674 void startSetupActivityLocked() {
3675 // Only do this once per boot.
3676 if (mCheckedForSetup) {
3680 // We will show this screen if the current one is a different
3681 // version than the last one shown, and we are not running in
3682 // low-level factory test mode.
3683 final ContentResolver resolver = mContext.getContentResolver();
3684 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3685 Settings.Global.getInt(resolver,
3686 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3687 mCheckedForSetup = true;
3689 // See if we should be showing the platform update setup UI.
3690 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3691 List<ResolveInfo> ris = mContext.getPackageManager()
3692 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3694 // We don't allow third party apps to replace this.
3695 ResolveInfo ri = null;
3696 for (int i=0; ris != null && i<ris.size(); i++) {
3697 if ((ris.get(i).activityInfo.applicationInfo.flags
3698 & ApplicationInfo.FLAG_SYSTEM) != 0) {
3705 String vers = ri.activityInfo.metaData != null
3706 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3708 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3709 vers = ri.activityInfo.applicationInfo.metaData.getString(
3710 Intent.METADATA_SETUP_VERSION);
3712 String lastVers = Settings.Secure.getString(
3713 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3714 if (vers != null && !vers.equals(lastVers)) {
3715 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3716 intent.setComponent(new ComponentName(
3717 ri.activityInfo.packageName, ri.activityInfo.name));
3718 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3719 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3726 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3727 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3730 void enforceNotIsolatedCaller(String caller) {
3731 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3732 throw new SecurityException("Isolated process not allowed to call " + caller);
3736 void enforceShellRestriction(String restriction, int userHandle) {
3737 if (Binder.getCallingUid() == Process.SHELL_UID) {
3738 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3739 throw new SecurityException("Shell does not have permission to access user "
3746 public int getFrontActivityScreenCompatMode() {
3747 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3748 synchronized (this) {
3749 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3754 public void setFrontActivityScreenCompatMode(int mode) {
3755 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3756 "setFrontActivityScreenCompatMode");
3757 synchronized (this) {
3758 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3763 public int getPackageScreenCompatMode(String packageName) {
3764 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3765 synchronized (this) {
3766 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3771 public void setPackageScreenCompatMode(String packageName, int mode) {
3772 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3773 "setPackageScreenCompatMode");
3774 synchronized (this) {
3775 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3780 public boolean getPackageAskScreenCompat(String packageName) {
3781 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3782 synchronized (this) {
3783 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3788 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3789 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3790 "setPackageAskScreenCompat");
3791 synchronized (this) {
3792 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3796 private boolean hasUsageStatsPermission(String callingPackage) {
3797 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3798 Binder.getCallingUid(), callingPackage);
3799 if (mode == AppOpsManager.MODE_DEFAULT) {
3800 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3801 == PackageManager.PERMISSION_GRANTED;
3803 return mode == AppOpsManager.MODE_ALLOWED;
3807 public int getPackageProcessState(String packageName, String callingPackage) {
3808 if (!hasUsageStatsPermission(callingPackage)) {
3809 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3810 "getPackageProcessState");
3813 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3814 synchronized (this) {
3815 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3816 final ProcessRecord proc = mLruProcesses.get(i);
3817 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3818 || procState > proc.setProcState) {
3819 boolean found = false;
3820 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3821 if (proc.pkgList.keyAt(j).equals(packageName)) {
3822 procState = proc.setProcState;
3826 if (proc.pkgDeps != null && !found) {
3827 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3828 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3829 procState = proc.setProcState;
3841 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3842 synchronized (this) {
3843 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3847 if (app.trimMemoryLevel < level && app.thread != null &&
3848 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3849 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3851 app.thread.scheduleTrimMemory(level);
3852 app.trimMemoryLevel = level;
3854 } catch (RemoteException e) {
3855 // Fallthrough to failure case.
3862 private void dispatchProcessesChanged() {
3864 synchronized (this) {
3865 N = mPendingProcessChanges.size();
3866 if (mActiveProcessChanges.length < N) {
3867 mActiveProcessChanges = new ProcessChangeItem[N];
3869 mPendingProcessChanges.toArray(mActiveProcessChanges);
3870 mPendingProcessChanges.clear();
3871 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3872 "*** Delivering " + N + " process changes");
3875 int i = mProcessObservers.beginBroadcast();
3878 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3879 if (observer != null) {
3881 for (int j=0; j<N; j++) {
3882 ProcessChangeItem item = mActiveProcessChanges[j];
3883 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3884 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3885 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3886 + item.uid + ": " + item.foregroundActivities);
3887 observer.onForegroundActivitiesChanged(item.pid, item.uid,
3888 item.foregroundActivities);
3890 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3891 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3892 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3893 + ": " + item.processState);
3894 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3897 } catch (RemoteException e) {
3901 mProcessObservers.finishBroadcast();
3903 synchronized (this) {
3904 for (int j=0; j<N; j++) {
3905 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3910 private void dispatchProcessDied(int pid, int uid) {
3911 int i = mProcessObservers.beginBroadcast();
3914 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3915 if (observer != null) {
3917 observer.onProcessDied(pid, uid);
3918 } catch (RemoteException e) {
3922 mProcessObservers.finishBroadcast();
3925 private void dispatchUidsChanged() {
3927 synchronized (this) {
3928 N = mPendingUidChanges.size();
3929 if (mActiveUidChanges.length < N) {
3930 mActiveUidChanges = new UidRecord.ChangeItem[N];
3932 for (int i=0; i<N; i++) {
3933 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3934 mActiveUidChanges[i] = change;
3935 if (change.uidRecord != null) {
3936 change.uidRecord.pendingChange = null;
3937 change.uidRecord = null;
3940 mPendingUidChanges.clear();
3941 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3942 "*** Delivering " + N + " uid changes");
3945 if (mLocalPowerManager != null) {
3946 for (int j=0; j<N; j++) {
3947 UidRecord.ChangeItem item = mActiveUidChanges[j];
3948 if (item.change == UidRecord.CHANGE_GONE
3949 || item.change == UidRecord.CHANGE_GONE_IDLE) {
3950 mLocalPowerManager.uidGone(item.uid);
3952 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3957 int i = mUidObservers.beginBroadcast();
3960 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3961 final int which = (Integer)mUidObservers.getBroadcastCookie(i);
3962 if (observer != null) {
3964 for (int j=0; j<N; j++) {
3965 UidRecord.ChangeItem item = mActiveUidChanges[j];
3966 final int change = item.change;
3967 UidRecord validateUid = null;
3968 if (VALIDATE_UID_STATES && i == 0) {
3969 validateUid = mValidateUids.get(item.uid);
3970 if (validateUid == null && change != UidRecord.CHANGE_GONE
3971 && change != UidRecord.CHANGE_GONE_IDLE) {
3972 validateUid = new UidRecord(item.uid);
3973 mValidateUids.put(item.uid, validateUid);
3976 if (change == UidRecord.CHANGE_IDLE
3977 || change == UidRecord.CHANGE_GONE_IDLE) {
3978 if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
3979 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3980 "UID idle uid=" + item.uid);
3981 observer.onUidIdle(item.uid);
3983 if (VALIDATE_UID_STATES && i == 0) {
3984 if (validateUid != null) {
3985 validateUid.idle = true;
3988 } else if (change == UidRecord.CHANGE_ACTIVE) {
3989 if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
3990 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3991 "UID active uid=" + item.uid);
3992 observer.onUidActive(item.uid);
3994 if (VALIDATE_UID_STATES && i == 0) {
3995 validateUid.idle = false;
3998 if (change == UidRecord.CHANGE_GONE
3999 || change == UidRecord.CHANGE_GONE_IDLE) {
4000 if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4001 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4002 "UID gone uid=" + item.uid);
4003 observer.onUidGone(item.uid);
4005 if (VALIDATE_UID_STATES && i == 0) {
4006 if (validateUid != null) {
4007 mValidateUids.remove(item.uid);
4011 if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4012 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4013 "UID CHANGED uid=" + item.uid
4014 + ": " + item.processState);
4015 observer.onUidStateChanged(item.uid, item.processState);
4017 if (VALIDATE_UID_STATES && i == 0) {
4018 validateUid.curProcState = validateUid.setProcState
4019 = item.processState;
4023 } catch (RemoteException e) {
4027 mUidObservers.finishBroadcast();
4029 synchronized (this) {
4030 for (int j=0; j<N; j++) {
4031 mAvailUidChanges.add(mActiveUidChanges[j]);
4037 public final int startActivity(IApplicationThread caller, String callingPackage,
4038 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4039 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4040 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4041 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4042 UserHandle.getCallingUserId());
4046 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4047 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4048 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4049 enforceNotIsolatedCaller("startActivity");
4050 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4051 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4052 // TODO: Switch to user app stacks here.
4053 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
4054 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4055 profilerInfo, null, null, bOptions, false, userId, null, null);
4059 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4060 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4061 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4064 // This is very dangerous -- it allows you to perform a start activity (including
4065 // permission grants) as any app that may launch one of your own activities. So
4066 // we will only allow this to be done from activities that are part of the core framework,
4067 // and then only when they are running as the system.
4068 final ActivityRecord sourceRecord;
4069 final int targetUid;
4070 final String targetPackage;
4071 synchronized (this) {
4072 if (resultTo == null) {
4073 throw new SecurityException("Must be called from an activity");
4075 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4076 if (sourceRecord == null) {
4077 throw new SecurityException("Called with bad activity token: " + resultTo);
4079 if (!sourceRecord.info.packageName.equals("android")) {
4080 throw new SecurityException(
4081 "Must be called from an activity that is declared in the android package");
4083 if (sourceRecord.app == null) {
4084 throw new SecurityException("Called without a process attached to activity");
4086 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4087 // This is still okay, as long as this activity is running under the
4088 // uid of the original calling activity.
4089 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4090 throw new SecurityException(
4091 "Calling activity in uid " + sourceRecord.app.uid
4092 + " must be system uid or original calling uid "
4093 + sourceRecord.launchedFromUid);
4096 if (ignoreTargetSecurity) {
4097 if (intent.getComponent() == null) {
4098 throw new SecurityException(
4099 "Component must be specified with ignoreTargetSecurity");
4101 if (intent.getSelector() != null) {
4102 throw new SecurityException(
4103 "Selector not allowed with ignoreTargetSecurity");
4106 targetUid = sourceRecord.launchedFromUid;
4107 targetPackage = sourceRecord.launchedFromPackage;
4110 if (userId == UserHandle.USER_NULL) {
4111 userId = UserHandle.getUserId(sourceRecord.app.uid);
4114 // TODO: Switch to user app stacks here.
4116 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
4117 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4118 null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4120 } catch (SecurityException e) {
4121 // XXX need to figure out how to propagate to original app.
4122 // A SecurityException here is generally actually a fault of the original
4123 // calling activity (such as a fairly granting permissions), so propagate it
4126 StringBuilder msg = new StringBuilder();
4127 msg.append("While launching");
4128 msg.append(intent.toString());
4130 msg.append(e.getMessage());
4137 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4138 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4139 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4140 enforceNotIsolatedCaller("startActivityAndWait");
4141 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4142 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4143 WaitResult res = new WaitResult();
4144 // TODO: Switch to user app stacks here.
4145 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4146 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4147 bOptions, false, userId, null, null);
4152 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4153 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4154 int startFlags, Configuration config, Bundle bOptions, int userId) {
4155 enforceNotIsolatedCaller("startActivityWithConfig");
4156 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4157 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4158 // TODO: Switch to user app stacks here.
4159 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
4160 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4161 null, null, config, bOptions, false, userId, null, null);
4166 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4167 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4168 int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4169 throws TransactionTooLargeException {
4170 enforceNotIsolatedCaller("startActivityIntentSender");
4171 // Refuse possible leaked file descriptors
4172 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4173 throw new IllegalArgumentException("File descriptors passed in Intent");
4176 IIntentSender sender = intent.getTarget();
4177 if (!(sender instanceof PendingIntentRecord)) {
4178 throw new IllegalArgumentException("Bad PendingIntent object");
4181 PendingIntentRecord pir = (PendingIntentRecord)sender;
4183 synchronized (this) {
4184 // If this is coming from the currently resumed activity, it is
4185 // effectively saying that app switches are allowed at this point.
4186 final ActivityStack stack = getFocusedStack();
4187 if (stack.mResumedActivity != null &&
4188 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4189 mAppSwitchesAllowedTime = 0;
4192 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4193 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4198 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4199 Intent intent, String resolvedType, IVoiceInteractionSession session,
4200 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4201 Bundle bOptions, int userId) {
4202 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4203 != PackageManager.PERMISSION_GRANTED) {
4204 String msg = "Permission Denial: startVoiceActivity() from pid="
4205 + Binder.getCallingPid()
4206 + ", uid=" + Binder.getCallingUid()
4207 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4209 throw new SecurityException(msg);
4211 if (session == null || interactor == null) {
4212 throw new NullPointerException("null session or interactor");
4214 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4215 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4216 // TODO: Switch to user app stacks here.
4217 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4218 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4219 null, bOptions, false, userId, null, null);
4223 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4224 synchronized (this) {
4225 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4227 mVoiceWakeLock.acquire();
4229 mVoiceWakeLock.release();
4236 public boolean startNextMatchingActivity(IBinder callingActivity,
4237 Intent intent, Bundle bOptions) {
4238 // Refuse possible leaked file descriptors
4239 if (intent != null && intent.hasFileDescriptors() == true) {
4240 throw new IllegalArgumentException("File descriptors passed in Intent");
4242 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4244 synchronized (this) {
4245 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4247 ActivityOptions.abort(options);
4250 if (r.app == null || r.app.thread == null) {
4251 // The caller is not running... d'oh!
4252 ActivityOptions.abort(options);
4255 intent = new Intent(intent);
4256 // The caller is not allowed to change the data.
4257 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4258 // And we are resetting to find the next component...
4259 intent.setComponent(null);
4261 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4263 ActivityInfo aInfo = null;
4265 List<ResolveInfo> resolves =
4266 AppGlobals.getPackageManager().queryIntentActivities(
4267 intent, r.resolvedType,
4268 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4269 UserHandle.getCallingUserId());
4271 // Look for the original activity in the list...
4272 final int N = resolves != null ? resolves.size() : 0;
4273 for (int i=0; i<N; i++) {
4274 ResolveInfo rInfo = resolves.get(i);
4275 if (rInfo.activityInfo.packageName.equals(r.packageName)
4276 && rInfo.activityInfo.name.equals(r.info.name)) {
4277 // We found the current one... the next matching is
4281 aInfo = resolves.get(i).activityInfo;
4284 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4285 + "/" + r.info.name);
4286 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4287 ? "null" : aInfo.packageName + "/" + aInfo.name));
4292 } catch (RemoteException e) {
4295 if (aInfo == null) {
4296 // Nobody who is next!
4297 ActivityOptions.abort(options);
4298 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4302 intent.setComponent(new ComponentName(
4303 aInfo.applicationInfo.packageName, aInfo.name));
4304 intent.setFlags(intent.getFlags()&~(
4305 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4306 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4307 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4308 Intent.FLAG_ACTIVITY_NEW_TASK));
4310 // Okay now we need to start the new activity, replacing the
4311 // currently running activity. This is a little tricky because
4312 // we want to start the new one as if the current one is finished,
4313 // but not finish the current one first so that there is no flicker.
4315 final boolean wasFinishing = r.finishing;
4318 // Propagate reply information over to the new activity.
4319 final ActivityRecord resultTo = r.resultTo;
4320 final String resultWho = r.resultWho;
4321 final int requestCode = r.requestCode;
4323 if (resultTo != null) {
4324 resultTo.removeResultsLocked(r, resultWho, requestCode);
4327 final long origId = Binder.clearCallingIdentity();
4328 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4329 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4330 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4331 -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4332 Binder.restoreCallingIdentity(origId);
4334 r.finishing = wasFinishing;
4335 if (res != ActivityManager.START_SUCCESS) {
4343 public final int startActivityFromRecents(int taskId, int launchStackId, Bundle bOptions) {
4344 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4345 String msg = "Permission Denial: startActivityFromRecents called without " +
4346 START_TASKS_FROM_RECENTS;
4348 throw new SecurityException(msg);
4350 final long origId = Binder.clearCallingIdentity();
4352 return startActivityFromRecentsInner(taskId, launchStackId, bOptions);
4354 Binder.restoreCallingIdentity(origId);
4358 final int startActivityFromRecentsInner(int taskId, int launchStackId, Bundle bOptions) {
4359 final TaskRecord task;
4360 final int callingUid;
4361 final String callingPackage;
4362 final Intent intent;
4364 synchronized (this) {
4365 if (launchStackId == HOME_STACK_ID) {
4366 throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4367 + taskId + " can't be launch in the home stack.");
4370 task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4372 throw new IllegalArgumentException(
4373 "startActivityFromRecentsInner: Task " + taskId + " not found.");
4376 if (launchStackId != INVALID_STACK_ID) {
4377 if (launchStackId == DOCKED_STACK_ID && bOptions != null) {
4378 ActivityOptions activityOptions = new ActivityOptions(bOptions);
4379 mWindowManager.setDockedStackCreateState(activityOptions.getDockCreateMode(),
4380 null /* initialBounds */);
4382 if (task.stack.mStackId != launchStackId) {
4383 mStackSupervisor.moveTaskToStackLocked(
4384 taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4385 true /* animate */);
4389 if (task.getRootActivity() != null) {
4390 moveTaskToFrontLocked(task.taskId, 0, bOptions);
4391 return ActivityManager.START_TASK_TO_FRONT;
4393 callingUid = task.mCallingUid;
4394 callingPackage = task.mCallingPackage;
4395 intent = task.intent;
4396 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4397 userId = task.userId;
4399 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4400 bOptions, userId, null, task);
4403 final int startActivityInPackage(int uid, String callingPackage,
4404 Intent intent, String resolvedType, IBinder resultTo,
4405 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4406 IActivityContainer container, TaskRecord inTask) {
4408 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4409 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4411 // TODO: Switch to user app stacks here.
4412 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4413 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4414 null, null, null, bOptions, false, userId, container, inTask);
4419 public final int startActivities(IApplicationThread caller, String callingPackage,
4420 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4422 enforceNotIsolatedCaller("startActivities");
4423 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4424 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4425 // TODO: Switch to user app stacks here.
4426 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4427 resolvedTypes, resultTo, bOptions, userId);
4431 final int startActivitiesInPackage(int uid, String callingPackage,
4432 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4433 Bundle bOptions, int userId) {
4435 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4436 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4437 // TODO: Switch to user app stacks here.
4438 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4439 resultTo, bOptions, userId);
4444 public void reportActivityFullyDrawn(IBinder token) {
4445 synchronized (this) {
4446 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4450 r.reportFullyDrawnLocked();
4455 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4456 synchronized (this) {
4457 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4461 TaskRecord task = r.task;
4462 if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4463 // Fixed screen orientation isn't supported when activities aren't in full screen
4467 final long origId = Binder.clearCallingIdentity();
4468 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4469 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4470 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4471 if (config != null) {
4472 r.frozenBeforeDestroy = true;
4473 if (!updateConfigurationLocked(config, r, false)) {
4474 mStackSupervisor.resumeTopActivitiesLocked();
4477 Binder.restoreCallingIdentity(origId);
4482 public int getRequestedOrientation(IBinder token) {
4483 synchronized (this) {
4484 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4486 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4488 return mWindowManager.getAppOrientation(r.appToken);
4493 * This is the internal entry point for handling Activity.finish().
4495 * @param token The Binder token referencing the Activity we want to finish.
4496 * @param resultCode Result code, if any, from this Activity.
4497 * @param resultData Result data (Intent), if any, from this Activity.
4498 * @param finishTask Whether to finish the task associated with this Activity.
4500 * @return Returns true if the activity successfully finished, or false if it is still running.
4503 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4505 // Refuse possible leaked file descriptors
4506 if (resultData != null && resultData.hasFileDescriptors() == true) {
4507 throw new IllegalArgumentException("File descriptors passed in Intent");
4510 synchronized(this) {
4511 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4515 // Keep track of the root activity of the task before we finish it
4516 TaskRecord tr = r.task;
4517 ActivityRecord rootR = tr.getRootActivity();
4518 if (rootR == null) {
4519 Slog.w(TAG, "Finishing task with all activities already finished");
4521 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4523 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4524 mStackSupervisor.isLastLockedTask(tr)) {
4525 Slog.i(TAG, "Not finishing task in lock task mode");
4526 mStackSupervisor.showLockTaskToast();
4529 if (mController != null) {
4530 // Find the first activity that is not finishing.
4531 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4533 // ask watcher if this is allowed
4534 boolean resumeOK = true;
4536 resumeOK = mController.activityResuming(next.packageName);
4537 } catch (RemoteException e) {
4539 Watchdog.getInstance().setActivityController(null);
4543 Slog.i(TAG, "Not finishing activity because controller resumed");
4548 final long origId = Binder.clearCallingIdentity();
4551 final boolean finishWithRootActivity =
4552 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4553 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4554 || (finishWithRootActivity && r == rootR)) {
4555 // If requested, remove the task that is associated to this activity only if it
4556 // was the root activity in the task. The result code and data is ignored
4557 // because we don't support returning them across task boundaries. Also, to
4558 // keep backwards compatibility we remove the task from recents when finishing
4559 // task with root activity.
4560 res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4562 Slog.i(TAG, "Removing task failed to finish activity");
4565 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4566 resultData, "app-request", true);
4568 Slog.i(TAG, "Failed to finish by app-request");
4573 Binder.restoreCallingIdentity(origId);
4579 public final void finishHeavyWeightApp() {
4580 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4581 != PackageManager.PERMISSION_GRANTED) {
4582 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4583 + Binder.getCallingPid()
4584 + ", uid=" + Binder.getCallingUid()
4585 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4587 throw new SecurityException(msg);
4590 synchronized(this) {
4591 if (mHeavyWeightProcess == null) {
4595 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4596 for (int i = 0; i < activities.size(); i++) {
4597 ActivityRecord r = activities.get(i);
4598 if (!r.finishing && r.isInStackLocked()) {
4599 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4600 null, "finish-heavy", true);
4604 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4605 mHeavyWeightProcess.userId, 0));
4606 mHeavyWeightProcess = null;
4611 public void crashApplication(int uid, int initialPid, String packageName,
4613 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4614 != PackageManager.PERMISSION_GRANTED) {
4615 String msg = "Permission Denial: crashApplication() from pid="
4616 + Binder.getCallingPid()
4617 + ", uid=" + Binder.getCallingUid()
4618 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4620 throw new SecurityException(msg);
4623 synchronized(this) {
4624 ProcessRecord proc = null;
4626 // Figure out which process to kill. We don't trust that initialPid
4627 // still has any relation to current pids, so must scan through the
4629 synchronized (mPidsSelfLocked) {
4630 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4631 ProcessRecord p = mPidsSelfLocked.valueAt(i);
4635 if (p.pid == initialPid) {
4639 if (p.pkgList.containsKey(packageName)) {
4646 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4647 + " initialPid=" + initialPid
4648 + " packageName=" + packageName);
4652 if (proc.thread != null) {
4653 if (proc.pid == Process.myPid()) {
4654 Log.w(TAG, "crashApplication: trying to crash self!");
4657 long ident = Binder.clearCallingIdentity();
4659 proc.thread.scheduleCrash(message);
4660 } catch (RemoteException e) {
4662 Binder.restoreCallingIdentity(ident);
4668 public final void finishSubActivity(IBinder token, String resultWho,
4670 synchronized(this) {
4671 final long origId = Binder.clearCallingIdentity();
4672 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4674 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4676 Binder.restoreCallingIdentity(origId);
4681 public boolean finishActivityAffinity(IBinder token) {
4682 synchronized(this) {
4683 final long origId = Binder.clearCallingIdentity();
4685 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4690 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4692 final TaskRecord task = r.task;
4693 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4694 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4695 mStackSupervisor.showLockTaskToast();
4698 return task.stack.finishActivityAffinityLocked(r);
4700 Binder.restoreCallingIdentity(origId);
4706 public void finishVoiceTask(IVoiceInteractionSession session) {
4707 synchronized(this) {
4708 final long origId = Binder.clearCallingIdentity();
4710 mStackSupervisor.finishVoiceTask(session);
4712 Binder.restoreCallingIdentity(origId);
4719 public boolean releaseActivityInstance(IBinder token) {
4720 synchronized(this) {
4721 final long origId = Binder.clearCallingIdentity();
4723 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4727 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4729 Binder.restoreCallingIdentity(origId);
4735 public void releaseSomeActivities(IApplicationThread appInt) {
4736 synchronized(this) {
4737 final long origId = Binder.clearCallingIdentity();
4739 ProcessRecord app = getRecordForAppLocked(appInt);
4740 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4742 Binder.restoreCallingIdentity(origId);
4748 public boolean willActivityBeVisible(IBinder token) {
4749 synchronized(this) {
4750 ActivityStack stack = ActivityRecord.getStackLocked(token);
4751 if (stack != null) {
4752 return stack.willActivityBeVisibleLocked(token);
4759 public void overridePendingTransition(IBinder token, String packageName,
4760 int enterAnim, int exitAnim) {
4761 synchronized(this) {
4762 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4767 final long origId = Binder.clearCallingIdentity();
4769 if (self.state == ActivityState.RESUMED
4770 || self.state == ActivityState.PAUSING) {
4771 mWindowManager.overridePendingAppTransition(packageName,
4772 enterAnim, exitAnim, null);
4775 Binder.restoreCallingIdentity(origId);
4780 * Main function for removing an existing process from the activity manager
4781 * as a result of that process going away. Clears out all connections
4784 private final void handleAppDiedLocked(ProcessRecord app,
4785 boolean restarting, boolean allowRestart) {
4787 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4788 if (!kept && !restarting) {
4789 removeLruProcessLocked(app);
4791 ProcessList.remove(pid);
4795 if (mProfileProc == app) {
4796 clearProfilerLocked();
4799 // Remove this application's activities from active lists.
4800 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4802 app.activities.clear();
4804 if (app.instrumentationClass != null) {
4805 Slog.w(TAG, "Crash of app " + app.processName
4806 + " running instrumentation " + app.instrumentationClass);
4807 Bundle info = new Bundle();
4808 info.putString("shortMsg", "Process crashed.");
4809 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4812 if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4813 // If there was nothing to resume, and we are not already
4814 // restarting this process, but there is a visible activity that
4815 // is hosted by the process... then make sure all visible
4816 // activities are running, taking care of restarting this
4818 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4822 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4823 IBinder threadBinder = thread.asBinder();
4824 // Find the application record.
4825 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4826 ProcessRecord rec = mLruProcesses.get(i);
4827 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4834 final ProcessRecord getRecordForAppLocked(
4835 IApplicationThread thread) {
4836 if (thread == null) {
4840 int appIndex = getLRURecordIndexForAppLocked(thread);
4841 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4844 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4845 // If there are no longer any background processes running,
4846 // and the app that died was not running instrumentation,
4847 // then tell everyone we are now low on memory.
4848 boolean haveBg = false;
4849 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4850 ProcessRecord rec = mLruProcesses.get(i);
4851 if (rec.thread != null
4852 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4859 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4861 long now = SystemClock.uptimeMillis();
4862 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4865 mLastMemUsageReportTime = now;
4868 final ArrayList<ProcessMemInfo> memInfos
4869 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4870 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4871 long now = SystemClock.uptimeMillis();
4872 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4873 ProcessRecord rec = mLruProcesses.get(i);
4874 if (rec == dyingProc || rec.thread == null) {
4878 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4879 rec.setProcState, rec.adjType, rec.makeAdjReason()));
4881 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4882 // The low memory report is overriding any current
4883 // state for a GC request. Make sure to do
4884 // heavy/important/visible/foreground processes first.
4885 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4886 rec.lastRequestedGc = 0;
4888 rec.lastRequestedGc = rec.lastLowMemory;
4890 rec.reportLowMemory = true;
4891 rec.lastLowMemory = now;
4892 mProcessesToGc.remove(rec);
4893 addProcessToGcListLocked(rec);
4897 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4898 mHandler.sendMessage(msg);
4900 scheduleAppGcsLocked();
4904 final void appDiedLocked(ProcessRecord app) {
4905 appDiedLocked(app, app.pid, app.thread, false);
4908 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4909 boolean fromBinderDied) {
4910 // First check if this ProcessRecord is actually active for the pid.
4911 synchronized (mPidsSelfLocked) {
4912 ProcessRecord curProc = mPidsSelfLocked.get(pid);
4913 if (curProc != app) {
4914 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4919 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4920 synchronized (stats) {
4921 stats.noteProcessDiedLocked(app.info.uid, pid);
4925 if (!fromBinderDied) {
4926 Process.killProcessQuiet(pid);
4928 killProcessGroup(app.info.uid, pid);
4932 // Clean up already done if the process has been re-started.
4933 if (app.pid == pid && app.thread != null &&
4934 app.thread.asBinder() == thread.asBinder()) {
4935 boolean doLowMem = app.instrumentationClass == null;
4936 boolean doOomAdj = doLowMem;
4937 if (!app.killedByAm) {
4938 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4940 mAllowLowerMemLevel = true;
4942 // Note that we always want to do oom adj to update our state with the
4943 // new number of procs.
4944 mAllowLowerMemLevel = false;
4947 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4948 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4949 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4950 handleAppDiedLocked(app, false, true);
4953 updateOomAdjLocked();
4956 doLowMemReportIfNeededLocked(app);
4958 } else if (app.pid != pid) {
4959 // A new process has already been started.
4960 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4961 + ") has died and restarted (pid " + app.pid + ").");
4962 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4963 } else if (DEBUG_PROCESSES) {
4964 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4965 + thread.asBinder());
4970 * If a stack trace dump file is configured, dump process stack traces.
4971 * @param clearTraces causes the dump file to be erased prior to the new
4972 * traces being written, if true; when false, the new traces will be
4973 * appended to any existing file content.
4974 * @param firstPids of dalvik VM processes to dump stack traces for first
4975 * @param lastPids of dalvik VM processes to dump stack traces for last
4976 * @param nativeProcs optional list of native process names to dump stack crawls
4977 * @return file containing stack traces, or null if no dump file is configured
4979 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4980 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4981 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4982 if (tracesPath == null || tracesPath.length() == 0) {
4986 File tracesFile = new File(tracesPath);
4988 if (clearTraces && tracesFile.exists()) tracesFile.delete();
4989 tracesFile.createNewFile();
4990 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4991 } catch (IOException e) {
4992 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4996 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5000 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5001 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5002 // Use a FileObserver to detect when traces finish writing.
5003 // The order of traces is considered important to maintain for legibility.
5004 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5006 public synchronized void onEvent(int event, String path) { notify(); }
5010 observer.startWatching();
5012 // First collect all of the stacks of the most important pids.
5013 if (firstPids != null) {
5015 int num = firstPids.size();
5016 for (int i = 0; i < num; i++) {
5017 synchronized (observer) {
5018 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5019 observer.wait(200); // Wait for write-close, give up after 200msec
5022 } catch (InterruptedException e) {
5027 // Next collect the stacks of the native pids
5028 if (nativeProcs != null) {
5029 int[] pids = Process.getPidsForCommands(nativeProcs);
5031 for (int pid : pids) {
5032 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5037 // Lastly, measure CPU usage.
5038 if (processCpuTracker != null) {
5039 processCpuTracker.init();
5041 processCpuTracker.update();
5043 synchronized (processCpuTracker) {
5044 processCpuTracker.wait(500); // measure over 1/2 second.
5046 } catch (InterruptedException e) {
5048 processCpuTracker.update();
5050 // We'll take the stack crawls of just the top apps using CPU.
5051 final int N = processCpuTracker.countWorkingStats();
5053 for (int i=0; i<N && numProcs<5; i++) {
5054 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5055 if (lastPids.indexOfKey(stats.pid) >= 0) {
5058 synchronized (observer) {
5059 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5060 observer.wait(200); // Wait for write-close, give up after 200msec
5062 } catch (InterruptedException e) {
5070 observer.stopWatching();
5074 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5075 if (true || IS_USER_BUILD) {
5078 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5079 if (tracesPath == null || tracesPath.length() == 0) {
5083 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5084 StrictMode.allowThreadDiskWrites();
5086 final File tracesFile = new File(tracesPath);
5087 final File tracesDir = tracesFile.getParentFile();
5088 final File tracesTmp = new File(tracesDir, "__tmp__");
5090 if (tracesFile.exists()) {
5092 tracesFile.renameTo(tracesTmp);
5094 StringBuilder sb = new StringBuilder();
5095 Time tobj = new Time();
5096 tobj.set(System.currentTimeMillis());
5097 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5099 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5100 sb.append(" since ");
5102 FileOutputStream fos = new FileOutputStream(tracesFile);
5103 fos.write(sb.toString().getBytes());
5105 fos.write("\n*** No application process!".getBytes());
5108 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5109 } catch (IOException e) {
5110 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5115 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5116 firstPids.add(app.pid);
5117 dumpStackTraces(tracesPath, firstPids, null, null, null);
5120 File lastTracesFile = null;
5121 File curTracesFile = null;
5122 for (int i=9; i>=0; i--) {
5123 String name = String.format(Locale.US, "slow%02d.txt", i);
5124 curTracesFile = new File(tracesDir, name);
5125 if (curTracesFile.exists()) {
5126 if (lastTracesFile != null) {
5127 curTracesFile.renameTo(lastTracesFile);
5129 curTracesFile.delete();
5132 lastTracesFile = curTracesFile;
5134 tracesFile.renameTo(curTracesFile);
5135 if (tracesTmp.exists()) {
5136 tracesTmp.renameTo(tracesFile);
5139 StrictMode.setThreadPolicy(oldPolicy);
5143 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5144 ActivityRecord parent, boolean aboveSystem, final String annotation) {
5145 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5146 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5148 if (mController != null) {
5150 // 0 == continue, -1 = kill process immediately
5151 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5152 if (res < 0 && app.pid != MY_PID) {
5153 app.kill("anr", true);
5155 } catch (RemoteException e) {
5157 Watchdog.getInstance().setActivityController(null);
5161 long anrTime = SystemClock.uptimeMillis();
5162 if (MONITOR_CPU_USAGE) {
5163 updateCpuStatsNow();
5166 synchronized (this) {
5167 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5168 if (mShuttingDown) {
5169 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5171 } else if (app.notResponding) {
5172 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5174 } else if (app.crashing) {
5175 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5179 // In case we come through here for the same app before completing
5180 // this one, mark as anring now so we will bail out.
5181 app.notResponding = true;
5183 // Log the ANR to the event log.
5184 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5185 app.processName, app.info.flags, annotation);
5187 // Dump thread traces as quickly as we can, starting with "interesting" processes.
5188 firstPids.add(app.pid);
5190 int parentPid = app.pid;
5191 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5192 if (parentPid != app.pid) firstPids.add(parentPid);
5194 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5196 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5197 ProcessRecord r = mLruProcesses.get(i);
5198 if (r != null && r.thread != null) {
5200 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5204 lastPids.put(pid, Boolean.TRUE);
5211 // Log the ANR to the main log.
5212 StringBuilder info = new StringBuilder();
5214 info.append("ANR in ").append(app.processName);
5215 if (activity != null && activity.shortComponentName != null) {
5216 info.append(" (").append(activity.shortComponentName).append(")");
5219 info.append("PID: ").append(app.pid).append("\n");
5220 if (annotation != null) {
5221 info.append("Reason: ").append(annotation).append("\n");
5223 if (parent != null && parent != activity) {
5224 info.append("Parent: ").append(parent.shortComponentName).append("\n");
5227 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5229 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5230 NATIVE_STACKS_OF_INTEREST);
5232 String cpuInfo = null;
5233 if (MONITOR_CPU_USAGE) {
5234 updateCpuStatsNow();
5235 synchronized (mProcessCpuTracker) {
5236 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5238 info.append(processCpuTracker.printCurrentLoad());
5239 info.append(cpuInfo);
5242 info.append(processCpuTracker.printCurrentState(anrTime));
5244 Slog.e(TAG, info.toString());
5245 if (tracesFile == null) {
5246 // There is no trace file, so dump (only) the alleged culprit's threads to the log
5247 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5250 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5251 cpuInfo, tracesFile, null);
5253 if (mController != null) {
5255 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5256 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5258 if (res < 0 && app.pid != MY_PID) {
5259 app.kill("anr", true);
5261 synchronized (this) {
5262 mServices.scheduleServiceTimeoutLocked(app);
5267 } catch (RemoteException e) {
5269 Watchdog.getInstance().setActivityController(null);
5273 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5274 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5275 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5277 synchronized (this) {
5278 mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5280 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5281 app.kill("bg anr", true);
5285 // Set the app's notResponding state, and look up the errorReportReceiver
5286 makeAppNotRespondingLocked(app,
5287 activity != null ? activity.shortComponentName : null,
5288 annotation != null ? "ANR " + annotation : "ANR",
5291 // Bring up the infamous App Not Responding dialog
5292 Message msg = Message.obtain();
5293 HashMap<String, Object> map = new HashMap<String, Object>();
5294 msg.what = SHOW_NOT_RESPONDING_UI_MSG;
5296 msg.arg1 = aboveSystem ? 1 : 0;
5297 map.put("app", app);
5298 if (activity != null) {
5299 map.put("activity", activity);
5302 mUiHandler.sendMessage(msg);
5306 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5307 if (!mLaunchWarningShown) {
5308 mLaunchWarningShown = true;
5309 mUiHandler.post(new Runnable() {
5312 synchronized (ActivityManagerService.this) {
5313 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5315 mUiHandler.postDelayed(new Runnable() {
5318 synchronized (ActivityManagerService.this) {
5320 mLaunchWarningShown = false;
5331 public boolean clearApplicationUserData(final String packageName,
5332 final IPackageDataObserver observer, int userId) {
5333 enforceNotIsolatedCaller("clearApplicationUserData");
5334 if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5335 throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5337 int uid = Binder.getCallingUid();
5338 int pid = Binder.getCallingPid();
5339 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5340 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5341 long callingId = Binder.clearCallingIdentity();
5343 IPackageManager pm = AppGlobals.getPackageManager();
5345 synchronized(this) {
5347 pkgUid = pm.getPackageUid(packageName, userId);
5348 } catch (RemoteException e) {
5351 Slog.w(TAG, "Invalid packageName: " + packageName);
5352 if (observer != null) {
5354 observer.onRemoveCompleted(packageName, false);
5355 } catch (RemoteException e) {
5356 Slog.i(TAG, "Observer no longer exists.");
5361 if (uid == pkgUid || checkComponentPermission(
5362 android.Manifest.permission.CLEAR_APP_USER_DATA,
5364 == PackageManager.PERMISSION_GRANTED) {
5365 forceStopPackageLocked(packageName, pkgUid, "clear data");
5367 throw new SecurityException("PID " + pid + " does not have permission "
5368 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5369 + " of package " + packageName);
5372 // Remove all tasks match the cleared application package and user
5373 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5374 final TaskRecord tr = mRecentTasks.get(i);
5375 final String taskPackageName =
5376 tr.getBaseIntent().getComponent().getPackageName();
5377 if (tr.userId != userId) continue;
5378 if (!taskPackageName.equals(packageName)) continue;
5379 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5384 // Clear application user data
5385 pm.clearApplicationUserData(packageName, observer, userId);
5387 synchronized(this) {
5388 // Remove all permissions granted from/to this package
5389 removeUriPermissionsForPackageLocked(packageName, userId, true);
5392 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5393 Uri.fromParts("package", packageName, null));
5394 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5395 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5396 null, null, 0, null, null, null, null, false, false, userId);
5397 } catch (RemoteException e) {
5400 Binder.restoreCallingIdentity(callingId);
5406 public void killBackgroundProcesses(final String packageName, int userId) {
5407 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5408 != PackageManager.PERMISSION_GRANTED &&
5409 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5410 != PackageManager.PERMISSION_GRANTED) {
5411 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5412 + Binder.getCallingPid()
5413 + ", uid=" + Binder.getCallingUid()
5414 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5416 throw new SecurityException(msg);
5419 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5420 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5421 long callingId = Binder.clearCallingIdentity();
5423 IPackageManager pm = AppGlobals.getPackageManager();
5424 synchronized(this) {
5427 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5428 } catch (RemoteException e) {
5431 Slog.w(TAG, "Invalid packageName: " + packageName);
5434 killPackageProcessesLocked(packageName, appId, userId,
5435 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5438 Binder.restoreCallingIdentity(callingId);
5443 public void killAllBackgroundProcesses() {
5444 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5445 != PackageManager.PERMISSION_GRANTED) {
5446 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5447 + Binder.getCallingPid()
5448 + ", uid=" + Binder.getCallingUid()
5449 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5451 throw new SecurityException(msg);
5454 long callingId = Binder.clearCallingIdentity();
5456 synchronized(this) {
5457 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5458 final int NP = mProcessNames.getMap().size();
5459 for (int ip=0; ip<NP; ip++) {
5460 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5461 final int NA = apps.size();
5462 for (int ia=0; ia<NA; ia++) {
5463 ProcessRecord app = apps.valueAt(ia);
5464 if (app.persistent) {
5465 // we don't kill persistent processes
5470 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5477 int N = procs.size();
5478 for (int i=0; i<N; i++) {
5479 removeProcessLocked(procs.get(i), false, true, "kill all background");
5481 mAllowLowerMemLevel = true;
5482 updateOomAdjLocked();
5483 doLowMemReportIfNeededLocked(null);
5486 Binder.restoreCallingIdentity(callingId);
5491 public void forceStopPackage(final String packageName, int userId) {
5492 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5493 != PackageManager.PERMISSION_GRANTED) {
5494 String msg = "Permission Denial: forceStopPackage() from pid="
5495 + Binder.getCallingPid()
5496 + ", uid=" + Binder.getCallingUid()
5497 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5499 throw new SecurityException(msg);
5501 final int callingPid = Binder.getCallingPid();
5502 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5503 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5504 long callingId = Binder.clearCallingIdentity();
5506 IPackageManager pm = AppGlobals.getPackageManager();
5507 synchronized(this) {
5508 int[] users = userId == UserHandle.USER_ALL
5509 ? mUserController.getUsers() : new int[] { userId };
5510 for (int user : users) {
5513 pkgUid = pm.getPackageUid(packageName, user);
5514 } catch (RemoteException e) {
5517 Slog.w(TAG, "Invalid packageName: " + packageName);
5521 pm.setPackageStoppedState(packageName, true, user);
5522 } catch (RemoteException e) {
5523 } catch (IllegalArgumentException e) {
5524 Slog.w(TAG, "Failed trying to unstop package "
5525 + packageName + ": " + e);
5527 if (mUserController.isUserRunningLocked(user, 0)) {
5528 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5533 Binder.restoreCallingIdentity(callingId);
5538 public void addPackageDependency(String packageName) {
5539 synchronized (this) {
5540 int callingPid = Binder.getCallingPid();
5541 if (callingPid == Process.myPid()) {
5546 synchronized (mPidsSelfLocked) {
5547 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5550 if (proc.pkgDeps == null) {
5551 proc.pkgDeps = new ArraySet<String>(1);
5553 proc.pkgDeps.add(packageName);
5559 * The pkg name and app id have to be specified.
5562 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5566 // Make sure the uid is valid.
5568 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5571 int callerUid = Binder.getCallingUid();
5572 // Only the system server can kill an application
5573 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5574 // Post an aysnc message to kill the application
5575 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5578 Bundle bundle = new Bundle();
5579 bundle.putString("pkg", pkg);
5580 bundle.putString("reason", reason);
5582 mHandler.sendMessage(msg);
5584 throw new SecurityException(callerUid + " cannot kill pkg: " +
5590 public void closeSystemDialogs(String reason) {
5591 enforceNotIsolatedCaller("closeSystemDialogs");
5593 final int pid = Binder.getCallingPid();
5594 final int uid = Binder.getCallingUid();
5595 final long origId = Binder.clearCallingIdentity();
5597 synchronized (this) {
5598 // Only allow this from foreground processes, so that background
5599 // applications can't abuse it to prevent system UI from being shown.
5600 if (uid >= Process.FIRST_APPLICATION_UID) {
5602 synchronized (mPidsSelfLocked) {
5603 proc = mPidsSelfLocked.get(pid);
5605 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5606 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5607 + " from background process " + proc);
5611 closeSystemDialogsLocked(reason);
5614 Binder.restoreCallingIdentity(origId);
5618 void closeSystemDialogsLocked(String reason) {
5619 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5620 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5621 | Intent.FLAG_RECEIVER_FOREGROUND);
5622 if (reason != null) {
5623 intent.putExtra("reason", reason);
5625 mWindowManager.closeSystemDialogs(reason);
5627 mStackSupervisor.closeSystemDialogsLocked();
5629 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5630 AppOpsManager.OP_NONE, null, false, false,
5631 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5635 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5636 enforceNotIsolatedCaller("getProcessMemoryInfo");
5637 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5638 for (int i=pids.length-1; i>=0; i--) {
5641 synchronized (this) {
5642 synchronized (mPidsSelfLocked) {
5643 proc = mPidsSelfLocked.get(pids[i]);
5644 oomAdj = proc != null ? proc.setAdj : 0;
5647 infos[i] = new Debug.MemoryInfo();
5648 Debug.getMemoryInfo(pids[i], infos[i]);
5650 synchronized (this) {
5651 if (proc.thread != null && proc.setAdj == oomAdj) {
5652 // Record this for posterity if the process has been stable.
5653 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5654 infos[i].getTotalUss(), false, proc.pkgList);
5663 public long[] getProcessPss(int[] pids) {
5664 enforceNotIsolatedCaller("getProcessPss");
5665 long[] pss = new long[pids.length];
5666 for (int i=pids.length-1; i>=0; i--) {
5669 synchronized (this) {
5670 synchronized (mPidsSelfLocked) {
5671 proc = mPidsSelfLocked.get(pids[i]);
5672 oomAdj = proc != null ? proc.setAdj : 0;
5675 long[] tmpUss = new long[1];
5676 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5678 synchronized (this) {
5679 if (proc.thread != null && proc.setAdj == oomAdj) {
5680 // Record this for posterity if the process has been stable.
5681 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5690 public void killApplicationProcess(String processName, int uid) {
5691 if (processName == null) {
5695 int callerUid = Binder.getCallingUid();
5696 // Only the system server can kill an application
5697 if (callerUid == Process.SYSTEM_UID) {
5698 synchronized (this) {
5699 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5700 if (app != null && app.thread != null) {
5702 app.thread.scheduleSuicide();
5703 } catch (RemoteException e) {
5704 // If the other end already died, then our work here is done.
5707 Slog.w(TAG, "Process/uid not found attempting kill of "
5708 + processName + " / " + uid);
5712 throw new SecurityException(callerUid + " cannot kill app process: " +
5717 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5718 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5719 false, true, false, false, UserHandle.getUserId(uid), reason);
5720 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5721 Uri.fromParts("package", packageName, null));
5722 if (!mProcessesReady) {
5723 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5724 | Intent.FLAG_RECEIVER_FOREGROUND);
5726 intent.putExtra(Intent.EXTRA_UID, uid);
5727 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5728 broadcastIntentLocked(null, null, intent,
5729 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5730 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5734 private final boolean killPackageProcessesLocked(String packageName, int appId,
5735 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5736 boolean doit, boolean evenPersistent, String reason) {
5737 ArrayList<ProcessRecord> procs = new ArrayList<>();
5739 // Remove all processes this package may have touched: all with the
5740 // same UID (except for the system or root user), and all whose name
5741 // matches the package name.
5742 final int NP = mProcessNames.getMap().size();
5743 for (int ip=0; ip<NP; ip++) {
5744 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5745 final int NA = apps.size();
5746 for (int ia=0; ia<NA; ia++) {
5747 ProcessRecord app = apps.valueAt(ia);
5748 if (app.persistent && !evenPersistent) {
5749 // we don't kill persistent processes
5759 // Skip process if it doesn't meet our oom adj requirement.
5760 if (app.setAdj < minOomAdj) {
5764 // If no package is specified, we call all processes under the
5766 if (packageName == null) {
5767 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5770 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5773 // Package has been specified, we want to hit all processes
5774 // that match it. We need to qualify this by the processes
5775 // that are running under the specified app and user ID.
5777 final boolean isDep = app.pkgDeps != null
5778 && app.pkgDeps.contains(packageName);
5779 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5782 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5785 if (!app.pkgList.containsKey(packageName) && !isDep) {
5790 // Process has passed all conditions, kill it!
5799 int N = procs.size();
5800 for (int i=0; i<N; i++) {
5801 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5803 updateOomAdjLocked();
5807 private void cleanupDisabledPackageComponentsLocked(
5808 String packageName, int userId, boolean killProcess, String[] changedClasses) {
5810 Set<String> disabledClasses = null;
5811 boolean packageDisabled = false;
5812 IPackageManager pm = AppGlobals.getPackageManager();
5814 if (changedClasses == null) {
5815 // Nothing changed...
5819 // Determine enable/disable state of the package and its components.
5820 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5821 for (int i = changedClasses.length - 1; i >= 0; i--) {
5822 final String changedClass = changedClasses[i];
5824 if (changedClass.equals(packageName)) {
5826 // Entire package setting changed
5827 enabled = pm.getApplicationEnabledSetting(packageName,
5828 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5829 } catch (Exception e) {
5830 // No such package/component; probably racing with uninstall. In any
5831 // event it means we have nothing further to do here.
5834 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5835 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5836 if (packageDisabled) {
5837 // Entire package is disabled.
5838 // No need to continue to check component states.
5839 disabledClasses = null;
5844 enabled = pm.getComponentEnabledSetting(
5845 new ComponentName(packageName, changedClass),
5846 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5847 } catch (Exception e) {
5848 // As above, probably racing with uninstall.
5851 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5852 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5853 if (disabledClasses == null) {
5854 disabledClasses = new ArraySet<>(changedClasses.length);
5856 disabledClasses.add(changedClass);
5861 if (!packageDisabled && disabledClasses == null) {
5862 // Nothing to do here...
5866 // Clean-up disabled activities.
5867 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5868 packageName, disabledClasses, true, false, userId) && mBooted) {
5869 mStackSupervisor.resumeTopActivitiesLocked();
5870 mStackSupervisor.scheduleIdleLocked();
5873 // Clean-up disabled tasks
5874 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5876 // Clean-up disabled services.
5877 mServices.bringDownDisabledPackageServicesLocked(
5878 packageName, disabledClasses, userId, false, killProcess, true);
5880 // Clean-up disabled providers.
5881 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5882 mProviderMap.collectPackageProvidersLocked(
5883 packageName, disabledClasses, true, false, userId, providers);
5884 for (int i = providers.size() - 1; i >= 0; i--) {
5885 removeDyingProviderLocked(null, providers.get(i), true);
5888 // Clean-up disabled broadcast receivers.
5889 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5890 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5891 packageName, disabledClasses, userId, true);
5896 final boolean forceStopPackageLocked(String packageName, int appId,
5897 boolean callerWillRestart, boolean purgeCache, boolean doit,
5898 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5901 if (userId == UserHandle.USER_ALL && packageName == null) {
5902 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5905 if (appId < 0 && packageName != null) {
5907 appId = UserHandle.getAppId(
5908 AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5909 } catch (RemoteException e) {
5914 if (packageName != null) {
5915 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5916 + " user=" + userId + ": " + reason);
5918 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5921 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5922 for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5923 SparseArray<Long> ba = pmap.valueAt(ip);
5924 for (i = ba.size() - 1; i >= 0; i--) {
5925 boolean remove = false;
5926 final int entUid = ba.keyAt(i);
5927 if (packageName != null) {
5928 if (userId == UserHandle.USER_ALL) {
5929 if (UserHandle.getAppId(entUid) == appId) {
5933 if (entUid == UserHandle.getUid(userId, appId)) {
5937 } else if (UserHandle.getUserId(entUid) == userId) {
5944 if (ba.size() == 0) {
5950 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5951 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5952 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5954 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5955 packageName, null, doit, evenPersistent, userId)) {
5959 didSomething = true;
5962 if (mServices.bringDownDisabledPackageServicesLocked(
5963 packageName, null, userId, evenPersistent, true, doit)) {
5967 didSomething = true;
5970 if (packageName == null) {
5971 // Remove all sticky broadcasts from this user.
5972 mStickyBroadcasts.remove(userId);
5975 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5976 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5977 userId, providers)) {
5981 didSomething = true;
5983 for (i = providers.size() - 1; i >= 0; i--) {
5984 removeDyingProviderLocked(null, providers.get(i), true);
5987 // Remove transient permissions granted from/to this package/user
5988 removeUriPermissionsForPackageLocked(packageName, userId, false);
5991 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5992 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5993 packageName, null, userId, doit);
5997 if (packageName == null || uninstalling) {
5998 // Remove pending intents. For now we only do this when force
5999 // stopping users, because we have some problems when doing this
6000 // for packages -- app widgets are not currently cleaned up for
6001 // such packages, so they can be left with bad pending intents.
6002 if (mIntentSenderRecords.size() > 0) {
6003 Iterator<WeakReference<PendingIntentRecord>> it
6004 = mIntentSenderRecords.values().iterator();
6005 while (it.hasNext()) {
6006 WeakReference<PendingIntentRecord> wpir = it.next();
6011 PendingIntentRecord pir = wpir.get();
6016 if (packageName == null) {
6017 // Stopping user, remove all objects for the user.
6018 if (pir.key.userId != userId) {
6019 // Not the same user, skip it.
6023 if (UserHandle.getAppId(pir.uid) != appId) {
6024 // Different app id, skip it.
6027 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6028 // Different user, skip it.
6031 if (!pir.key.packageName.equals(packageName)) {
6032 // Different package, skip it.
6039 didSomething = true;
6041 pir.canceled = true;
6042 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6043 pir.key.activity.pendingResults.remove(pir.ref);
6050 if (purgeCache && packageName != null) {
6051 AttributeCache ac = AttributeCache.instance();
6053 ac.removePackage(packageName);
6057 mStackSupervisor.resumeTopActivitiesLocked();
6058 mStackSupervisor.scheduleIdleLocked();
6062 return didSomething;
6065 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6066 ProcessRecord old = mProcessNames.remove(name, uid);
6068 old.uidRecord.numProcs--;
6069 if (old.uidRecord.numProcs == 0) {
6070 // No more processes using this uid, tell clients it is gone.
6071 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6072 "No more processes in " + old.uidRecord);
6073 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6074 mActiveUids.remove(uid);
6076 old.uidRecord = null;
6078 mIsolatedProcesses.remove(uid);
6082 private final void addProcessNameLocked(ProcessRecord proc) {
6083 // We shouldn't already have a process under this name, but just in case we
6084 // need to clean up whatever may be there now.
6085 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6086 if (old == proc && proc.persistent) {
6087 // We are re-adding a persistent process. Whatevs! Just leave it there.
6088 Slog.w(TAG, "Re-adding persistent process " + proc);
6089 } else if (old != null) {
6090 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6092 UidRecord uidRec = mActiveUids.get(proc.uid);
6093 if (uidRec == null) {
6094 uidRec = new UidRecord(proc.uid);
6095 // This is the first appearance of the uid, report it now!
6096 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6097 "Creating new process uid: " + uidRec);
6098 mActiveUids.put(proc.uid, uidRec);
6099 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6101 proc.uidRecord = uidRec;
6103 mProcessNames.put(proc.processName, proc.uid, proc);
6104 if (proc.isolated) {
6105 mIsolatedProcesses.put(proc.uid, proc);
6109 private final boolean removeProcessLocked(ProcessRecord app,
6110 boolean callerWillRestart, boolean allowRestart, String reason) {
6111 final String name = app.processName;
6112 final int uid = app.uid;
6113 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6114 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6116 removeProcessNameLocked(name, uid);
6117 if (mHeavyWeightProcess == app) {
6118 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6119 mHeavyWeightProcess.userId, 0));
6120 mHeavyWeightProcess = null;
6122 boolean needRestart = false;
6123 if (app.pid > 0 && app.pid != MY_PID) {
6125 synchronized (mPidsSelfLocked) {
6126 mPidsSelfLocked.remove(pid);
6127 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6129 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6131 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6133 boolean willRestart = false;
6134 if (app.persistent && !app.isolated) {
6135 if (!callerWillRestart) {
6141 app.kill(reason, true);
6142 handleAppDiedLocked(app, willRestart, allowRestart);
6144 removeLruProcessLocked(app);
6145 addAppLocked(app.info, false, null /* ABI override */);
6148 mRemovedProcesses.add(app);
6154 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6155 cleanupAppInLaunchingProvidersLocked(app, true);
6156 removeProcessLocked(app, false, true, "timeout publishing content providers");
6159 private final void processStartTimedOutLocked(ProcessRecord app) {
6160 final int pid = app.pid;
6161 boolean gone = false;
6162 synchronized (mPidsSelfLocked) {
6163 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6164 if (knownApp != null && knownApp.thread == null) {
6165 mPidsSelfLocked.remove(pid);
6171 Slog.w(TAG, "Process " + app + " failed to attach");
6172 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6173 pid, app.uid, app.processName);
6174 removeProcessNameLocked(app.processName, app.uid);
6175 if (mHeavyWeightProcess == app) {
6176 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6177 mHeavyWeightProcess.userId, 0));
6178 mHeavyWeightProcess = null;
6180 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6182 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6184 // Take care of any launching providers waiting for this process.
6185 cleanupAppInLaunchingProvidersLocked(app, true);
6186 // Take care of any services that are waiting for the process.
6187 mServices.processStartTimedOutLocked(app);
6188 app.kill("start timeout", true);
6189 removeLruProcessLocked(app);
6190 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6191 Slog.w(TAG, "Unattached app died before backup, skipping");
6193 IBackupManager bm = IBackupManager.Stub.asInterface(
6194 ServiceManager.getService(Context.BACKUP_SERVICE));
6195 bm.agentDisconnected(app.info.packageName);
6196 } catch (RemoteException e) {
6197 // Can't happen; the backup manager is local
6200 if (isPendingBroadcastProcessLocked(pid)) {
6201 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6202 skipPendingBroadcastLocked(pid);
6205 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6209 private final boolean attachApplicationLocked(IApplicationThread thread,
6212 // Find the application record that is being attached... either via
6213 // the pid if we are running in multiple processes, or just pull the
6214 // next app record if we are emulating process with anonymous threads.
6216 if (pid != MY_PID && pid >= 0) {
6217 synchronized (mPidsSelfLocked) {
6218 app = mPidsSelfLocked.get(pid);
6225 Slog.w(TAG, "No pending application record for pid " + pid
6226 + " (IApplicationThread " + thread + "); dropping process");
6227 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6228 if (pid > 0 && pid != MY_PID) {
6229 Process.killProcessQuiet(pid);
6230 //TODO: killProcessGroup(app.info.uid, pid);
6233 thread.scheduleExit();
6234 } catch (Exception e) {
6235 // Ignore exceptions.
6241 // If this application record is still attached to a previous
6242 // process, clean it up now.
6243 if (app.thread != null) {
6244 handleAppDiedLocked(app, true, true);
6247 // Tell the process all about itself.
6249 if (DEBUG_ALL) Slog.v(
6250 TAG, "Binding process pid " + pid + " to record " + app);
6252 final String processName = app.processName;
6254 AppDeathRecipient adr = new AppDeathRecipient(
6256 thread.asBinder().linkToDeath(adr, 0);
6257 app.deathRecipient = adr;
6258 } catch (RemoteException e) {
6259 app.resetPackageList(mProcessStats);
6260 startProcessLocked(app, "link fail", processName);
6264 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6266 app.makeActive(thread, mProcessStats);
6267 app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6268 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6269 app.forcingToForeground = null;
6270 updateProcessForegroundLocked(app, false, false);
6271 app.hasShownUi = false;
6272 app.debugging = false;
6274 app.killedByAm = false;
6276 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6278 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6279 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6281 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6282 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6284 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6288 Slog.i(TAG, "Launching preboot mode app: " + app);
6291 if (DEBUG_ALL) Slog.v(
6292 TAG, "New app record " + app
6293 + " thread=" + thread.asBinder() + " pid=" + pid);
6295 int testMode = IApplicationThread.DEBUG_OFF;
6296 if (mDebugApp != null && mDebugApp.equals(processName)) {
6297 testMode = mWaitForDebugger
6298 ? IApplicationThread.DEBUG_WAIT
6299 : IApplicationThread.DEBUG_ON;
6300 app.debugging = true;
6301 if (mDebugTransient) {
6302 mDebugApp = mOrigDebugApp;
6303 mWaitForDebugger = mOrigWaitForDebugger;
6306 String profileFile = app.instrumentationProfileFile;
6307 ParcelFileDescriptor profileFd = null;
6308 int samplingInterval = 0;
6309 boolean profileAutoStop = false;
6310 if (mProfileApp != null && mProfileApp.equals(processName)) {
6312 profileFile = mProfileFile;
6313 profileFd = mProfileFd;
6314 samplingInterval = mSamplingInterval;
6315 profileAutoStop = mAutoStopProfiler;
6317 boolean enableTrackAllocation = false;
6318 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6319 enableTrackAllocation = true;
6320 mTrackAllocationApp = null;
6323 // If the app is being launched for restore or full backup, set it up specially
6324 boolean isRestrictedBackupMode = false;
6325 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6326 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6327 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6328 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6331 notifyPackageUse(app.instrumentationInfo != null
6332 ? app.instrumentationInfo.packageName
6333 : app.info.packageName);
6334 if (app.instrumentationClass != null) {
6335 notifyPackageUse(app.instrumentationClass.getPackageName());
6337 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6338 + processName + " with config " + mConfiguration);
6339 ApplicationInfo appInfo = app.instrumentationInfo != null
6340 ? app.instrumentationInfo : app.info;
6341 app.compat = compatibilityInfoForPackageLocked(appInfo);
6342 if (profileFd != null) {
6343 profileFd = profileFd.dup();
6345 ProfilerInfo profilerInfo = profileFile == null ? null
6346 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6347 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6348 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6349 app.instrumentationUiAutomationConnection, testMode,
6350 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6351 isRestrictedBackupMode || !normalMode, app.persistent,
6352 new Configuration(mConfiguration), app.compat,
6353 getCommonServicesLocked(app.isolated),
6354 mCoreSettingsObserver.getCoreSettingsLocked());
6355 updateLruProcessLocked(app, false, null);
6356 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6357 } catch (Exception e) {
6358 // todo: Yikes! What should we do? For now we will try to
6359 // start another process, but that could easily get us in
6360 // an infinite loop of restarting processes...
6361 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6363 app.resetPackageList(mProcessStats);
6364 app.unlinkDeathRecipient();
6365 startProcessLocked(app, "bind fail", processName);
6369 // Remove this record from the list of starting applications.
6370 mPersistentStartingProcesses.remove(app);
6371 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6372 "Attach application locked removing on hold: " + app);
6373 mProcessesOnHold.remove(app);
6375 boolean badApp = false;
6376 boolean didSomething = false;
6378 // See if the top visible activity is waiting to run in this process...
6381 if (mStackSupervisor.attachApplicationLocked(app)) {
6382 didSomething = true;
6384 } catch (Exception e) {
6385 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6390 // Find any services that should be running in this process...
6393 didSomething |= mServices.attachApplicationLocked(app, processName);
6394 } catch (Exception e) {
6395 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6400 // Check if a next-broadcast receiver is in this process...
6401 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6403 didSomething |= sendPendingBroadcastsLocked(app);
6404 } catch (Exception e) {
6405 // If the app died trying to launch the receiver we declare it 'bad'
6406 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6411 // Check whether the next backup agent is in this process...
6412 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6413 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6414 "New app is backup target, launching agent for " + app);
6415 notifyPackageUse(mBackupTarget.appInfo.packageName);
6417 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6418 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6419 mBackupTarget.backupMode);
6420 } catch (Exception e) {
6421 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6427 app.kill("error during init", true);
6428 handleAppDiedLocked(app, false, true);
6432 if (!didSomething) {
6433 updateOomAdjLocked();
6440 public final void attachApplication(IApplicationThread thread) {
6441 synchronized (this) {
6442 int callingPid = Binder.getCallingPid();
6443 final long origId = Binder.clearCallingIdentity();
6444 attachApplicationLocked(thread, callingPid);
6445 Binder.restoreCallingIdentity(origId);
6450 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6451 final long origId = Binder.clearCallingIdentity();
6452 synchronized (this) {
6453 ActivityStack stack = ActivityRecord.getStackLocked(token);
6454 if (stack != null) {
6456 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6457 if (stopProfiling) {
6458 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6461 } catch (IOException e) {
6463 clearProfilerLocked();
6468 Binder.restoreCallingIdentity(origId);
6471 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6472 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6473 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6476 void enableScreenAfterBoot() {
6477 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6478 SystemClock.uptimeMillis());
6479 mWindowManager.enableScreenAfterBoot();
6481 synchronized (this) {
6482 updateEventDispatchingLocked();
6487 public void showBootMessage(final CharSequence msg, final boolean always) {
6488 if (Binder.getCallingUid() != Process.myUid()) {
6489 // These days only the core system can call this, so apps can't get in
6490 // the way of what we show about running them.
6492 mWindowManager.showBootMessage(msg, always);
6496 public void keyguardWaitingForActivityDrawn() {
6497 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6498 final long token = Binder.clearCallingIdentity();
6500 synchronized (this) {
6501 if (DEBUG_LOCKSCREEN) logLockScreen("");
6502 mWindowManager.keyguardWaitingForActivityDrawn();
6503 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6504 mLockScreenShown = LOCK_SCREEN_LEAVING;
6505 updateSleepIfNeededLocked();
6509 Binder.restoreCallingIdentity(token);
6514 public void keyguardGoingAway(boolean disableWindowAnimations,
6515 boolean keyguardGoingToNotificationShade) {
6516 enforceNotIsolatedCaller("keyguardGoingAway");
6517 final long token = Binder.clearCallingIdentity();
6519 synchronized (this) {
6520 if (DEBUG_LOCKSCREEN) logLockScreen("");
6521 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6522 keyguardGoingToNotificationShade);
6523 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6524 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6525 updateSleepIfNeededLocked();
6529 Binder.restoreCallingIdentity(token);
6533 final void finishBooting() {
6534 synchronized (this) {
6535 if (!mBootAnimationComplete) {
6536 mCallFinishBooting = true;
6539 mCallFinishBooting = false;
6542 ArraySet<String> completedIsas = new ArraySet<String>();
6543 for (String abi : Build.SUPPORTED_ABIS) {
6544 Process.establishZygoteConnectionForAbi(abi);
6545 final String instructionSet = VMRuntime.getInstructionSet(abi);
6546 if (!completedIsas.contains(instructionSet)) {
6547 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6548 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6550 completedIsas.add(instructionSet);
6554 IntentFilter pkgFilter = new IntentFilter();
6555 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6556 pkgFilter.addDataScheme("package");
6557 mContext.registerReceiver(new BroadcastReceiver() {
6559 public void onReceive(Context context, Intent intent) {
6560 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6562 for (String pkg : pkgs) {
6563 synchronized (ActivityManagerService.this) {
6564 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6565 0, "query restart")) {
6566 setResultCode(Activity.RESULT_OK);
6575 IntentFilter dumpheapFilter = new IntentFilter();
6576 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6577 mContext.registerReceiver(new BroadcastReceiver() {
6579 public void onReceive(Context context, Intent intent) {
6580 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6581 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6583 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6588 // Let system services know.
6589 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6591 synchronized (this) {
6592 // Ensure that any processes we had put on hold are now started
6594 final int NP = mProcessesOnHold.size();
6596 ArrayList<ProcessRecord> procs =
6597 new ArrayList<ProcessRecord>(mProcessesOnHold);
6598 for (int ip=0; ip<NP; ip++) {
6599 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6601 startProcessLocked(procs.get(ip), "on-hold", null);
6605 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6606 // Start looking for apps that are abusing wake locks.
6607 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6608 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6609 // Tell anyone interested that we are done booting!
6610 SystemProperties.set("sys.boot_completed", "1");
6612 // And trigger dev.bootcomplete if we are not showing encryption progress
6613 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6614 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6615 SystemProperties.set("dev.bootcomplete", "1");
6617 mUserController.sendBootCompletedLocked(
6618 new IIntentReceiver.Stub() {
6620 public void performReceive(Intent intent, int resultCode,
6621 String data, Bundle extras, boolean ordered,
6622 boolean sticky, int sendingUser) {
6623 synchronized (ActivityManagerService.this) {
6624 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6629 scheduleStartProfilesLocked();
6635 public void bootAnimationComplete() {
6636 final boolean callFinishBooting;
6637 synchronized (this) {
6638 callFinishBooting = mCallFinishBooting;
6639 mBootAnimationComplete = true;
6641 if (callFinishBooting) {
6642 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6644 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6648 final void ensureBootCompleted() {
6650 boolean enableScreen;
6651 synchronized (this) {
6654 enableScreen = !mBooted;
6659 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6661 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6665 enableScreenAfterBoot();
6670 public final void activityResumed(IBinder token) {
6671 final long origId = Binder.clearCallingIdentity();
6672 synchronized(this) {
6673 ActivityStack stack = ActivityRecord.getStackLocked(token);
6674 if (stack != null) {
6675 ActivityRecord.activityResumedLocked(token);
6678 Binder.restoreCallingIdentity(origId);
6682 public final void activityPaused(IBinder token) {
6683 final long origId = Binder.clearCallingIdentity();
6684 synchronized(this) {
6685 ActivityStack stack = ActivityRecord.getStackLocked(token);
6686 if (stack != null) {
6687 stack.activityPausedLocked(token, false);
6690 Binder.restoreCallingIdentity(origId);
6694 public final void activityStopped(IBinder token, Bundle icicle,
6695 PersistableBundle persistentState, CharSequence description) {
6696 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6698 // Refuse possible leaked file descriptors
6699 if (icicle != null && icicle.hasFileDescriptors()) {
6700 throw new IllegalArgumentException("File descriptors passed in Bundle");
6703 final long origId = Binder.clearCallingIdentity();
6705 synchronized (this) {
6706 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6708 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6714 Binder.restoreCallingIdentity(origId);
6718 public final void activityDestroyed(IBinder token) {
6719 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6720 synchronized (this) {
6721 ActivityStack stack = ActivityRecord.getStackLocked(token);
6722 if (stack != null) {
6723 stack.activityDestroyedLocked(token, "activityDestroyed");
6729 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6730 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6731 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6732 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6733 synchronized (this) {
6734 ActivityRecord record = ActivityRecord.isInStackLocked(token);
6735 if (record == null) {
6736 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6737 + "found for: " + token);
6739 record.setSizeConfigurations(horizontalSizeConfiguration,
6740 verticalSizeConfigurations, smallestSizeConfigurations);
6745 public final void backgroundResourcesReleased(IBinder token) {
6746 final long origId = Binder.clearCallingIdentity();
6748 synchronized (this) {
6749 ActivityStack stack = ActivityRecord.getStackLocked(token);
6750 if (stack != null) {
6751 stack.backgroundResourcesReleased();
6755 Binder.restoreCallingIdentity(origId);
6760 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6761 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6765 public final void notifyEnterAnimationComplete(IBinder token) {
6766 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6770 public String getCallingPackage(IBinder token) {
6771 synchronized (this) {
6772 ActivityRecord r = getCallingRecordLocked(token);
6773 return r != null ? r.info.packageName : null;
6778 public ComponentName getCallingActivity(IBinder token) {
6779 synchronized (this) {
6780 ActivityRecord r = getCallingRecordLocked(token);
6781 return r != null ? r.intent.getComponent() : null;
6785 private ActivityRecord getCallingRecordLocked(IBinder token) {
6786 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6794 public ComponentName getActivityClassForToken(IBinder token) {
6795 synchronized(this) {
6796 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6800 return r.intent.getComponent();
6805 public String getPackageForToken(IBinder token) {
6806 synchronized(this) {
6807 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6811 return r.packageName;
6816 public boolean isRootVoiceInteraction(IBinder token) {
6817 synchronized(this) {
6818 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6822 return r.rootVoiceInteraction;
6827 public IIntentSender getIntentSender(int type,
6828 String packageName, IBinder token, String resultWho,
6829 int requestCode, Intent[] intents, String[] resolvedTypes,
6830 int flags, Bundle bOptions, int userId) {
6831 enforceNotIsolatedCaller("getIntentSender");
6832 // Refuse possible leaked file descriptors
6833 if (intents != null) {
6834 if (intents.length < 1) {
6835 throw new IllegalArgumentException("Intents array length must be >= 1");
6837 for (int i=0; i<intents.length; i++) {
6838 Intent intent = intents[i];
6839 if (intent != null) {
6840 if (intent.hasFileDescriptors()) {
6841 throw new IllegalArgumentException("File descriptors passed in Intent");
6843 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6844 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6845 throw new IllegalArgumentException(
6846 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6848 intents[i] = new Intent(intent);
6851 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6852 throw new IllegalArgumentException(
6853 "Intent array length does not match resolvedTypes length");
6856 if (bOptions != null) {
6857 if (bOptions.hasFileDescriptors()) {
6858 throw new IllegalArgumentException("File descriptors passed in options");
6862 synchronized(this) {
6863 int callingUid = Binder.getCallingUid();
6864 int origUserId = userId;
6865 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6866 type == ActivityManager.INTENT_SENDER_BROADCAST,
6867 ALLOW_NON_FULL, "getIntentSender", null);
6868 if (origUserId == UserHandle.USER_CURRENT) {
6869 // We don't want to evaluate this until the pending intent is
6870 // actually executed. However, we do want to always do the
6871 // security checking for it above.
6872 userId = UserHandle.USER_CURRENT;
6875 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6876 int uid = AppGlobals.getPackageManager()
6877 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6878 if (!UserHandle.isSameApp(callingUid, uid)) {
6879 String msg = "Permission Denial: getIntentSender() from pid="
6880 + Binder.getCallingPid()
6881 + ", uid=" + Binder.getCallingUid()
6882 + ", (need uid=" + uid + ")"
6883 + " is not allowed to send as package " + packageName;
6885 throw new SecurityException(msg);
6889 return getIntentSenderLocked(type, packageName, callingUid, userId,
6890 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6892 } catch (RemoteException e) {
6893 throw new SecurityException(e);
6898 IIntentSender getIntentSenderLocked(int type, String packageName,
6899 int callingUid, int userId, IBinder token, String resultWho,
6900 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6902 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6903 ActivityRecord activity = null;
6904 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6905 activity = ActivityRecord.isInStackLocked(token);
6906 if (activity == null) {
6907 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6910 if (activity.finishing) {
6911 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6916 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6917 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6918 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6919 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6920 |PendingIntent.FLAG_UPDATE_CURRENT);
6922 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6923 type, packageName, activity, resultWho,
6924 requestCode, intents, resolvedTypes, flags, bOptions, userId);
6925 WeakReference<PendingIntentRecord> ref;
6926 ref = mIntentSenderRecords.get(key);
6927 PendingIntentRecord rec = ref != null ? ref.get() : null;
6929 if (!cancelCurrent) {
6930 if (updateCurrent) {
6931 if (rec.key.requestIntent != null) {
6932 rec.key.requestIntent.replaceExtras(intents != null ?
6933 intents[intents.length - 1] : null);
6935 if (intents != null) {
6936 intents[intents.length-1] = rec.key.requestIntent;
6937 rec.key.allIntents = intents;
6938 rec.key.allResolvedTypes = resolvedTypes;
6940 rec.key.allIntents = null;
6941 rec.key.allResolvedTypes = null;
6946 rec.canceled = true;
6947 mIntentSenderRecords.remove(key);
6952 rec = new PendingIntentRecord(this, key, callingUid);
6953 mIntentSenderRecords.put(key, rec.ref);
6954 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6955 if (activity.pendingResults == null) {
6956 activity.pendingResults
6957 = new HashSet<WeakReference<PendingIntentRecord>>();
6959 activity.pendingResults.add(rec.ref);
6965 public void cancelIntentSender(IIntentSender sender) {
6966 if (!(sender instanceof PendingIntentRecord)) {
6969 synchronized(this) {
6970 PendingIntentRecord rec = (PendingIntentRecord)sender;
6972 int uid = AppGlobals.getPackageManager()
6973 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6974 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6975 String msg = "Permission Denial: cancelIntentSender() from pid="
6976 + Binder.getCallingPid()
6977 + ", uid=" + Binder.getCallingUid()
6978 + " is not allowed to cancel packges "
6979 + rec.key.packageName;
6981 throw new SecurityException(msg);
6983 } catch (RemoteException e) {
6984 throw new SecurityException(e);
6986 cancelIntentSenderLocked(rec, true);
6990 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6991 rec.canceled = true;
6992 mIntentSenderRecords.remove(rec.key);
6993 if (cleanActivity && rec.key.activity != null) {
6994 rec.key.activity.pendingResults.remove(rec.ref);
6999 public String getPackageForIntentSender(IIntentSender pendingResult) {
7000 if (!(pendingResult instanceof PendingIntentRecord)) {
7004 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7005 return res.key.packageName;
7006 } catch (ClassCastException e) {
7012 public int getUidForIntentSender(IIntentSender sender) {
7013 if (sender instanceof PendingIntentRecord) {
7015 PendingIntentRecord res = (PendingIntentRecord)sender;
7017 } catch (ClassCastException e) {
7024 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7025 if (!(pendingResult instanceof PendingIntentRecord)) {
7029 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7030 if (res.key.allIntents == null) {
7033 for (int i=0; i<res.key.allIntents.length; i++) {
7034 Intent intent = res.key.allIntents[i];
7035 if (intent.getPackage() != null && intent.getComponent() != null) {
7040 } catch (ClassCastException e) {
7046 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7047 if (!(pendingResult instanceof PendingIntentRecord)) {
7051 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7052 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7056 } catch (ClassCastException e) {
7062 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7063 if (!(pendingResult instanceof PendingIntentRecord)) {
7067 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7068 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7069 } catch (ClassCastException e) {
7075 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7076 if (!(pendingResult instanceof PendingIntentRecord)) {
7080 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7081 synchronized (this) {
7082 return getTagForIntentSenderLocked(res, prefix);
7084 } catch (ClassCastException e) {
7089 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7090 final Intent intent = res.key.requestIntent;
7091 if (intent != null) {
7092 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7093 || res.lastTagPrefix.equals(prefix))) {
7096 res.lastTagPrefix = prefix;
7097 final StringBuilder sb = new StringBuilder(128);
7098 if (prefix != null) {
7101 if (intent.getAction() != null) {
7102 sb.append(intent.getAction());
7103 } else if (intent.getComponent() != null) {
7104 intent.getComponent().appendShortString(sb);
7108 return res.lastTag = sb.toString();
7114 public void setProcessLimit(int max) {
7115 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7116 "setProcessLimit()");
7117 synchronized (this) {
7118 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7119 mProcessLimitOverride = max;
7125 public int getProcessLimit() {
7126 synchronized (this) {
7127 return mProcessLimitOverride;
7131 void foregroundTokenDied(ForegroundToken token) {
7132 synchronized (ActivityManagerService.this) {
7133 synchronized (mPidsSelfLocked) {
7135 = mForegroundProcesses.get(token.pid);
7139 mForegroundProcesses.remove(token.pid);
7140 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7144 pr.forcingToForeground = null;
7145 updateProcessForegroundLocked(pr, false, false);
7147 updateOomAdjLocked();
7152 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7153 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7154 "setProcessForeground()");
7155 synchronized(this) {
7156 boolean changed = false;
7158 synchronized (mPidsSelfLocked) {
7159 ProcessRecord pr = mPidsSelfLocked.get(pid);
7160 if (pr == null && isForeground) {
7161 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7164 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7165 if (oldToken != null) {
7166 oldToken.token.unlinkToDeath(oldToken, 0);
7167 mForegroundProcesses.remove(pid);
7169 pr.forcingToForeground = null;
7173 if (isForeground && token != null) {
7174 ForegroundToken newToken = new ForegroundToken() {
7176 public void binderDied() {
7177 foregroundTokenDied(this);
7181 newToken.token = token;
7183 token.linkToDeath(newToken, 0);
7184 mForegroundProcesses.put(pid, newToken);
7185 pr.forcingToForeground = token;
7187 } catch (RemoteException e) {
7188 // If the process died while doing this, we will later
7189 // do the cleanup with the process death link.
7195 updateOomAdjLocked();
7200 // =========================================================
7202 // =========================================================
7204 static class ProcessInfoService extends IProcessInfoService.Stub {
7205 final ActivityManagerService mActivityManagerService;
7206 ProcessInfoService(ActivityManagerService activityManagerService) {
7207 mActivityManagerService = activityManagerService;
7211 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7212 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7213 /*in*/ pids, /*out*/ states, null);
7217 public void getProcessStatesAndOomScoresFromPids(
7218 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7219 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7220 /*in*/ pids, /*out*/ states, /*out*/ scores);
7225 * For each PID in the given input array, write the current process state
7226 * for that process into the states array, or -1 to indicate that no
7227 * process with the given PID exists. If scores array is provided, write
7228 * the oom score for the process into the scores array, with INVALID_ADJ
7229 * indicating the PID doesn't exist.
7231 public void getProcessStatesAndOomScoresForPIDs(
7232 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7234 throw new NullPointerException("pids");
7235 } else if (states == null) {
7236 throw new NullPointerException("states");
7237 } else if (pids.length != states.length) {
7238 throw new IllegalArgumentException("pids and states arrays have different lengths!");
7239 } else if (scores != null && pids.length != scores.length) {
7240 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7243 synchronized (mPidsSelfLocked) {
7244 for (int i = 0; i < pids.length; i++) {
7245 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7246 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7248 if (scores != null) {
7249 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7255 // =========================================================
7257 // =========================================================
7259 static class PermissionController extends IPermissionController.Stub {
7260 ActivityManagerService mActivityManagerService;
7261 PermissionController(ActivityManagerService activityManagerService) {
7262 mActivityManagerService = activityManagerService;
7266 public boolean checkPermission(String permission, int pid, int uid) {
7267 return mActivityManagerService.checkPermission(permission, pid,
7268 uid) == PackageManager.PERMISSION_GRANTED;
7272 public String[] getPackagesForUid(int uid) {
7273 return mActivityManagerService.mContext.getPackageManager()
7274 .getPackagesForUid(uid);
7278 public boolean isRuntimePermission(String permission) {
7280 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7281 .getPermissionInfo(permission, 0);
7282 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7283 } catch (NameNotFoundException nnfe) {
7284 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7290 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7292 public int checkComponentPermission(String permission, int pid, int uid,
7293 int owningUid, boolean exported) {
7294 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7295 owningUid, exported);
7299 public Object getAMSLock() {
7300 return ActivityManagerService.this;
7305 * This can be called with or without the global lock held.
7307 int checkComponentPermission(String permission, int pid, int uid,
7308 int owningUid, boolean exported) {
7309 if (pid == MY_PID) {
7310 return PackageManager.PERMISSION_GRANTED;
7312 return ActivityManager.checkComponentPermission(permission, uid,
7313 owningUid, exported);
7317 * As the only public entry point for permissions checking, this method
7318 * can enforce the semantic that requesting a check on a null global
7319 * permission is automatically denied. (Internally a null permission
7320 * string is used when calling {@link #checkComponentPermission} in cases
7321 * when only uid-based security is needed.)
7323 * This can be called with or without the global lock held.
7326 public int checkPermission(String permission, int pid, int uid) {
7327 if (permission == null) {
7328 return PackageManager.PERMISSION_DENIED;
7330 return checkComponentPermission(permission, pid, uid, -1, true);
7334 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7335 if (permission == null) {
7336 return PackageManager.PERMISSION_DENIED;
7339 // We might be performing an operation on behalf of an indirect binder
7340 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7341 // client identity accordingly before proceeding.
7342 Identity tlsIdentity = sCallerIdentity.get();
7343 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7344 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7345 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7346 uid = tlsIdentity.uid;
7347 pid = tlsIdentity.pid;
7350 return checkComponentPermission(permission, pid, uid, -1, true);
7354 * Binder IPC calls go through the public entry point.
7355 * This can be called with or without the global lock held.
7357 int checkCallingPermission(String permission) {
7358 return checkPermission(permission,
7359 Binder.getCallingPid(),
7360 UserHandle.getAppId(Binder.getCallingUid()));
7364 * This can be called with or without the global lock held.
7366 void enforceCallingPermission(String permission, String func) {
7367 if (checkCallingPermission(permission)
7368 == PackageManager.PERMISSION_GRANTED) {
7372 String msg = "Permission Denial: " + func + " from pid="
7373 + Binder.getCallingPid()
7374 + ", uid=" + Binder.getCallingUid()
7375 + " requires " + permission;
7377 throw new SecurityException(msg);
7381 * Determine if UID is holding permissions required to access {@link Uri} in
7382 * the given {@link ProviderInfo}. Final permission checking is always done
7383 * in {@link ContentProvider}.
7385 private final boolean checkHoldingPermissionsLocked(
7386 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7387 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7388 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7389 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7390 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7391 != PERMISSION_GRANTED) {
7395 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7398 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7399 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7400 if (pi.applicationInfo.uid == uid) {
7402 } else if (!pi.exported) {
7406 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7407 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7409 // check if target holds top-level <provider> permissions
7410 if (!readMet && pi.readPermission != null && considerUidPermissions
7411 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7414 if (!writeMet && pi.writePermission != null && considerUidPermissions
7415 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7419 // track if unprotected read/write is allowed; any denied
7420 // <path-permission> below removes this ability
7421 boolean allowDefaultRead = pi.readPermission == null;
7422 boolean allowDefaultWrite = pi.writePermission == null;
7424 // check if target holds any <path-permission> that match uri
7425 final PathPermission[] pps = pi.pathPermissions;
7427 final String path = grantUri.uri.getPath();
7429 while (i > 0 && (!readMet || !writeMet)) {
7431 PathPermission pp = pps[i];
7432 if (pp.match(path)) {
7434 final String pprperm = pp.getReadPermission();
7435 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7436 "Checking read perm for " + pprperm + " for " + pp.getPath()
7437 + ": match=" + pp.match(path)
7438 + " check=" + pm.checkUidPermission(pprperm, uid));
7439 if (pprperm != null) {
7440 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7441 == PERMISSION_GRANTED) {
7444 allowDefaultRead = false;
7449 final String ppwperm = pp.getWritePermission();
7450 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7451 "Checking write perm " + ppwperm + " for " + pp.getPath()
7452 + ": match=" + pp.match(path)
7453 + " check=" + pm.checkUidPermission(ppwperm, uid));
7454 if (ppwperm != null) {
7455 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7456 == PERMISSION_GRANTED) {
7459 allowDefaultWrite = false;
7467 // grant unprotected <provider> read/write, if not blocked by
7468 // <path-permission> above
7469 if (allowDefaultRead) readMet = true;
7470 if (allowDefaultWrite) writeMet = true;
7472 } catch (RemoteException e) {
7476 return readMet && writeMet;
7479 public int getAppStartMode(int uid, String packageName) {
7480 synchronized (this) {
7481 boolean bg = checkAllowBackgroundLocked(uid, packageName, -1);
7482 return bg ? ActivityManager.APP_START_MODE_NORMAL
7483 : ActivityManager.APP_START_MODE_DISABLED;
7487 boolean checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7488 UidRecord uidRec = mActiveUids.get(uid);
7489 if (uidRec == null || uidRec.idle) {
7490 if (callingPid >= 0) {
7492 synchronized (mPidsSelfLocked) {
7493 proc = mPidsSelfLocked.get(callingPid);
7495 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7496 // Whoever is instigating this is in the foreground, so we will allow it
7501 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7502 != AppOpsManager.MODE_ALLOWED) {
7509 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7510 ProviderInfo pi = null;
7511 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7516 pi = AppGlobals.getPackageManager().resolveContentProvider(
7517 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7518 } catch (RemoteException ex) {
7524 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7525 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7526 if (targetUris != null) {
7527 return targetUris.get(grantUri);
7532 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7533 String targetPkg, int targetUid, GrantUri grantUri) {
7534 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7535 if (targetUris == null) {
7536 targetUris = Maps.newArrayMap();
7537 mGrantedUriPermissions.put(targetUid, targetUris);
7540 UriPermission perm = targetUris.get(grantUri);
7542 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7543 targetUris.put(grantUri, perm);
7549 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7550 final int modeFlags) {
7551 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7552 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7553 : UriPermission.STRENGTH_OWNED;
7555 // Root gets to do everything.
7560 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7561 if (perms == null) return false;
7563 // First look for exact match
7564 final UriPermission exactPerm = perms.get(grantUri);
7565 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7569 // No exact match, look for prefixes
7570 final int N = perms.size();
7571 for (int i = 0; i < N; i++) {
7572 final UriPermission perm = perms.valueAt(i);
7573 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7574 && perm.getStrength(modeFlags) >= minStrength) {
7583 * @param uri This uri must NOT contain an embedded userId.
7584 * @param userId The userId in which the uri is to be resolved.
7587 public int checkUriPermission(Uri uri, int pid, int uid,
7588 final int modeFlags, int userId, IBinder callerToken) {
7589 enforceNotIsolatedCaller("checkUriPermission");
7591 // Another redirected-binder-call permissions check as in
7592 // {@link checkPermissionWithToken}.
7593 Identity tlsIdentity = sCallerIdentity.get();
7594 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7595 uid = tlsIdentity.uid;
7596 pid = tlsIdentity.pid;
7599 // Our own process gets to do everything.
7600 if (pid == MY_PID) {
7601 return PackageManager.PERMISSION_GRANTED;
7603 synchronized (this) {
7604 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7605 ? PackageManager.PERMISSION_GRANTED
7606 : PackageManager.PERMISSION_DENIED;
7611 * Check if the targetPkg can be granted permission to access uri by
7612 * the callingUid using the given modeFlags. Throws a security exception
7613 * if callingUid is not allowed to do this. Returns the uid of the target
7614 * if the URI permission grant should be performed; returns -1 if it is not
7615 * needed (for example targetPkg already has permission to access the URI).
7616 * If you already know the uid of the target, you can supply it in
7617 * lastTargetUid else set that to -1.
7619 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7620 final int modeFlags, int lastTargetUid) {
7621 if (!Intent.isAccessUriMode(modeFlags)) {
7625 if (targetPkg != null) {
7626 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7627 "Checking grant " + targetPkg + " permission to " + grantUri);
7630 final IPackageManager pm = AppGlobals.getPackageManager();
7632 // If this is not a content: uri, we can't do anything with it.
7633 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7634 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7635 "Can't grant URI permission for non-content URI: " + grantUri);
7639 final String authority = grantUri.uri.getAuthority();
7640 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7642 Slog.w(TAG, "No content provider found for permission check: " +
7643 grantUri.uri.toSafeString());
7647 int targetUid = lastTargetUid;
7648 if (targetUid < 0 && targetPkg != null) {
7650 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7651 if (targetUid < 0) {
7652 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7653 "Can't grant URI permission no uid for: " + targetPkg);
7656 } catch (RemoteException ex) {
7661 if (targetUid >= 0) {
7662 // First... does the target actually need this permission?
7663 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7664 // No need to grant the target this permission.
7665 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7666 "Target " + targetPkg + " already has full permission to " + grantUri);
7670 // First... there is no target package, so can anyone access it?
7671 boolean allowed = pi.exported;
7672 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7673 if (pi.readPermission != null) {
7677 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7678 if (pi.writePermission != null) {
7687 /* There is a special cross user grant if:
7688 * - The target is on another user.
7689 * - Apps on the current user can access the uri without any uid permissions.
7690 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7691 * grant uri permissions.
7693 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7694 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7695 modeFlags, false /*without considering the uid permissions*/);
7697 // Second... is the provider allowing granting of URI permissions?
7698 if (!specialCrossUserGrant) {
7699 if (!pi.grantUriPermissions) {
7700 throw new SecurityException("Provider " + pi.packageName
7702 + " does not allow granting of Uri permissions (uri "
7705 if (pi.uriPermissionPatterns != null) {
7706 final int N = pi.uriPermissionPatterns.length;
7707 boolean allowed = false;
7708 for (int i=0; i<N; i++) {
7709 if (pi.uriPermissionPatterns[i] != null
7710 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7716 throw new SecurityException("Provider " + pi.packageName
7718 + " does not allow granting of permission to path of Uri "
7724 // Third... does the caller itself have permission to access
7726 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7727 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7728 // Require they hold a strong enough Uri permission
7729 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7730 throw new SecurityException("Uid " + callingUid
7731 + " does not have permission to uri " + grantUri);
7739 * @param uri This uri must NOT contain an embedded userId.
7740 * @param userId The userId in which the uri is to be resolved.
7743 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7744 final int modeFlags, int userId) {
7745 enforceNotIsolatedCaller("checkGrantUriPermission");
7746 synchronized(this) {
7747 return checkGrantUriPermissionLocked(callingUid, targetPkg,
7748 new GrantUri(userId, uri, false), modeFlags, -1);
7752 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7753 final int modeFlags, UriPermissionOwner owner) {
7754 if (!Intent.isAccessUriMode(modeFlags)) {
7758 // So here we are: the caller has the assumed permission
7759 // to the uri, and the target doesn't. Let's now give this to
7762 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7763 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7765 final String authority = grantUri.uri.getAuthority();
7766 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7768 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7772 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7773 grantUri.prefix = true;
7775 final UriPermission perm = findOrCreateUriPermissionLocked(
7776 pi.packageName, targetPkg, targetUid, grantUri);
7777 perm.grantModes(modeFlags, owner);
7780 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7781 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7782 if (targetPkg == null) {
7783 throw new NullPointerException("targetPkg");
7786 final IPackageManager pm = AppGlobals.getPackageManager();
7788 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7789 } catch (RemoteException ex) {
7793 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7795 if (targetUid < 0) {
7799 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7803 static class NeededUriGrants extends ArrayList<GrantUri> {
7804 final String targetPkg;
7805 final int targetUid;
7808 NeededUriGrants(String targetPkg, int targetUid, int flags) {
7809 this.targetPkg = targetPkg;
7810 this.targetUid = targetUid;
7816 * Like checkGrantUriPermissionLocked, but takes an Intent.
7818 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7819 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7820 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7821 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7822 + " clip=" + (intent != null ? intent.getClipData() : null)
7823 + " from " + intent + "; flags=0x"
7824 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7826 if (targetPkg == null) {
7827 throw new NullPointerException("targetPkg");
7830 if (intent == null) {
7833 Uri data = intent.getData();
7834 ClipData clip = intent.getClipData();
7835 if (data == null && clip == null) {
7838 // Default userId for uris in the intent (if they don't specify it themselves)
7839 int contentUserHint = intent.getContentUserHint();
7840 if (contentUserHint == UserHandle.USER_CURRENT) {
7841 contentUserHint = UserHandle.getUserId(callingUid);
7843 final IPackageManager pm = AppGlobals.getPackageManager();
7845 if (needed != null) {
7846 targetUid = needed.targetUid;
7849 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7850 } catch (RemoteException ex) {
7853 if (targetUid < 0) {
7854 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7855 "Can't grant URI permission no uid for: " + targetPkg
7856 + " on user " + targetUserId);
7861 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7862 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7864 if (targetUid > 0) {
7865 if (needed == null) {
7866 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7868 needed.add(grantUri);
7872 for (int i=0; i<clip.getItemCount(); i++) {
7873 Uri uri = clip.getItemAt(i).getUri();
7875 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7876 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7878 if (targetUid > 0) {
7879 if (needed == null) {
7880 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7882 needed.add(grantUri);
7885 Intent clipIntent = clip.getItemAt(i).getIntent();
7886 if (clipIntent != null) {
7887 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7888 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7889 if (newNeeded != null) {
7901 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7903 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7904 UriPermissionOwner owner) {
7905 if (needed != null) {
7906 for (int i=0; i<needed.size(); i++) {
7907 GrantUri grantUri = needed.get(i);
7908 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7909 grantUri, needed.flags, owner);
7914 void grantUriPermissionFromIntentLocked(int callingUid,
7915 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7916 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7917 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7918 if (needed == null) {
7922 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7926 * @param uri This uri must NOT contain an embedded userId.
7927 * @param userId The userId in which the uri is to be resolved.
7930 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7931 final int modeFlags, int userId) {
7932 enforceNotIsolatedCaller("grantUriPermission");
7933 GrantUri grantUri = new GrantUri(userId, uri, false);
7934 synchronized(this) {
7935 final ProcessRecord r = getRecordForAppLocked(caller);
7937 throw new SecurityException("Unable to find app for caller "
7939 + " when granting permission to uri " + grantUri);
7941 if (targetPkg == null) {
7942 throw new IllegalArgumentException("null target");
7944 if (grantUri == null) {
7945 throw new IllegalArgumentException("null uri");
7948 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7949 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7950 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7951 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7953 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7954 UserHandle.getUserId(r.uid));
7958 void removeUriPermissionIfNeededLocked(UriPermission perm) {
7959 if (perm.modeFlags == 0) {
7960 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7962 if (perms != null) {
7963 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7964 "Removing " + perm.targetUid + " permission to " + perm.uri);
7966 perms.remove(perm.uri);
7967 if (perms.isEmpty()) {
7968 mGrantedUriPermissions.remove(perm.targetUid);
7974 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7975 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7976 "Revoking all granted permissions to " + grantUri);
7978 final IPackageManager pm = AppGlobals.getPackageManager();
7979 final String authority = grantUri.uri.getAuthority();
7980 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7982 Slog.w(TAG, "No content provider found for permission revoke: "
7983 + grantUri.toSafeString());
7987 // Does the caller have this permission on the URI?
7988 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7989 // If they don't have direct access to the URI, then revoke any
7990 // ownerless URI permissions that have been granted to them.
7991 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7992 if (perms != null) {
7993 boolean persistChanged = false;
7994 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7995 final UriPermission perm = it.next();
7996 if (perm.uri.sourceUserId == grantUri.sourceUserId
7997 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7998 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7999 "Revoking non-owned " + perm.targetUid
8000 + " permission to " + perm.uri);
8001 persistChanged |= perm.revokeModes(
8002 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8003 if (perm.modeFlags == 0) {
8008 if (perms.isEmpty()) {
8009 mGrantedUriPermissions.remove(callingUid);
8011 if (persistChanged) {
8012 schedulePersistUriGrants();
8018 boolean persistChanged = false;
8020 // Go through all of the permissions and remove any that match.
8021 int N = mGrantedUriPermissions.size();
8022 for (int i = 0; i < N; i++) {
8023 final int targetUid = mGrantedUriPermissions.keyAt(i);
8024 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8026 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8027 final UriPermission perm = it.next();
8028 if (perm.uri.sourceUserId == grantUri.sourceUserId
8029 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8030 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8031 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8032 persistChanged |= perm.revokeModes(
8033 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8034 if (perm.modeFlags == 0) {
8040 if (perms.isEmpty()) {
8041 mGrantedUriPermissions.remove(targetUid);
8047 if (persistChanged) {
8048 schedulePersistUriGrants();
8053 * @param uri This uri must NOT contain an embedded userId.
8054 * @param userId The userId in which the uri is to be resolved.
8057 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8059 enforceNotIsolatedCaller("revokeUriPermission");
8060 synchronized(this) {
8061 final ProcessRecord r = getRecordForAppLocked(caller);
8063 throw new SecurityException("Unable to find app for caller "
8065 + " when revoking permission to uri " + uri);
8068 Slog.w(TAG, "revokeUriPermission: null uri");
8072 if (!Intent.isAccessUriMode(modeFlags)) {
8076 final String authority = uri.getAuthority();
8077 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8079 Slog.w(TAG, "No content provider found for permission revoke: "
8080 + uri.toSafeString());
8084 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8089 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8092 * @param packageName Package name to match, or {@code null} to apply to all
8094 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8096 * @param persistable If persistable grants should be removed.
8098 private void removeUriPermissionsForPackageLocked(
8099 String packageName, int userHandle, boolean persistable) {
8100 if (userHandle == UserHandle.USER_ALL && packageName == null) {
8101 throw new IllegalArgumentException("Must narrow by either package or user");
8104 boolean persistChanged = false;
8106 int N = mGrantedUriPermissions.size();
8107 for (int i = 0; i < N; i++) {
8108 final int targetUid = mGrantedUriPermissions.keyAt(i);
8109 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8111 // Only inspect grants matching user
8112 if (userHandle == UserHandle.USER_ALL
8113 || userHandle == UserHandle.getUserId(targetUid)) {
8114 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8115 final UriPermission perm = it.next();
8117 // Only inspect grants matching package
8118 if (packageName == null || perm.sourcePkg.equals(packageName)
8119 || perm.targetPkg.equals(packageName)) {
8120 persistChanged |= perm.revokeModes(persistable
8121 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8123 // Only remove when no modes remain; any persisted grants
8124 // will keep this alive.
8125 if (perm.modeFlags == 0) {
8131 if (perms.isEmpty()) {
8132 mGrantedUriPermissions.remove(targetUid);
8139 if (persistChanged) {
8140 schedulePersistUriGrants();
8145 public IBinder newUriPermissionOwner(String name) {
8146 enforceNotIsolatedCaller("newUriPermissionOwner");
8147 synchronized(this) {
8148 UriPermissionOwner owner = new UriPermissionOwner(this, name);
8149 return owner.getExternalTokenLocked();
8154 * @param uri This uri must NOT contain an embedded userId.
8155 * @param sourceUserId The userId in which the uri is to be resolved.
8156 * @param targetUserId The userId of the app that receives the grant.
8159 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8160 final int modeFlags, int sourceUserId, int targetUserId) {
8161 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8162 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8163 "grantUriPermissionFromOwner", null);
8164 synchronized(this) {
8165 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8166 if (owner == null) {
8167 throw new IllegalArgumentException("Unknown owner: " + token);
8169 if (fromUid != Binder.getCallingUid()) {
8170 if (Binder.getCallingUid() != Process.myUid()) {
8171 // Only system code can grant URI permissions on behalf
8173 throw new SecurityException("nice try");
8176 if (targetPkg == null) {
8177 throw new IllegalArgumentException("null target");
8180 throw new IllegalArgumentException("null uri");
8183 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8184 modeFlags, owner, targetUserId);
8189 * @param uri This uri must NOT contain an embedded userId.
8190 * @param userId The userId in which the uri is to be resolved.
8193 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8194 synchronized(this) {
8195 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8196 if (owner == null) {
8197 throw new IllegalArgumentException("Unknown owner: " + token);
8201 owner.removeUriPermissionsLocked(mode);
8203 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8208 private void schedulePersistUriGrants() {
8209 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8210 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8211 10 * DateUtils.SECOND_IN_MILLIS);
8215 private void writeGrantedUriPermissions() {
8216 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8218 // Snapshot permissions so we can persist without lock
8219 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8220 synchronized (this) {
8221 final int size = mGrantedUriPermissions.size();
8222 for (int i = 0; i < size; i++) {
8223 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8224 for (UriPermission perm : perms.values()) {
8225 if (perm.persistedModeFlags != 0) {
8226 persist.add(perm.snapshot());
8232 FileOutputStream fos = null;
8234 fos = mGrantFile.startWrite();
8236 XmlSerializer out = new FastXmlSerializer();
8237 out.setOutput(fos, StandardCharsets.UTF_8.name());
8238 out.startDocument(null, true);
8239 out.startTag(null, TAG_URI_GRANTS);
8240 for (UriPermission.Snapshot perm : persist) {
8241 out.startTag(null, TAG_URI_GRANT);
8242 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8243 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8244 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8245 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8246 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8247 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8248 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8249 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8250 out.endTag(null, TAG_URI_GRANT);
8252 out.endTag(null, TAG_URI_GRANTS);
8255 mGrantFile.finishWrite(fos);
8256 } catch (IOException e) {
8258 mGrantFile.failWrite(fos);
8263 private void readGrantedUriPermissionsLocked() {
8264 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8266 final long now = System.currentTimeMillis();
8268 FileInputStream fis = null;
8270 fis = mGrantFile.openRead();
8271 final XmlPullParser in = Xml.newPullParser();
8272 in.setInput(fis, StandardCharsets.UTF_8.name());
8275 while ((type = in.next()) != END_DOCUMENT) {
8276 final String tag = in.getName();
8277 if (type == START_TAG) {
8278 if (TAG_URI_GRANT.equals(tag)) {
8279 final int sourceUserId;
8280 final int targetUserId;
8281 final int userHandle = readIntAttribute(in,
8282 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8283 if (userHandle != UserHandle.USER_NULL) {
8284 // For backwards compatibility.
8285 sourceUserId = userHandle;
8286 targetUserId = userHandle;
8288 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8289 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8291 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8292 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8293 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8294 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8295 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8296 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8298 // Sanity check that provider still belongs to source package
8299 final ProviderInfo pi = getProviderInfoLocked(
8300 uri.getAuthority(), sourceUserId);
8301 if (pi != null && sourcePkg.equals(pi.packageName)) {
8304 targetUid = AppGlobals.getPackageManager()
8305 .getPackageUid(targetPkg, targetUserId);
8306 } catch (RemoteException e) {
8308 if (targetUid != -1) {
8309 final UriPermission perm = findOrCreateUriPermissionLocked(
8310 sourcePkg, targetPkg, targetUid,
8311 new GrantUri(sourceUserId, uri, prefix));
8312 perm.initPersistedModes(modeFlags, createdTime);
8315 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8316 + " but instead found " + pi);
8321 } catch (FileNotFoundException e) {
8322 // Missing grants is okay
8323 } catch (IOException e) {
8324 Slog.wtf(TAG, "Failed reading Uri grants", e);
8325 } catch (XmlPullParserException e) {
8326 Slog.wtf(TAG, "Failed reading Uri grants", e);
8328 IoUtils.closeQuietly(fis);
8333 * @param uri This uri must NOT contain an embedded userId.
8334 * @param userId The userId in which the uri is to be resolved.
8337 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8338 enforceNotIsolatedCaller("takePersistableUriPermission");
8340 Preconditions.checkFlagsArgument(modeFlags,
8341 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8343 synchronized (this) {
8344 final int callingUid = Binder.getCallingUid();
8345 boolean persistChanged = false;
8346 GrantUri grantUri = new GrantUri(userId, uri, false);
8348 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8349 new GrantUri(userId, uri, false));
8350 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8351 new GrantUri(userId, uri, true));
8353 final boolean exactValid = (exactPerm != null)
8354 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8355 final boolean prefixValid = (prefixPerm != null)
8356 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8358 if (!(exactValid || prefixValid)) {
8359 throw new SecurityException("No persistable permission grants found for UID "
8360 + callingUid + " and Uri " + grantUri.toSafeString());
8364 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8367 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8370 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8372 if (persistChanged) {
8373 schedulePersistUriGrants();
8379 * @param uri This uri must NOT contain an embedded userId.
8380 * @param userId The userId in which the uri is to be resolved.
8383 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8384 enforceNotIsolatedCaller("releasePersistableUriPermission");
8386 Preconditions.checkFlagsArgument(modeFlags,
8387 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8389 synchronized (this) {
8390 final int callingUid = Binder.getCallingUid();
8391 boolean persistChanged = false;
8393 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8394 new GrantUri(userId, uri, false));
8395 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8396 new GrantUri(userId, uri, true));
8397 if (exactPerm == null && prefixPerm == null) {
8398 throw new SecurityException("No permission grants found for UID " + callingUid
8399 + " and Uri " + uri.toSafeString());
8402 if (exactPerm != null) {
8403 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8404 removeUriPermissionIfNeededLocked(exactPerm);
8406 if (prefixPerm != null) {
8407 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8408 removeUriPermissionIfNeededLocked(prefixPerm);
8411 if (persistChanged) {
8412 schedulePersistUriGrants();
8418 * Prune any older {@link UriPermission} for the given UID until outstanding
8419 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8421 * @return if any mutations occured that require persisting.
8423 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8424 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8425 if (perms == null) return false;
8426 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8428 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8429 for (UriPermission perm : perms.values()) {
8430 if (perm.persistedModeFlags != 0) {
8431 persisted.add(perm);
8435 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8436 if (trimCount <= 0) return false;
8438 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8439 for (int i = 0; i < trimCount; i++) {
8440 final UriPermission perm = persisted.get(i);
8442 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8443 "Trimming grant created at " + perm.persistedCreateTime);
8445 perm.releasePersistableModes(~0);
8446 removeUriPermissionIfNeededLocked(perm);
8453 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8454 String packageName, boolean incoming) {
8455 enforceNotIsolatedCaller("getPersistedUriPermissions");
8456 Preconditions.checkNotNull(packageName, "packageName");
8458 final int callingUid = Binder.getCallingUid();
8459 final IPackageManager pm = AppGlobals.getPackageManager();
8461 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8462 if (packageUid != callingUid) {
8463 throw new SecurityException(
8464 "Package " + packageName + " does not belong to calling UID " + callingUid);
8466 } catch (RemoteException e) {
8467 throw new SecurityException("Failed to verify package name ownership");
8470 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8471 synchronized (this) {
8473 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8475 if (perms == null) {
8476 Slog.w(TAG, "No permission grants found for " + packageName);
8478 for (UriPermission perm : perms.values()) {
8479 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8480 result.add(perm.buildPersistedPublicApiObject());
8485 final int size = mGrantedUriPermissions.size();
8486 for (int i = 0; i < size; i++) {
8487 final ArrayMap<GrantUri, UriPermission> perms =
8488 mGrantedUriPermissions.valueAt(i);
8489 for (UriPermission perm : perms.values()) {
8490 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8491 result.add(perm.buildPersistedPublicApiObject());
8497 return new ParceledListSlice<android.content.UriPermission>(result);
8501 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8502 synchronized (this) {
8504 who != null ? getRecordForAppLocked(who) : null;
8505 if (app == null) return;
8507 Message msg = Message.obtain();
8508 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8510 msg.arg1 = waiting ? 1 : 0;
8511 mUiHandler.sendMessage(msg);
8516 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8517 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8518 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8519 outInfo.availMem = Process.getFreeMemory();
8520 outInfo.totalMem = Process.getTotalMemory();
8521 outInfo.threshold = homeAppMem;
8522 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8523 outInfo.hiddenAppThreshold = cachedAppMem;
8524 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8525 ProcessList.SERVICE_ADJ);
8526 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8527 ProcessList.VISIBLE_APP_ADJ);
8528 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8529 ProcessList.FOREGROUND_APP_ADJ);
8532 // =========================================================
8534 // =========================================================
8537 public List<IAppTask> getAppTasks(String callingPackage) {
8538 int callingUid = Binder.getCallingUid();
8539 long ident = Binder.clearCallingIdentity();
8541 synchronized(this) {
8542 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8544 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8546 final int N = mRecentTasks.size();
8547 for (int i = 0; i < N; i++) {
8548 TaskRecord tr = mRecentTasks.get(i);
8549 // Skip tasks that do not match the caller. We don't need to verify
8550 // callingPackage, because we are also limiting to callingUid and know
8551 // that will limit to the correct security sandbox.
8552 if (tr.effectiveUid != callingUid) {
8555 Intent intent = tr.getBaseIntent();
8556 if (intent == null ||
8557 !callingPackage.equals(intent.getComponent().getPackageName())) {
8560 ActivityManager.RecentTaskInfo taskInfo =
8561 createRecentTaskInfoFromTaskRecord(tr);
8562 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8566 Binder.restoreCallingIdentity(ident);
8573 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8574 final int callingUid = Binder.getCallingUid();
8575 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8577 synchronized(this) {
8578 if (DEBUG_ALL) Slog.v(
8579 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8581 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8584 // TODO: Improve with MRU list from all ActivityStacks.
8585 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8592 * Creates a new RecentTaskInfo from a TaskRecord.
8594 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8595 // Update the task description to reflect any changes in the task stack
8596 tr.updateTaskDescription();
8598 // Compose the recent task info
8599 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8600 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8601 rti.persistentId = tr.taskId;
8602 rti.baseIntent = new Intent(tr.getBaseIntent());
8603 rti.origActivity = tr.origActivity;
8604 rti.realActivity = tr.realActivity;
8605 rti.description = tr.lastDescription;
8606 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8607 rti.userId = tr.userId;
8608 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8609 rti.firstActiveTime = tr.firstActiveTime;
8610 rti.lastActiveTime = tr.lastActiveTime;
8611 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8612 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8613 rti.numActivities = 0;
8614 if (tr.mBounds != null) {
8615 rti.bounds = new Rect(tr.mBounds);
8618 ActivityRecord base = null;
8619 ActivityRecord top = null;
8622 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8623 tmp = tr.mActivities.get(i);
8624 if (tmp.finishing) {
8628 if (top == null || (top.state == ActivityState.INITIALIZING)) {
8631 rti.numActivities++;
8634 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8635 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8640 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8641 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8642 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8644 if (checkPermission(android.Manifest.permission.GET_TASKS,
8645 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8646 // Temporary compatibility: some existing apps on the system image may
8647 // still be requesting the old permission and not switched to the new
8648 // one; if so, we'll still allow them full access. This means we need
8649 // to see if they are holding the old permission and are a system app.
8651 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8653 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8654 + " is using old GET_TASKS but privileged; allowing");
8656 } catch (RemoteException e) {
8661 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8662 + " does not hold REAL_GET_TASKS; limiting output");
8668 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8669 final int callingUid = Binder.getCallingUid();
8670 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8671 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8673 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8674 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8675 synchronized (this) {
8676 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8678 final boolean detailed = checkCallingPermission(
8679 android.Manifest.permission.GET_DETAILED_TASKS)
8680 == PackageManager.PERMISSION_GRANTED;
8682 final int recentsCount = mRecentTasks.size();
8683 ArrayList<ActivityManager.RecentTaskInfo> res =
8684 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8686 final Set<Integer> includedUsers;
8687 if (includeProfiles) {
8688 includedUsers = mUserController.getProfileIds(userId);
8690 includedUsers = new HashSet<>();
8692 includedUsers.add(Integer.valueOf(userId));
8694 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8695 TaskRecord tr = mRecentTasks.get(i);
8696 // Only add calling user or related users recent tasks
8697 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8698 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8702 // Return the entry if desired by the caller. We always return
8703 // the first entry, because callers always expect this to be the
8704 // foreground app. We may filter others if the caller has
8705 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8706 // we should exclude the entry.
8710 || (tr.intent == null)
8711 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8714 // If the caller doesn't have the GET_TASKS permission, then only
8715 // allow them to see a small subset of tasks -- their own and home.
8716 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8717 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8721 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8722 if (tr.stack != null && tr.stack.isHomeStack()) {
8723 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8724 "Skipping, home stack task: " + tr);
8728 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8729 // Don't include auto remove tasks that are finished or finishing.
8730 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8731 "Skipping, auto-remove without activity: " + tr);
8734 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8735 && !tr.isAvailable) {
8736 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8737 "Skipping, unavail real act: " + tr);
8741 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8743 rti.baseIntent.replaceExtras((Bundle)null);
8755 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8756 synchronized (this) {
8757 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8758 "getTaskThumbnail()");
8759 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8760 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8762 return tr.getTaskThumbnailLocked();
8769 public int addAppTask(IBinder activityToken, Intent intent,
8770 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8771 final int callingUid = Binder.getCallingUid();
8772 final long callingIdent = Binder.clearCallingIdentity();
8775 synchronized (this) {
8776 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8778 throw new IllegalArgumentException("Activity does not exist; token="
8781 ComponentName comp = intent.getComponent();
8783 throw new IllegalArgumentException("Intent " + intent
8784 + " must specify explicit component");
8786 if (thumbnail.getWidth() != mThumbnailWidth
8787 || thumbnail.getHeight() != mThumbnailHeight) {
8788 throw new IllegalArgumentException("Bad thumbnail size: got "
8789 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8790 + mThumbnailWidth + "x" + mThumbnailHeight);
8792 if (intent.getSelector() != null) {
8793 intent.setSelector(null);
8795 if (intent.getSourceBounds() != null) {
8796 intent.setSourceBounds(null);
8798 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8799 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8800 // The caller has added this as an auto-remove task... that makes no
8801 // sense, so turn off auto-remove.
8802 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8804 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8805 // Must be a new task.
8806 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8808 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8809 mLastAddedTaskActivity = null;
8811 ActivityInfo ainfo = mLastAddedTaskActivity;
8812 if (ainfo == null) {
8813 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8814 comp, 0, UserHandle.getUserId(callingUid));
8815 if (ainfo.applicationInfo.uid != callingUid) {
8816 throw new SecurityException(
8817 "Can't add task for another application: target uid="
8818 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8822 // Use the full screen as the context for the task thumbnail
8823 final Point displaySize = new Point();
8824 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
8825 r.task.stack.getDisplaySize(displaySize);
8826 thumbnailInfo.taskWidth = displaySize.x;
8827 thumbnailInfo.taskHeight = displaySize.y;
8828 thumbnailInfo.screenOrientation = mConfiguration.orientation;
8830 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8831 intent, description, thumbnailInfo);
8833 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8835 // If this would have caused a trim, then we'll abort because that
8836 // means it would be added at the end of the list but then just removed.
8837 return INVALID_TASK_ID;
8840 final int N = mRecentTasks.size();
8841 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8842 final TaskRecord tr = mRecentTasks.remove(N - 1);
8843 tr.removedFromRecents();
8846 task.inRecents = true;
8847 mRecentTasks.add(task);
8848 r.task.stack.addTask(task, false, false);
8850 task.setLastThumbnailLocked(thumbnail);
8851 task.freeLastThumbnail();
8856 Binder.restoreCallingIdentity(callingIdent);
8861 public Point getAppTaskThumbnailSize() {
8862 synchronized (this) {
8863 return new Point(mThumbnailWidth, mThumbnailHeight);
8868 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8869 synchronized (this) {
8870 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8872 r.setTaskDescription(td);
8873 r.task.updateTaskDescription();
8879 public void setTaskResizeable(int taskId, boolean resizeable) {
8880 synchronized (this) {
8881 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8882 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8884 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8887 if (task.mResizeable != resizeable) {
8888 task.mResizeable = resizeable;
8889 mWindowManager.setTaskResizeable(taskId, resizeable);
8890 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
8891 mStackSupervisor.resumeTopActivitiesLocked();
8897 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
8898 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8900 long ident = Binder.clearCallingIdentity();
8902 synchronized (this) {
8903 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8905 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8908 int stackId = task.stack.mStackId;
8909 // First, check if this is a non-resizeble task in docked stack or if the task size
8910 // is affected by the docked stack changing size. If so, instead of resizing, we
8911 // can only scroll the task. No need to update configuration.
8912 if (bounds != null && !task.mResizeable
8913 && mStackSupervisor.isStackDockedInEffect(stackId)) {
8914 mWindowManager.scrollTask(task.taskId, bounds);
8918 // Place the task in the right stack if it isn't there already based on
8919 // the requested bounds.
8920 // The stack transition logic is:
8921 // - a null bounds on a freeform task moves that task to fullscreen
8922 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
8923 // that task to freeform
8924 // - otherwise the task is not moved
8925 if (!StackId.isTaskResizeAllowed(stackId)) {
8926 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
8928 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
8929 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
8930 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
8931 stackId = FREEFORM_WORKSPACE_STACK_ID;
8933 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
8934 if (stackId != task.stack.mStackId) {
8935 mStackSupervisor.moveTaskToStackUncheckedLocked(
8936 task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
8937 preserveWindow = false;
8940 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow);
8943 Binder.restoreCallingIdentity(ident);
8948 public Rect getTaskBounds(int taskId) {
8949 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8951 long ident = Binder.clearCallingIdentity();
8952 Rect rect = new Rect();
8954 synchronized (this) {
8955 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
8956 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8958 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
8961 if (task.stack != null) {
8962 // Return the bounds from window manager since it will be adjusted for various
8963 // things like the presense of a docked stack for tasks that aren't resizeable.
8964 mWindowManager.getTaskBounds(task.taskId, rect);
8966 // Task isn't in window manager yet since it isn't associated with a stack.
8967 // Return the persist value from activity manager
8968 if (task.mBounds != null) {
8969 rect.set(task.mBounds);
8970 } else if (task.mLastNonFullscreenBounds != null) {
8971 rect.set(task.mLastNonFullscreenBounds);
8976 Binder.restoreCallingIdentity(ident);
8982 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
8983 if (userId != UserHandle.getCallingUserId()) {
8984 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8985 "getTaskDescriptionIcon");
8987 final File passedIconFile = new File(filePath);
8988 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
8989 passedIconFile.getName());
8990 if (!legitIconFile.getPath().equals(filePath)
8991 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8992 throw new IllegalArgumentException("Bad file path: " + filePath);
8994 return mTaskPersister.getTaskDescriptionIcon(filePath);
8998 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8999 throws RemoteException {
9000 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9001 opts.getCustomInPlaceResId() == 0) {
9002 throw new IllegalArgumentException("Expected in-place ActivityOption " +
9003 "with valid animation");
9005 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
9006 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9007 opts.getCustomInPlaceResId());
9008 mWindowManager.executeAppTransition();
9011 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9012 boolean removeFromRecents) {
9013 if (removeFromRecents) {
9014 mRecentTasks.remove(tr);
9015 tr.removedFromRecents();
9017 ComponentName component = tr.getBaseIntent().getComponent();
9018 if (component == null) {
9019 Slog.w(TAG, "No component for base intent of task: " + tr);
9023 // Find any running services associated with this app and stop if needed.
9024 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9030 // Determine if the process(es) for this task should be killed.
9031 final String pkg = component.getPackageName();
9032 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9033 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9034 for (int i = 0; i < pmap.size(); i++) {
9036 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9037 for (int j = 0; j < uids.size(); j++) {
9038 ProcessRecord proc = uids.valueAt(j);
9039 if (proc.userId != tr.userId) {
9040 // Don't kill process for a different user.
9043 if (proc == mHomeProcess) {
9044 // Don't kill the home process along with tasks from the same package.
9047 if (!proc.pkgList.containsKey(pkg)) {
9048 // Don't kill process that is not associated with this task.
9052 for (int k = 0; k < proc.activities.size(); k++) {
9053 TaskRecord otherTask = proc.activities.get(k).task;
9054 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9055 // Don't kill process(es) that has an activity in a different task that is
9061 if (proc.foregroundServices) {
9062 // Don't kill process(es) with foreground service.
9066 // Add process to kill list.
9067 procsToKill.add(proc);
9071 // Kill the running processes.
9072 for (int i = 0; i < procsToKill.size(); i++) {
9073 ProcessRecord pr = procsToKill.get(i);
9074 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
9075 && pr.curReceiver == null) {
9076 pr.kill("remove task", true);
9078 // We delay killing processes that are not in the background or running a receiver.
9079 pr.waitingToKill = "remove task";
9084 private void removeTasksByPackageNameLocked(String packageName, int userId) {
9085 // Remove all tasks with activities in the specified package from the list of recent tasks
9086 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9087 TaskRecord tr = mRecentTasks.get(i);
9088 if (tr.userId != userId) continue;
9090 ComponentName cn = tr.intent.getComponent();
9091 if (cn != null && cn.getPackageName().equals(packageName)) {
9092 // If the package name matches, remove the task.
9093 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9098 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9101 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9102 TaskRecord tr = mRecentTasks.get(i);
9103 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9107 ComponentName cn = tr.intent.getComponent();
9108 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9109 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9110 if (sameComponent) {
9111 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9117 * Removes the task with the specified task id.
9119 * @param taskId Identifier of the task to be removed.
9120 * @param killProcess Kill any process associated with the task if possible.
9121 * @param removeFromRecents Whether to also remove the task from recents.
9122 * @return Returns true if the given task was found and removed.
9124 private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9125 boolean removeFromRecents) {
9126 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9127 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9129 tr.removeTaskActivitiesLocked();
9130 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9131 if (tr.isPersistable) {
9132 notifyTaskPersisterLocked(null, true);
9136 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9141 public boolean removeTask(int taskId) {
9142 synchronized (this) {
9143 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
9145 long ident = Binder.clearCallingIdentity();
9147 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9149 Binder.restoreCallingIdentity(ident);
9155 * TODO: Add mController hook
9158 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9159 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9161 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9162 synchronized(this) {
9163 moveTaskToFrontLocked(taskId, flags, bOptions);
9167 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9168 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9170 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9171 Binder.getCallingUid(), -1, -1, "Task to front")) {
9172 ActivityOptions.abort(options);
9175 final long origId = Binder.clearCallingIdentity();
9177 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9179 Slog.d(TAG, "Could not find task for id: "+ taskId);
9182 if (mStackSupervisor.isLockTaskModeViolation(task)) {
9183 mStackSupervisor.showLockTaskToast();
9184 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9187 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9188 if (prev != null && prev.isRecentsActivity()) {
9189 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9191 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9193 Binder.restoreCallingIdentity(origId);
9195 ActivityOptions.abort(options);
9199 * Moves an activity, and all of the other activities within the same task, to the bottom
9200 * of the history stack. The activity's order within the task is unchanged.
9202 * @param token A reference to the activity we wish to move
9203 * @param nonRoot If false then this only works if the activity is the root
9204 * of a task; if true it will work for any activity in a task.
9205 * @return Returns true if the move completed, false if not.
9208 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9209 enforceNotIsolatedCaller("moveActivityTaskToBack");
9210 synchronized(this) {
9211 final long origId = Binder.clearCallingIdentity();
9213 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9214 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9216 if (mStackSupervisor.isLockedTask(task)) {
9217 mStackSupervisor.showLockTaskToast();
9220 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9223 Binder.restoreCallingIdentity(origId);
9230 public void moveTaskBackwards(int task) {
9231 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9232 "moveTaskBackwards()");
9234 synchronized(this) {
9235 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9236 Binder.getCallingUid(), -1, -1, "Task backwards")) {
9239 final long origId = Binder.clearCallingIdentity();
9240 moveTaskBackwardsLocked(task);
9241 Binder.restoreCallingIdentity(origId);
9245 private final void moveTaskBackwardsLocked(int task) {
9246 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9250 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9251 IActivityContainerCallback callback) throws RemoteException {
9252 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9253 "createActivityContainer()");
9254 synchronized (this) {
9255 if (parentActivityToken == null) {
9256 throw new IllegalArgumentException("parent token must not be null");
9258 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9262 if (callback == null) {
9263 throw new IllegalArgumentException("callback must not be null");
9265 return mStackSupervisor.createVirtualActivityContainer(r, callback);
9270 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9271 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9272 "deleteActivityContainer()");
9273 synchronized (this) {
9274 mStackSupervisor.deleteActivityContainer(container);
9279 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9280 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9281 "createStackOnDisplay()");
9282 synchronized (this) {
9283 final int stackId = mStackSupervisor.getNextStackId();
9284 final ActivityStack stack =
9285 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9286 if (stack == null) {
9289 return stack.mActivityContainer;
9294 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9295 synchronized (this) {
9296 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9297 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9298 return stack.mActivityContainer.getDisplayId();
9300 return Display.DEFAULT_DISPLAY;
9305 public int getActivityStackId(IBinder token) throws RemoteException {
9306 synchronized (this) {
9307 ActivityStack stack = ActivityRecord.getStackLocked(token);
9308 if (stack == null) {
9309 return INVALID_STACK_ID;
9311 return stack.mStackId;
9316 public void moveActivityToStack(IBinder token, int stackId) throws RemoteException {
9317 if (stackId == HOME_STACK_ID) {
9318 throw new IllegalArgumentException(
9319 "moveActivityToStack: Attempt to move token " + token + " to home stack");
9321 synchronized (this) {
9322 long ident = Binder.clearCallingIdentity();
9324 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9326 throw new IllegalArgumentException(
9327 "moveActivityToStack: No activity record matching token=" + token);
9329 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveActivityToStack: moving r=" + r
9330 + " to stackId=" + stackId);
9331 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, stackId, ON_TOP, !FORCE_FOCUS,
9332 "moveActivityToStack", true /* animate */);
9334 Binder.restoreCallingIdentity(ident);
9340 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9341 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9342 "moveTaskToStack()");
9343 if (stackId == HOME_STACK_ID) {
9344 throw new IllegalArgumentException(
9345 "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9347 synchronized (this) {
9348 long ident = Binder.clearCallingIdentity();
9350 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9351 + " to stackId=" + stackId + " toTop=" + toTop);
9352 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9353 "moveTaskToStack", true /* animate */);
9355 Binder.restoreCallingIdentity(ident);
9361 * Moves the input task to the docked stack.
9363 * @param taskId Id of task to move.
9364 * @param createMode The mode the docked stack should be created in if it doesn't exist
9366 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9368 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9369 * @param toTop If the task and stack should be moved to the top.
9370 * @param animate Whether we should play an animation for the moving the task
9371 * @param initialBounds If the docked stack gets created, it will use these bounds for the
9372 * docked stack. Pass {@code null} to use default bounds.
9375 public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9376 Rect initialBounds) {
9377 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9378 "moveTaskToDockedStack()");
9379 synchronized (this) {
9380 long ident = Binder.clearCallingIdentity();
9382 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9383 + " to createMode=" + createMode + " toTop=" + toTop);
9384 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9385 mStackSupervisor.moveTaskToStackLocked(taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9386 "moveTaskToDockedStack", animate);
9388 Binder.restoreCallingIdentity(ident);
9394 * Moves the top activity in the input stackId to the pinned stack.
9396 * @param stackId Id of stack to move the top activity to pinned stack.
9397 * @param bounds Bounds to use for pinned stack.
9399 * @return True if the top activity of the input stack was successfully moved to the pinned
9403 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9404 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9405 "moveTopActivityToPinnedStack()");
9406 synchronized (this) {
9407 long ident = Binder.clearCallingIdentity();
9409 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9411 Binder.restoreCallingIdentity(ident);
9417 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
9418 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9420 long ident = Binder.clearCallingIdentity();
9422 synchronized (this) {
9423 mStackSupervisor.resizeStackLocked(
9424 stackId, bounds, !PRESERVE_WINDOWS, allowResizeInDockedMode);
9427 Binder.restoreCallingIdentity(ident);
9432 public void positionTaskInStack(int taskId, int stackId, int position) {
9433 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9434 "positionTaskInStack()");
9435 if (stackId == HOME_STACK_ID) {
9436 throw new IllegalArgumentException(
9437 "positionTaskInStack: Attempt to change the position of task "
9438 + taskId + " in/to home stack");
9440 synchronized (this) {
9441 long ident = Binder.clearCallingIdentity();
9443 if (DEBUG_STACK) Slog.d(TAG_STACK,
9444 "positionTaskInStack: positioning task=" + taskId
9445 + " in stackId=" + stackId + " at position=" + position);
9446 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9448 Binder.restoreCallingIdentity(ident);
9454 public List<StackInfo> getAllStackInfos() {
9455 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9456 "getAllStackInfos()");
9457 long ident = Binder.clearCallingIdentity();
9459 synchronized (this) {
9460 return mStackSupervisor.getAllStackInfosLocked();
9463 Binder.restoreCallingIdentity(ident);
9468 public StackInfo getStackInfo(int stackId) {
9469 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9471 long ident = Binder.clearCallingIdentity();
9473 synchronized (this) {
9474 return mStackSupervisor.getStackInfoLocked(stackId);
9477 Binder.restoreCallingIdentity(ident);
9482 public boolean isInHomeStack(int taskId) {
9483 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9485 long ident = Binder.clearCallingIdentity();
9487 synchronized (this) {
9488 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9489 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9490 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9493 Binder.restoreCallingIdentity(ident);
9498 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9499 synchronized(this) {
9500 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9505 public void updateDeviceOwner(String packageName) {
9506 final int callingUid = Binder.getCallingUid();
9507 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9508 throw new SecurityException("updateDeviceOwner called from non-system process");
9510 synchronized (this) {
9511 mDeviceOwnerName = packageName;
9516 public void updateLockTaskPackages(int userId, String[] packages) {
9517 final int callingUid = Binder.getCallingUid();
9518 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9519 throw new SecurityException("updateLockTaskPackage called from non-system process");
9521 synchronized (this) {
9522 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9523 Arrays.toString(packages));
9524 mLockTaskPackages.put(userId, packages);
9525 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9530 void startLockTaskModeLocked(TaskRecord task) {
9531 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9532 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9536 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9537 // is initiated by system after the pinning request was shown and locked mode is initiated
9538 // by an authorized app directly
9539 final int callingUid = Binder.getCallingUid();
9540 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9541 long ident = Binder.clearCallingIdentity();
9543 final ActivityStack stack = mStackSupervisor.getFocusedStack();
9544 if (!isSystemInitiated) {
9545 task.mLockTaskUid = callingUid;
9546 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9547 // startLockTask() called by app and task mode is lockTaskModeDefault.
9548 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9549 StatusBarManagerInternal statusBarManager =
9550 LocalServices.getService(StatusBarManagerInternal.class);
9551 if (statusBarManager != null) {
9552 statusBarManager.showScreenPinningRequest();
9557 if (stack == null || task != stack.topTask()) {
9558 throw new IllegalArgumentException("Invalid task, not in foreground");
9561 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9563 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9564 ActivityManager.LOCK_TASK_MODE_PINNED :
9565 ActivityManager.LOCK_TASK_MODE_LOCKED,
9566 "startLockTask", true);
9568 Binder.restoreCallingIdentity(ident);
9573 public void startLockTaskMode(int taskId) {
9574 synchronized (this) {
9575 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9577 startLockTaskModeLocked(task);
9583 public void startLockTaskMode(IBinder token) {
9584 synchronized (this) {
9585 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9589 final TaskRecord task = r.task;
9591 startLockTaskModeLocked(task);
9597 public void startLockTaskModeOnCurrent() throws RemoteException {
9598 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9599 "startLockTaskModeOnCurrent");
9600 long ident = Binder.clearCallingIdentity();
9602 synchronized (this) {
9603 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9605 startLockTaskModeLocked(r.task);
9609 Binder.restoreCallingIdentity(ident);
9614 public void stopLockTaskMode() {
9615 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9616 if (lockTask == null) {
9617 // Our work here is done.
9621 final int callingUid = Binder.getCallingUid();
9622 final int lockTaskUid = lockTask.mLockTaskUid;
9623 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9624 // It is possible lockTaskMode was started by the system process because
9625 // android:lockTaskMode is set to a locking value in the application manifest instead of
9626 // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9627 // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9628 if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9629 callingUid != lockTaskUid
9630 && (lockTaskUid != 0
9631 || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9632 throw new SecurityException("Invalid uid, expected " + lockTaskUid
9633 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9636 long ident = Binder.clearCallingIdentity();
9638 Log.d(TAG, "stopLockTaskMode");
9640 synchronized (this) {
9641 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9642 "stopLockTask", true);
9645 Binder.restoreCallingIdentity(ident);
9650 public void stopLockTaskModeOnCurrent() throws RemoteException {
9651 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9652 "stopLockTaskModeOnCurrent");
9653 long ident = Binder.clearCallingIdentity();
9657 Binder.restoreCallingIdentity(ident);
9662 public boolean isInLockTaskMode() {
9663 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9667 public int getLockTaskModeState() {
9668 synchronized (this) {
9669 return mStackSupervisor.getLockTaskModeState();
9674 public void showLockTaskEscapeMessage(IBinder token) {
9675 synchronized (this) {
9676 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9680 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9684 // =========================================================
9685 // CONTENT PROVIDERS
9686 // =========================================================
9688 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9689 List<ProviderInfo> providers = null;
9691 ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9692 queryContentProviders(app.processName, app.uid,
9693 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9694 providers = slice != null ? slice.getList() : null;
9695 } catch (RemoteException ex) {
9697 if (DEBUG_MU) Slog.v(TAG_MU,
9698 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9699 int userId = app.userId;
9700 if (providers != null) {
9701 int N = providers.size();
9702 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9703 for (int i=0; i<N; i++) {
9705 (ProviderInfo)providers.get(i);
9706 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9707 cpi.name, cpi.flags);
9708 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
9709 // This is a singleton provider, but a user besides the
9710 // default user is asking to initialize a process it runs
9711 // in... well, no, it doesn't actually run in this process,
9712 // it runs in the process of the default user. Get rid of it.
9713 providers.remove(i);
9719 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9720 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9722 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9723 mProviderMap.putProviderByClass(comp, cpr);
9725 if (DEBUG_MU) Slog.v(TAG_MU,
9726 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9727 app.pubProviders.put(cpi.name, cpr);
9728 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9729 // Don't add this if it is a platform component that is marked
9730 // to run in multiple processes, because this is actually
9731 // part of the framework so doesn't make sense to track as a
9732 // separate apk in the process.
9733 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9736 notifyPackageUse(cpi.applicationInfo.packageName);
9743 * Check if {@link ProcessRecord} has a possible chance at accessing the
9744 * given {@link ProviderInfo}. Final permission checking is always done
9745 * in {@link ContentProvider}.
9747 private final String checkContentProviderPermissionLocked(
9748 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9749 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9750 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9751 boolean checkedGrants = false;
9753 // Looking for cross-user grants before enforcing the typical cross-users permissions
9754 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
9755 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9756 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9759 checkedGrants = true;
9761 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
9762 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
9763 if (userId != tmpTargetUserId) {
9764 // When we actually went to determine the final targer user ID, this ended
9765 // up different than our initial check for the authority. This is because
9766 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9767 // SELF. So we need to re-check the grants again.
9768 checkedGrants = false;
9771 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9772 cpi.applicationInfo.uid, cpi.exported)
9773 == PackageManager.PERMISSION_GRANTED) {
9776 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9777 cpi.applicationInfo.uid, cpi.exported)
9778 == PackageManager.PERMISSION_GRANTED) {
9782 PathPermission[] pps = cpi.pathPermissions;
9787 PathPermission pp = pps[i];
9788 String pprperm = pp.getReadPermission();
9789 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9790 cpi.applicationInfo.uid, cpi.exported)
9791 == PackageManager.PERMISSION_GRANTED) {
9794 String ppwperm = pp.getWritePermission();
9795 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9796 cpi.applicationInfo.uid, cpi.exported)
9797 == PackageManager.PERMISSION_GRANTED) {
9802 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9807 if (!cpi.exported) {
9808 msg = "Permission Denial: opening provider " + cpi.name
9809 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9810 + ", uid=" + callingUid + ") that is not exported from uid "
9811 + cpi.applicationInfo.uid;
9813 msg = "Permission Denial: opening provider " + cpi.name
9814 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9815 + ", uid=" + callingUid + ") requires "
9816 + cpi.readPermission + " or " + cpi.writePermission;
9823 * Returns if the ContentProvider has granted a uri to callingUid
9825 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9826 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9827 if (perms != null) {
9828 for (int i=perms.size()-1; i>=0; i--) {
9829 GrantUri grantUri = perms.keyAt(i);
9830 if (grantUri.sourceUserId == userId || !checkUser) {
9831 if (matchesProvider(grantUri.uri, cpi)) {
9841 * Returns true if the uri authority is one of the authorities specified in the provider.
9843 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9844 String uriAuth = uri.getAuthority();
9845 String cpiAuth = cpi.authority;
9846 if (cpiAuth.indexOf(';') == -1) {
9847 return cpiAuth.equals(uriAuth);
9849 String[] cpiAuths = cpiAuth.split(";");
9850 int length = cpiAuths.length;
9851 for (int i = 0; i < length; i++) {
9852 if (cpiAuths[i].equals(uriAuth)) return true;
9857 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9858 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9860 for (int i=0; i<r.conProviders.size(); i++) {
9861 ContentProviderConnection conn = r.conProviders.get(i);
9862 if (conn.provider == cpr) {
9863 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9864 "Adding provider requested by "
9865 + r.processName + " from process "
9866 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9867 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9870 conn.numStableIncs++;
9872 conn.unstableCount++;
9873 conn.numUnstableIncs++;
9878 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9880 conn.stableCount = 1;
9881 conn.numStableIncs = 1;
9883 conn.unstableCount = 1;
9884 conn.numUnstableIncs = 1;
9886 cpr.connections.add(conn);
9887 r.conProviders.add(conn);
9888 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9891 cpr.addExternalProcessHandleLocked(externalProcessToken);
9895 boolean decProviderCountLocked(ContentProviderConnection conn,
9896 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9898 cpr = conn.provider;
9899 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9900 "Removing provider requested by "
9901 + conn.client.processName + " from process "
9902 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9903 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9907 conn.unstableCount--;
9909 if (conn.stableCount == 0 && conn.unstableCount == 0) {
9910 cpr.connections.remove(conn);
9911 conn.client.conProviders.remove(conn);
9912 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
9913 // The client is more important than last activity -- note the time this
9914 // is happening, so we keep the old provider process around a bit as last
9915 // activity to avoid thrashing it.
9916 if (cpr.proc != null) {
9917 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
9920 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9925 cpr.removeExternalProcessHandleLocked(externalProcessToken);
9929 private void checkTime(long startTime, String where) {
9930 long now = SystemClock.elapsedRealtime();
9931 if ((now-startTime) > 1000) {
9932 // If we are taking more than a second, log about it.
9933 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9937 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9938 String name, IBinder token, boolean stable, int userId) {
9939 ContentProviderRecord cpr;
9940 ContentProviderConnection conn = null;
9941 ProviderInfo cpi = null;
9943 synchronized(this) {
9944 long startTime = SystemClock.elapsedRealtime();
9946 ProcessRecord r = null;
9947 if (caller != null) {
9948 r = getRecordForAppLocked(caller);
9950 throw new SecurityException(
9951 "Unable to find app for caller " + caller
9952 + " (pid=" + Binder.getCallingPid()
9953 + ") when getting content provider " + name);
9957 boolean checkCrossUser = true;
9959 checkTime(startTime, "getContentProviderImpl: getProviderByName");
9961 // First check if this content provider has been published...
9962 cpr = mProviderMap.getProviderByName(name, userId);
9963 // If that didn't work, check if it exists for user 0 and then
9964 // verify that it's a singleton provider before using it.
9965 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
9966 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
9969 if (isSingleton(cpi.processName, cpi.applicationInfo,
9970 cpi.name, cpi.flags)
9971 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9972 userId = UserHandle.USER_SYSTEM;
9973 checkCrossUser = false;
9981 boolean providerRunning = cpr != null;
9982 if (providerRunning) {
9985 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9986 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9988 throw new SecurityException(msg);
9990 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9992 if (r != null && cpr.canRunHere(r)) {
9993 // This provider has been published or is in the process
9994 // of being published... but it is also allowed to run
9995 // in the caller's process, so don't make a connection
9996 // and just let the caller instantiate its own instance.
9997 ContentProviderHolder holder = cpr.newHolder(null);
9998 // don't give caller the provider object, it needs
10000 holder.provider = null;
10004 final long origId = Binder.clearCallingIdentity();
10006 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10008 // In this case the provider instance already exists, so we can
10009 // return it right away.
10010 conn = incProviderCountLocked(r, cpr, token, stable);
10011 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10012 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10013 // If this is a perceptible app accessing the provider,
10014 // make sure to count it as being accessed and thus
10015 // back up on the LRU list. This is good because
10016 // content providers are often expensive to start.
10017 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10018 updateLruProcessLocked(cpr.proc, false, null);
10019 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10023 if (cpr.proc != null) {
10024 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10025 boolean success = updateOomAdjLocked(cpr.proc);
10026 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10027 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10028 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10029 // NOTE: there is still a race here where a signal could be
10030 // pending on the process even though we managed to update its
10031 // adj level. Not sure what to do about this, but at least
10032 // the race is now smaller.
10034 // Uh oh... it looks like the provider's process
10035 // has been killed on us. We need to wait for a new
10036 // process to be started, and make sure its death
10037 // doesn't kill our process.
10038 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10039 + " is crashing; detaching " + r);
10040 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10041 checkTime(startTime, "getContentProviderImpl: before appDied");
10042 appDiedLocked(cpr.proc);
10043 checkTime(startTime, "getContentProviderImpl: after appDied");
10045 // This wasn't the last ref our process had on
10046 // the provider... we have now been killed, bail.
10049 providerRunning = false;
10054 Binder.restoreCallingIdentity(origId);
10057 if (!providerRunning) {
10059 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10060 cpi = AppGlobals.getPackageManager().
10061 resolveContentProvider(name,
10062 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10063 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10064 } catch (RemoteException ex) {
10069 // If the provider is a singleton AND
10070 // (it's a call within the same user || the provider is a
10072 // Then allow connecting to the singleton provider
10073 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10074 cpi.name, cpi.flags)
10075 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10077 userId = UserHandle.USER_SYSTEM;
10079 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10080 checkTime(startTime, "getContentProviderImpl: got app info for user");
10083 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10084 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10086 throw new SecurityException(msg);
10088 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10090 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10091 && !cpi.processName.equals("system")) {
10092 // If this content provider does not run in the system
10093 // process, and the system is not yet ready to run other
10094 // processes, then fail fast instead of hanging.
10095 throw new IllegalArgumentException(
10096 "Attempt to launch content provider before system ready");
10099 // Make sure that the user who owns this provider is running. If not,
10100 // we don't want to allow it to run.
10101 if (!mUserController.isUserRunningLocked(userId, 0)) {
10102 Slog.w(TAG, "Unable to launch app "
10103 + cpi.applicationInfo.packageName + "/"
10104 + cpi.applicationInfo.uid + " for provider "
10105 + name + ": user " + userId + " is stopped");
10109 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10110 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10111 cpr = mProviderMap.getProviderByClass(comp, userId);
10112 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10113 final boolean firstClass = cpr == null;
10115 final long ident = Binder.clearCallingIdentity();
10117 // If permissions need a review before any of the app components can run,
10118 // we return no provider and launch a review activity if the calling app
10119 // is in the foreground.
10120 if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10121 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10127 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10128 ApplicationInfo ai =
10129 AppGlobals.getPackageManager().
10130 getApplicationInfo(
10131 cpi.applicationInfo.packageName,
10132 STOCK_PM_FLAGS, userId);
10133 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10135 Slog.w(TAG, "No package info for content provider "
10139 ai = getAppInfoForUser(ai, userId);
10140 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10141 } catch (RemoteException ex) {
10142 // pm is in same process, this will never happen.
10144 Binder.restoreCallingIdentity(ident);
10148 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10150 if (r != null && cpr.canRunHere(r)) {
10151 // If this is a multiprocess provider, then just return its
10152 // info and allow the caller to instantiate it. Only do
10153 // this if the provider is the same user as the caller's
10154 // process, or can run as root (so can be in any process).
10155 return cpr.newHolder(null);
10158 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10159 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10160 + cpr.info.name + " callers=" + Debug.getCallers(6));
10162 // This is single process, and our app is now connecting to it.
10163 // See if we are already in the process of launching this
10165 final int N = mLaunchingProviders.size();
10167 for (i = 0; i < N; i++) {
10168 if (mLaunchingProviders.get(i) == cpr) {
10173 // If the provider is not already being launched, then get it
10176 final long origId = Binder.clearCallingIdentity();
10179 // Content provider is now in use, its package can't be stopped.
10181 checkTime(startTime, "getContentProviderImpl: before set stopped state");
10182 AppGlobals.getPackageManager().setPackageStoppedState(
10183 cpr.appInfo.packageName, false, userId);
10184 checkTime(startTime, "getContentProviderImpl: after set stopped state");
10185 } catch (RemoteException e) {
10186 } catch (IllegalArgumentException e) {
10187 Slog.w(TAG, "Failed trying to unstop package "
10188 + cpr.appInfo.packageName + ": " + e);
10191 // Use existing process if already started
10192 checkTime(startTime, "getContentProviderImpl: looking for process record");
10193 ProcessRecord proc = getProcessRecordLocked(
10194 cpi.processName, cpr.appInfo.uid, false);
10195 if (proc != null && proc.thread != null) {
10196 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10197 "Installing in existing process " + proc);
10198 if (!proc.pubProviders.containsKey(cpi.name)) {
10199 checkTime(startTime, "getContentProviderImpl: scheduling install");
10200 proc.pubProviders.put(cpi.name, cpr);
10202 proc.thread.scheduleInstallProvider(cpi);
10203 } catch (RemoteException e) {
10207 checkTime(startTime, "getContentProviderImpl: before start process");
10208 proc = startProcessLocked(cpi.processName,
10209 cpr.appInfo, false, 0, "content provider",
10210 new ComponentName(cpi.applicationInfo.packageName,
10211 cpi.name), false, false, false);
10212 checkTime(startTime, "getContentProviderImpl: after start process");
10213 if (proc == null) {
10214 Slog.w(TAG, "Unable to launch app "
10215 + cpi.applicationInfo.packageName + "/"
10216 + cpi.applicationInfo.uid + " for provider "
10217 + name + ": process is bad");
10221 cpr.launchingApp = proc;
10222 mLaunchingProviders.add(cpr);
10224 Binder.restoreCallingIdentity(origId);
10228 checkTime(startTime, "getContentProviderImpl: updating data structures");
10230 // Make sure the provider is published (the same provider class
10231 // may be published under multiple names).
10233 mProviderMap.putProviderByClass(comp, cpr);
10236 mProviderMap.putProviderByName(name, cpr);
10237 conn = incProviderCountLocked(r, cpr, token, stable);
10238 if (conn != null) {
10239 conn.waiting = true;
10242 checkTime(startTime, "getContentProviderImpl: done!");
10245 // Wait for the provider to be published...
10246 synchronized (cpr) {
10247 while (cpr.provider == null) {
10248 if (cpr.launchingApp == null) {
10249 Slog.w(TAG, "Unable to launch app "
10250 + cpi.applicationInfo.packageName + "/"
10251 + cpi.applicationInfo.uid + " for provider "
10252 + name + ": launching app became null");
10253 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10254 UserHandle.getUserId(cpi.applicationInfo.uid),
10255 cpi.applicationInfo.packageName,
10256 cpi.applicationInfo.uid, name);
10260 if (DEBUG_MU) Slog.v(TAG_MU,
10261 "Waiting to start provider " + cpr
10262 + " launchingApp=" + cpr.launchingApp);
10263 if (conn != null) {
10264 conn.waiting = true;
10267 } catch (InterruptedException ex) {
10269 if (conn != null) {
10270 conn.waiting = false;
10275 return cpr != null ? cpr.newHolder(conn) : null;
10278 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10279 ProcessRecord r, final int userId) {
10280 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10281 cpi.packageName, r.userId)) {
10283 final boolean callerForeground = r != null ? r.setSchedGroup
10284 != Process.THREAD_GROUP_BG_NONINTERACTIVE : true;
10286 // Show a permission review UI only for starting from a foreground app
10287 if (!callerForeground) {
10288 Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10289 + cpi.packageName + " requires a permissions review");
10293 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10294 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10295 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10296 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10298 if (DEBUG_PERMISSIONS_REVIEW) {
10299 Slog.i(TAG, "u" + r.userId + " Launching permission review "
10300 + "for package " + cpi.packageName);
10303 final UserHandle userHandle = new UserHandle(userId);
10304 mHandler.post(new Runnable() {
10306 public void run() {
10307 mContext.startActivityAsUser(intent, userHandle);
10317 PackageManagerInternal getPackageManagerInternalLocked() {
10318 if (mPackageManagerInt == null) {
10319 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10321 return mPackageManagerInt;
10325 public final ContentProviderHolder getContentProvider(
10326 IApplicationThread caller, String name, int userId, boolean stable) {
10327 enforceNotIsolatedCaller("getContentProvider");
10328 if (caller == null) {
10329 String msg = "null IApplicationThread when getting content provider "
10332 throw new SecurityException(msg);
10334 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10335 // with cross-user grant.
10336 return getContentProviderImpl(caller, name, null, stable, userId);
10339 public ContentProviderHolder getContentProviderExternal(
10340 String name, int userId, IBinder token) {
10341 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10342 "Do not have permission in call getContentProviderExternal()");
10343 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10344 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10345 return getContentProviderExternalUnchecked(name, token, userId);
10348 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10349 IBinder token, int userId) {
10350 return getContentProviderImpl(null, name, token, true, userId);
10354 * Drop a content provider from a ProcessRecord's bookkeeping
10356 public void removeContentProvider(IBinder connection, boolean stable) {
10357 enforceNotIsolatedCaller("removeContentProvider");
10358 long ident = Binder.clearCallingIdentity();
10360 synchronized (this) {
10361 ContentProviderConnection conn;
10363 conn = (ContentProviderConnection)connection;
10364 } catch (ClassCastException e) {
10365 String msg ="removeContentProvider: " + connection
10366 + " not a ContentProviderConnection";
10368 throw new IllegalArgumentException(msg);
10370 if (conn == null) {
10371 throw new NullPointerException("connection is null");
10373 if (decProviderCountLocked(conn, null, null, stable)) {
10374 updateOomAdjLocked();
10378 Binder.restoreCallingIdentity(ident);
10382 public void removeContentProviderExternal(String name, IBinder token) {
10383 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10384 "Do not have permission in call removeContentProviderExternal()");
10385 int userId = UserHandle.getCallingUserId();
10386 long ident = Binder.clearCallingIdentity();
10388 removeContentProviderExternalUnchecked(name, token, userId);
10390 Binder.restoreCallingIdentity(ident);
10394 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10395 synchronized (this) {
10396 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10398 //remove from mProvidersByClass
10399 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10403 //update content provider record entry info
10404 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10405 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10406 if (localCpr.hasExternalProcessHandles()) {
10407 if (localCpr.removeExternalProcessHandleLocked(token)) {
10408 updateOomAdjLocked();
10410 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10411 + " with no external reference for token: "
10415 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10416 + " with no external references.");
10421 public final void publishContentProviders(IApplicationThread caller,
10422 List<ContentProviderHolder> providers) {
10423 if (providers == null) {
10427 enforceNotIsolatedCaller("publishContentProviders");
10428 synchronized (this) {
10429 final ProcessRecord r = getRecordForAppLocked(caller);
10430 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10432 throw new SecurityException(
10433 "Unable to find app for caller " + caller
10434 + " (pid=" + Binder.getCallingPid()
10435 + ") when publishing content providers");
10438 final long origId = Binder.clearCallingIdentity();
10440 final int N = providers.size();
10441 for (int i = 0; i < N; i++) {
10442 ContentProviderHolder src = providers.get(i);
10443 if (src == null || src.info == null || src.provider == null) {
10446 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10447 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10449 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10450 mProviderMap.putProviderByClass(comp, dst);
10451 String names[] = dst.info.authority.split(";");
10452 for (int j = 0; j < names.length; j++) {
10453 mProviderMap.putProviderByName(names[j], dst);
10456 int launchingCount = mLaunchingProviders.size();
10458 boolean wasInLaunchingProviders = false;
10459 for (j = 0; j < launchingCount; j++) {
10460 if (mLaunchingProviders.get(j) == dst) {
10461 mLaunchingProviders.remove(j);
10462 wasInLaunchingProviders = true;
10467 if (wasInLaunchingProviders) {
10468 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10470 synchronized (dst) {
10471 dst.provider = src.provider;
10475 updateOomAdjLocked(r);
10476 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10477 src.info.authority);
10481 Binder.restoreCallingIdentity(origId);
10485 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10486 ContentProviderConnection conn;
10488 conn = (ContentProviderConnection)connection;
10489 } catch (ClassCastException e) {
10490 String msg ="refContentProvider: " + connection
10491 + " not a ContentProviderConnection";
10493 throw new IllegalArgumentException(msg);
10495 if (conn == null) {
10496 throw new NullPointerException("connection is null");
10499 synchronized (this) {
10501 conn.numStableIncs += stable;
10503 stable = conn.stableCount + stable;
10505 throw new IllegalStateException("stableCount < 0: " + stable);
10508 if (unstable > 0) {
10509 conn.numUnstableIncs += unstable;
10511 unstable = conn.unstableCount + unstable;
10512 if (unstable < 0) {
10513 throw new IllegalStateException("unstableCount < 0: " + unstable);
10516 if ((stable+unstable) <= 0) {
10517 throw new IllegalStateException("ref counts can't go to zero here: stable="
10518 + stable + " unstable=" + unstable);
10520 conn.stableCount = stable;
10521 conn.unstableCount = unstable;
10526 public void unstableProviderDied(IBinder connection) {
10527 ContentProviderConnection conn;
10529 conn = (ContentProviderConnection)connection;
10530 } catch (ClassCastException e) {
10531 String msg ="refContentProvider: " + connection
10532 + " not a ContentProviderConnection";
10534 throw new IllegalArgumentException(msg);
10536 if (conn == null) {
10537 throw new NullPointerException("connection is null");
10540 // Safely retrieve the content provider associated with the connection.
10541 IContentProvider provider;
10542 synchronized (this) {
10543 provider = conn.provider.provider;
10546 if (provider == null) {
10547 // Um, yeah, we're way ahead of you.
10551 // Make sure the caller is being honest with us.
10552 if (provider.asBinder().pingBinder()) {
10553 // Er, no, still looks good to us.
10554 synchronized (this) {
10555 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10556 + " says " + conn + " died, but we don't agree");
10561 // Well look at that! It's dead!
10562 synchronized (this) {
10563 if (conn.provider.provider != provider) {
10564 // But something changed... good enough.
10568 ProcessRecord proc = conn.provider.proc;
10569 if (proc == null || proc.thread == null) {
10570 // Seems like the process is already cleaned up.
10574 // As far as we're concerned, this is just like receiving a
10575 // death notification... just a bit prematurely.
10576 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10577 + ") early provider death");
10578 final long ident = Binder.clearCallingIdentity();
10580 appDiedLocked(proc);
10582 Binder.restoreCallingIdentity(ident);
10588 public void appNotRespondingViaProvider(IBinder connection) {
10589 enforceCallingPermission(
10590 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10592 final ContentProviderConnection conn = (ContentProviderConnection) connection;
10593 if (conn == null) {
10594 Slog.w(TAG, "ContentProviderConnection is null");
10598 final ProcessRecord host = conn.provider.proc;
10599 if (host == null) {
10600 Slog.w(TAG, "Failed to find hosting ProcessRecord");
10604 final long token = Binder.clearCallingIdentity();
10606 appNotResponding(host, null, null, false, "ContentProvider not responding");
10608 Binder.restoreCallingIdentity(token);
10612 public final void installSystemProviders() {
10613 List<ProviderInfo> providers;
10614 synchronized (this) {
10615 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10616 providers = generateApplicationProvidersLocked(app);
10617 if (providers != null) {
10618 for (int i=providers.size()-1; i>=0; i--) {
10619 ProviderInfo pi = (ProviderInfo)providers.get(i);
10620 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10621 Slog.w(TAG, "Not installing system proc provider " + pi.name
10622 + ": not system .apk");
10623 providers.remove(i);
10628 if (providers != null) {
10629 mSystemThread.installSystemProviders(providers);
10632 mCoreSettingsObserver = new CoreSettingsObserver(this);
10634 //mUsageStatsService.monitorPackages();
10638 * Allows apps to retrieve the MIME type of a URI.
10639 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10640 * users, then it does not need permission to access the ContentProvider.
10641 * Either, it needs cross-user uri grants.
10643 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10645 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10646 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10648 public String getProviderMimeType(Uri uri, int userId) {
10649 enforceNotIsolatedCaller("getProviderMimeType");
10650 final String name = uri.getAuthority();
10651 int callingUid = Binder.getCallingUid();
10652 int callingPid = Binder.getCallingPid();
10654 boolean clearedIdentity = false;
10655 synchronized (this) {
10656 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
10658 if (canClearIdentity(callingPid, callingUid, userId)) {
10659 clearedIdentity = true;
10660 ident = Binder.clearCallingIdentity();
10662 ContentProviderHolder holder = null;
10664 holder = getContentProviderExternalUnchecked(name, null, userId);
10665 if (holder != null) {
10666 return holder.provider.getType(uri);
10668 } catch (RemoteException e) {
10669 Log.w(TAG, "Content provider dead retrieving " + uri, e);
10672 // We need to clear the identity to call removeContentProviderExternalUnchecked
10673 if (!clearedIdentity) {
10674 ident = Binder.clearCallingIdentity();
10677 if (holder != null) {
10678 removeContentProviderExternalUnchecked(name, null, userId);
10681 Binder.restoreCallingIdentity(ident);
10688 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10689 if (UserHandle.getUserId(callingUid) == userId) {
10692 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10693 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10694 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10695 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10701 // =========================================================
10702 // GLOBAL MANAGEMENT
10703 // =========================================================
10705 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10706 boolean isolated, int isolatedUid) {
10707 String proc = customProcess != null ? customProcess : info.processName;
10708 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10709 final int userId = UserHandle.getUserId(info.uid);
10710 int uid = info.uid;
10712 if (isolatedUid == 0) {
10713 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10715 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10716 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10717 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10719 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10720 mNextIsolatedProcessUid++;
10721 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10722 // No process for this uid, use it.
10726 if (stepsLeft <= 0) {
10731 // Special case for startIsolatedProcess (internal only), where
10732 // the uid of the isolated process is specified by the caller.
10736 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10737 if (!mBooted && !mBooting
10738 && userId == UserHandle.USER_SYSTEM
10739 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10740 r.persistent = true;
10742 addProcessNameLocked(r);
10746 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10747 String abiOverride) {
10750 app = getProcessRecordLocked(info.processName, info.uid, true);
10756 app = newProcessRecordLocked(info, null, isolated, 0);
10757 updateLruProcessLocked(app, false, null);
10758 updateOomAdjLocked();
10761 // This package really, really can not be stopped.
10763 AppGlobals.getPackageManager().setPackageStoppedState(
10764 info.packageName, false, UserHandle.getUserId(app.uid));
10765 } catch (RemoteException e) {
10766 } catch (IllegalArgumentException e) {
10767 Slog.w(TAG, "Failed trying to unstop package "
10768 + info.packageName + ": " + e);
10771 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10772 app.persistent = true;
10773 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10775 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10776 mPersistentStartingProcesses.add(app);
10777 startProcessLocked(app, "added application", app.processName, abiOverride,
10778 null /* entryPoint */, null /* entryPointArgs */);
10784 public void unhandledBack() {
10785 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10786 "unhandledBack()");
10788 synchronized(this) {
10789 final long origId = Binder.clearCallingIdentity();
10791 getFocusedStack().unhandledBackLocked();
10793 Binder.restoreCallingIdentity(origId);
10798 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10799 enforceNotIsolatedCaller("openContentUri");
10800 final int userId = UserHandle.getCallingUserId();
10801 String name = uri.getAuthority();
10802 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10803 ParcelFileDescriptor pfd = null;
10805 // We record the binder invoker's uid in thread-local storage before
10806 // going to the content provider to open the file. Later, in the code
10807 // that handles all permissions checks, we look for this uid and use
10808 // that rather than the Activity Manager's own uid. The effect is that
10809 // we do the check against the caller's permissions even though it looks
10810 // to the content provider like the Activity Manager itself is making
10812 Binder token = new Binder();
10813 sCallerIdentity.set(new Identity(
10814 token, Binder.getCallingPid(), Binder.getCallingUid()));
10816 pfd = cph.provider.openFile(null, uri, "r", null, token);
10817 } catch (FileNotFoundException e) {
10818 // do nothing; pfd will be returned null
10820 // Ensure that whatever happens, we clean up the identity state
10821 sCallerIdentity.remove();
10822 // Ensure we're done with the provider.
10823 removeContentProviderExternalUnchecked(name, null, userId);
10826 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10831 // Actually is sleeping or shutting down or whatever else in the future
10832 // is an inactive state.
10833 public boolean isSleepingOrShuttingDown() {
10834 return isSleeping() || mShuttingDown;
10837 public boolean isSleeping() {
10841 void onWakefulnessChanged(int wakefulness) {
10842 synchronized(this) {
10843 mWakefulness = wakefulness;
10844 updateSleepIfNeededLocked();
10848 void finishRunningVoiceLocked() {
10849 if (mRunningVoice != null) {
10850 mRunningVoice = null;
10851 mVoiceWakeLock.release();
10852 updateSleepIfNeededLocked();
10856 void startTimeTrackingFocusedActivityLocked() {
10857 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10858 mCurAppTimeTracker.start(mFocusedActivity.packageName);
10862 void updateSleepIfNeededLocked() {
10863 if (mSleeping && !shouldSleepLocked()) {
10865 startTimeTrackingFocusedActivityLocked();
10866 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10867 mStackSupervisor.comeOutOfSleepIfNeededLocked();
10868 updateOomAdjLocked();
10869 } else if (!mSleeping && shouldSleepLocked()) {
10871 if (mCurAppTimeTracker != null) {
10872 mCurAppTimeTracker.stop();
10874 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10875 mStackSupervisor.goingToSleepLocked();
10876 updateOomAdjLocked();
10878 // Initialize the wake times of all processes.
10879 checkExcessivePowerUsageLocked(false);
10880 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10881 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10882 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10886 private boolean shouldSleepLocked() {
10887 // Resume applications while running a voice interactor.
10888 if (mRunningVoice != null) {
10892 // TODO: Transform the lock screen state into a sleep token instead.
10893 switch (mWakefulness) {
10894 case PowerManagerInternal.WAKEFULNESS_AWAKE:
10895 case PowerManagerInternal.WAKEFULNESS_DREAMING:
10896 case PowerManagerInternal.WAKEFULNESS_DOZING:
10897 // Pause applications whenever the lock screen is shown or any sleep
10898 // tokens have been acquired.
10899 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10900 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10902 // If we're asleep then pause applications unconditionally.
10907 /** Pokes the task persister. */
10908 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10909 if (task != null && task.stack != null && task.stack.isHomeStack()) {
10910 // Never persist the home stack.
10913 mTaskPersister.wakeup(task, flush);
10916 /** Notifies all listeners when the task stack has changed. */
10917 void notifyTaskStackChangedLocked() {
10918 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10919 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10920 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10924 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10925 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10929 public boolean shutdown(int timeout) {
10930 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10931 != PackageManager.PERMISSION_GRANTED) {
10932 throw new SecurityException("Requires permission "
10933 + android.Manifest.permission.SHUTDOWN);
10936 boolean timedout = false;
10938 synchronized(this) {
10939 mShuttingDown = true;
10940 updateEventDispatchingLocked();
10941 timedout = mStackSupervisor.shutdownLocked(timeout);
10944 mAppOpsService.shutdown();
10945 if (mUsageStatsService != null) {
10946 mUsageStatsService.prepareShutdown();
10948 mBatteryStatsService.shutdown();
10949 synchronized (this) {
10950 mProcessStats.shutdownLocked();
10951 notifyTaskPersisterLocked(null, true);
10957 public final void activitySlept(IBinder token) {
10958 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10960 final long origId = Binder.clearCallingIdentity();
10962 synchronized (this) {
10963 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10965 mStackSupervisor.activitySleptLocked(r);
10969 Binder.restoreCallingIdentity(origId);
10972 private String lockScreenShownToString() {
10973 switch (mLockScreenShown) {
10974 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10975 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10976 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10977 default: return "Unknown=" + mLockScreenShown;
10981 void logLockScreen(String msg) {
10982 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10983 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10984 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10985 + " mSleeping=" + mSleeping);
10988 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10989 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10990 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10991 boolean wasRunningVoice = mRunningVoice != null;
10992 mRunningVoice = session;
10993 if (!wasRunningVoice) {
10994 mVoiceWakeLock.acquire();
10995 updateSleepIfNeededLocked();
11000 private void updateEventDispatchingLocked() {
11001 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11004 public void setLockScreenShown(boolean shown) {
11005 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11006 != PackageManager.PERMISSION_GRANTED) {
11007 throw new SecurityException("Requires permission "
11008 + android.Manifest.permission.DEVICE_POWER);
11011 synchronized(this) {
11012 long ident = Binder.clearCallingIdentity();
11014 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11015 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11016 updateSleepIfNeededLocked();
11018 Binder.restoreCallingIdentity(ident);
11024 public void stopAppSwitches() {
11025 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11026 != PackageManager.PERMISSION_GRANTED) {
11027 throw new SecurityException("viewquires permission "
11028 + android.Manifest.permission.STOP_APP_SWITCHES);
11031 synchronized(this) {
11032 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11033 + APP_SWITCH_DELAY_TIME;
11034 mDidAppSwitch = false;
11035 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11036 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11037 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11041 public void resumeAppSwitches() {
11042 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11043 != PackageManager.PERMISSION_GRANTED) {
11044 throw new SecurityException("Requires permission "
11045 + android.Manifest.permission.STOP_APP_SWITCHES);
11048 synchronized(this) {
11049 // Note that we don't execute any pending app switches... we will
11050 // let those wait until either the timeout, or the next start
11051 // activity request.
11052 mAppSwitchesAllowedTime = 0;
11056 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11057 int callingPid, int callingUid, String name) {
11058 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11062 int perm = checkComponentPermission(
11063 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11064 sourceUid, -1, true);
11065 if (perm == PackageManager.PERMISSION_GRANTED) {
11069 // If the actual IPC caller is different from the logical source, then
11070 // also see if they are allowed to control app switches.
11071 if (callingUid != -1 && callingUid != sourceUid) {
11072 perm = checkComponentPermission(
11073 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11074 callingUid, -1, true);
11075 if (perm == PackageManager.PERMISSION_GRANTED) {
11080 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11084 public void setDebugApp(String packageName, boolean waitForDebugger,
11085 boolean persistent) {
11086 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11089 long ident = Binder.clearCallingIdentity();
11091 // Note that this is not really thread safe if there are multiple
11092 // callers into it at the same time, but that's not a situation we
11095 final ContentResolver resolver = mContext.getContentResolver();
11096 Settings.Global.putString(
11097 resolver, Settings.Global.DEBUG_APP,
11099 Settings.Global.putInt(
11100 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11101 waitForDebugger ? 1 : 0);
11104 synchronized (this) {
11106 mOrigDebugApp = mDebugApp;
11107 mOrigWaitForDebugger = mWaitForDebugger;
11109 mDebugApp = packageName;
11110 mWaitForDebugger = waitForDebugger;
11111 mDebugTransient = !persistent;
11112 if (packageName != null) {
11113 forceStopPackageLocked(packageName, -1, false, false, true, true,
11114 false, UserHandle.USER_ALL, "set debug app");
11118 Binder.restoreCallingIdentity(ident);
11122 void setTrackAllocationApp(ApplicationInfo app, String processName) {
11123 synchronized (this) {
11124 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11125 if (!isDebuggable) {
11126 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11127 throw new SecurityException("Process not debuggable: " + app.packageName);
11131 mTrackAllocationApp = processName;
11135 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11136 synchronized (this) {
11137 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11138 if (!isDebuggable) {
11139 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11140 throw new SecurityException("Process not debuggable: " + app.packageName);
11143 mProfileApp = processName;
11144 mProfileFile = profilerInfo.profileFile;
11145 if (mProfileFd != null) {
11147 mProfileFd.close();
11148 } catch (IOException e) {
11152 mProfileFd = profilerInfo.profileFd;
11153 mSamplingInterval = profilerInfo.samplingInterval;
11154 mAutoStopProfiler = profilerInfo.autoStopProfiler;
11160 public void setAlwaysFinish(boolean enabled) {
11161 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11162 "setAlwaysFinish()");
11164 Settings.Global.putInt(
11165 mContext.getContentResolver(),
11166 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11168 synchronized (this) {
11169 mAlwaysFinishActivities = enabled;
11174 public void setActivityController(IActivityController controller) {
11175 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11176 "setActivityController()");
11177 synchronized (this) {
11178 mController = controller;
11179 Watchdog.getInstance().setActivityController(controller);
11184 public void setUserIsMonkey(boolean userIsMonkey) {
11185 synchronized (this) {
11186 synchronized (mPidsSelfLocked) {
11187 final int callingPid = Binder.getCallingPid();
11188 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11189 if (precessRecord == null) {
11190 throw new SecurityException("Unknown process: " + callingPid);
11192 if (precessRecord.instrumentationUiAutomationConnection == null) {
11193 throw new SecurityException("Only an instrumentation process "
11194 + "with a UiAutomation can call setUserIsMonkey");
11197 mUserIsMonkey = userIsMonkey;
11202 public boolean isUserAMonkey() {
11203 synchronized (this) {
11204 // If there is a controller also implies the user is a monkey.
11205 return (mUserIsMonkey || mController != null);
11209 public void requestBugReport() {
11210 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11211 SystemProperties.set("ctl.start", "bugreport");
11214 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11215 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11218 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11219 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11220 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11222 return KEY_DISPATCHING_TIMEOUT;
11226 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11227 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11228 != PackageManager.PERMISSION_GRANTED) {
11229 throw new SecurityException("Requires permission "
11230 + android.Manifest.permission.FILTER_EVENTS);
11232 ProcessRecord proc;
11234 synchronized (this) {
11235 synchronized (mPidsSelfLocked) {
11236 proc = mPidsSelfLocked.get(pid);
11238 timeout = getInputDispatchingTimeoutLocked(proc);
11241 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11249 * Handle input dispatching timeouts.
11250 * Returns whether input dispatching should be aborted or not.
11252 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11253 final ActivityRecord activity, final ActivityRecord parent,
11254 final boolean aboveSystem, String reason) {
11255 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11256 != PackageManager.PERMISSION_GRANTED) {
11257 throw new SecurityException("Requires permission "
11258 + android.Manifest.permission.FILTER_EVENTS);
11261 final String annotation;
11262 if (reason == null) {
11263 annotation = "Input dispatching timed out";
11265 annotation = "Input dispatching timed out (" + reason + ")";
11268 if (proc != null) {
11269 synchronized (this) {
11270 if (proc.debugging) {
11275 // Give more time since we were dexopting.
11276 mDidDexOpt = false;
11280 if (proc.instrumentationClass != null) {
11281 Bundle info = new Bundle();
11282 info.putString("shortMsg", "keyDispatchingTimedOut");
11283 info.putString("longMsg", annotation);
11284 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11288 mHandler.post(new Runnable() {
11290 public void run() {
11291 appNotResponding(proc, activity, parent, aboveSystem, annotation);
11300 public Bundle getAssistContextExtras(int requestType) {
11301 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11302 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11306 synchronized (pae) {
11307 while (!pae.haveResult) {
11310 } catch (InterruptedException e) {
11314 synchronized (this) {
11315 buildAssistBundleLocked(pae, pae.result);
11316 mPendingAssistExtras.remove(pae);
11317 mUiHandler.removeCallbacks(pae);
11323 public boolean isAssistDataAllowedOnCurrentActivity() {
11325 synchronized (this) {
11326 userId = mUserController.getCurrentUserIdLocked();
11327 ActivityRecord activity = getFocusedStack().topActivity();
11328 if (activity == null) {
11331 userId = activity.userId;
11333 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11334 Context.DEVICE_POLICY_SERVICE);
11335 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11339 public boolean showAssistFromActivity(IBinder token, Bundle args) {
11340 long ident = Binder.clearCallingIdentity();
11342 synchronized (this) {
11343 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11344 ActivityRecord top = getFocusedStack().topActivity();
11345 if (top != caller) {
11346 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11347 + " is not current top " + top);
11350 if (!top.nowVisible) {
11351 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11352 + " is not visible");
11356 AssistUtils utils = new AssistUtils(mContext);
11357 return utils.showSessionForActiveService(args,
11358 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11360 Binder.restoreCallingIdentity(ident);
11365 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11366 IBinder activityToken) {
11367 return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11368 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11371 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11372 IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11374 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11375 "enqueueAssistContext()");
11376 synchronized (this) {
11377 ActivityRecord activity = getFocusedStack().topActivity();
11378 if (activity == null) {
11379 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11382 if (activity.app == null || activity.app.thread == null) {
11383 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11386 if (activityToken != null) {
11387 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11388 if (activity != caller) {
11389 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11390 + " is not current top " + activity);
11394 PendingAssistExtras pae;
11395 Bundle extras = new Bundle();
11396 if (args != null) {
11397 extras.putAll(args);
11399 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11400 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11401 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11403 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11405 mPendingAssistExtras.add(pae);
11406 mUiHandler.postDelayed(pae, timeout);
11407 } catch (RemoteException e) {
11408 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11415 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11416 IResultReceiver receiver;
11417 synchronized (this) {
11418 mPendingAssistExtras.remove(pae);
11419 receiver = pae.receiver;
11421 if (receiver != null) {
11422 // Caller wants result sent back to them.
11424 pae.receiver.send(0, null);
11425 } catch (RemoteException e) {
11430 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11431 if (result != null) {
11432 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11434 if (pae.hint != null) {
11435 pae.extras.putBoolean(pae.hint, true);
11439 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11440 AssistContent content, Uri referrer) {
11441 PendingAssistExtras pae = (PendingAssistExtras)token;
11442 synchronized (pae) {
11443 pae.result = extras;
11444 pae.structure = structure;
11445 pae.content = content;
11446 if (referrer != null) {
11447 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11449 pae.haveResult = true;
11451 if (pae.intent == null && pae.receiver == null) {
11452 // Caller is just waiting for the result.
11457 // We are now ready to launch the assist activity.
11458 IResultReceiver sendReceiver = null;
11459 Bundle sendBundle = null;
11460 synchronized (this) {
11461 buildAssistBundleLocked(pae, extras);
11462 boolean exists = mPendingAssistExtras.remove(pae);
11463 mUiHandler.removeCallbacks(pae);
11468 if ((sendReceiver=pae.receiver) != null) {
11469 // Caller wants result sent back to them.
11470 sendBundle = new Bundle();
11471 sendBundle.putBundle("data", pae.extras);
11472 sendBundle.putParcelable("structure", pae.structure);
11473 sendBundle.putParcelable("content", pae.content);
11476 if (sendReceiver != null) {
11478 sendReceiver.send(0, sendBundle);
11479 } catch (RemoteException e) {
11484 long ident = Binder.clearCallingIdentity();
11486 pae.intent.replaceExtras(pae.extras);
11487 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11488 | Intent.FLAG_ACTIVITY_SINGLE_TOP
11489 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11490 closeSystemDialogs("assist");
11492 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11493 } catch (ActivityNotFoundException e) {
11494 Slog.w(TAG, "No activity to handle assist action.", e);
11497 Binder.restoreCallingIdentity(ident);
11501 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11503 return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11504 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11507 public void registerProcessObserver(IProcessObserver observer) {
11508 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11509 "registerProcessObserver()");
11510 synchronized (this) {
11511 mProcessObservers.register(observer);
11516 public void unregisterProcessObserver(IProcessObserver observer) {
11517 synchronized (this) {
11518 mProcessObservers.unregister(observer);
11523 public void registerUidObserver(IUidObserver observer, int which) {
11524 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11525 "registerUidObserver()");
11526 synchronized (this) {
11527 mUidObservers.register(observer, which);
11532 public void unregisterUidObserver(IUidObserver observer) {
11533 synchronized (this) {
11534 mUidObservers.unregister(observer);
11539 public boolean convertFromTranslucent(IBinder token) {
11540 final long origId = Binder.clearCallingIdentity();
11542 synchronized (this) {
11543 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11547 final boolean translucentChanged = r.changeWindowTranslucency(true);
11548 if (translucentChanged) {
11549 r.task.stack.releaseBackgroundResources(r);
11550 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11552 mWindowManager.setAppFullscreen(token, true);
11553 return translucentChanged;
11556 Binder.restoreCallingIdentity(origId);
11561 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11562 final long origId = Binder.clearCallingIdentity();
11564 synchronized (this) {
11565 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11569 int index = r.task.mActivities.lastIndexOf(r);
11571 ActivityRecord under = r.task.mActivities.get(index - 1);
11572 under.returningOptions = options;
11574 final boolean translucentChanged = r.changeWindowTranslucency(false);
11575 if (translucentChanged) {
11576 r.task.stack.convertActivityToTranslucent(r);
11578 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
11579 mWindowManager.setAppFullscreen(token, false);
11580 return translucentChanged;
11583 Binder.restoreCallingIdentity(origId);
11588 public boolean requestVisibleBehind(IBinder token, boolean visible) {
11589 final long origId = Binder.clearCallingIdentity();
11591 synchronized (this) {
11592 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11594 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11599 Binder.restoreCallingIdentity(origId);
11604 public boolean isBackgroundVisibleBehind(IBinder token) {
11605 final long origId = Binder.clearCallingIdentity();
11607 synchronized (this) {
11608 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11609 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11610 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11611 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11615 Binder.restoreCallingIdentity(origId);
11620 public ActivityOptions getActivityOptions(IBinder token) {
11621 final long origId = Binder.clearCallingIdentity();
11623 synchronized (this) {
11624 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11626 final ActivityOptions activityOptions = r.pendingOptions;
11627 r.pendingOptions = null;
11628 return activityOptions;
11633 Binder.restoreCallingIdentity(origId);
11638 public void setImmersive(IBinder token, boolean immersive) {
11639 synchronized(this) {
11640 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11642 throw new IllegalArgumentException();
11644 r.immersive = immersive;
11646 // update associated state if we're frontmost
11647 if (r == mFocusedActivity) {
11648 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11649 applyUpdateLockStateLocked(r);
11655 public boolean isImmersive(IBinder token) {
11656 synchronized (this) {
11657 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11659 throw new IllegalArgumentException();
11661 return r.immersive;
11665 public boolean isTopActivityImmersive() {
11666 enforceNotIsolatedCaller("startActivity");
11667 synchronized (this) {
11668 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
11669 return (r != null) ? r.immersive : false;
11674 public boolean isTopOfTask(IBinder token) {
11675 synchronized (this) {
11676 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11678 throw new IllegalArgumentException();
11680 return r.task.getTopActivity() == r;
11684 public final void enterSafeMode() {
11685 synchronized(this) {
11686 // It only makes sense to do this before the system is ready
11687 // and started launching other packages.
11688 if (!mSystemReady) {
11690 AppGlobals.getPackageManager().enterSafeMode();
11691 } catch (RemoteException e) {
11699 public final void showSafeModeOverlay() {
11700 View v = LayoutInflater.from(mContext).inflate(
11701 com.android.internal.R.layout.safe_mode, null);
11702 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11703 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11704 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11705 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11706 lp.gravity = Gravity.BOTTOM | Gravity.START;
11707 lp.format = v.getBackground().getOpacity();
11708 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11709 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11710 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11711 ((WindowManager)mContext.getSystemService(
11712 Context.WINDOW_SERVICE)).addView(v, lp);
11715 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11716 if (sender != null && !(sender instanceof PendingIntentRecord)) {
11719 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11720 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11721 synchronized (stats) {
11722 if (mBatteryStatsService.isOnBattery()) {
11723 mBatteryStatsService.enforceCallingPermission();
11724 int MY_UID = Binder.getCallingUid();
11726 if (sender == null) {
11729 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11731 BatteryStatsImpl.Uid.Pkg pkg =
11732 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11733 sourcePkg != null ? sourcePkg : rec.key.packageName);
11734 pkg.noteWakeupAlarmLocked(tag);
11739 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11740 if (sender != null && !(sender instanceof PendingIntentRecord)) {
11743 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11744 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11745 synchronized (stats) {
11746 mBatteryStatsService.enforceCallingPermission();
11747 int MY_UID = Binder.getCallingUid();
11749 if (sender == null) {
11752 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11754 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11758 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11759 if (sender != null && !(sender instanceof PendingIntentRecord)) {
11762 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11763 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11764 synchronized (stats) {
11765 mBatteryStatsService.enforceCallingPermission();
11766 int MY_UID = Binder.getCallingUid();
11768 if (sender == null) {
11771 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11773 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11777 public boolean killPids(int[] pids, String pReason, boolean secure) {
11778 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11779 throw new SecurityException("killPids only available to the system");
11781 String reason = (pReason == null) ? "Unknown" : pReason;
11782 // XXX Note: don't acquire main activity lock here, because the window
11783 // manager calls in with its locks held.
11785 boolean killed = false;
11786 synchronized (mPidsSelfLocked) {
11787 int[] types = new int[pids.length];
11789 for (int i=0; i<pids.length; i++) {
11790 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11791 if (proc != null) {
11792 int type = proc.setAdj;
11794 if (type > worstType) {
11800 // If the worst oom_adj is somewhere in the cached proc LRU range,
11801 // then constrain it so we will kill all cached procs.
11802 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11803 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11804 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11807 // If this is not a secure call, don't let it kill processes that
11809 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11810 worstType = ProcessList.SERVICE_ADJ;
11813 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11814 for (int i=0; i<pids.length; i++) {
11815 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11816 if (proc == null) {
11819 int adj = proc.setAdj;
11820 if (adj >= worstType && !proc.killedByAm) {
11821 proc.kill(reason, true);
11830 public void killUid(int appId, int userId, String reason) {
11831 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11832 synchronized (this) {
11833 final long identity = Binder.clearCallingIdentity();
11835 killPackageProcessesLocked(null, appId, userId,
11836 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11837 reason != null ? reason : "kill uid");
11839 Binder.restoreCallingIdentity(identity);
11845 public boolean killProcessesBelowForeground(String reason) {
11846 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11847 throw new SecurityException("killProcessesBelowForeground() only available to system");
11850 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11853 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11854 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11855 throw new SecurityException("killProcessesBelowAdj() only available to system");
11858 boolean killed = false;
11859 synchronized (mPidsSelfLocked) {
11860 final int size = mPidsSelfLocked.size();
11861 for (int i = 0; i < size; i++) {
11862 final int pid = mPidsSelfLocked.keyAt(i);
11863 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11864 if (proc == null) continue;
11866 final int adj = proc.setAdj;
11867 if (adj > belowAdj && !proc.killedByAm) {
11868 proc.kill(reason, true);
11877 public void hang(final IBinder who, boolean allowRestart) {
11878 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11879 != PackageManager.PERMISSION_GRANTED) {
11880 throw new SecurityException("Requires permission "
11881 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11884 final IBinder.DeathRecipient death = new DeathRecipient() {
11886 public void binderDied() {
11887 synchronized (this) {
11894 who.linkToDeath(death, 0);
11895 } catch (RemoteException e) {
11896 Slog.w(TAG, "hang: given caller IBinder is already dead.");
11900 synchronized (this) {
11901 Watchdog.getInstance().setAllowRestart(allowRestart);
11902 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11903 synchronized (death) {
11904 while (who.isBinderAlive()) {
11907 } catch (InterruptedException e) {
11911 Watchdog.getInstance().setAllowRestart(true);
11916 public void restart() {
11917 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11918 != PackageManager.PERMISSION_GRANTED) {
11919 throw new SecurityException("Requires permission "
11920 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11923 Log.i(TAG, "Sending shutdown broadcast...");
11925 BroadcastReceiver br = new BroadcastReceiver() {
11926 @Override public void onReceive(Context context, Intent intent) {
11927 // Now the broadcast is done, finish up the low-level shutdown.
11928 Log.i(TAG, "Shutting down activity manager...");
11930 Log.i(TAG, "Shutdown complete, restarting!");
11931 Process.killProcess(Process.myPid());
11936 // First send the high-level shut down broadcast.
11937 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11938 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11939 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11940 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11941 mContext.sendOrderedBroadcastAsUser(intent,
11942 UserHandle.ALL, null, br, mHandler, 0, null, null);
11944 br.onReceive(mContext, intent);
11947 private long getLowRamTimeSinceIdle(long now) {
11948 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11952 public void performIdleMaintenance() {
11953 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11954 != PackageManager.PERMISSION_GRANTED) {
11955 throw new SecurityException("Requires permission "
11956 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11959 synchronized (this) {
11960 final long now = SystemClock.uptimeMillis();
11961 final long timeSinceLastIdle = now - mLastIdleTime;
11962 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11963 mLastIdleTime = now;
11964 mLowRamTimeSinceLastIdle = 0;
11965 if (mLowRamStartTime != 0) {
11966 mLowRamStartTime = now;
11969 StringBuilder sb = new StringBuilder(128);
11970 sb.append("Idle maintenance over ");
11971 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11972 sb.append(" low RAM for ");
11973 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11974 Slog.i(TAG, sb.toString());
11976 // If at least 1/3 of our time since the last idle period has been spent
11977 // with RAM low, then we want to kill processes.
11978 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11980 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11981 ProcessRecord proc = mLruProcesses.get(i);
11982 if (proc.notCachedSinceIdle) {
11983 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11984 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11985 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11986 if (doKilling && proc.initialIdlePss != 0
11987 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11988 sb = new StringBuilder(128);
11990 sb.append(proc.processName);
11991 sb.append(" in idle maint: pss=");
11992 sb.append(proc.lastPss);
11993 sb.append(", initialPss=");
11994 sb.append(proc.initialIdlePss);
11995 sb.append(", period=");
11996 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11997 sb.append(", lowRamPeriod=");
11998 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11999 Slog.wtfQuiet(TAG, sb.toString());
12000 proc.kill("idle maint (pss " + proc.lastPss
12001 + " from " + proc.initialIdlePss + ")", true);
12004 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
12005 proc.notCachedSinceIdle = true;
12006 proc.initialIdlePss = 0;
12007 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
12008 mTestPssMode, isSleeping(), now);
12012 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12013 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12017 private void retrieveSettings() {
12018 final ContentResolver resolver = mContext.getContentResolver();
12019 final boolean freeformWindowManagement =
12020 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT);
12022 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12023 final String fsScreenshots = Settings.Secure.getString(resolver,
12024 "overview_fullscreen_thumbnails");
12025 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12026 final boolean alwaysFinishActivities =
12027 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12028 final boolean takeFullscreenScreenshots = fsScreenshots != null &&
12029 Integer.parseInt(fsScreenshots) != 0;
12030 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12031 final int defaultForceResizable = Build.IS_DEBUGGABLE ? 1 : 0;
12032 final boolean forceResizable = Settings.Global.getInt(
12033 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, defaultForceResizable) != 0;
12034 // Transfer any global setting for forcing RTL layout, into a System Property
12035 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12037 final Configuration configuration = new Configuration();
12038 Settings.System.getConfiguration(resolver, configuration);
12040 // This will take care of setting the correct layout direction flags
12041 configuration.setLayoutDirection(configuration.locale);
12044 synchronized (this) {
12045 mDebugApp = mOrigDebugApp = debugApp;
12046 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12047 mAlwaysFinishActivities = alwaysFinishActivities;
12048 mForceResizableActivities = forceResizable;
12049 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12050 mTakeFullscreenScreenshots = takeFullscreenScreenshots;
12051 // This happens before any activities are started, so we can
12052 // change mConfiguration in-place.
12053 updateConfigurationLocked(configuration, null, true);
12054 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12055 "Initial config: " + mConfiguration);
12059 /** Loads resources after the current configuration has been set. */
12060 private void loadResourcesOnSystemReady() {
12061 final Resources res = mContext.getResources();
12062 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12063 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
12064 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
12067 public boolean testIsSystemReady() {
12068 // no need to synchronize(this) just to read & return the value
12069 return mSystemReady;
12072 private static File getCalledPreBootReceiversFile() {
12073 File dataDir = Environment.getDataDirectory();
12074 File systemDir = new File(dataDir, "system");
12075 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12079 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12080 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12081 File file = getCalledPreBootReceiversFile();
12082 FileInputStream fis = null;
12084 fis = new FileInputStream(file);
12085 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12086 int fvers = dis.readInt();
12087 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12088 String vers = dis.readUTF();
12089 String codename = dis.readUTF();
12090 String build = dis.readUTF();
12091 if (android.os.Build.VERSION.RELEASE.equals(vers)
12092 && android.os.Build.VERSION.CODENAME.equals(codename)
12093 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12094 int num = dis.readInt();
12097 String pkg = dis.readUTF();
12098 String cls = dis.readUTF();
12099 lastDoneReceivers.add(new ComponentName(pkg, cls));
12103 } catch (FileNotFoundException e) {
12104 } catch (IOException e) {
12105 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12110 } catch (IOException e) {
12114 return lastDoneReceivers;
12117 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12118 File file = getCalledPreBootReceiversFile();
12119 FileOutputStream fos = null;
12120 DataOutputStream dos = null;
12122 fos = new FileOutputStream(file);
12123 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12124 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12125 dos.writeUTF(android.os.Build.VERSION.RELEASE);
12126 dos.writeUTF(android.os.Build.VERSION.CODENAME);
12127 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12128 dos.writeInt(list.size());
12129 for (int i=0; i<list.size(); i++) {
12130 dos.writeUTF(list.get(i).getPackageName());
12131 dos.writeUTF(list.get(i).getClassName());
12133 } catch (IOException e) {
12134 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12137 FileUtils.sync(fos);
12141 } catch (IOException e) {
12142 // TODO Auto-generated catch block
12143 e.printStackTrace();
12149 final class PreBootContinuation extends IIntentReceiver.Stub {
12150 final Intent intent;
12151 final Runnable onFinishCallback;
12152 final ArrayList<ComponentName> doneReceivers;
12153 final List<ResolveInfo> ris;
12159 PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12160 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12162 onFinishCallback = _onFinishCallback;
12163 doneReceivers = _doneReceivers;
12169 if (lastRi != curRi) {
12170 ActivityInfo ai = ris.get(curRi).activityInfo;
12171 ComponentName comp = new ComponentName(ai.packageName, ai.name);
12172 intent.setComponent(comp);
12173 doneReceivers.add(comp);
12175 CharSequence label = ai.loadLabel(mContext.getPackageManager());
12176 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12178 Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12179 + " for user " + users[curUser]);
12180 EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12181 broadcastIntentLocked(null, null, intent, null, this,
12182 0, null, null, null, AppOpsManager.OP_NONE,
12183 null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12186 public void performReceive(Intent intent, int resultCode,
12187 String data, Bundle extras, boolean ordered,
12188 boolean sticky, int sendingUser) {
12190 if (curUser >= users.length) {
12193 if (curRi >= ris.size()) {
12194 // All done sending broadcasts!
12195 if (onFinishCallback != null) {
12196 // The raw IIntentReceiver interface is called
12197 // with the AM lock held, so redispatch to
12198 // execute our code without the lock.
12199 mHandler.post(onFinishCallback);
12208 private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12209 ArrayList<ComponentName> doneReceivers) {
12210 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12211 List<ResolveInfo> ris = null;
12213 ris = AppGlobals.getPackageManager().queryIntentReceivers(
12214 intent, null, 0, UserHandle.USER_SYSTEM);
12215 } catch (RemoteException e) {
12220 for (int i=ris.size()-1; i>=0; i--) {
12221 if ((ris.get(i).activityInfo.applicationInfo.flags
12222 &ApplicationInfo.FLAG_SYSTEM) == 0) {
12226 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
12228 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12229 for (int i=0; i<ris.size(); i++) {
12230 ActivityInfo ai = ris.get(i).activityInfo;
12231 ComponentName comp = new ComponentName(ai.packageName, ai.name);
12232 if (lastDoneReceivers.contains(comp)) {
12233 // We already did the pre boot receiver for this app with the current
12234 // platform version, so don't do it again...
12237 // ...however, do keep it as one that has been done, so we don't
12238 // forget about it when rewriting the file of last done receivers.
12239 doneReceivers.add(comp);
12243 if (ris.size() <= 0) {
12247 // TODO: can we still do this with per user encryption?
12248 final int[] users = mUserController.getUsers();
12249 if (users.length <= 0) {
12253 PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12259 public void systemReady(final Runnable goingCallback) {
12260 synchronized(this) {
12261 if (mSystemReady) {
12262 // If we're done calling all the receivers, run the next "boot phase" passed in
12263 // by the SystemServer
12264 if (goingCallback != null) {
12265 goingCallback.run();
12270 mLocalDeviceIdleController
12271 = LocalServices.getService(DeviceIdleController.LocalService.class);
12273 // Make sure we have the current profile info, since it is needed for
12274 // security checks.
12275 mUserController.updateCurrentProfileIdsLocked();
12277 mRecentTasks.clear();
12278 mRecentTasks.addAll(mTaskPersister.restoreTasksLocked(mUserController.getUserIds()));
12279 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
12280 mTaskPersister.startPersisting();
12282 // Check to see if there are any update receivers to run.
12284 if (mWaitingUpdate) {
12287 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12288 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12289 public void run() {
12290 synchronized (ActivityManagerService.this) {
12293 showBootMessage(mContext.getText(
12294 R.string.android_upgrading_complete),
12296 writeLastDonePreBootReceivers(doneReceivers);
12297 systemReady(goingCallback);
12301 if (mWaitingUpdate) {
12307 mAppOpsService.systemReady();
12308 mSystemReady = true;
12311 ArrayList<ProcessRecord> procsToKill = null;
12312 synchronized(mPidsSelfLocked) {
12313 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12314 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12315 if (!isAllowedWhileBooting(proc.info)){
12316 if (procsToKill == null) {
12317 procsToKill = new ArrayList<ProcessRecord>();
12319 procsToKill.add(proc);
12324 synchronized(this) {
12325 if (procsToKill != null) {
12326 for (int i=procsToKill.size()-1; i>=0; i--) {
12327 ProcessRecord proc = procsToKill.get(i);
12328 Slog.i(TAG, "Removing system update proc: " + proc);
12329 removeProcessLocked(proc, true, false, "system update done");
12333 // Now that we have cleaned up any update processes, we
12334 // are ready to start launching real processes and know that
12335 // we won't trample on them any more.
12336 mProcessesReady = true;
12339 Slog.i(TAG, "System now ready");
12340 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12341 SystemClock.uptimeMillis());
12343 synchronized(this) {
12344 // Make sure we have no pre-ready processes sitting around.
12346 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12347 ResolveInfo ri = mContext.getPackageManager()
12348 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12350 CharSequence errorMsg = null;
12352 ActivityInfo ai = ri.activityInfo;
12353 ApplicationInfo app = ai.applicationInfo;
12354 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12355 mTopAction = Intent.ACTION_FACTORY_TEST;
12357 mTopComponent = new ComponentName(app.packageName,
12360 errorMsg = mContext.getResources().getText(
12361 com.android.internal.R.string.factorytest_not_system);
12364 errorMsg = mContext.getResources().getText(
12365 com.android.internal.R.string.factorytest_no_action);
12367 if (errorMsg != null) {
12370 mTopComponent = null;
12371 Message msg = Message.obtain();
12372 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12373 msg.getData().putCharSequence("msg", errorMsg);
12374 mUiHandler.sendMessage(msg);
12379 retrieveSettings();
12380 loadResourcesOnSystemReady();
12381 final int currentUserId;
12382 synchronized (this) {
12383 currentUserId = mUserController.getCurrentUserIdLocked();
12384 readGrantedUriPermissionsLocked();
12387 if (goingCallback != null) goingCallback.run();
12390 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12391 Integer.toString(currentUserId), currentUserId);
12392 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12393 Integer.toString(currentUserId), currentUserId);
12394 mSystemServiceManager.startUser(currentUserId);
12396 synchronized (this) {
12397 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12399 List apps = AppGlobals.getPackageManager().
12400 getPersistentApplications(STOCK_PM_FLAGS);
12401 if (apps != null) {
12402 int N = apps.size();
12404 for (i=0; i<N; i++) {
12405 ApplicationInfo info
12406 = (ApplicationInfo)apps.get(i);
12407 if (info != null &&
12408 !info.packageName.equals("android")) {
12409 addAppLocked(info, false, null /* ABI override */);
12413 } catch (RemoteException ex) {
12414 // pm is in same process, this will never happen.
12418 // Start up initial activity.
12420 // Enable home activity for system user, so that the system can always boot
12421 if (UserManager.isSplitSystemUser()) {
12422 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12424 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12425 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12426 UserHandle.USER_SYSTEM);
12427 } catch (RemoteException e) {
12428 e.rethrowAsRuntimeException();
12431 startHomeActivityLocked(currentUserId, "systemReady");
12434 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12435 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12436 + " data partition or your device will be unstable.");
12437 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12439 } catch (RemoteException e) {
12442 if (!Build.isBuildConsistent()) {
12443 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12444 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12447 long ident = Binder.clearCallingIdentity();
12449 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12450 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12451 | Intent.FLAG_RECEIVER_FOREGROUND);
12452 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12453 broadcastIntentLocked(null, null, intent,
12454 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12455 null, false, false, MY_PID, Process.SYSTEM_UID,
12457 intent = new Intent(Intent.ACTION_USER_STARTING);
12458 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12459 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12460 broadcastIntentLocked(null, null, intent,
12461 null, new IIntentReceiver.Stub() {
12463 public void performReceive(Intent intent, int resultCode, String data,
12464 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12465 throws RemoteException {
12468 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12469 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12470 } catch (Throwable t) {
12471 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12473 Binder.restoreCallingIdentity(ident);
12475 mStackSupervisor.resumeTopActivitiesLocked();
12476 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12480 private boolean makeAppCrashingLocked(ProcessRecord app,
12481 String shortMsg, String longMsg, String stackTrace) {
12482 app.crashing = true;
12483 app.crashingReport = generateProcessError(app,
12484 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12485 startAppProblemLocked(app);
12486 app.stopFreezingAllLocked();
12487 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12490 private void makeAppNotRespondingLocked(ProcessRecord app,
12491 String activity, String shortMsg, String longMsg) {
12492 app.notResponding = true;
12493 app.notRespondingReport = generateProcessError(app,
12494 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12495 activity, shortMsg, longMsg, null);
12496 startAppProblemLocked(app);
12497 app.stopFreezingAllLocked();
12501 * Generate a process error record, suitable for attachment to a ProcessRecord.
12503 * @param app The ProcessRecord in which the error occurred.
12504 * @param condition Crashing, Application Not Responding, etc. Values are defined in
12505 * ActivityManager.AppErrorStateInfo
12506 * @param activity The activity associated with the crash, if known.
12507 * @param shortMsg Short message describing the crash.
12508 * @param longMsg Long message describing the crash.
12509 * @param stackTrace Full crash stack trace, may be null.
12511 * @return Returns a fully-formed AppErrorStateInfo record.
12513 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12514 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12515 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12517 report.condition = condition;
12518 report.processName = app.processName;
12519 report.pid = app.pid;
12520 report.uid = app.info.uid;
12521 report.tag = activity;
12522 report.shortMsg = shortMsg;
12523 report.longMsg = longMsg;
12524 report.stackTrace = stackTrace;
12529 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12530 synchronized (this) {
12531 app.crashing = false;
12532 app.crashingReport = null;
12533 app.notResponding = false;
12534 app.notRespondingReport = null;
12535 if (app.anrDialog == fromDialog) {
12536 app.anrDialog = null;
12538 if (app.waitDialog == fromDialog) {
12539 app.waitDialog = null;
12541 if (app.pid > 0 && app.pid != MY_PID) {
12542 handleAppCrashLocked(app, "user-terminated" /*reason*/,
12543 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12544 app.kill("user request after error", true);
12549 private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12550 String shortMsg, String longMsg, String stackTrace) {
12551 long now = SystemClock.uptimeMillis();
12554 if (!app.isolated) {
12555 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12559 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12560 // This process loses!
12561 Slog.w(TAG, "Process " + app.info.processName
12562 + " has crashed too many times: killing!");
12563 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12564 app.userId, app.info.processName, app.uid);
12565 mStackSupervisor.handleAppCrashLocked(app);
12566 if (!app.persistent) {
12567 // We don't want to start this process again until the user
12568 // explicitly does so... but for persistent process, we really
12569 // need to keep it running. If a persistent process is actually
12570 // repeatedly crashing, then badness for everyone.
12571 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12572 app.info.processName);
12573 if (!app.isolated) {
12574 // XXX We don't have a way to mark isolated processes
12575 // as bad, since they don't have a peristent identity.
12576 mBadProcesses.put(app.info.processName, app.uid,
12577 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12578 mProcessCrashTimes.remove(app.info.processName, app.uid);
12581 app.removed = true;
12582 // Don't let services in this process be restarted and potentially
12583 // annoy the user repeatedly. Unless it is persistent, since those
12584 // processes run critical code.
12585 removeProcessLocked(app, false, false, "crash");
12586 mStackSupervisor.resumeTopActivitiesLocked();
12589 mStackSupervisor.resumeTopActivitiesLocked();
12591 mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12594 // Bump up the crash count of any services currently running in the proc.
12595 for (int i=app.services.size()-1; i>=0; i--) {
12596 // Any services running in the application need to be placed
12597 // back in the pending list.
12598 ServiceRecord sr = app.services.valueAt(i);
12602 // If the crashing process is what we consider to be the "home process" and it has been
12603 // replaced by a third-party app, clear the package preferred activities from packages
12604 // with a home activity running in the process to prevent a repeatedly crashing app
12605 // from blocking the user to manually clear the list.
12606 final ArrayList<ActivityRecord> activities = app.activities;
12607 if (app == mHomeProcess && activities.size() > 0
12608 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12609 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12610 final ActivityRecord r = activities.get(activityNdx);
12611 if (r.isHomeActivity()) {
12612 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12614 ActivityThread.getPackageManager()
12615 .clearPackagePreferredActivities(r.packageName);
12616 } catch (RemoteException c) {
12617 // pm is in same process, this will never happen.
12623 if (!app.isolated) {
12624 // XXX Can't keep track of crash times for isolated processes,
12625 // because they don't have a perisistent identity.
12626 mProcessCrashTimes.put(app.info.processName, app.uid, now);
12629 if (app.crashHandler != null) mHandler.post(app.crashHandler);
12633 void startAppProblemLocked(ProcessRecord app) {
12634 // If this app is not running under the current user, then we
12635 // can't give it a report button because that would require
12636 // launching the report UI under a different user.
12637 app.errorReportReceiver = null;
12639 for (int userId : mUserController.getCurrentProfileIdsLocked()) {
12640 if (app.userId == userId) {
12641 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12642 mContext, app.info.packageName, app.info.flags);
12645 skipCurrentReceiverLocked(app);
12648 void skipCurrentReceiverLocked(ProcessRecord app) {
12649 for (BroadcastQueue queue : mBroadcastQueues) {
12650 queue.skipCurrentReceiverLocked(app);
12655 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12656 * The application process will exit immediately after this call returns.
12657 * @param app object of the crashing app, null for the system server
12658 * @param crashInfo describing the exception
12660 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12661 ProcessRecord r = findAppProcess(app, "Crash");
12662 final String processName = app == null ? "system_server"
12663 : (r == null ? "unknown" : r.processName);
12665 handleApplicationCrashInner("crash", r, processName, crashInfo);
12668 /* Native crash reporting uses this inner version because it needs to be somewhat
12669 * decoupled from the AM-managed cleanup lifecycle
12671 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12672 ApplicationErrorReport.CrashInfo crashInfo) {
12673 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12674 UserHandle.getUserId(Binder.getCallingUid()), processName,
12675 r == null ? -1 : r.info.flags,
12676 crashInfo.exceptionClassName,
12677 crashInfo.exceptionMessage,
12678 crashInfo.throwFileName,
12679 crashInfo.throwLineNumber);
12681 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12683 crashApplication(r, crashInfo);
12686 public void handleApplicationStrictModeViolation(
12689 StrictMode.ViolationInfo info) {
12690 ProcessRecord r = findAppProcess(app, "StrictMode");
12695 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12696 Integer stackFingerprint = info.hashCode();
12697 boolean logIt = true;
12698 synchronized (mAlreadyLoggedViolatedStacks) {
12699 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12701 // TODO: sub-sample into EventLog for these, with
12702 // the info.durationMillis? Then we'd get
12703 // the relative pain numbers, without logging all
12704 // the stack traces repeatedly. We'd want to do
12705 // likewise in the client code, which also does
12706 // dup suppression, before the Binder call.
12708 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12709 mAlreadyLoggedViolatedStacks.clear();
12711 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12715 logStrictModeViolationToDropBox(r, info);
12719 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12720 AppErrorResult result = new AppErrorResult();
12721 synchronized (this) {
12722 final long origId = Binder.clearCallingIdentity();
12724 Message msg = Message.obtain();
12725 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
12726 HashMap<String, Object> data = new HashMap<String, Object>();
12727 data.put("result", result);
12728 data.put("app", r);
12729 data.put("violationMask", violationMask);
12730 data.put("info", info);
12732 mUiHandler.sendMessage(msg);
12734 Binder.restoreCallingIdentity(origId);
12736 int res = result.get();
12737 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12741 // Depending on the policy in effect, there could be a bunch of
12742 // these in quick succession so we try to batch these together to
12743 // minimize disk writes, number of dropbox entries, and maximize
12744 // compression, by having more fewer, larger records.
12745 private void logStrictModeViolationToDropBox(
12746 ProcessRecord process,
12747 StrictMode.ViolationInfo info) {
12748 if (info == null) {
12751 final boolean isSystemApp = process == null ||
12752 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12753 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12754 final String processName = process == null ? "unknown" : process.processName;
12755 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12756 final DropBoxManager dbox = (DropBoxManager)
12757 mContext.getSystemService(Context.DROPBOX_SERVICE);
12759 // Exit early if the dropbox isn't configured to accept this report type.
12760 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12762 boolean bufferWasEmpty;
12763 boolean needsFlush;
12764 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12765 synchronized (sb) {
12766 bufferWasEmpty = sb.length() == 0;
12767 appendDropBoxProcessHeaders(process, processName, sb);
12768 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12769 sb.append("System-App: ").append(isSystemApp).append("\n");
12770 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12771 if (info.violationNumThisLoop != 0) {
12772 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12774 if (info.numAnimationsRunning != 0) {
12775 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12777 if (info.broadcastIntentAction != null) {
12778 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12780 if (info.durationMillis != -1) {
12781 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12783 if (info.numInstances != -1) {
12784 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12786 if (info.tags != null) {
12787 for (String tag : info.tags) {
12788 sb.append("Span-Tag: ").append(tag).append("\n");
12792 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12793 sb.append(info.crashInfo.stackTrace);
12796 if (info.message != null) {
12797 sb.append(info.message);
12801 // Only buffer up to ~64k. Various logging bits truncate
12803 needsFlush = (sb.length() > 64 * 1024);
12806 // Flush immediately if the buffer's grown too large, or this
12807 // is a non-system app. Non-system apps are isolated with a
12808 // different tag & policy and not batched.
12810 // Batching is useful during internal testing with
12811 // StrictMode settings turned up high. Without batching,
12812 // thousands of separate files could be created on boot.
12813 if (!isSystemApp || needsFlush) {
12814 new Thread("Error dump: " + dropboxTag) {
12816 public void run() {
12818 synchronized (sb) {
12819 report = sb.toString();
12820 sb.delete(0, sb.length());
12823 if (report.length() != 0) {
12824 dbox.addText(dropboxTag, report);
12831 // System app batching:
12832 if (!bufferWasEmpty) {
12833 // An existing dropbox-writing thread is outstanding, so
12834 // we don't need to start it up. The existing thread will
12835 // catch the buffer appends we just did.
12839 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12840 // (After this point, we shouldn't access AMS internal data structures.)
12841 new Thread("Error dump: " + dropboxTag) {
12843 public void run() {
12844 // 5 second sleep to let stacks arrive and be batched together
12846 Thread.sleep(5000); // 5 seconds
12847 } catch (InterruptedException e) {}
12849 String errorReport;
12850 synchronized (mStrictModeBuffer) {
12851 errorReport = mStrictModeBuffer.toString();
12852 if (errorReport.length() == 0) {
12855 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12856 mStrictModeBuffer.trimToSize();
12858 dbox.addText(dropboxTag, errorReport);
12864 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12865 * @param app object of the crashing app, null for the system server
12866 * @param tag reported by the caller
12867 * @param system whether this wtf is coming from the system
12868 * @param crashInfo describing the context of the error
12869 * @return true if the process should exit immediately (WTF is fatal)
12871 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12872 final ApplicationErrorReport.CrashInfo crashInfo) {
12873 final int callingUid = Binder.getCallingUid();
12874 final int callingPid = Binder.getCallingPid();
12877 // If this is coming from the system, we could very well have low-level
12878 // system locks held, so we want to do this all asynchronously. And we
12879 // never want this to become fatal, so there is that too.
12880 mHandler.post(new Runnable() {
12881 @Override public void run() {
12882 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12888 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12891 if (r != null && r.pid != Process.myPid() &&
12892 Settings.Global.getInt(mContext.getContentResolver(),
12893 Settings.Global.WTF_IS_FATAL, 0) != 0) {
12894 crashApplication(r, crashInfo);
12901 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12902 final ApplicationErrorReport.CrashInfo crashInfo) {
12903 final ProcessRecord r = findAppProcess(app, "WTF");
12904 final String processName = app == null ? "system_server"
12905 : (r == null ? "unknown" : r.processName);
12907 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12908 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12910 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12916 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12917 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12919 private ProcessRecord findAppProcess(IBinder app, String reason) {
12924 synchronized (this) {
12925 final int NP = mProcessNames.getMap().size();
12926 for (int ip=0; ip<NP; ip++) {
12927 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12928 final int NA = apps.size();
12929 for (int ia=0; ia<NA; ia++) {
12930 ProcessRecord p = apps.valueAt(ia);
12931 if (p.thread != null && p.thread.asBinder() == app) {
12937 Slog.w(TAG, "Can't find mystery application for " + reason
12938 + " from pid=" + Binder.getCallingPid()
12939 + " uid=" + Binder.getCallingUid() + ": " + app);
12945 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12946 * to append various headers to the dropbox log text.
12948 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12949 StringBuilder sb) {
12950 // Watchdog thread ends up invoking this function (with
12951 // a null ProcessRecord) to add the stack file to dropbox.
12952 // Do not acquire a lock on this (am) in such cases, as it
12953 // could cause a potential deadlock, if and when watchdog
12954 // is invoked due to unavailability of lock on am and it
12955 // would prevent watchdog from killing system_server.
12956 if (process == null) {
12957 sb.append("Process: ").append(processName).append("\n");
12960 // Note: ProcessRecord 'process' is guarded by the service
12961 // instance. (notably process.pkgList, which could otherwise change
12962 // concurrently during execution of this method)
12963 synchronized (this) {
12964 sb.append("Process: ").append(processName).append("\n");
12965 int flags = process.info.flags;
12966 IPackageManager pm = AppGlobals.getPackageManager();
12967 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12968 for (int ip=0; ip<process.pkgList.size(); ip++) {
12969 String pkg = process.pkgList.keyAt(ip);
12970 sb.append("Package: ").append(pkg);
12972 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12974 sb.append(" v").append(pi.versionCode);
12975 if (pi.versionName != null) {
12976 sb.append(" (").append(pi.versionName).append(")");
12979 } catch (RemoteException e) {
12980 Slog.e(TAG, "Error getting package info: " + pkg, e);
12987 private static String processClass(ProcessRecord process) {
12988 if (process == null || process.pid == MY_PID) {
12989 return "system_server";
12990 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12991 return "system_app";
12998 * Write a description of an error (crash, WTF, ANR) to the drop box.
12999 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13000 * @param process which caused the error, null means the system server
13001 * @param activity which triggered the error, null if unknown
13002 * @param parent activity related to the error, null if unknown
13003 * @param subject line related to the error, null if absent
13004 * @param report in long form describing the error, null if absent
13005 * @param logFile to include in the report, null if none
13006 * @param crashInfo giving an application stack trace, null if absent
13008 public void addErrorToDropBox(String eventType,
13009 ProcessRecord process, String processName, ActivityRecord activity,
13010 ActivityRecord parent, String subject,
13011 final String report, final File logFile,
13012 final ApplicationErrorReport.CrashInfo crashInfo) {
13013 // NOTE -- this must never acquire the ActivityManagerService lock,
13014 // otherwise the watchdog may be prevented from resetting the system.
13016 final String dropboxTag = processClass(process) + "_" + eventType;
13017 final DropBoxManager dbox = (DropBoxManager)
13018 mContext.getSystemService(Context.DROPBOX_SERVICE);
13020 // Exit early if the dropbox isn't configured to accept this report type.
13021 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13023 final StringBuilder sb = new StringBuilder(1024);
13024 appendDropBoxProcessHeaders(process, processName, sb);
13025 if (activity != null) {
13026 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13028 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13029 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13031 if (parent != null && parent != activity) {
13032 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13034 if (subject != null) {
13035 sb.append("Subject: ").append(subject).append("\n");
13037 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13038 if (Debug.isDebuggerConnected()) {
13039 sb.append("Debugger: Connected\n");
13043 // Do the rest in a worker thread to avoid blocking the caller on I/O
13044 // (After this point, we shouldn't access AMS internal data structures.)
13045 Thread worker = new Thread("Error dump: " + dropboxTag) {
13047 public void run() {
13048 if (report != null) {
13051 if (logFile != null) {
13053 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13054 "\n\n[[TRUNCATED]]"));
13055 } catch (IOException e) {
13056 Slog.e(TAG, "Error reading " + logFile, e);
13059 if (crashInfo != null && crashInfo.stackTrace != null) {
13060 sb.append(crashInfo.stackTrace);
13063 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13064 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13068 // Merge several logcat streams, and take the last N lines
13069 InputStreamReader input = null;
13071 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13072 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13074 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13076 try { logcat.getOutputStream().close(); } catch (IOException e) {}
13077 try { logcat.getErrorStream().close(); } catch (IOException e) {}
13078 input = new InputStreamReader(logcat.getInputStream());
13081 char[] buf = new char[8192];
13082 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13083 } catch (IOException e) {
13084 Slog.e(TAG, "Error running logcat", e);
13086 if (input != null) try { input.close(); } catch (IOException e) {}
13090 dbox.addText(dropboxTag, sb.toString());
13094 if (process == null) {
13095 // If process is null, we are being called from some internal code
13096 // and may be about to die -- run this synchronously.
13104 * Bring up the "unexpected error" dialog box for a crashing app.
13105 * Deal with edge cases (intercepts from instrumented applications,
13106 * ActivityController, error intent receivers, that sort of thing).
13107 * @param r the application crashing
13108 * @param crashInfo describing the failure
13110 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
13111 long timeMillis = System.currentTimeMillis();
13112 String shortMsg = crashInfo.exceptionClassName;
13113 String longMsg = crashInfo.exceptionMessage;
13114 String stackTrace = crashInfo.stackTrace;
13115 if (shortMsg != null && longMsg != null) {
13116 longMsg = shortMsg + ": " + longMsg;
13117 } else if (shortMsg != null) {
13118 longMsg = shortMsg;
13121 AppErrorResult result = new AppErrorResult();
13122 synchronized (this) {
13123 if (mController != null) {
13125 String name = r != null ? r.processName : null;
13126 int pid = r != null ? r.pid : Binder.getCallingPid();
13127 int uid = r != null ? r.info.uid : Binder.getCallingUid();
13128 if (!mController.appCrashed(name, pid,
13129 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
13130 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
13131 && "Native crash".equals(crashInfo.exceptionClassName)) {
13132 Slog.w(TAG, "Skip killing native crashed app " + name
13133 + "(" + pid + ") during testing");
13135 Slog.w(TAG, "Force-killing crashed app " + name
13136 + " at watcher's request");
13138 r.kill("crash", true);
13141 Process.killProcess(pid);
13142 killProcessGroup(uid, pid);
13147 } catch (RemoteException e) {
13148 mController = null;
13149 Watchdog.getInstance().setActivityController(null);
13153 final long origId = Binder.clearCallingIdentity();
13155 // If this process is running instrumentation, finish it.
13156 if (r != null && r.instrumentationClass != null) {
13157 Slog.w(TAG, "Error in app " + r.processName
13158 + " running instrumentation " + r.instrumentationClass + ":");
13159 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
13160 if (longMsg != null) Slog.w(TAG, " " + longMsg);
13161 Bundle info = new Bundle();
13162 info.putString("shortMsg", shortMsg);
13163 info.putString("longMsg", longMsg);
13164 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
13165 Binder.restoreCallingIdentity(origId);
13169 // Log crash in battery stats.
13171 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
13174 // If we can't identify the process or it's already exceeded its crash quota,
13175 // quit right away without showing a crash dialog.
13176 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
13177 Binder.restoreCallingIdentity(origId);
13181 Message msg = Message.obtain();
13182 msg.what = SHOW_ERROR_UI_MSG;
13183 HashMap data = new HashMap();
13184 data.put("result", result);
13185 data.put("app", r);
13187 mUiHandler.sendMessage(msg);
13189 Binder.restoreCallingIdentity(origId);
13192 int res = result.get();
13194 Intent appErrorIntent = null;
13195 synchronized (this) {
13196 if (r != null && !r.isolated) {
13197 // XXX Can't keep track of crash time for isolated processes,
13198 // since they don't have a persistent identity.
13199 mProcessCrashTimes.put(r.info.processName, r.uid,
13200 SystemClock.uptimeMillis());
13202 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
13203 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
13207 if (appErrorIntent != null) {
13209 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
13210 } catch (ActivityNotFoundException e) {
13211 Slog.w(TAG, "bug report receiver dissappeared", e);
13216 Intent createAppErrorIntentLocked(ProcessRecord r,
13217 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13218 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
13219 if (report == null) {
13222 Intent result = new Intent(Intent.ACTION_APP_ERROR);
13223 result.setComponent(r.errorReportReceiver);
13224 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
13225 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
13229 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
13230 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
13231 if (r.errorReportReceiver == null) {
13235 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
13239 ApplicationErrorReport report = new ApplicationErrorReport();
13240 report.packageName = r.info.packageName;
13241 report.installerPackageName = r.errorReportReceiver.getPackageName();
13242 report.processName = r.processName;
13243 report.time = timeMillis;
13244 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
13246 if (r.crashing || r.forceCrashReport) {
13247 report.type = ApplicationErrorReport.TYPE_CRASH;
13248 report.crashInfo = crashInfo;
13249 } else if (r.notResponding) {
13250 report.type = ApplicationErrorReport.TYPE_ANR;
13251 report.anrInfo = new ApplicationErrorReport.AnrInfo();
13253 report.anrInfo.activity = r.notRespondingReport.tag;
13254 report.anrInfo.cause = r.notRespondingReport.shortMsg;
13255 report.anrInfo.info = r.notRespondingReport.longMsg;
13261 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13262 enforceNotIsolatedCaller("getProcessesInErrorState");
13263 // assume our apps are happy - lazy create the list
13264 List<ActivityManager.ProcessErrorStateInfo> errList = null;
13266 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13267 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13268 int userId = UserHandle.getUserId(Binder.getCallingUid());
13270 synchronized (this) {
13272 // iterate across all processes
13273 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13274 ProcessRecord app = mLruProcesses.get(i);
13275 if (!allUsers && app.userId != userId) {
13278 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13279 // This one's in trouble, so we'll generate a report for it
13280 // crashes are higher priority (in case there's a crash *and* an anr)
13281 ActivityManager.ProcessErrorStateInfo report = null;
13282 if (app.crashing) {
13283 report = app.crashingReport;
13284 } else if (app.notResponding) {
13285 report = app.notRespondingReport;
13288 if (report != null) {
13289 if (errList == null) {
13290 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13292 errList.add(report);
13294 Slog.w(TAG, "Missing app error report, app = " + app.processName +
13295 " crashing = " + app.crashing +
13296 " notResponding = " + app.notResponding);
13305 static int procStateToImportance(int procState, int memAdj,
13306 ActivityManager.RunningAppProcessInfo currApp) {
13307 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13308 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13309 currApp.lru = memAdj;
13316 private void fillInProcMemInfo(ProcessRecord app,
13317 ActivityManager.RunningAppProcessInfo outInfo) {
13318 outInfo.pid = app.pid;
13319 outInfo.uid = app.info.uid;
13320 if (mHeavyWeightProcess == app) {
13321 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13323 if (app.persistent) {
13324 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13326 if (app.activities.size() > 0) {
13327 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13329 outInfo.lastTrimLevel = app.trimMemoryLevel;
13330 int adj = app.curAdj;
13331 int procState = app.curProcState;
13332 outInfo.importance = procStateToImportance(procState, adj, outInfo);
13333 outInfo.importanceReasonCode = app.adjTypeCode;
13334 outInfo.processState = app.curProcState;
13337 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13338 enforceNotIsolatedCaller("getRunningAppProcesses");
13340 final int callingUid = Binder.getCallingUid();
13342 // Lazy instantiation of list
13343 List<ActivityManager.RunningAppProcessInfo> runList = null;
13344 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13345 callingUid) == PackageManager.PERMISSION_GRANTED;
13346 final int userId = UserHandle.getUserId(callingUid);
13347 final boolean allUids = isGetTasksAllowed(
13348 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13350 synchronized (this) {
13351 // Iterate across all processes
13352 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13353 ProcessRecord app = mLruProcesses.get(i);
13354 if ((!allUsers && app.userId != userId)
13355 || (!allUids && app.uid != callingUid)) {
13358 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13359 // Generate process state info for running application
13360 ActivityManager.RunningAppProcessInfo currApp =
13361 new ActivityManager.RunningAppProcessInfo(app.processName,
13362 app.pid, app.getPackageList());
13363 fillInProcMemInfo(app, currApp);
13364 if (app.adjSource instanceof ProcessRecord) {
13365 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13366 currApp.importanceReasonImportance =
13367 ActivityManager.RunningAppProcessInfo.procStateToImportance(
13368 app.adjSourceProcState);
13369 } else if (app.adjSource instanceof ActivityRecord) {
13370 ActivityRecord r = (ActivityRecord)app.adjSource;
13371 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13373 if (app.adjTarget instanceof ComponentName) {
13374 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13376 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13377 // + " lru=" + currApp.lru);
13378 if (runList == null) {
13379 runList = new ArrayList<>();
13381 runList.add(currApp);
13388 public List<ApplicationInfo> getRunningExternalApplications() {
13389 enforceNotIsolatedCaller("getRunningExternalApplications");
13390 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13391 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13392 if (runningApps != null && runningApps.size() > 0) {
13393 Set<String> extList = new HashSet<String>();
13394 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13395 if (app.pkgList != null) {
13396 for (String pkg : app.pkgList) {
13401 IPackageManager pm = AppGlobals.getPackageManager();
13402 for (String pkg : extList) {
13404 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13405 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13408 } catch (RemoteException e) {
13416 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13417 enforceNotIsolatedCaller("getMyMemoryState");
13418 synchronized (this) {
13419 ProcessRecord proc;
13420 synchronized (mPidsSelfLocked) {
13421 proc = mPidsSelfLocked.get(Binder.getCallingPid());
13423 fillInProcMemInfo(proc, outInfo);
13428 public void onShellCommand(FileDescriptor in, FileDescriptor out,
13429 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13430 (new ActivityManagerShellCommand(this, false)).exec(
13431 this, in, out, err, args, resultReceiver);
13435 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13436 if (checkCallingPermission(android.Manifest.permission.DUMP)
13437 != PackageManager.PERMISSION_GRANTED) {
13438 pw.println("Permission Denial: can't dump ActivityManager from from pid="
13439 + Binder.getCallingPid()
13440 + ", uid=" + Binder.getCallingUid()
13441 + " without permission "
13442 + android.Manifest.permission.DUMP);
13446 boolean dumpAll = false;
13447 boolean dumpClient = false;
13448 String dumpPackage = null;
13451 while (opti < args.length) {
13452 String opt = args[opti];
13453 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13457 if ("-a".equals(opt)) {
13459 } else if ("-c".equals(opt)) {
13461 } else if ("-p".equals(opt)) {
13462 if (opti < args.length) {
13463 dumpPackage = args[opti];
13466 pw.println("Error: -p option requires package argument");
13470 } else if ("-h".equals(opt)) {
13471 ActivityManagerShellCommand.dumpHelp(pw, true);
13474 pw.println("Unknown argument: " + opt + "; use -h for help");
13478 long origId = Binder.clearCallingIdentity();
13479 boolean more = false;
13480 // Is the caller requesting to dump a particular piece of data?
13481 if (opti < args.length) {
13482 String cmd = args[opti];
13484 if ("activities".equals(cmd) || "a".equals(cmd)) {
13485 synchronized (this) {
13486 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13488 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13489 synchronized (this) {
13490 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13492 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13495 if (opti >= args.length) {
13497 newArgs = EMPTY_STRING_ARRAY;
13499 dumpPackage = args[opti];
13501 newArgs = new String[args.length - opti];
13502 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13503 args.length - opti);
13505 synchronized (this) {
13506 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13508 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13511 if (opti >= args.length) {
13513 newArgs = EMPTY_STRING_ARRAY;
13515 dumpPackage = args[opti];
13517 newArgs = new String[args.length - opti];
13518 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13519 args.length - opti);
13521 synchronized (this) {
13522 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13524 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13527 if (opti >= args.length) {
13529 newArgs = EMPTY_STRING_ARRAY;
13531 dumpPackage = args[opti];
13533 newArgs = new String[args.length - opti];
13534 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13535 args.length - opti);
13537 synchronized (this) {
13538 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13540 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13541 synchronized (this) {
13542 dumpOomLocked(fd, pw, args, opti, true);
13544 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13545 synchronized (this) {
13546 dumpPermissionsLocked(fd, pw, args, opti, true, null);
13548 } else if ("provider".equals(cmd)) {
13551 if (opti >= args.length) {
13553 newArgs = EMPTY_STRING_ARRAY;
13557 newArgs = new String[args.length - opti];
13558 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13560 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13561 pw.println("No providers match: " + name);
13562 pw.println("Use -h for help.");
13564 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13565 synchronized (this) {
13566 dumpProvidersLocked(fd, pw, args, opti, true, null);
13568 } else if ("service".equals(cmd)) {
13571 if (opti >= args.length) {
13573 newArgs = EMPTY_STRING_ARRAY;
13577 newArgs = new String[args.length - opti];
13578 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13579 args.length - opti);
13581 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13582 pw.println("No services match: " + name);
13583 pw.println("Use -h for help.");
13585 } else if ("package".equals(cmd)) {
13587 if (opti >= args.length) {
13588 pw.println("package: no package name specified");
13589 pw.println("Use -h for help.");
13591 dumpPackage = args[opti];
13593 newArgs = new String[args.length - opti];
13594 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13595 args.length - opti);
13600 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13601 synchronized (this) {
13602 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13604 } else if ("services".equals(cmd) || "s".equals(cmd)) {
13605 synchronized (this) {
13606 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13609 // Dumping a single activity?
13610 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13611 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13612 int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13614 pw.println("Bad activity command, or no activities match: " + cmd);
13615 pw.println("Use -h for help.");
13620 Binder.restoreCallingIdentity(origId);
13625 // No piece of data specified, dump everything.
13626 synchronized (this) {
13627 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13630 pw.println("-------------------------------------------------------------------------------");
13632 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13635 pw.println("-------------------------------------------------------------------------------");
13637 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13640 pw.println("-------------------------------------------------------------------------------");
13642 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13645 pw.println("-------------------------------------------------------------------------------");
13647 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13650 pw.println("-------------------------------------------------------------------------------");
13652 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13655 pw.println("-------------------------------------------------------------------------------");
13657 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13658 if (mAssociations.size() > 0) {
13661 pw.println("-------------------------------------------------------------------------------");
13663 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13667 pw.println("-------------------------------------------------------------------------------");
13669 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13671 Binder.restoreCallingIdentity(origId);
13674 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13675 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13676 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13678 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13680 boolean needSep = printedAnything;
13682 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13683 dumpPackage, needSep, " mFocusedActivity: ");
13685 printedAnything = true;
13689 if (dumpPackage == null) {
13694 printedAnything = true;
13695 mStackSupervisor.dump(pw, " ");
13698 if (!printedAnything) {
13699 pw.println(" (nothing)");
13703 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13704 int opti, boolean dumpAll, String dumpPackage) {
13705 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13707 boolean printedAnything = false;
13709 if (mRecentTasks != null && mRecentTasks.size() > 0) {
13710 boolean printedHeader = false;
13712 final int N = mRecentTasks.size();
13713 for (int i=0; i<N; i++) {
13714 TaskRecord tr = mRecentTasks.get(i);
13715 if (dumpPackage != null) {
13716 if (tr.realActivity == null ||
13717 !dumpPackage.equals(tr.realActivity)) {
13721 if (!printedHeader) {
13722 pw.println(" Recent tasks:");
13723 printedHeader = true;
13724 printedAnything = true;
13726 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
13729 mRecentTasks.get(i).dump(pw, " ");
13734 if (!printedAnything) {
13735 pw.println(" (nothing)");
13739 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13740 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13741 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13744 if (dumpPackage != null) {
13745 IPackageManager pm = AppGlobals.getPackageManager();
13747 dumpUid = pm.getPackageUid(dumpPackage, 0);
13748 } catch (RemoteException e) {
13752 boolean printedAnything = false;
13754 final long now = SystemClock.uptimeMillis();
13756 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13757 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13758 = mAssociations.valueAt(i1);
13759 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13760 SparseArray<ArrayMap<String, Association>> sourceUids
13761 = targetComponents.valueAt(i2);
13762 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13763 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13764 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13765 Association ass = sourceProcesses.valueAt(i4);
13766 if (dumpPackage != null) {
13767 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13768 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13772 printedAnything = true;
13774 pw.print(ass.mTargetProcess);
13776 UserHandle.formatUid(pw, ass.mTargetUid);
13778 pw.print(ass.mSourceProcess);
13780 UserHandle.formatUid(pw, ass.mSourceUid);
13783 pw.print(ass.mTargetComponent.flattenToShortString());
13786 long dur = ass.mTime;
13787 if (ass.mNesting > 0) {
13788 dur += now - ass.mStartTime;
13790 TimeUtils.formatDuration(dur, pw);
13792 pw.print(ass.mCount);
13793 pw.println(" times)");
13794 if (ass.mNesting > 0) {
13796 pw.print(" Currently active: ");
13797 TimeUtils.formatDuration(now - ass.mStartTime, pw);
13806 if (!printedAnything) {
13807 pw.println(" (nothing)");
13811 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13812 String header, boolean needSep) {
13813 boolean printed = false;
13814 int whichAppId = -1;
13815 if (dumpPackage != null) {
13817 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
13819 whichAppId = UserHandle.getAppId(info.uid);
13820 } catch (NameNotFoundException e) {
13821 e.printStackTrace();
13824 for (int i=0; i<uids.size(); i++) {
13825 UidRecord uidRec = uids.valueAt(i);
13826 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
13835 pw.println(header);
13838 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
13839 pw.print(": "); pw.println(uidRec);
13844 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13845 int opti, boolean dumpAll, String dumpPackage) {
13846 boolean needSep = false;
13847 boolean printedAnything = false;
13850 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13853 final int NP = mProcessNames.getMap().size();
13854 for (int ip=0; ip<NP; ip++) {
13855 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13856 final int NA = procs.size();
13857 for (int ia=0; ia<NA; ia++) {
13858 ProcessRecord r = procs.valueAt(ia);
13859 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13863 pw.println(" All known processes:");
13865 printedAnything = true;
13867 pw.print(r.persistent ? " *PERS*" : " *APP*");
13868 pw.print(" UID "); pw.print(procs.keyAt(ia));
13869 pw.print(" "); pw.println(r);
13871 if (r.persistent) {
13878 if (mIsolatedProcesses.size() > 0) {
13879 boolean printed = false;
13880 for (int i=0; i<mIsolatedProcesses.size(); i++) {
13881 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13882 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13889 pw.println(" Isolated process list (sorted by uid):");
13890 printedAnything = true;
13894 pw.println(String.format("%sIsolated #%2d: %s",
13895 " ", i, r.toString()));
13899 if (mActiveUids.size() > 0) {
13900 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
13901 printedAnything = needSep = true;
13904 if (mValidateUids.size() > 0) {
13905 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
13906 printedAnything = needSep = true;
13910 if (mLruProcesses.size() > 0) {
13914 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13915 pw.print(" total, non-act at ");
13916 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13917 pw.print(", non-svc at ");
13918 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13920 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
13922 printedAnything = true;
13925 if (dumpAll || dumpPackage != null) {
13926 synchronized (mPidsSelfLocked) {
13927 boolean printed = false;
13928 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13929 ProcessRecord r = mPidsSelfLocked.valueAt(i);
13930 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13934 if (needSep) pw.println();
13936 pw.println(" PID mappings:");
13938 printedAnything = true;
13940 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13941 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13946 if (mForegroundProcesses.size() > 0) {
13947 synchronized (mPidsSelfLocked) {
13948 boolean printed = false;
13949 for (int i=0; i<mForegroundProcesses.size(); i++) {
13950 ProcessRecord r = mPidsSelfLocked.get(
13951 mForegroundProcesses.valueAt(i).pid);
13952 if (dumpPackage != null && (r == null
13953 || !r.pkgList.containsKey(dumpPackage))) {
13957 if (needSep) pw.println();
13959 pw.println(" Foreground Processes:");
13961 printedAnything = true;
13963 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
13964 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13969 if (mPersistentStartingProcesses.size() > 0) {
13970 if (needSep) pw.println();
13972 printedAnything = true;
13973 pw.println(" Persisent processes that are starting:");
13974 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
13975 "Starting Norm", "Restarting PERS", dumpPackage);
13978 if (mRemovedProcesses.size() > 0) {
13979 if (needSep) pw.println();
13981 printedAnything = true;
13982 pw.println(" Processes that are being removed:");
13983 dumpProcessList(pw, this, mRemovedProcesses, " ",
13984 "Removed Norm", "Removed PERS", dumpPackage);
13987 if (mProcessesOnHold.size() > 0) {
13988 if (needSep) pw.println();
13990 printedAnything = true;
13991 pw.println(" Processes that are on old until the system is ready:");
13992 dumpProcessList(pw, this, mProcessesOnHold, " ",
13993 "OnHold Norm", "OnHold PERS", dumpPackage);
13996 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13998 if (mProcessCrashTimes.getMap().size() > 0) {
13999 boolean printed = false;
14000 long now = SystemClock.uptimeMillis();
14001 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
14002 final int NP = pmap.size();
14003 for (int ip=0; ip<NP; ip++) {
14004 String pname = pmap.keyAt(ip);
14005 SparseArray<Long> uids = pmap.valueAt(ip);
14006 final int N = uids.size();
14007 for (int i=0; i<N; i++) {
14008 int puid = uids.keyAt(i);
14009 ProcessRecord r = mProcessNames.get(pname, puid);
14010 if (dumpPackage != null && (r == null
14011 || !r.pkgList.containsKey(dumpPackage))) {
14015 if (needSep) pw.println();
14017 pw.println(" Time since processes crashed:");
14019 printedAnything = true;
14021 pw.print(" Process "); pw.print(pname);
14022 pw.print(" uid "); pw.print(puid);
14023 pw.print(": last crashed ");
14024 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
14025 pw.println(" ago");
14030 if (mBadProcesses.getMap().size() > 0) {
14031 boolean printed = false;
14032 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
14033 final int NP = pmap.size();
14034 for (int ip=0; ip<NP; ip++) {
14035 String pname = pmap.keyAt(ip);
14036 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
14037 final int N = uids.size();
14038 for (int i=0; i<N; i++) {
14039 int puid = uids.keyAt(i);
14040 ProcessRecord r = mProcessNames.get(pname, puid);
14041 if (dumpPackage != null && (r == null
14042 || !r.pkgList.containsKey(dumpPackage))) {
14046 if (needSep) pw.println();
14048 pw.println(" Bad processes:");
14049 printedAnything = true;
14051 BadProcessInfo info = uids.valueAt(i);
14052 pw.print(" Bad process "); pw.print(pname);
14053 pw.print(" uid "); pw.print(puid);
14054 pw.print(": crashed at time "); pw.println(info.time);
14055 if (info.shortMsg != null) {
14056 pw.print(" Short msg: "); pw.println(info.shortMsg);
14058 if (info.longMsg != null) {
14059 pw.print(" Long msg: "); pw.println(info.longMsg);
14061 if (info.stack != null) {
14062 pw.println(" Stack:");
14064 for (int pos=0; pos<info.stack.length(); pos++) {
14065 if (info.stack.charAt(pos) == '\n') {
14067 pw.write(info.stack, lastPos, pos-lastPos);
14072 if (lastPos < info.stack.length()) {
14074 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
14082 if (dumpPackage == null) {
14085 mUserController.dump(pw, dumpAll);
14087 if (mHomeProcess != null && (dumpPackage == null
14088 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14093 pw.println(" mHomeProcess: " + mHomeProcess);
14095 if (mPreviousProcess != null && (dumpPackage == null
14096 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14101 pw.println(" mPreviousProcess: " + mPreviousProcess);
14104 StringBuilder sb = new StringBuilder(128);
14105 sb.append(" mPreviousProcessVisibleTime: ");
14106 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14109 if (mHeavyWeightProcess != null && (dumpPackage == null
14110 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14115 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14117 if (dumpPackage == null) {
14118 pw.println(" mConfiguration: " + mConfiguration);
14121 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14122 if (mCompatModePackages.getPackages().size() > 0) {
14123 boolean printed = false;
14124 for (Map.Entry<String, Integer> entry
14125 : mCompatModePackages.getPackages().entrySet()) {
14126 String pkg = entry.getKey();
14127 int mode = entry.getValue();
14128 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14132 pw.println(" mScreenCompatPackages:");
14135 pw.print(" "); pw.print(pkg); pw.print(": ");
14136 pw.print(mode); pw.println();
14140 if (dumpPackage == null) {
14141 pw.println(" mWakefulness="
14142 + PowerManagerInternal.wakefulnessToString(mWakefulness));
14143 pw.println(" mSleepTokens=" + mSleepTokens);
14144 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
14145 + lockScreenShownToString());
14146 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14147 if (mRunningVoice != null) {
14148 pw.println(" mRunningVoice=" + mRunningVoice);
14149 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
14152 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14153 || mOrigWaitForDebugger) {
14154 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14155 || dumpPackage.equals(mOrigDebugApp)) {
14160 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14161 + " mDebugTransient=" + mDebugTransient
14162 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14165 if (mCurAppTimeTracker != null) {
14166 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
14168 if (mMemWatchProcesses.getMap().size() > 0) {
14169 pw.println(" Mem watch processes:");
14170 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14171 = mMemWatchProcesses.getMap();
14172 for (int i=0; i<procs.size(); i++) {
14173 final String proc = procs.keyAt(i);
14174 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14175 for (int j=0; j<uids.size(); j++) {
14180 StringBuilder sb = new StringBuilder();
14181 sb.append(" ").append(proc).append('/');
14182 UserHandle.formatUid(sb, uids.keyAt(j));
14183 Pair<Long, String> val = uids.valueAt(j);
14184 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14185 if (val.second != null) {
14186 sb.append(", report to ").append(val.second);
14188 pw.println(sb.toString());
14191 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14192 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14193 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14194 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14196 if (mTrackAllocationApp != null) {
14197 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14202 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
14205 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14206 || mProfileFd != null) {
14207 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14212 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14213 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14214 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14215 + mAutoStopProfiler);
14216 pw.println(" mProfileType=" + mProfileType);
14219 if (dumpPackage == null) {
14220 if (mAlwaysFinishActivities || mController != null) {
14221 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
14222 + " mController=" + mController);
14225 pw.println(" Total persistent processes: " + numPers);
14226 pw.println(" mProcessesReady=" + mProcessesReady
14227 + " mSystemReady=" + mSystemReady
14228 + " mBooted=" + mBooted
14229 + " mFactoryTest=" + mFactoryTest);
14230 pw.println(" mBooting=" + mBooting
14231 + " mCallFinishBooting=" + mCallFinishBooting
14232 + " mBootAnimationComplete=" + mBootAnimationComplete);
14233 pw.print(" mLastPowerCheckRealtime=");
14234 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14236 pw.print(" mLastPowerCheckUptime=");
14237 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14239 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14240 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14241 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14242 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
14243 + " (" + mLruProcesses.size() + " total)"
14244 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14245 + " mNumServiceProcs=" + mNumServiceProcs
14246 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14247 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
14248 + " mLastMemoryLevel" + mLastMemoryLevel
14249 + " mLastNumProcesses" + mLastNumProcesses);
14250 long now = SystemClock.uptimeMillis();
14251 pw.print(" mLastIdleTime=");
14252 TimeUtils.formatDuration(now, mLastIdleTime, pw);
14253 pw.print(" mLowRamSinceLastIdle=");
14254 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14259 if (!printedAnything) {
14260 pw.println(" (nothing)");
14264 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14265 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14266 if (mProcessesToGc.size() > 0) {
14267 boolean printed = false;
14268 long now = SystemClock.uptimeMillis();
14269 for (int i=0; i<mProcessesToGc.size(); i++) {
14270 ProcessRecord proc = mProcessesToGc.get(i);
14271 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14275 if (needSep) pw.println();
14277 pw.println(" Processes that are waiting to GC:");
14280 pw.print(" Process "); pw.println(proc);
14281 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
14282 pw.print(", last gced=");
14283 pw.print(now-proc.lastRequestedGc);
14284 pw.print(" ms ago, last lowMem=");
14285 pw.print(now-proc.lastLowMemory);
14286 pw.println(" ms ago");
14293 void printOomLevel(PrintWriter pw, String name, int adj) {
14297 if (adj < 10) pw.print(' ');
14299 if (adj > -10) pw.print(' ');
14305 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14309 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14310 int opti, boolean dumpAll) {
14311 boolean needSep = false;
14313 if (mLruProcesses.size() > 0) {
14314 if (needSep) pw.println();
14316 pw.println(" OOM levels:");
14317 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14318 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14319 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14320 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14321 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14322 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14323 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14324 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14325 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14326 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14327 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14328 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14329 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14330 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14332 if (needSep) pw.println();
14333 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
14334 pw.print(" total, non-act at ");
14335 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14336 pw.print(", non-svc at ");
14337 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14339 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
14343 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14346 pw.println(" mHomeProcess: " + mHomeProcess);
14347 pw.println(" mPreviousProcess: " + mPreviousProcess);
14348 if (mHeavyWeightProcess != null) {
14349 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14356 * There are three ways to call this:
14357 * - no provider specified: dump all the providers
14358 * - a flattened component name that matched an existing provider was specified as the
14359 * first arg: dump that one provider
14360 * - the first arg isn't the flattened component name of an existing provider:
14361 * dump all providers whose component contains the first arg as a substring
14363 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14364 int opti, boolean dumpAll) {
14365 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14368 static class ItemMatcher {
14369 ArrayList<ComponentName> components;
14370 ArrayList<String> strings;
14371 ArrayList<Integer> objects;
14378 void build(String name) {
14379 ComponentName componentName = ComponentName.unflattenFromString(name);
14380 if (componentName != null) {
14381 if (components == null) {
14382 components = new ArrayList<ComponentName>();
14384 components.add(componentName);
14388 // Not a '/' separated full component name; maybe an object ID?
14390 objectId = Integer.parseInt(name, 16);
14391 if (objects == null) {
14392 objects = new ArrayList<Integer>();
14394 objects.add(objectId);
14396 } catch (RuntimeException e) {
14397 // Not an integer; just do string match.
14398 if (strings == null) {
14399 strings = new ArrayList<String>();
14407 int build(String[] args, int opti) {
14408 for (; opti<args.length; opti++) {
14409 String name = args[opti];
14410 if ("--".equals(name)) {
14418 boolean match(Object object, ComponentName comp) {
14422 if (components != null) {
14423 for (int i=0; i<components.size(); i++) {
14424 if (components.get(i).equals(comp)) {
14429 if (objects != null) {
14430 for (int i=0; i<objects.size(); i++) {
14431 if (System.identityHashCode(object) == objects.get(i)) {
14436 if (strings != null) {
14437 String flat = comp.flattenToString();
14438 for (int i=0; i<strings.size(); i++) {
14439 if (flat.contains(strings.get(i))) {
14449 * There are three things that cmd can be:
14450 * - a flattened component name that matches an existing activity
14451 * - the cmd arg isn't the flattened component name of an existing activity:
14452 * dump all activity whose component contains the cmd as a substring
14453 * - A hex number of the ActivityRecord object instance.
14455 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14456 int opti, boolean dumpAll) {
14457 ArrayList<ActivityRecord> activities;
14459 synchronized (this) {
14460 activities = mStackSupervisor.getDumpActivitiesLocked(name);
14463 if (activities.size() <= 0) {
14467 String[] newArgs = new String[args.length - opti];
14468 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14470 TaskRecord lastTask = null;
14471 boolean needSep = false;
14472 for (int i=activities.size()-1; i>=0; i--) {
14473 ActivityRecord r = activities.get(i);
14478 synchronized (this) {
14479 if (lastTask != r.task) {
14481 pw.print("TASK "); pw.print(lastTask.affinity);
14482 pw.print(" id="); pw.println(lastTask.taskId);
14484 lastTask.dump(pw, " ");
14488 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
14494 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14495 * there is a thread associated with the activity.
14497 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14498 final ActivityRecord r, String[] args, boolean dumpAll) {
14499 String innerPrefix = prefix + " ";
14500 synchronized (this) {
14501 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14502 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14504 if (r.app != null) pw.println(r.app.pid);
14505 else pw.println("(not running)");
14507 r.dump(pw, innerPrefix);
14510 if (r.app != null && r.app.thread != null) {
14511 // flush anything that is already in the PrintWriter since the thread is going
14512 // to write to the file descriptor directly
14515 TransferPipe tp = new TransferPipe();
14517 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14518 r.appToken, innerPrefix, args);
14523 } catch (IOException e) {
14524 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14525 } catch (RemoteException e) {
14526 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14531 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14532 int opti, boolean dumpAll, String dumpPackage) {
14533 boolean needSep = false;
14534 boolean onlyHistory = false;
14535 boolean printedAnything = false;
14537 if ("history".equals(dumpPackage)) {
14538 if (opti < args.length && "-s".equals(args[opti])) {
14541 onlyHistory = true;
14542 dumpPackage = null;
14545 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14546 if (!onlyHistory && dumpAll) {
14547 if (mRegisteredReceivers.size() > 0) {
14548 boolean printed = false;
14549 Iterator it = mRegisteredReceivers.values().iterator();
14550 while (it.hasNext()) {
14551 ReceiverList r = (ReceiverList)it.next();
14552 if (dumpPackage != null && (r.app == null ||
14553 !dumpPackage.equals(r.app.info.packageName))) {
14557 pw.println(" Registered Receivers:");
14560 printedAnything = true;
14562 pw.print(" * "); pw.println(r);
14567 if (mReceiverResolver.dump(pw, needSep ?
14568 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
14569 " ", dumpPackage, false, false)) {
14571 printedAnything = true;
14575 for (BroadcastQueue q : mBroadcastQueues) {
14576 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14577 printedAnything |= needSep;
14582 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14583 for (int user=0; user<mStickyBroadcasts.size(); user++) {
14588 printedAnything = true;
14589 pw.print(" Sticky broadcasts for user ");
14590 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14591 StringBuilder sb = new StringBuilder(128);
14592 for (Map.Entry<String, ArrayList<Intent>> ent
14593 : mStickyBroadcasts.valueAt(user).entrySet()) {
14594 pw.print(" * Sticky action "); pw.print(ent.getKey());
14597 ArrayList<Intent> intents = ent.getValue();
14598 final int N = intents.size();
14599 for (int i=0; i<N; i++) {
14601 sb.append(" Intent: ");
14602 intents.get(i).toShortString(sb, false, true, false, false);
14603 pw.println(sb.toString());
14604 Bundle bundle = intents.get(i).getExtras();
14605 if (bundle != null) {
14607 pw.println(bundle.toString());
14617 if (!onlyHistory && dumpAll) {
14619 for (BroadcastQueue queue : mBroadcastQueues) {
14620 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
14621 + queue.mBroadcastsScheduled);
14623 pw.println(" mHandler:");
14624 mHandler.dump(new PrintWriterPrinter(pw), " ");
14626 printedAnything = true;
14629 if (!printedAnything) {
14630 pw.println(" (nothing)");
14634 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14635 int opti, boolean dumpAll, String dumpPackage) {
14637 boolean printedAnything = false;
14639 ItemMatcher matcher = new ItemMatcher();
14640 matcher.build(args, opti);
14642 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14644 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14645 printedAnything |= needSep;
14647 if (mLaunchingProviders.size() > 0) {
14648 boolean printed = false;
14649 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14650 ContentProviderRecord r = mLaunchingProviders.get(i);
14651 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14655 if (needSep) pw.println();
14657 pw.println(" Launching content providers:");
14659 printedAnything = true;
14661 pw.print(" Launching #"); pw.print(i); pw.print(": ");
14666 if (!printedAnything) {
14667 pw.println(" (nothing)");
14671 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14672 int opti, boolean dumpAll, String dumpPackage) {
14673 boolean needSep = false;
14674 boolean printedAnything = false;
14676 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14678 if (mGrantedUriPermissions.size() > 0) {
14679 boolean printed = false;
14681 if (dumpPackage != null) {
14683 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14684 } catch (NameNotFoundException e) {
14688 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14689 int uid = mGrantedUriPermissions.keyAt(i);
14690 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14693 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14695 if (needSep) pw.println();
14697 pw.println(" Granted Uri Permissions:");
14699 printedAnything = true;
14701 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
14702 for (UriPermission perm : perms.values()) {
14703 pw.print(" "); pw.println(perm);
14705 perm.dump(pw, " ");
14711 if (!printedAnything) {
14712 pw.println(" (nothing)");
14716 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14717 int opti, boolean dumpAll, String dumpPackage) {
14718 boolean printed = false;
14720 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14722 if (mIntentSenderRecords.size() > 0) {
14723 Iterator<WeakReference<PendingIntentRecord>> it
14724 = mIntentSenderRecords.values().iterator();
14725 while (it.hasNext()) {
14726 WeakReference<PendingIntentRecord> ref = it.next();
14727 PendingIntentRecord rec = ref != null ? ref.get(): null;
14728 if (dumpPackage != null && (rec == null
14729 || !dumpPackage.equals(rec.key.packageName))) {
14734 pw.print(" * "); pw.println(rec);
14739 pw.print(" * "); pw.println(ref);
14745 pw.println(" (nothing)");
14749 private static final int dumpProcessList(PrintWriter pw,
14750 ActivityManagerService service, List list,
14751 String prefix, String normalLabel, String persistentLabel,
14752 String dumpPackage) {
14754 final int N = list.size()-1;
14755 for (int i=N; i>=0; i--) {
14756 ProcessRecord r = (ProcessRecord)list.get(i);
14757 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14760 pw.println(String.format("%s%s #%2d: %s",
14761 prefix, (r.persistent ? persistentLabel : normalLabel),
14763 if (r.persistent) {
14770 private static final boolean dumpProcessOomList(PrintWriter pw,
14771 ActivityManagerService service, List<ProcessRecord> origList,
14772 String prefix, String normalLabel, String persistentLabel,
14773 boolean inclDetails, String dumpPackage) {
14775 ArrayList<Pair<ProcessRecord, Integer>> list
14776 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14777 for (int i=0; i<origList.size(); i++) {
14778 ProcessRecord r = origList.get(i);
14779 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14782 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14785 if (list.size() <= 0) {
14789 Comparator<Pair<ProcessRecord, Integer>> comparator
14790 = new Comparator<Pair<ProcessRecord, Integer>>() {
14792 public int compare(Pair<ProcessRecord, Integer> object1,
14793 Pair<ProcessRecord, Integer> object2) {
14794 if (object1.first.setAdj != object2.first.setAdj) {
14795 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14797 if (object1.first.setProcState != object2.first.setProcState) {
14798 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14800 if (object1.second.intValue() != object2.second.intValue()) {
14801 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14807 Collections.sort(list, comparator);
14809 final long curRealtime = SystemClock.elapsedRealtime();
14810 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14811 final long curUptime = SystemClock.uptimeMillis();
14812 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14814 for (int i=list.size()-1; i>=0; i--) {
14815 ProcessRecord r = list.get(i).first;
14816 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14818 switch (r.setSchedGroup) {
14819 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14822 case Process.THREAD_GROUP_DEFAULT:
14830 if (r.foregroundActivities) {
14832 } else if (r.foregroundServices) {
14837 String procState = ProcessList.makeProcStateString(r.curProcState);
14839 pw.print(r.persistent ? persistentLabel : normalLabel);
14841 int num = (origList.size()-1)-list.get(i).second;
14842 if (num < 10) pw.print(' ');
14847 pw.print(schedGroup);
14849 pw.print(foreground);
14851 pw.print(procState);
14853 if (r.trimMemoryLevel < 10) pw.print(' ');
14854 pw.print(r.trimMemoryLevel);
14856 pw.print(r.toShortString());
14858 pw.print(r.adjType);
14860 if (r.adjSource != null || r.adjTarget != null) {
14863 if (r.adjTarget instanceof ComponentName) {
14864 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14865 } else if (r.adjTarget != null) {
14866 pw.print(r.adjTarget.toString());
14868 pw.print("{null}");
14871 if (r.adjSource instanceof ProcessRecord) {
14873 pw.print(((ProcessRecord)r.adjSource).toShortString());
14875 } else if (r.adjSource != null) {
14876 pw.println(r.adjSource.toString());
14878 pw.println("{null}");
14884 pw.print("oom: max="); pw.print(r.maxAdj);
14885 pw.print(" curRaw="); pw.print(r.curRawAdj);
14886 pw.print(" setRaw="); pw.print(r.setRawAdj);
14887 pw.print(" cur="); pw.print(r.curAdj);
14888 pw.print(" set="); pw.println(r.setAdj);
14891 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14892 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14893 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14894 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14898 pw.print("cached="); pw.print(r.cached);
14899 pw.print(" empty="); pw.print(r.empty);
14900 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14902 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14903 if (r.lastWakeTime != 0) {
14905 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14906 synchronized (stats) {
14907 wtime = stats.getProcessWakeTime(r.info.uid,
14908 r.pid, curRealtime);
14910 long timeUsed = wtime - r.lastWakeTime;
14913 pw.print("keep awake over ");
14914 TimeUtils.formatDuration(realtimeSince, pw);
14915 pw.print(" used ");
14916 TimeUtils.formatDuration(timeUsed, pw);
14918 pw.print((timeUsed*100)/realtimeSince);
14921 if (r.lastCpuTime != 0) {
14922 long timeUsed = r.curCpuTime - r.lastCpuTime;
14925 pw.print("run cpu over ");
14926 TimeUtils.formatDuration(uptimeSince, pw);
14927 pw.print(" used ");
14928 TimeUtils.formatDuration(timeUsed, pw);
14930 pw.print((timeUsed*100)/uptimeSince);
14939 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14941 ArrayList<ProcessRecord> procs;
14942 synchronized (this) {
14943 if (args != null && args.length > start
14944 && args[start].charAt(0) != '-') {
14945 procs = new ArrayList<ProcessRecord>();
14948 pid = Integer.parseInt(args[start]);
14949 } catch (NumberFormatException e) {
14951 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14952 ProcessRecord proc = mLruProcesses.get(i);
14953 if (proc.pid == pid) {
14955 } else if (allPkgs && proc.pkgList != null
14956 && proc.pkgList.containsKey(args[start])) {
14958 } else if (proc.processName.equals(args[start])) {
14962 if (procs.size() <= 0) {
14966 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14972 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14973 PrintWriter pw, String[] args) {
14974 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14975 if (procs == null) {
14976 pw.println("No process found for: " + args[0]);
14980 long uptime = SystemClock.uptimeMillis();
14981 long realtime = SystemClock.elapsedRealtime();
14982 pw.println("Applications Graphics Acceleration Info:");
14983 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14985 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14986 ProcessRecord r = procs.get(i);
14987 if (r.thread != null) {
14988 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14991 TransferPipe tp = new TransferPipe();
14993 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14998 } catch (IOException e) {
14999 pw.println("Failure while dumping the app: " + r);
15001 } catch (RemoteException e) {
15002 pw.println("Got a RemoteException while dumping the app " + r);
15009 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15010 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15011 if (procs == null) {
15012 pw.println("No process found for: " + args[0]);
15016 pw.println("Applications Database Info:");
15018 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15019 ProcessRecord r = procs.get(i);
15020 if (r.thread != null) {
15021 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15024 TransferPipe tp = new TransferPipe();
15026 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15031 } catch (IOException e) {
15032 pw.println("Failure while dumping the app: " + r);
15034 } catch (RemoteException e) {
15035 pw.println("Got a RemoteException while dumping the app " + r);
15042 final static class MemItem {
15043 final boolean isProc;
15044 final String label;
15045 final String shortLabel;
15048 final boolean hasActivities;
15049 ArrayList<MemItem> subitems;
15051 public MemItem(String _label, String _shortLabel, long _pss, int _id,
15052 boolean _hasActivities) {
15055 shortLabel = _shortLabel;
15058 hasActivities = _hasActivities;
15061 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
15064 shortLabel = _shortLabel;
15067 hasActivities = false;
15071 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15072 ArrayList<MemItem> items, boolean sort, boolean isCompact) {
15073 if (sort && !isCompact) {
15074 Collections.sort(items, new Comparator<MemItem>() {
15076 public int compare(MemItem lhs, MemItem rhs) {
15077 if (lhs.pss < rhs.pss) {
15079 } else if (lhs.pss > rhs.pss) {
15087 for (int i=0; i<items.size(); i++) {
15088 MemItem mi = items.get(i);
15090 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15091 } else if (mi.isProc) {
15092 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15093 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
15094 pw.println(mi.hasActivities ? ",a" : ",e");
15096 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15097 pw.println(mi.pss);
15099 if (mi.subitems != null) {
15100 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
15106 // These are in KB.
15107 static final long[] DUMP_MEM_BUCKETS = new long[] {
15108 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15109 120*1024, 160*1024, 200*1024,
15110 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15111 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15114 static final void appendMemBucket(StringBuilder out, long memKB, String label,
15115 boolean stackLike) {
15116 int start = label.lastIndexOf('.');
15117 if (start >= 0) start++;
15119 int end = label.length();
15120 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15121 if (DUMP_MEM_BUCKETS[i] >= memKB) {
15122 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15123 out.append(bucket);
15124 out.append(stackLike ? "MB." : "MB ");
15125 out.append(label, start, end);
15129 out.append(memKB/1024);
15130 out.append(stackLike ? "MB." : "MB ");
15131 out.append(label, start, end);
15134 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15135 ProcessList.NATIVE_ADJ,
15136 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15137 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15138 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15139 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15140 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15141 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15143 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15145 "System", "Persistent", "Persistent Service", "Foreground",
15146 "Visible", "Perceptible",
15147 "Heavy Weight", "Backup",
15148 "A Services", "Home",
15149 "Previous", "B Services", "Cached"
15151 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15153 "sys", "pers", "persvc", "fore",
15156 "servicea", "home",
15157 "prev", "serviceb", "cached"
15160 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15161 long realtime, boolean isCheckinRequest, boolean isCompact) {
15162 if (isCheckinRequest || isCompact) {
15163 // short checkin version
15164 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15166 pw.println("Applications Memory Usage (in Kilobytes):");
15167 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15171 private static final int KSM_SHARED = 0;
15172 private static final int KSM_SHARING = 1;
15173 private static final int KSM_UNSHARED = 2;
15174 private static final int KSM_VOLATILE = 3;
15176 private final long[] getKsmInfo() {
15177 long[] longOut = new long[4];
15178 final int[] SINGLE_LONG_FORMAT = new int[] {
15179 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15181 long[] longTmp = new long[1];
15182 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15183 SINGLE_LONG_FORMAT, null, longTmp, null);
15184 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15186 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15187 SINGLE_LONG_FORMAT, null, longTmp, null);
15188 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15190 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15191 SINGLE_LONG_FORMAT, null, longTmp, null);
15192 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15194 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15195 SINGLE_LONG_FORMAT, null, longTmp, null);
15196 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15200 private static String stringifySize(long size, int order) {
15201 Locale locale = Locale.US;
15204 return String.format(locale, "%,13d", size);
15206 return String.format(locale, "%,9dK", size / 1024);
15208 return String.format(locale, "%,5dM", size / 1024 / 1024);
15209 case 1024 * 1024 * 1024:
15210 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15212 throw new IllegalArgumentException("Invalid size order");
15216 private static String stringifyKBSize(long size) {
15217 return stringifySize(size * 1024, 1024);
15220 final void dumpApplicationMemoryUsage(FileDescriptor fd,
15221 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15222 boolean dumpDetails = false;
15223 boolean dumpFullDetails = false;
15224 boolean dumpDalvik = false;
15225 boolean dumpSummaryOnly = false;
15226 boolean oomOnly = false;
15227 boolean isCompact = false;
15228 boolean localOnly = false;
15229 boolean packages = false;
15232 while (opti < args.length) {
15233 String opt = args[opti];
15234 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15238 if ("-a".equals(opt)) {
15239 dumpDetails = true;
15240 dumpFullDetails = true;
15242 } else if ("-d".equals(opt)) {
15244 } else if ("-c".equals(opt)) {
15246 } else if ("-s".equals(opt)) {
15247 dumpDetails = true;
15248 dumpSummaryOnly = true;
15249 } else if ("--oom".equals(opt)) {
15251 } else if ("--local".equals(opt)) {
15253 } else if ("--package".equals(opt)) {
15255 } else if ("-h".equals(opt)) {
15256 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15257 pw.println(" -a: include all available information for each process.");
15258 pw.println(" -d: include dalvik details.");
15259 pw.println(" -c: dump in a compact machine-parseable representation.");
15260 pw.println(" -s: dump only summary of application memory usage.");
15261 pw.println(" --oom: only show processes organized by oom adj.");
15262 pw.println(" --local: only collect details locally, don't call process.");
15263 pw.println(" --package: interpret process arg as package, dumping all");
15264 pw.println(" processes that have loaded that package.");
15265 pw.println("If [process] is specified it can be the name or ");
15266 pw.println("pid of a specific process to dump.");
15269 pw.println("Unknown argument: " + opt + "; use -h for help");
15273 final boolean isCheckinRequest = scanArgs(args, "--checkin");
15274 long uptime = SystemClock.uptimeMillis();
15275 long realtime = SystemClock.elapsedRealtime();
15276 final long[] tmpLong = new long[1];
15278 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15279 if (procs == null) {
15280 // No Java processes. Maybe they want to print a native process.
15281 if (args != null && args.length > opti
15282 && args[opti].charAt(0) != '-') {
15283 ArrayList<ProcessCpuTracker.Stats> nativeProcs
15284 = new ArrayList<ProcessCpuTracker.Stats>();
15285 updateCpuStatsNow();
15288 findPid = Integer.parseInt(args[opti]);
15289 } catch (NumberFormatException e) {
15291 synchronized (mProcessCpuTracker) {
15292 final int N = mProcessCpuTracker.countStats();
15293 for (int i=0; i<N; i++) {
15294 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15295 if (st.pid == findPid || (st.baseName != null
15296 && st.baseName.equals(args[opti]))) {
15297 nativeProcs.add(st);
15301 if (nativeProcs.size() > 0) {
15302 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15304 Debug.MemoryInfo mi = null;
15305 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15306 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15307 final int pid = r.pid;
15308 if (!isCheckinRequest && dumpDetails) {
15309 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15312 mi = new Debug.MemoryInfo();
15314 if (dumpDetails || (!brief && !oomOnly)) {
15315 Debug.getMemoryInfo(pid, mi);
15317 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15318 mi.dalvikPrivateDirty = (int)tmpLong[0];
15320 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15321 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15322 if (isCheckinRequest) {
15329 pw.println("No process found for: " + args[opti]);
15333 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15334 dumpDetails = true;
15337 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15339 String[] innerArgs = new String[args.length-opti];
15340 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15342 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15343 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15344 long nativePss = 0;
15345 long dalvikPss = 0;
15346 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15349 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15351 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15352 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15353 new ArrayList[DUMP_MEM_OOM_LABEL.length];
15356 long cachedPss = 0;
15358 Debug.MemoryInfo mi = null;
15359 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15360 final ProcessRecord r = procs.get(i);
15361 final IApplicationThread thread;
15364 final boolean hasActivities;
15365 synchronized (this) {
15368 oomAdj = r.getSetAdjWithServices();
15369 hasActivities = r.activities.size() > 0;
15371 if (thread != null) {
15372 if (!isCheckinRequest && dumpDetails) {
15373 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15376 mi = new Debug.MemoryInfo();
15378 if (dumpDetails || (!brief && !oomOnly)) {
15379 Debug.getMemoryInfo(pid, mi);
15381 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15382 mi.dalvikPrivateDirty = (int)tmpLong[0];
15386 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15387 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15388 if (isCheckinRequest) {
15394 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15395 dumpDalvik, dumpSummaryOnly, innerArgs);
15396 } catch (RemoteException e) {
15397 if (!isCheckinRequest) {
15398 pw.println("Got RemoteException!");
15405 final long myTotalPss = mi.getTotalPss();
15406 final long myTotalUss = mi.getTotalUss();
15408 synchronized (this) {
15409 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15410 // Record this for posterity if the process has been stable.
15411 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15415 if (!isCheckinRequest && mi != null) {
15416 totalPss += myTotalPss;
15417 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15418 (hasActivities ? " / activities)" : ")"),
15419 r.processName, myTotalPss, pid, hasActivities);
15420 procMems.add(pssItem);
15421 procMemsMap.put(pid, pssItem);
15423 nativePss += mi.nativePss;
15424 dalvikPss += mi.dalvikPss;
15425 for (int j=0; j<dalvikSubitemPss.length; j++) {
15426 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15428 otherPss += mi.otherPss;
15429 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15430 long mem = mi.getOtherPss(j);
15435 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15436 cachedPss += myTotalPss;
15439 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15440 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15441 || oomIndex == (oomPss.length-1)) {
15442 oomPss[oomIndex] += myTotalPss;
15443 if (oomProcs[oomIndex] == null) {
15444 oomProcs[oomIndex] = new ArrayList<MemItem>();
15446 oomProcs[oomIndex].add(pssItem);
15454 long nativeProcTotalPss = 0;
15456 if (!isCheckinRequest && procs.size() > 1 && !packages) {
15457 // If we are showing aggregations, also look for native processes to
15458 // include so that our aggregations are more accurate.
15459 updateCpuStatsNow();
15461 synchronized (mProcessCpuTracker) {
15462 final int N = mProcessCpuTracker.countStats();
15463 for (int i=0; i<N; i++) {
15464 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15465 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15467 mi = new Debug.MemoryInfo();
15469 if (!brief && !oomOnly) {
15470 Debug.getMemoryInfo(st.pid, mi);
15472 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15473 mi.nativePrivateDirty = (int)tmpLong[0];
15476 final long myTotalPss = mi.getTotalPss();
15477 totalPss += myTotalPss;
15478 nativeProcTotalPss += myTotalPss;
15480 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15481 st.name, myTotalPss, st.pid, false);
15482 procMems.add(pssItem);
15484 nativePss += mi.nativePss;
15485 dalvikPss += mi.dalvikPss;
15486 for (int j=0; j<dalvikSubitemPss.length; j++) {
15487 dalvikSubitemPss[j] += mi.getOtherPss(
15488 Debug.MemoryInfo.NUM_OTHER_STATS + j);
15490 otherPss += mi.otherPss;
15491 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15492 long mem = mi.getOtherPss(j);
15496 oomPss[0] += myTotalPss;
15497 if (oomProcs[0] == null) {
15498 oomProcs[0] = new ArrayList<MemItem>();
15500 oomProcs[0].add(pssItem);
15505 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15507 catMems.add(new MemItem("Native", "Native", nativePss, -1));
15508 final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15509 if (dalvikSubitemPss.length > 0) {
15510 dalvikItem.subitems = new ArrayList<MemItem>();
15511 for (int j=0; j<dalvikSubitemPss.length; j++) {
15512 final String name = Debug.MemoryInfo.getOtherLabel(
15513 Debug.MemoryInfo.NUM_OTHER_STATS + j);
15514 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15517 catMems.add(dalvikItem);
15518 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15519 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15520 String label = Debug.MemoryInfo.getOtherLabel(j);
15521 catMems.add(new MemItem(label, label, miscPss[j], j));
15524 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15525 for (int j=0; j<oomPss.length; j++) {
15526 if (oomPss[j] != 0) {
15527 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15528 : DUMP_MEM_OOM_LABEL[j];
15529 MemItem item = new MemItem(label, label, oomPss[j],
15530 DUMP_MEM_OOM_ADJ[j]);
15531 item.subitems = oomProcs[j];
15536 if (!brief && !oomOnly && !isCompact) {
15538 pw.println("Total PSS by process:");
15539 dumpMemItems(pw, " ", "proc", procMems, true, isCompact);
15543 pw.println("Total PSS by OOM adjustment:");
15545 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact);
15546 if (!brief && !oomOnly) {
15547 PrintWriter out = categoryPw != null ? categoryPw : pw;
15550 out.println("Total PSS by category:");
15552 dumpMemItems(out, " ", "cat", catMems, true, isCompact);
15557 MemInfoReader memInfo = new MemInfoReader();
15558 memInfo.readMemInfo();
15559 if (nativeProcTotalPss > 0) {
15560 synchronized (this) {
15561 final long cachedKb = memInfo.getCachedSizeKb();
15562 final long freeKb = memInfo.getFreeSizeKb();
15563 final long zramKb = memInfo.getZramTotalSizeKb();
15564 final long kernelKb = memInfo.getKernelUsedSizeKb();
15565 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15566 kernelKb*1024, nativeProcTotalPss*1024);
15567 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15568 nativeProcTotalPss);
15573 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15574 pw.print(" (status ");
15575 switch (mLastMemoryLevel) {
15576 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15577 pw.println("normal)");
15579 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15580 pw.println("moderate)");
15582 case ProcessStats.ADJ_MEM_FACTOR_LOW:
15583 pw.println("low)");
15585 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15586 pw.println("critical)");
15589 pw.print(mLastMemoryLevel);
15593 pw.print(" Free RAM: ");
15594 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15595 + memInfo.getFreeSizeKb()));
15597 pw.print(stringifyKBSize(cachedPss));
15598 pw.print(" cached pss + ");
15599 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15600 pw.print(" cached kernel + ");
15601 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15602 pw.println(" free)");
15604 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15605 pw.print(cachedPss + memInfo.getCachedSizeKb()
15606 + memInfo.getFreeSizeKb()); pw.print(",");
15607 pw.println(totalPss - cachedPss);
15611 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15612 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15613 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15614 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15615 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(memInfo.getTotalSizeKb()
15616 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15617 - memInfo.getKernelUsedSizeKb()));
15619 pw.print("lostram,"); pw.println(memInfo.getTotalSizeKb()
15620 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15621 - memInfo.getKernelUsedSizeKb());
15624 if (memInfo.getZramTotalSizeKb() != 0) {
15626 pw.print(" ZRAM: ");
15627 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15628 pw.print(" physical used for ");
15629 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15630 - memInfo.getSwapFreeSizeKb()));
15631 pw.print(" in swap (");
15632 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15633 pw.println(" total swap)");
15635 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15636 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15637 pw.println(memInfo.getSwapFreeSizeKb());
15640 final long[] ksm = getKsmInfo();
15642 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15643 || ksm[KSM_VOLATILE] != 0) {
15644 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15645 pw.print(" saved from shared ");
15646 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15647 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15648 pw.print(" unshared; ");
15649 pw.print(stringifyKBSize(
15650 ksm[KSM_VOLATILE])); pw.println(" volatile");
15652 pw.print(" Tuning: ");
15653 pw.print(ActivityManager.staticGetMemoryClass());
15654 pw.print(" (large ");
15655 pw.print(ActivityManager.staticGetLargeMemoryClass());
15656 pw.print("), oom ");
15657 pw.print(stringifySize(
15658 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15659 pw.print(", restore limit ");
15660 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15661 if (ActivityManager.isLowRamDeviceStatic()) {
15662 pw.print(" (low-ram)");
15664 if (ActivityManager.isHighEndGfx()) {
15665 pw.print(" (high-end-gfx)");
15669 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15670 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15671 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15672 pw.print("tuning,");
15673 pw.print(ActivityManager.staticGetMemoryClass());
15675 pw.print(ActivityManager.staticGetLargeMemoryClass());
15677 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15678 if (ActivityManager.isLowRamDeviceStatic()) {
15679 pw.print(",low-ram");
15681 if (ActivityManager.isHighEndGfx()) {
15682 pw.print(",high-end-gfx");
15690 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15691 long memtrack, String name) {
15693 sb.append(ProcessList.makeOomAdjString(oomAdj));
15695 sb.append(ProcessList.makeProcStateString(procState));
15697 ProcessList.appendRamKb(sb, pss);
15700 if (memtrack > 0) {
15702 sb.append(stringifyKBSize(memtrack));
15703 sb.append(" memtrack)");
15707 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15708 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15709 sb.append(" (pid ");
15712 sb.append(mi.adjType);
15714 if (mi.adjReason != null) {
15716 sb.append(mi.adjReason);
15721 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15722 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15723 for (int i=0, N=memInfos.size(); i<N; i++) {
15724 ProcessMemInfo mi = memInfos.get(i);
15725 infoMap.put(mi.pid, mi);
15727 updateCpuStatsNow();
15728 long[] memtrackTmp = new long[1];
15729 synchronized (mProcessCpuTracker) {
15730 final int N = mProcessCpuTracker.countStats();
15731 for (int i=0; i<N; i++) {
15732 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15733 if (st.vsize > 0) {
15734 long pss = Debug.getPss(st.pid, null, memtrackTmp);
15736 if (infoMap.indexOfKey(st.pid) < 0) {
15737 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15738 ProcessList.NATIVE_ADJ, -1, "native", null);
15740 mi.memtrack = memtrackTmp[0];
15749 long totalMemtrack = 0;
15750 for (int i=0, N=memInfos.size(); i<N; i++) {
15751 ProcessMemInfo mi = memInfos.get(i);
15753 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15754 mi.memtrack = memtrackTmp[0];
15756 totalPss += mi.pss;
15757 totalMemtrack += mi.memtrack;
15759 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15760 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15761 if (lhs.oomAdj != rhs.oomAdj) {
15762 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15764 if (lhs.pss != rhs.pss) {
15765 return lhs.pss < rhs.pss ? 1 : -1;
15771 StringBuilder tag = new StringBuilder(128);
15772 StringBuilder stack = new StringBuilder(128);
15773 tag.append("Low on memory -- ");
15774 appendMemBucket(tag, totalPss, "total", false);
15775 appendMemBucket(stack, totalPss, "total", true);
15777 StringBuilder fullNativeBuilder = new StringBuilder(1024);
15778 StringBuilder shortNativeBuilder = new StringBuilder(1024);
15779 StringBuilder fullJavaBuilder = new StringBuilder(1024);
15781 boolean firstLine = true;
15782 int lastOomAdj = Integer.MIN_VALUE;
15783 long extraNativeRam = 0;
15784 long extraNativeMemtrack = 0;
15785 long cachedPss = 0;
15786 for (int i=0, N=memInfos.size(); i<N; i++) {
15787 ProcessMemInfo mi = memInfos.get(i);
15789 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15790 cachedPss += mi.pss;
15793 if (mi.oomAdj != ProcessList.NATIVE_ADJ
15794 && (mi.oomAdj < ProcessList.SERVICE_ADJ
15795 || mi.oomAdj == ProcessList.HOME_APP_ADJ
15796 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15797 if (lastOomAdj != mi.oomAdj) {
15798 lastOomAdj = mi.oomAdj;
15799 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15802 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15807 stack.append("\n\t at ");
15815 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15816 appendMemBucket(tag, mi.pss, mi.name, false);
15818 appendMemBucket(stack, mi.pss, mi.name, true);
15819 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15820 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15822 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15823 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15824 stack.append(DUMP_MEM_OOM_LABEL[k]);
15826 stack.append(DUMP_MEM_OOM_ADJ[k]);
15833 appendMemInfo(fullNativeBuilder, mi);
15834 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15835 // The short form only has native processes that are >= 512K.
15836 if (mi.pss >= 512) {
15837 appendMemInfo(shortNativeBuilder, mi);
15839 extraNativeRam += mi.pss;
15840 extraNativeMemtrack += mi.memtrack;
15843 // Short form has all other details, but if we have collected RAM
15844 // from smaller native processes let's dump a summary of that.
15845 if (extraNativeRam > 0) {
15846 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15847 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15848 shortNativeBuilder.append('\n');
15849 extraNativeRam = 0;
15851 appendMemInfo(fullJavaBuilder, mi);
15855 fullJavaBuilder.append(" ");
15856 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15857 fullJavaBuilder.append(": TOTAL");
15858 if (totalMemtrack > 0) {
15859 fullJavaBuilder.append(" (");
15860 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
15861 fullJavaBuilder.append(" memtrack)");
15864 fullJavaBuilder.append("\n");
15866 MemInfoReader memInfo = new MemInfoReader();
15867 memInfo.readMemInfo();
15868 final long[] infos = memInfo.getRawInfo();
15870 StringBuilder memInfoBuilder = new StringBuilder(1024);
15871 Debug.getMemInfo(infos);
15872 memInfoBuilder.append(" MemInfo: ");
15873 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
15874 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
15875 memInfoBuilder.append(stringifyKBSize(
15876 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
15877 memInfoBuilder.append(stringifyKBSize(
15878 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
15879 memInfoBuilder.append(stringifyKBSize(
15880 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
15881 memInfoBuilder.append(" ");
15882 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
15883 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
15884 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
15885 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
15886 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15887 memInfoBuilder.append(" ZRAM: ");
15888 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
15889 memInfoBuilder.append(" RAM, ");
15890 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
15891 memInfoBuilder.append(" swap total, ");
15892 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
15893 memInfoBuilder.append(" swap free\n");
15895 final long[] ksm = getKsmInfo();
15896 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15897 || ksm[KSM_VOLATILE] != 0) {
15898 memInfoBuilder.append(" KSM: ");
15899 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
15900 memInfoBuilder.append(" saved from shared ");
15901 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
15902 memInfoBuilder.append("\n ");
15903 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
15904 memInfoBuilder.append(" unshared; ");
15905 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
15906 memInfoBuilder.append(" volatile\n");
15908 memInfoBuilder.append(" Free RAM: ");
15909 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15910 + memInfo.getFreeSizeKb()));
15911 memInfoBuilder.append("\n");
15912 memInfoBuilder.append(" Used RAM: ");
15913 memInfoBuilder.append(stringifyKBSize(
15914 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
15915 memInfoBuilder.append("\n");
15916 memInfoBuilder.append(" Lost RAM: ");
15917 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
15918 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15919 - memInfo.getKernelUsedSizeKb()));
15920 memInfoBuilder.append("\n");
15921 Slog.i(TAG, "Low on memory:");
15922 Slog.i(TAG, shortNativeBuilder.toString());
15923 Slog.i(TAG, fullJavaBuilder.toString());
15924 Slog.i(TAG, memInfoBuilder.toString());
15926 StringBuilder dropBuilder = new StringBuilder(1024);
15928 StringWriter oomSw = new StringWriter();
15929 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15930 StringWriter catSw = new StringWriter();
15931 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15932 String[] emptyArgs = new String[] { };
15933 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
15935 String oomString = oomSw.toString();
15937 dropBuilder.append("Low on memory:");
15938 dropBuilder.append(stack);
15939 dropBuilder.append('\n');
15940 dropBuilder.append(fullNativeBuilder);
15941 dropBuilder.append(fullJavaBuilder);
15942 dropBuilder.append('\n');
15943 dropBuilder.append(memInfoBuilder);
15944 dropBuilder.append('\n');
15946 dropBuilder.append(oomString);
15947 dropBuilder.append('\n');
15949 StringWriter catSw = new StringWriter();
15950 synchronized (ActivityManagerService.this) {
15951 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15952 String[] emptyArgs = new String[] { };
15954 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15956 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15957 false, false, null);
15959 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15962 dropBuilder.append(catSw.toString());
15963 addErrorToDropBox("lowmem", null, "system_server", null,
15964 null, tag.toString(), dropBuilder.toString(), null, null);
15965 //Slog.i(TAG, "Sent to dropbox:");
15966 //Slog.i(TAG, dropBuilder.toString());
15967 synchronized (ActivityManagerService.this) {
15968 long now = SystemClock.uptimeMillis();
15969 if (mLastMemUsageReportTime < now) {
15970 mLastMemUsageReportTime = now;
15976 * Searches array of arguments for the specified string
15977 * @param args array of argument strings
15978 * @param value value to search for
15979 * @return true if the value is contained in the array
15981 private static boolean scanArgs(String[] args, String value) {
15982 if (args != null) {
15983 for (String arg : args) {
15984 if (value.equals(arg)) {
15992 private final boolean removeDyingProviderLocked(ProcessRecord proc,
15993 ContentProviderRecord cpr, boolean always) {
15994 final boolean inLaunching = mLaunchingProviders.contains(cpr);
15996 if (!inLaunching || always) {
15997 synchronized (cpr) {
15998 cpr.launchingApp = null;
16001 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16002 String names[] = cpr.info.authority.split(";");
16003 for (int j = 0; j < names.length; j++) {
16004 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16008 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16009 ContentProviderConnection conn = cpr.connections.get(i);
16010 if (conn.waiting) {
16011 // If this connection is waiting for the provider, then we don't
16012 // need to mess with its process unless we are always removing
16013 // or for some reason the provider is not currently launching.
16014 if (inLaunching && !always) {
16018 ProcessRecord capp = conn.client;
16020 if (conn.stableCount > 0) {
16021 if (!capp.persistent && capp.thread != null
16023 && capp.pid != MY_PID) {
16024 capp.kill("depends on provider "
16025 + cpr.name.flattenToShortString()
16026 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16028 } else if (capp.thread != null && conn.provider.provider != null) {
16030 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16031 } catch (RemoteException e) {
16033 // In the protocol here, we don't expect the client to correctly
16034 // clean up this connection, we'll just remove it.
16035 cpr.connections.remove(i);
16036 if (conn.client.conProviders.remove(conn)) {
16037 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16042 if (inLaunching && always) {
16043 mLaunchingProviders.remove(cpr);
16045 return inLaunching;
16049 * Main code for cleaning up a process when it has gone away. This is
16050 * called both as a result of the process dying, or directly when stopping
16051 * a process when running in single process mode.
16053 * @return Returns true if the given process has been restarted, so the
16054 * app that was passed in must remain on the process lists.
16056 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16057 boolean restarting, boolean allowRestart, int index) {
16059 removeLruProcessLocked(app);
16060 ProcessList.remove(app.pid);
16063 mProcessesToGc.remove(app);
16064 mPendingPssProcesses.remove(app);
16066 // Dismiss any open dialogs.
16067 if (app.crashDialog != null && !app.forceCrashReport) {
16068 app.crashDialog.dismiss();
16069 app.crashDialog = null;
16071 if (app.anrDialog != null) {
16072 app.anrDialog.dismiss();
16073 app.anrDialog = null;
16075 if (app.waitDialog != null) {
16076 app.waitDialog.dismiss();
16077 app.waitDialog = null;
16080 app.crashing = false;
16081 app.notResponding = false;
16083 app.resetPackageList(mProcessStats);
16084 app.unlinkDeathRecipient();
16085 app.makeInactive(mProcessStats);
16086 app.waitingToKill = null;
16087 app.forcingToForeground = null;
16088 updateProcessForegroundLocked(app, false, false);
16089 app.foregroundActivities = false;
16090 app.hasShownUi = false;
16091 app.treatLikeActivity = false;
16092 app.hasAboveClient = false;
16093 app.hasClientActivities = false;
16095 mServices.killServicesLocked(app, allowRestart);
16097 boolean restart = false;
16099 // Remove published content providers.
16100 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16101 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16102 final boolean always = app.bad || !allowRestart;
16103 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16104 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16105 // We left the provider in the launching list, need to
16110 cpr.provider = null;
16113 app.pubProviders.clear();
16115 // Take care of any launching providers waiting for this process.
16116 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16120 // Unregister from connected content providers.
16121 if (!app.conProviders.isEmpty()) {
16122 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16123 ContentProviderConnection conn = app.conProviders.get(i);
16124 conn.provider.connections.remove(conn);
16125 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16126 conn.provider.name);
16128 app.conProviders.clear();
16131 // At this point there may be remaining entries in mLaunchingProviders
16132 // where we were the only one waiting, so they are no longer of use.
16133 // Look for these and clean up if found.
16134 // XXX Commented out for now. Trying to figure out a way to reproduce
16135 // the actual situation to identify what is actually going on.
16137 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16138 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16139 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16140 synchronized (cpr) {
16141 cpr.launchingApp = null;
16148 skipCurrentReceiverLocked(app);
16150 // Unregister any receivers.
16151 for (int i = app.receivers.size() - 1; i >= 0; i--) {
16152 removeReceiverLocked(app.receivers.valueAt(i));
16154 app.receivers.clear();
16156 // If the app is undergoing backup, tell the backup manager about it
16157 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16158 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16159 + mBackupTarget.appInfo + " died during backup");
16161 IBackupManager bm = IBackupManager.Stub.asInterface(
16162 ServiceManager.getService(Context.BACKUP_SERVICE));
16163 bm.agentDisconnected(app.info.packageName);
16164 } catch (RemoteException e) {
16165 // can't happen; backup manager is local
16169 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16170 ProcessChangeItem item = mPendingProcessChanges.get(i);
16171 if (item.pid == app.pid) {
16172 mPendingProcessChanges.remove(i);
16173 mAvailProcessChanges.add(item);
16176 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16177 null).sendToTarget();
16179 // If the caller is restarting this app, then leave it in its
16180 // current lists and let the caller take care of it.
16185 if (!app.persistent || app.isolated) {
16186 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16187 "Removing non-persistent process during cleanup: " + app);
16188 removeProcessNameLocked(app.processName, app.uid);
16189 if (mHeavyWeightProcess == app) {
16190 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16191 mHeavyWeightProcess.userId, 0));
16192 mHeavyWeightProcess = null;
16194 } else if (!app.removed) {
16195 // This app is persistent, so we need to keep its record around.
16196 // If it is not already on the pending app list, add it there
16197 // and start a new process for it.
16198 if (mPersistentStartingProcesses.indexOf(app) < 0) {
16199 mPersistentStartingProcesses.add(app);
16203 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16204 TAG_CLEANUP, "Clean-up removing on hold: " + app);
16205 mProcessesOnHold.remove(app);
16207 if (app == mHomeProcess) {
16208 mHomeProcess = null;
16210 if (app == mPreviousProcess) {
16211 mPreviousProcess = null;
16214 if (restart && !app.isolated) {
16215 // We have components that still need to be running in the
16216 // process, so re-launch it.
16218 ProcessList.remove(app.pid);
16220 addProcessNameLocked(app);
16221 startProcessLocked(app, "restart", app.processName);
16223 } else if (app.pid > 0 && app.pid != MY_PID) {
16226 synchronized (mPidsSelfLocked) {
16227 mPidsSelfLocked.remove(app.pid);
16228 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16230 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16231 if (app.isolated) {
16232 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16239 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16240 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16241 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16242 if (cpr.launchingApp == app) {
16249 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16250 // Look through the content providers we are waiting to have launched,
16251 // and if any run in this process then either schedule a restart of
16252 // the process or kill the client waiting for it if this process has
16254 boolean restart = false;
16255 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16256 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16257 if (cpr.launchingApp == app) {
16258 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16261 removeDyingProviderLocked(app, cpr, true);
16268 // =========================================================
16270 // =========================================================
16273 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16275 enforceNotIsolatedCaller("getServices");
16276 synchronized (this) {
16277 return mServices.getRunningServiceInfoLocked(maxNum, flags);
16282 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16283 enforceNotIsolatedCaller("getRunningServiceControlPanel");
16284 synchronized (this) {
16285 return mServices.getRunningServiceControlPanelLocked(name);
16290 public ComponentName startService(IApplicationThread caller, Intent service,
16291 String resolvedType, String callingPackage, int userId)
16292 throws TransactionTooLargeException {
16293 enforceNotIsolatedCaller("startService");
16294 // Refuse possible leaked file descriptors
16295 if (service != null && service.hasFileDescriptors() == true) {
16296 throw new IllegalArgumentException("File descriptors passed in Intent");
16299 if (callingPackage == null) {
16300 throw new IllegalArgumentException("callingPackage cannot be null");
16303 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16304 "startService: " + service + " type=" + resolvedType);
16305 synchronized(this) {
16306 final int callingPid = Binder.getCallingPid();
16307 final int callingUid = Binder.getCallingUid();
16308 final long origId = Binder.clearCallingIdentity();
16309 ComponentName res = mServices.startServiceLocked(caller, service,
16310 resolvedType, callingPid, callingUid, callingPackage, userId);
16311 Binder.restoreCallingIdentity(origId);
16316 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16317 String callingPackage, int userId)
16318 throws TransactionTooLargeException {
16319 synchronized(this) {
16320 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16321 "startServiceInPackage: " + service + " type=" + resolvedType);
16322 final long origId = Binder.clearCallingIdentity();
16323 ComponentName res = mServices.startServiceLocked(null, service,
16324 resolvedType, -1, uid, callingPackage, userId);
16325 Binder.restoreCallingIdentity(origId);
16331 public int stopService(IApplicationThread caller, Intent service,
16332 String resolvedType, int userId) {
16333 enforceNotIsolatedCaller("stopService");
16334 // Refuse possible leaked file descriptors
16335 if (service != null && service.hasFileDescriptors() == true) {
16336 throw new IllegalArgumentException("File descriptors passed in Intent");
16339 synchronized(this) {
16340 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16345 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16346 enforceNotIsolatedCaller("peekService");
16347 // Refuse possible leaked file descriptors
16348 if (service != null && service.hasFileDescriptors() == true) {
16349 throw new IllegalArgumentException("File descriptors passed in Intent");
16352 if (callingPackage == null) {
16353 throw new IllegalArgumentException("callingPackage cannot be null");
16356 synchronized(this) {
16357 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16362 public boolean stopServiceToken(ComponentName className, IBinder token,
16364 synchronized(this) {
16365 return mServices.stopServiceTokenLocked(className, token, startId);
16370 public void setServiceForeground(ComponentName className, IBinder token,
16371 int id, Notification notification, boolean removeNotification) {
16372 synchronized(this) {
16373 mServices.setServiceForegroundLocked(className, token, id, notification,
16374 removeNotification);
16379 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16380 boolean requireFull, String name, String callerPackage) {
16381 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16382 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16385 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16386 String className, int flags) {
16387 boolean result = false;
16388 // For apps that don't have pre-defined UIDs, check for permission
16389 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16390 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16391 if (ActivityManager.checkUidPermission(
16392 INTERACT_ACROSS_USERS,
16393 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16394 ComponentName comp = new ComponentName(aInfo.packageName, className);
16395 String msg = "Permission Denial: Component " + comp.flattenToShortString()
16396 + " requests FLAG_SINGLE_USER, but app does not hold "
16397 + INTERACT_ACROSS_USERS;
16399 throw new SecurityException(msg);
16401 // Permission passed
16404 } else if ("system".equals(componentProcessName)) {
16406 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16407 // Phone app and persistent apps are allowed to export singleuser providers.
16408 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16409 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16411 if (DEBUG_MU) Slog.v(TAG_MU,
16412 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16413 + Integer.toHexString(flags) + ") = " + result);
16418 * Checks to see if the caller is in the same app as the singleton
16419 * component, or the component is in a special app. It allows special apps
16420 * to export singleton components but prevents exporting singleton
16421 * components for regular apps.
16423 boolean isValidSingletonCall(int callingUid, int componentUid) {
16424 int componentAppId = UserHandle.getAppId(componentUid);
16425 return UserHandle.isSameApp(callingUid, componentUid)
16426 || componentAppId == Process.SYSTEM_UID
16427 || componentAppId == Process.PHONE_UID
16428 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16429 == PackageManager.PERMISSION_GRANTED;
16432 public int bindService(IApplicationThread caller, IBinder token, Intent service,
16433 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16434 int userId) throws TransactionTooLargeException {
16435 enforceNotIsolatedCaller("bindService");
16437 // Refuse possible leaked file descriptors
16438 if (service != null && service.hasFileDescriptors() == true) {
16439 throw new IllegalArgumentException("File descriptors passed in Intent");
16442 if (callingPackage == null) {
16443 throw new IllegalArgumentException("callingPackage cannot be null");
16446 synchronized(this) {
16447 return mServices.bindServiceLocked(caller, token, service,
16448 resolvedType, connection, flags, callingPackage, userId);
16452 public boolean unbindService(IServiceConnection connection) {
16453 synchronized (this) {
16454 return mServices.unbindServiceLocked(connection);
16458 public void publishService(IBinder token, Intent intent, IBinder service) {
16459 // Refuse possible leaked file descriptors
16460 if (intent != null && intent.hasFileDescriptors() == true) {
16461 throw new IllegalArgumentException("File descriptors passed in Intent");
16464 synchronized(this) {
16465 if (!(token instanceof ServiceRecord)) {
16466 throw new IllegalArgumentException("Invalid service token");
16468 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16472 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16473 // Refuse possible leaked file descriptors
16474 if (intent != null && intent.hasFileDescriptors() == true) {
16475 throw new IllegalArgumentException("File descriptors passed in Intent");
16478 synchronized(this) {
16479 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16483 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16484 synchronized(this) {
16485 if (!(token instanceof ServiceRecord)) {
16486 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16487 throw new IllegalArgumentException("Invalid service token");
16489 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16493 // =========================================================
16494 // BACKUP AND RESTORE
16495 // =========================================================
16497 // Cause the target app to be launched if necessary and its backup agent
16498 // instantiated. The backup agent will invoke backupAgentCreated() on the
16499 // activity manager to announce its creation.
16500 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16501 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16502 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16503 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16505 synchronized(this) {
16506 // !!! TODO: currently no check here that we're already bound
16507 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16508 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16509 synchronized (stats) {
16510 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16513 // Backup agent is now in use, its package can't be stopped.
16515 AppGlobals.getPackageManager().setPackageStoppedState(
16516 app.packageName, false, UserHandle.getUserId(app.uid));
16517 } catch (RemoteException e) {
16518 } catch (IllegalArgumentException e) {
16519 Slog.w(TAG, "Failed trying to unstop package "
16520 + app.packageName + ": " + e);
16523 BackupRecord r = new BackupRecord(ss, app, backupMode);
16524 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16525 ? new ComponentName(app.packageName, app.backupAgentName)
16526 : new ComponentName("android", "FullBackupAgent");
16527 // startProcessLocked() returns existing proc's record if it's already running
16528 ProcessRecord proc = startProcessLocked(app.processName, app,
16529 false, 0, "backup", hostingName, false, false, false);
16530 if (proc == null) {
16531 Slog.e(TAG, "Unable to start backup agent process " + r);
16537 mBackupAppName = app.packageName;
16539 // Try not to kill the process during backup
16540 updateOomAdjLocked(proc);
16542 // If the process is already attached, schedule the creation of the backup agent now.
16543 // If it is not yet live, this will be done when it attaches to the framework.
16544 if (proc.thread != null) {
16545 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16547 proc.thread.scheduleCreateBackupAgent(app,
16548 compatibilityInfoForPackageLocked(app), backupMode);
16549 } catch (RemoteException e) {
16550 // Will time out on the backup manager side
16553 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16555 // Invariants: at this point, the target app process exists and the application
16556 // is either already running or in the process of coming up. mBackupTarget and
16557 // mBackupAppName describe the app, so that when it binds back to the AM we
16558 // know that it's scheduled for a backup-agent operation.
16565 public void clearPendingBackup() {
16566 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16567 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16569 synchronized (this) {
16570 mBackupTarget = null;
16571 mBackupAppName = null;
16575 // A backup agent has just come up
16576 public void backupAgentCreated(String agentPackageName, IBinder agent) {
16577 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16580 synchronized(this) {
16581 if (!agentPackageName.equals(mBackupAppName)) {
16582 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16587 long oldIdent = Binder.clearCallingIdentity();
16589 IBackupManager bm = IBackupManager.Stub.asInterface(
16590 ServiceManager.getService(Context.BACKUP_SERVICE));
16591 bm.agentConnected(agentPackageName, agent);
16592 } catch (RemoteException e) {
16593 // can't happen; the backup manager service is local
16594 } catch (Exception e) {
16595 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16596 e.printStackTrace();
16598 Binder.restoreCallingIdentity(oldIdent);
16602 // done with this agent
16603 public void unbindBackupAgent(ApplicationInfo appInfo) {
16604 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16605 if (appInfo == null) {
16606 Slog.w(TAG, "unbind backup agent for null app");
16610 synchronized(this) {
16612 if (mBackupAppName == null) {
16613 Slog.w(TAG, "Unbinding backup agent with no active backup");
16617 if (!mBackupAppName.equals(appInfo.packageName)) {
16618 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16622 // Not backing this app up any more; reset its OOM adjustment
16623 final ProcessRecord proc = mBackupTarget.app;
16624 updateOomAdjLocked(proc);
16626 // If the app crashed during backup, 'thread' will be null here
16627 if (proc.thread != null) {
16629 proc.thread.scheduleDestroyBackupAgent(appInfo,
16630 compatibilityInfoForPackageLocked(appInfo));
16631 } catch (Exception e) {
16632 Slog.e(TAG, "Exception when unbinding backup agent:");
16633 e.printStackTrace();
16637 mBackupTarget = null;
16638 mBackupAppName = null;
16642 // =========================================================
16644 // =========================================================
16646 boolean isPendingBroadcastProcessLocked(int pid) {
16647 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16648 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16651 void skipPendingBroadcastLocked(int pid) {
16652 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16653 for (BroadcastQueue queue : mBroadcastQueues) {
16654 queue.skipPendingBroadcastLocked(pid);
16658 // The app just attached; send any pending broadcasts that it should receive
16659 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16660 boolean didSomething = false;
16661 for (BroadcastQueue queue : mBroadcastQueues) {
16662 didSomething |= queue.sendPendingBroadcastsLocked(app);
16664 return didSomething;
16667 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16668 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16669 enforceNotIsolatedCaller("registerReceiver");
16670 ArrayList<Intent> stickyIntents = null;
16671 ProcessRecord callerApp = null;
16674 synchronized(this) {
16675 if (caller != null) {
16676 callerApp = getRecordForAppLocked(caller);
16677 if (callerApp == null) {
16678 throw new SecurityException(
16679 "Unable to find app for caller " + caller
16680 + " (pid=" + Binder.getCallingPid()
16681 + ") when registering receiver " + receiver);
16683 if (callerApp.info.uid != Process.SYSTEM_UID &&
16684 !callerApp.pkgList.containsKey(callerPackage) &&
16685 !"android".equals(callerPackage)) {
16686 throw new SecurityException("Given caller package " + callerPackage
16687 + " is not running in process " + callerApp);
16689 callingUid = callerApp.info.uid;
16690 callingPid = callerApp.pid;
16692 callerPackage = null;
16693 callingUid = Binder.getCallingUid();
16694 callingPid = Binder.getCallingPid();
16697 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16698 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16700 Iterator<String> actions = filter.actionsIterator();
16701 if (actions == null) {
16702 ArrayList<String> noAction = new ArrayList<String>(1);
16703 noAction.add(null);
16704 actions = noAction.iterator();
16707 // Collect stickies of users
16708 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16709 while (actions.hasNext()) {
16710 String action = actions.next();
16711 for (int id : userIds) {
16712 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16713 if (stickies != null) {
16714 ArrayList<Intent> intents = stickies.get(action);
16715 if (intents != null) {
16716 if (stickyIntents == null) {
16717 stickyIntents = new ArrayList<Intent>();
16719 stickyIntents.addAll(intents);
16726 ArrayList<Intent> allSticky = null;
16727 if (stickyIntents != null) {
16728 final ContentResolver resolver = mContext.getContentResolver();
16729 // Look for any matching sticky broadcasts...
16730 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16731 Intent intent = stickyIntents.get(i);
16732 // If intent has scheme "content", it will need to acccess
16733 // provider that needs to lock mProviderMap in ActivityThread
16734 // and also it may need to wait application response, so we
16735 // cannot lock ActivityManagerService here.
16736 if (filter.match(resolver, intent, true, TAG) >= 0) {
16737 if (allSticky == null) {
16738 allSticky = new ArrayList<Intent>();
16740 allSticky.add(intent);
16745 // The first sticky in the list is returned directly back to the client.
16746 Intent sticky = allSticky != null ? allSticky.get(0) : null;
16747 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16748 if (receiver == null) {
16752 synchronized (this) {
16753 if (callerApp != null && (callerApp.thread == null
16754 || callerApp.thread.asBinder() != caller.asBinder())) {
16755 // Original caller already died
16758 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16760 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16762 if (rl.app != null) {
16763 rl.app.receivers.add(rl);
16766 receiver.asBinder().linkToDeath(rl, 0);
16767 } catch (RemoteException e) {
16770 rl.linkedToDeath = true;
16772 mRegisteredReceivers.put(receiver.asBinder(), rl);
16773 } else if (rl.uid != callingUid) {
16774 throw new IllegalArgumentException(
16775 "Receiver requested to register for uid " + callingUid
16776 + " was previously registered for uid " + rl.uid);
16777 } else if (rl.pid != callingPid) {
16778 throw new IllegalArgumentException(
16779 "Receiver requested to register for pid " + callingPid
16780 + " was previously registered for pid " + rl.pid);
16781 } else if (rl.userId != userId) {
16782 throw new IllegalArgumentException(
16783 "Receiver requested to register for user " + userId
16784 + " was previously registered for user " + rl.userId);
16786 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16787 permission, callingUid, userId);
16789 if (!bf.debugCheck()) {
16790 Slog.w(TAG, "==> For Dynamic broadcast");
16792 mReceiverResolver.addFilter(bf);
16794 // Enqueue broadcasts for all existing stickies that match
16796 if (allSticky != null) {
16797 ArrayList receivers = new ArrayList();
16800 final int stickyCount = allSticky.size();
16801 for (int i = 0; i < stickyCount; i++) {
16802 Intent intent = allSticky.get(i);
16803 BroadcastQueue queue = broadcastQueueForIntent(intent);
16804 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16805 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16806 null, 0, null, null, false, true, true, -1);
16807 queue.enqueueParallelBroadcastLocked(r);
16808 queue.scheduleBroadcastsLocked();
16816 public void unregisterReceiver(IIntentReceiver receiver) {
16817 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16819 final long origId = Binder.clearCallingIdentity();
16821 boolean doTrim = false;
16823 synchronized(this) {
16824 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16826 final BroadcastRecord r = rl.curBroadcast;
16827 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16828 final boolean doNext = r.queue.finishReceiverLocked(
16829 r, r.resultCode, r.resultData, r.resultExtras,
16830 r.resultAbort, false);
16833 r.queue.processNextBroadcast(false);
16837 if (rl.app != null) {
16838 rl.app.receivers.remove(rl);
16840 removeReceiverLocked(rl);
16841 if (rl.linkedToDeath) {
16842 rl.linkedToDeath = false;
16843 rl.receiver.asBinder().unlinkToDeath(rl, 0);
16848 // If we actually concluded any broadcasts, we might now be able
16849 // to trim the recipients' apps from our working set
16851 trimApplications();
16856 Binder.restoreCallingIdentity(origId);
16860 void removeReceiverLocked(ReceiverList rl) {
16861 mRegisteredReceivers.remove(rl.receiver.asBinder());
16862 for (int i = rl.size() - 1; i >= 0; i--) {
16863 mReceiverResolver.removeFilter(rl.get(i));
16867 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16868 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16869 ProcessRecord r = mLruProcesses.get(i);
16870 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16872 r.thread.dispatchPackageBroadcast(cmd, packages);
16873 } catch (RemoteException ex) {
16879 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16880 int callingUid, int[] users) {
16881 List<ResolveInfo> receivers = null;
16883 HashSet<ComponentName> singleUserReceivers = null;
16884 boolean scannedFirstReceivers = false;
16885 for (int user : users) {
16886 // Skip users that have Shell restrictions
16887 if (callingUid == Process.SHELL_UID
16888 && mUserController.hasUserRestriction(
16889 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16892 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16893 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16894 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
16895 // If this is not the system user, we need to check for
16896 // any receivers that should be filtered out.
16897 for (int i=0; i<newReceivers.size(); i++) {
16898 ResolveInfo ri = newReceivers.get(i);
16899 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
16900 newReceivers.remove(i);
16905 if (newReceivers != null && newReceivers.size() == 0) {
16906 newReceivers = null;
16908 if (receivers == null) {
16909 receivers = newReceivers;
16910 } else if (newReceivers != null) {
16911 // We need to concatenate the additional receivers
16912 // found with what we have do far. This would be easy,
16913 // but we also need to de-dup any receivers that are
16915 if (!scannedFirstReceivers) {
16916 // Collect any single user receivers we had already retrieved.
16917 scannedFirstReceivers = true;
16918 for (int i=0; i<receivers.size(); i++) {
16919 ResolveInfo ri = receivers.get(i);
16920 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16921 ComponentName cn = new ComponentName(
16922 ri.activityInfo.packageName, ri.activityInfo.name);
16923 if (singleUserReceivers == null) {
16924 singleUserReceivers = new HashSet<ComponentName>();
16926 singleUserReceivers.add(cn);
16930 // Add the new results to the existing results, tracking
16931 // and de-dupping single user receivers.
16932 for (int i=0; i<newReceivers.size(); i++) {
16933 ResolveInfo ri = newReceivers.get(i);
16934 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16935 ComponentName cn = new ComponentName(
16936 ri.activityInfo.packageName, ri.activityInfo.name);
16937 if (singleUserReceivers == null) {
16938 singleUserReceivers = new HashSet<ComponentName>();
16940 if (!singleUserReceivers.contains(cn)) {
16941 singleUserReceivers.add(cn);
16950 } catch (RemoteException ex) {
16951 // pm is in same process, this will never happen.
16956 final int broadcastIntentLocked(ProcessRecord callerApp,
16957 String callerPackage, Intent intent, String resolvedType,
16958 IIntentReceiver resultTo, int resultCode, String resultData,
16959 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
16960 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16961 intent = new Intent(intent);
16963 // By default broadcasts do not go to stopped apps.
16964 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16966 // If we have not finished booting, don't allow this to launch new processes.
16967 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16968 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16971 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16972 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16973 + " ordered=" + ordered + " userid=" + userId);
16974 if ((resultTo != null) && !ordered) {
16975 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16978 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16979 ALLOW_NON_FULL, "broadcast", callerPackage);
16981 // Make sure that the user who is receiving this broadcast is running.
16982 // If not, we will just skip it. Make an exception for shutdown broadcasts
16983 // and upgrade steps.
16985 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
16986 if ((callingUid != Process.SYSTEM_UID
16987 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16988 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16989 Slog.w(TAG, "Skipping broadcast of " + intent
16990 + ": user " + userId + " is stopped");
16991 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16995 BroadcastOptions brOptions = null;
16996 if (bOptions != null) {
16997 brOptions = new BroadcastOptions(bOptions);
16998 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16999 // See if the caller is allowed to do this. Note we are checking against
17000 // the actual real caller (not whoever provided the operation as say a
17001 // PendingIntent), because that who is actually supplied the arguments.
17002 if (checkComponentPermission(
17003 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17004 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17005 != PackageManager.PERMISSION_GRANTED) {
17006 String msg = "Permission Denial: " + intent.getAction()
17007 + " broadcast from " + callerPackage + " (pid=" + callingPid
17008 + ", uid=" + callingUid + ")"
17010 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17012 throw new SecurityException(msg);
17018 * Prevent non-system code (defined here to be non-persistent
17019 * processes) from sending protected broadcasts.
17021 int callingAppId = UserHandle.getAppId(callingUid);
17022 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
17023 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
17024 || callingAppId == Process.NFC_UID || callingUid == 0) {
17026 } else if (callerApp == null || !callerApp.persistent) {
17028 if (AppGlobals.getPackageManager().isProtectedBroadcast(
17029 intent.getAction())) {
17030 String msg = "Permission Denial: not allowed to send broadcast "
17031 + intent.getAction() + " from pid="
17032 + callingPid + ", uid=" + callingUid;
17034 throw new SecurityException(msg);
17035 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
17036 // Special case for compatibility: we don't want apps to send this,
17037 // but historically it has not been protected and apps may be using it
17038 // to poke their own app widget. So, instead of making it protected,
17039 // just limit it to the caller.
17040 if (callerApp == null) {
17041 String msg = "Permission Denial: not allowed to send broadcast "
17042 + intent.getAction() + " from unknown caller.";
17044 throw new SecurityException(msg);
17045 } else if (intent.getComponent() != null) {
17046 // They are good enough to send to an explicit component... verify
17047 // it is being sent to the calling app.
17048 if (!intent.getComponent().getPackageName().equals(
17049 callerApp.info.packageName)) {
17050 String msg = "Permission Denial: not allowed to send broadcast "
17051 + intent.getAction() + " to "
17052 + intent.getComponent().getPackageName() + " from "
17053 + callerApp.info.packageName;
17055 throw new SecurityException(msg);
17058 // Limit broadcast to their own package.
17059 intent.setPackage(callerApp.info.packageName);
17062 } catch (RemoteException e) {
17063 Slog.w(TAG, "Remote exception", e);
17064 return ActivityManager.BROADCAST_SUCCESS;
17068 final String action = intent.getAction();
17069 if (action != null) {
17071 case Intent.ACTION_UID_REMOVED:
17072 case Intent.ACTION_PACKAGE_REMOVED:
17073 case Intent.ACTION_PACKAGE_CHANGED:
17074 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17075 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17076 // Handle special intents: if this broadcast is from the package
17077 // manager about a package being removed, we need to remove all of
17078 // its activities from the history stack.
17079 if (checkComponentPermission(
17080 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17081 callingPid, callingUid, -1, true)
17082 != PackageManager.PERMISSION_GRANTED) {
17083 String msg = "Permission Denial: " + intent.getAction()
17084 + " broadcast from " + callerPackage + " (pid=" + callingPid
17085 + ", uid=" + callingUid + ")"
17087 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17089 throw new SecurityException(msg);
17092 case Intent.ACTION_UID_REMOVED:
17093 final Bundle intentExtras = intent.getExtras();
17094 final int uid = intentExtras != null
17095 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17097 mBatteryStatsService.removeUid(uid);
17098 mAppOpsService.uidRemoved(uid);
17101 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17102 // If resources are unavailable just force stop all those packages
17103 // and flush the attribute cache as well.
17105 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17106 if (list != null && list.length > 0) {
17107 for (int i = 0; i < list.length; i++) {
17108 forceStopPackageLocked(list[i], -1, false, true, true,
17109 false, false, userId, "storage unmount");
17111 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17112 sendPackageBroadcastLocked(
17113 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17117 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17118 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17120 case Intent.ACTION_PACKAGE_REMOVED:
17121 case Intent.ACTION_PACKAGE_CHANGED:
17122 Uri data = intent.getData();
17124 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17125 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17126 boolean fullUninstall = removed &&
17127 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17128 final boolean killProcess =
17129 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17131 forceStopPackageLocked(ssp, UserHandle.getAppId(
17132 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17133 false, true, true, false, fullUninstall, userId,
17134 removed ? "pkg removed" : "pkg changed");
17137 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
17138 new String[] {ssp}, userId);
17139 if (fullUninstall) {
17140 mAppOpsService.packageRemoved(
17141 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17143 // Remove all permissions granted from/to this package
17144 removeUriPermissionsForPackageLocked(ssp, userId, true);
17146 removeTasksByPackageNameLocked(ssp, userId);
17147 mBatteryStatsService.notePackageUninstalled(ssp);
17150 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17151 intent.getStringArrayExtra(
17152 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17158 case Intent.ACTION_PACKAGE_ADDED:
17159 // Special case for adding a package: by default turn on compatibility mode.
17160 Uri data = intent.getData();
17162 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17163 final boolean replacing =
17164 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17165 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17168 ApplicationInfo ai = AppGlobals.getPackageManager().
17169 getApplicationInfo(ssp, 0, 0);
17170 mBatteryStatsService.notePackageInstalled(ssp,
17171 ai != null ? ai.versionCode : 0);
17172 } catch (RemoteException e) {
17176 case Intent.ACTION_TIMEZONE_CHANGED:
17177 // If this is the time zone changed action, queue up a message that will reset
17178 // the timezone of all currently running processes. This message will get
17179 // queued up before the broadcast happens.
17180 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17182 case Intent.ACTION_TIME_CHANGED:
17183 // If the user set the time, let all running processes know.
17184 final int is24Hour =
17185 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17187 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17188 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17189 synchronized (stats) {
17190 stats.noteCurrentTimeChangedLocked();
17193 case Intent.ACTION_CLEAR_DNS_CACHE:
17194 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17196 case Proxy.PROXY_CHANGE_ACTION:
17197 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17198 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17203 // Add to the sticky list if requested.
17205 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17206 callingPid, callingUid)
17207 != PackageManager.PERMISSION_GRANTED) {
17208 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17209 + callingPid + ", uid=" + callingUid
17210 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17212 throw new SecurityException(msg);
17214 if (requiredPermissions != null && requiredPermissions.length > 0) {
17215 Slog.w(TAG, "Can't broadcast sticky intent " + intent
17216 + " and enforce permissions " + Arrays.toString(requiredPermissions));
17217 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17219 if (intent.getComponent() != null) {
17220 throw new SecurityException(
17221 "Sticky broadcasts can't target a specific component");
17223 // We use userId directly here, since the "all" target is maintained
17224 // as a separate set of sticky broadcasts.
17225 if (userId != UserHandle.USER_ALL) {
17226 // But first, if this is not a broadcast to all users, then
17227 // make sure it doesn't conflict with an existing broadcast to
17229 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17230 UserHandle.USER_ALL);
17231 if (stickies != null) {
17232 ArrayList<Intent> list = stickies.get(intent.getAction());
17233 if (list != null) {
17234 int N = list.size();
17236 for (i=0; i<N; i++) {
17237 if (intent.filterEquals(list.get(i))) {
17238 throw new IllegalArgumentException(
17239 "Sticky broadcast " + intent + " for user "
17240 + userId + " conflicts with existing global broadcast");
17246 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17247 if (stickies == null) {
17248 stickies = new ArrayMap<>();
17249 mStickyBroadcasts.put(userId, stickies);
17251 ArrayList<Intent> list = stickies.get(intent.getAction());
17252 if (list == null) {
17253 list = new ArrayList<>();
17254 stickies.put(intent.getAction(), list);
17256 final int stickiesCount = list.size();
17258 for (i = 0; i < stickiesCount; i++) {
17259 if (intent.filterEquals(list.get(i))) {
17260 // This sticky already exists, replace it.
17261 list.set(i, new Intent(intent));
17265 if (i >= stickiesCount) {
17266 list.add(new Intent(intent));
17271 if (userId == UserHandle.USER_ALL) {
17272 // Caller wants broadcast to go to all started users.
17273 users = mUserController.getStartedUserArrayLocked();
17275 // Caller wants broadcast to go to one specific user.
17276 users = new int[] {userId};
17279 // Figure out who all will receive this broadcast.
17280 List receivers = null;
17281 List<BroadcastFilter> registeredReceivers = null;
17282 // Need to resolve the intent to interested receivers...
17283 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17285 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17287 if (intent.getComponent() == null) {
17288 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17289 // Query one target user at a time, excluding shell-restricted users
17290 for (int i = 0; i < users.length; i++) {
17291 if (mUserController.hasUserRestriction(
17292 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17295 List<BroadcastFilter> registeredReceiversForUser =
17296 mReceiverResolver.queryIntent(intent,
17297 resolvedType, false, users[i]);
17298 if (registeredReceivers == null) {
17299 registeredReceivers = registeredReceiversForUser;
17300 } else if (registeredReceiversForUser != null) {
17301 registeredReceivers.addAll(registeredReceiversForUser);
17305 registeredReceivers = mReceiverResolver.queryIntent(intent,
17306 resolvedType, false, userId);
17310 final boolean replacePending =
17311 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17313 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17314 + " replacePending=" + replacePending);
17316 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17317 if (!ordered && NR > 0) {
17318 // If we are not serializing this broadcast, then send the
17319 // registered receivers separately so they don't wait for the
17320 // components to be launched.
17321 final BroadcastQueue queue = broadcastQueueForIntent(intent);
17322 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17323 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17324 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17325 resultExtras, ordered, sticky, false, userId);
17326 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17327 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17329 queue.enqueueParallelBroadcastLocked(r);
17330 queue.scheduleBroadcastsLocked();
17332 registeredReceivers = null;
17336 // Merge into one list.
17338 if (receivers != null) {
17339 // A special case for PACKAGE_ADDED: do not allow the package
17340 // being added to see this broadcast. This prevents them from
17341 // using this as a back door to get run as soon as they are
17342 // installed. Maybe in the future we want to have a special install
17343 // broadcast or such for apps, but we'd like to deliberately make
17345 String skipPackages[] = null;
17346 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17347 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17348 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17349 Uri data = intent.getData();
17350 if (data != null) {
17351 String pkgName = data.getSchemeSpecificPart();
17352 if (pkgName != null) {
17353 skipPackages = new String[] { pkgName };
17356 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17357 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17359 if (skipPackages != null && (skipPackages.length > 0)) {
17360 for (String skipPackage : skipPackages) {
17361 if (skipPackage != null) {
17362 int NT = receivers.size();
17363 for (int it=0; it<NT; it++) {
17364 ResolveInfo curt = (ResolveInfo)receivers.get(it);
17365 if (curt.activityInfo.packageName.equals(skipPackage)) {
17366 receivers.remove(it);
17375 int NT = receivers != null ? receivers.size() : 0;
17377 ResolveInfo curt = null;
17378 BroadcastFilter curr = null;
17379 while (it < NT && ir < NR) {
17380 if (curt == null) {
17381 curt = (ResolveInfo)receivers.get(it);
17383 if (curr == null) {
17384 curr = registeredReceivers.get(ir);
17386 if (curr.getPriority() >= curt.priority) {
17387 // Insert this broadcast record into the final list.
17388 receivers.add(it, curr);
17394 // Skip to the next ResolveInfo in the final list.
17401 if (receivers == null) {
17402 receivers = new ArrayList();
17404 receivers.add(registeredReceivers.get(ir));
17408 if ((receivers != null && receivers.size() > 0)
17409 || resultTo != null) {
17410 BroadcastQueue queue = broadcastQueueForIntent(intent);
17411 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17412 callerPackage, callingPid, callingUid, resolvedType,
17413 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17414 resultData, resultExtras, ordered, sticky, false, userId);
17416 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17417 + ": prev had " + queue.mOrderedBroadcasts.size());
17418 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17419 "Enqueueing broadcast " + r.intent.getAction());
17421 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17423 queue.enqueueOrderedBroadcastLocked(r);
17424 queue.scheduleBroadcastsLocked();
17428 return ActivityManager.BROADCAST_SUCCESS;
17431 final Intent verifyBroadcastLocked(Intent intent) {
17432 // Refuse possible leaked file descriptors
17433 if (intent != null && intent.hasFileDescriptors() == true) {
17434 throw new IllegalArgumentException("File descriptors passed in Intent");
17437 int flags = intent.getFlags();
17439 if (!mProcessesReady) {
17440 // if the caller really truly claims to know what they're doing, go
17441 // ahead and allow the broadcast without launching any receivers
17442 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17443 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17444 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17445 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17446 + " before boot completion");
17447 throw new IllegalStateException("Cannot broadcast before boot completed");
17451 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17452 throw new IllegalArgumentException(
17453 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17459 public final int broadcastIntent(IApplicationThread caller,
17460 Intent intent, String resolvedType, IIntentReceiver resultTo,
17461 int resultCode, String resultData, Bundle resultExtras,
17462 String[] requiredPermissions, int appOp, Bundle bOptions,
17463 boolean serialized, boolean sticky, int userId) {
17464 enforceNotIsolatedCaller("broadcastIntent");
17465 synchronized(this) {
17466 intent = verifyBroadcastLocked(intent);
17468 final ProcessRecord callerApp = getRecordForAppLocked(caller);
17469 final int callingPid = Binder.getCallingPid();
17470 final int callingUid = Binder.getCallingUid();
17471 final long origId = Binder.clearCallingIdentity();
17472 int res = broadcastIntentLocked(callerApp,
17473 callerApp != null ? callerApp.info.packageName : null,
17474 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17475 requiredPermissions, appOp, null, serialized, sticky,
17476 callingPid, callingUid, userId);
17477 Binder.restoreCallingIdentity(origId);
17483 int broadcastIntentInPackage(String packageName, int uid,
17484 Intent intent, String resolvedType, IIntentReceiver resultTo,
17485 int resultCode, String resultData, Bundle resultExtras,
17486 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17488 synchronized(this) {
17489 intent = verifyBroadcastLocked(intent);
17491 final long origId = Binder.clearCallingIdentity();
17492 String[] requiredPermissions = requiredPermission == null ? null
17493 : new String[] {requiredPermission};
17494 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17495 resultTo, resultCode, resultData, resultExtras,
17496 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17497 sticky, -1, uid, userId);
17498 Binder.restoreCallingIdentity(origId);
17503 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17504 // Refuse possible leaked file descriptors
17505 if (intent != null && intent.hasFileDescriptors() == true) {
17506 throw new IllegalArgumentException("File descriptors passed in Intent");
17509 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17510 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17512 synchronized(this) {
17513 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17514 != PackageManager.PERMISSION_GRANTED) {
17515 String msg = "Permission Denial: unbroadcastIntent() from pid="
17516 + Binder.getCallingPid()
17517 + ", uid=" + Binder.getCallingUid()
17518 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17520 throw new SecurityException(msg);
17522 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17523 if (stickies != null) {
17524 ArrayList<Intent> list = stickies.get(intent.getAction());
17525 if (list != null) {
17526 int N = list.size();
17528 for (i=0; i<N; i++) {
17529 if (intent.filterEquals(list.get(i))) {
17534 if (list.size() <= 0) {
17535 stickies.remove(intent.getAction());
17538 if (stickies.size() <= 0) {
17539 mStickyBroadcasts.remove(userId);
17545 void backgroundServicesFinishedLocked(int userId) {
17546 for (BroadcastQueue queue : mBroadcastQueues) {
17547 queue.backgroundServicesFinishedLocked(userId);
17551 public void finishReceiver(IBinder who, int resultCode, String resultData,
17552 Bundle resultExtras, boolean resultAbort, int flags) {
17553 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17555 // Refuse possible leaked file descriptors
17556 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17557 throw new IllegalArgumentException("File descriptors passed in Bundle");
17560 final long origId = Binder.clearCallingIdentity();
17562 boolean doNext = false;
17565 synchronized(this) {
17566 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17567 ? mFgBroadcastQueue : mBgBroadcastQueue;
17568 r = queue.getMatchingOrderedReceiver(who);
17570 doNext = r.queue.finishReceiverLocked(r, resultCode,
17571 resultData, resultExtras, resultAbort, true);
17576 r.queue.processNextBroadcast(false);
17578 trimApplications();
17580 Binder.restoreCallingIdentity(origId);
17584 // =========================================================
17586 // =========================================================
17588 public boolean startInstrumentation(ComponentName className,
17589 String profileFile, int flags, Bundle arguments,
17590 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17591 int userId, String abiOverride) {
17592 enforceNotIsolatedCaller("startInstrumentation");
17593 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17594 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17595 // Refuse possible leaked file descriptors
17596 if (arguments != null && arguments.hasFileDescriptors()) {
17597 throw new IllegalArgumentException("File descriptors passed in Bundle");
17600 synchronized(this) {
17601 InstrumentationInfo ii = null;
17602 ApplicationInfo ai = null;
17604 ii = mContext.getPackageManager().getInstrumentationInfo(
17605 className, STOCK_PM_FLAGS);
17606 ai = AppGlobals.getPackageManager().getApplicationInfo(
17607 ii.targetPackage, STOCK_PM_FLAGS, userId);
17608 } catch (PackageManager.NameNotFoundException e) {
17609 } catch (RemoteException e) {
17612 reportStartInstrumentationFailure(watcher, className,
17613 "Unable to find instrumentation info for: " + className);
17617 reportStartInstrumentationFailure(watcher, className,
17618 "Unable to find instrumentation target package: " + ii.targetPackage);
17622 int match = mContext.getPackageManager().checkSignatures(
17623 ii.targetPackage, ii.packageName);
17624 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17625 String msg = "Permission Denial: starting instrumentation "
17626 + className + " from pid="
17627 + Binder.getCallingPid()
17628 + ", uid=" + Binder.getCallingPid()
17629 + " not allowed because package " + ii.packageName
17630 + " does not have a signature matching the target "
17631 + ii.targetPackage;
17632 reportStartInstrumentationFailure(watcher, className, msg);
17633 throw new SecurityException(msg);
17636 final long origId = Binder.clearCallingIdentity();
17637 // Instrumentation can kill and relaunch even persistent processes
17638 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17640 ProcessRecord app = addAppLocked(ai, false, abiOverride);
17641 app.instrumentationClass = className;
17642 app.instrumentationInfo = ai;
17643 app.instrumentationProfileFile = profileFile;
17644 app.instrumentationArguments = arguments;
17645 app.instrumentationWatcher = watcher;
17646 app.instrumentationUiAutomationConnection = uiAutomationConnection;
17647 app.instrumentationResultClass = className;
17648 Binder.restoreCallingIdentity(origId);
17655 * Report errors that occur while attempting to start Instrumentation. Always writes the
17656 * error to the logs, but if somebody is watching, send the report there too. This enables
17657 * the "am" command to report errors with more information.
17659 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
17660 * @param cn The component name of the instrumentation.
17661 * @param report The error report.
17663 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17664 ComponentName cn, String report) {
17665 Slog.w(TAG, report);
17667 if (watcher != null) {
17668 Bundle results = new Bundle();
17669 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17670 results.putString("Error", report);
17671 watcher.instrumentationStatus(cn, -1, results);
17673 } catch (RemoteException e) {
17678 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17679 if (app.instrumentationWatcher != null) {
17681 // NOTE: IInstrumentationWatcher *must* be oneway here
17682 app.instrumentationWatcher.instrumentationFinished(
17683 app.instrumentationClass,
17686 } catch (RemoteException e) {
17690 // Can't call out of the system process with a lock held, so post a message.
17691 if (app.instrumentationUiAutomationConnection != null) {
17692 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17693 app.instrumentationUiAutomationConnection).sendToTarget();
17696 app.instrumentationWatcher = null;
17697 app.instrumentationUiAutomationConnection = null;
17698 app.instrumentationClass = null;
17699 app.instrumentationInfo = null;
17700 app.instrumentationProfileFile = null;
17701 app.instrumentationArguments = null;
17703 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17707 public void finishInstrumentation(IApplicationThread target,
17708 int resultCode, Bundle results) {
17709 int userId = UserHandle.getCallingUserId();
17710 // Refuse possible leaked file descriptors
17711 if (results != null && results.hasFileDescriptors()) {
17712 throw new IllegalArgumentException("File descriptors passed in Intent");
17715 synchronized(this) {
17716 ProcessRecord app = getRecordForAppLocked(target);
17718 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17721 final long origId = Binder.clearCallingIdentity();
17722 finishInstrumentationLocked(app, resultCode, results);
17723 Binder.restoreCallingIdentity(origId);
17727 // =========================================================
17729 // =========================================================
17731 public ConfigurationInfo getDeviceConfigurationInfo() {
17732 ConfigurationInfo config = new ConfigurationInfo();
17733 synchronized (this) {
17734 config.reqTouchScreen = mConfiguration.touchscreen;
17735 config.reqKeyboardType = mConfiguration.keyboard;
17736 config.reqNavigation = mConfiguration.navigation;
17737 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17738 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17739 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17741 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17742 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17743 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17745 config.reqGlEsVersion = GL_ES_VERSION;
17750 ActivityStack getFocusedStack() {
17751 return mStackSupervisor.getFocusedStack();
17755 public int getFocusedStackId() throws RemoteException {
17756 ActivityStack focusedStack = getFocusedStack();
17757 if (focusedStack != null) {
17758 return focusedStack.getStackId();
17763 public Configuration getConfiguration() {
17765 synchronized(this) {
17766 ci = new Configuration(mConfiguration);
17767 ci.userSetLocale = false;
17773 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
17774 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17775 "suppressResizeConfigChanges()");
17776 synchronized (this) {
17777 mSuppressResizeConfigChanges = suppress;
17782 public void removeStack(int stackId) {
17783 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
17785 if (stackId == HOME_STACK_ID) {
17786 throw new IllegalArgumentException("Removing home stack is not allowed.");
17788 synchronized (this) {
17789 long origId = Binder.clearCallingIdentity();
17790 ActivityStack stack = mStackSupervisor.getStack(stackId);
17791 if (stack != null) {
17792 ArrayList<TaskRecord> tasks = stack.getAllTasks();
17793 for (int i = tasks.size() - 1; i >= 0; i--) {
17794 removeTaskByIdLocked(tasks.get(i).taskId, false /* killProcess */,
17795 !REMOVE_FROM_RECENTS);
17798 Binder.restoreCallingIdentity(origId);
17803 public void updatePersistentConfiguration(Configuration values) {
17804 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17805 "updateConfiguration()");
17806 enforceWriteSettingsPermission("updateConfiguration()");
17807 if (values == null) {
17808 throw new NullPointerException("Configuration must not be null");
17811 int userId = UserHandle.getCallingUserId();
17813 synchronized(this) {
17814 final long origId = Binder.clearCallingIdentity();
17815 updateConfigurationLocked(values, null, false, true, userId);
17816 Binder.restoreCallingIdentity(origId);
17820 private void enforceWriteSettingsPermission(String func) {
17821 int uid = Binder.getCallingUid();
17822 if (uid == Process.ROOT_UID) {
17826 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17827 Settings.getPackageNameForUid(mContext, uid), false)) {
17831 String msg = "Permission Denial: " + func + " from pid="
17832 + Binder.getCallingPid()
17834 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17836 throw new SecurityException(msg);
17839 public void updateConfiguration(Configuration values) {
17840 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17841 "updateConfiguration()");
17843 synchronized(this) {
17844 if (values == null && mWindowManager != null) {
17845 // sentinel: fetch the current configuration from the window manager
17846 values = mWindowManager.computeNewConfiguration();
17849 if (mWindowManager != null) {
17850 mProcessList.applyDisplaySize(mWindowManager);
17853 final long origId = Binder.clearCallingIdentity();
17854 if (values != null) {
17855 Settings.System.clearConfiguration(values);
17857 updateConfigurationLocked(values, null, false);
17858 Binder.restoreCallingIdentity(origId);
17862 void updateUserConfigurationLocked() {
17863 Configuration configuration = new Configuration(mConfiguration);
17864 Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
17865 mUserController.getCurrentUserIdLocked());
17866 updateConfigurationLocked(configuration, null, false);
17869 boolean updateConfigurationLocked(Configuration values,
17870 ActivityRecord starting, boolean initLocale) {
17871 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
17872 return updateConfigurationLocked(values, starting, initLocale, false,
17873 UserHandle.USER_NULL);
17876 // To cache the list of supported system locales
17877 private String[] mSupportedSystemLocales = null;
17880 * Do either or both things: (1) change the current configuration, and (2)
17881 * make sure the given activity is running with the (now) current
17882 * configuration. Returns true if the activity has been left running, or
17883 * false if <var>starting</var> is being destroyed to match the new
17886 * @param userId is only used when persistent parameter is set to true to persist configuration
17887 * for that particular user
17889 private boolean updateConfigurationLocked(Configuration values,
17890 ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
17893 if (values != null) {
17894 Configuration newConfig = new Configuration(mConfiguration);
17895 changes = newConfig.updateFrom(values);
17896 if (changes != 0) {
17897 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17898 "Updating configuration to: " + values);
17900 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17902 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
17903 if (mSupportedSystemLocales == null) {
17904 mSupportedSystemLocales = Resources.getSystem().getAssets().getLocales();
17906 final Locale locale = values.getLocales().getBestMatch(mSupportedSystemLocales);
17907 SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
17908 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17912 mConfigurationSeq++;
17913 if (mConfigurationSeq <= 0) {
17914 mConfigurationSeq = 1;
17916 newConfig.seq = mConfigurationSeq;
17917 mConfiguration = newConfig;
17918 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17919 mUsageStatsService.reportConfigurationChange(newConfig,
17920 mUserController.getCurrentUserIdLocked());
17921 //mUsageStatsService.noteStartConfig(newConfig);
17923 final Configuration configCopy = new Configuration(mConfiguration);
17925 // TODO: If our config changes, should we auto dismiss any currently
17926 // showing dialogs?
17927 mShowDialogs = shouldShowDialogs(newConfig);
17929 AttributeCache ac = AttributeCache.instance();
17931 ac.updateConfiguration(configCopy);
17934 // Make sure all resources in our process are updated
17935 // right now, so that anyone who is going to retrieve
17936 // resource values after we return will be sure to get
17937 // the new ones. This is especially important during
17938 // boot, where the first config change needs to guarantee
17939 // all resources have that config before following boot
17940 // code is executed.
17941 mSystemThread.applyConfigurationToResources(configCopy);
17943 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17944 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17945 msg.obj = new Configuration(configCopy);
17947 mHandler.sendMessage(msg);
17950 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17951 ProcessRecord app = mLruProcesses.get(i);
17953 if (app.thread != null) {
17954 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17955 + app.processName + " new config " + mConfiguration);
17956 app.thread.scheduleConfigurationChanged(configCopy);
17958 } catch (Exception e) {
17961 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17962 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17963 | Intent.FLAG_RECEIVER_REPLACE_PENDING
17964 | Intent.FLAG_RECEIVER_FOREGROUND);
17965 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17966 null, AppOpsManager.OP_NONE, null, false, false,
17967 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17968 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17969 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17970 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17971 if (!mProcessesReady) {
17972 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17974 broadcastIntentLocked(null, null, intent,
17975 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17976 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17981 boolean kept = true;
17982 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17983 // mainStack is null during startup.
17984 if (mainStack != null) {
17985 if (changes != 0 && starting == null) {
17986 // If the configuration changed, and the caller is not already
17987 // in the process of starting an activity, then find the top
17988 // activity to check if its configuration needs to change.
17989 starting = mainStack.topRunningActivityLocked();
17992 if (starting != null) {
17993 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
17994 // And we need to make sure at this point that all other activities
17995 // are made visible with the correct configuration.
17996 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
17997 !PRESERVE_WINDOWS);
18001 if (values != null && mWindowManager != null) {
18002 mWindowManager.setNewConfiguration(mConfiguration);
18009 * Decide based on the configuration whether we should shouw the ANR,
18010 * crash, etc dialogs. The idea is that if there is no affordnace to
18011 * press the on-screen buttons, we shouldn't show the dialog.
18013 * A thought: SystemUI might also want to get told about this, the Power
18014 * dialog / global actions also might want different behaviors.
18016 private static final boolean shouldShowDialogs(Configuration config) {
18017 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18018 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18019 && config.navigation == Configuration.NAVIGATION_NONAV);
18023 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18024 synchronized (this) {
18025 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18026 if (srec != null) {
18027 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18033 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18034 Intent resultData) {
18036 synchronized (this) {
18037 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18039 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18045 public int getLaunchedFromUid(IBinder activityToken) {
18046 ActivityRecord srec;
18047 synchronized (this) {
18048 srec = ActivityRecord.forTokenLocked(activityToken);
18050 if (srec == null) {
18053 return srec.launchedFromUid;
18056 public String getLaunchedFromPackage(IBinder activityToken) {
18057 ActivityRecord srec;
18058 synchronized (this) {
18059 srec = ActivityRecord.forTokenLocked(activityToken);
18061 if (srec == null) {
18064 return srec.launchedFromPackage;
18067 // =========================================================
18068 // LIFETIME MANAGEMENT
18069 // =========================================================
18071 // Returns which broadcast queue the app is the current [or imminent] receiver
18072 // on, or 'null' if the app is not an active broadcast recipient.
18073 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18074 BroadcastRecord r = app.curReceiver;
18079 // It's not the current receiver, but it might be starting up to become one
18080 synchronized (this) {
18081 for (BroadcastQueue queue : mBroadcastQueues) {
18082 r = queue.mPendingBroadcast;
18083 if (r != null && r.curApp == app) {
18084 // found it; report which queue it's in
18093 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18094 ComponentName targetComponent, String targetProcess) {
18095 if (!mTrackingAssociations) {
18098 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18099 = mAssociations.get(targetUid);
18100 if (components == null) {
18101 components = new ArrayMap<>();
18102 mAssociations.put(targetUid, components);
18104 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18105 if (sourceUids == null) {
18106 sourceUids = new SparseArray<>();
18107 components.put(targetComponent, sourceUids);
18109 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18110 if (sourceProcesses == null) {
18111 sourceProcesses = new ArrayMap<>();
18112 sourceUids.put(sourceUid, sourceProcesses);
18114 Association ass = sourceProcesses.get(sourceProcess);
18116 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18118 sourceProcesses.put(sourceProcess, ass);
18122 if (ass.mNesting == 1) {
18123 ass.mStartTime = SystemClock.uptimeMillis();
18128 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18129 ComponentName targetComponent) {
18130 if (!mTrackingAssociations) {
18133 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18134 = mAssociations.get(targetUid);
18135 if (components == null) {
18138 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18139 if (sourceUids == null) {
18142 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18143 if (sourceProcesses == null) {
18146 Association ass = sourceProcesses.get(sourceProcess);
18147 if (ass == null || ass.mNesting <= 0) {
18151 if (ass.mNesting == 0) {
18152 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18156 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18157 boolean doingAll, long now) {
18158 if (mAdjSeq == app.adjSeq) {
18159 // This adjustment has already been computed.
18160 return app.curRawAdj;
18163 if (app.thread == null) {
18164 app.adjSeq = mAdjSeq;
18165 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18166 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18167 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18170 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18171 app.adjSource = null;
18172 app.adjTarget = null;
18174 app.cached = false;
18176 final int activitiesSize = app.activities.size();
18178 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18179 // The max adjustment doesn't allow this app to be anything
18180 // below foreground, so it is not worth doing work for it.
18181 app.adjType = "fixed";
18182 app.adjSeq = mAdjSeq;
18183 app.curRawAdj = app.maxAdj;
18184 app.foregroundActivities = false;
18185 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
18186 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18187 // System processes can do UI, and when they do we want to have
18188 // them trim their memory after the user leaves the UI. To
18189 // facilitate this, here we need to determine whether or not it
18190 // is currently showing UI.
18191 app.systemNoUi = true;
18192 if (app == TOP_APP) {
18193 app.systemNoUi = false;
18194 } else if (activitiesSize > 0) {
18195 for (int j = 0; j < activitiesSize; j++) {
18196 final ActivityRecord r = app.activities.get(j);
18198 app.systemNoUi = false;
18202 if (!app.systemNoUi) {
18203 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18205 return (app.curAdj=app.maxAdj);
18208 app.systemNoUi = false;
18210 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18212 // Determine the importance of the process, starting with most
18213 // important to least, and assign an appropriate OOM adjustment.
18217 boolean foregroundActivities = false;
18218 BroadcastQueue queue;
18219 if (app == TOP_APP) {
18220 // The last app on the list is the foreground app.
18221 adj = ProcessList.FOREGROUND_APP_ADJ;
18222 schedGroup = Process.THREAD_GROUP_DEFAULT;
18223 app.adjType = "top-activity";
18224 foregroundActivities = true;
18225 procState = PROCESS_STATE_CUR_TOP;
18226 } else if (app.instrumentationClass != null) {
18227 // Don't want to kill running instrumentation.
18228 adj = ProcessList.FOREGROUND_APP_ADJ;
18229 schedGroup = Process.THREAD_GROUP_DEFAULT;
18230 app.adjType = "instrumentation";
18231 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18232 } else if ((queue = isReceivingBroadcast(app)) != null) {
18233 // An app that is currently receiving a broadcast also
18234 // counts as being in the foreground for OOM killer purposes.
18235 // It's placed in a sched group based on the nature of the
18236 // broadcast as reflected by which queue it's active in.
18237 adj = ProcessList.FOREGROUND_APP_ADJ;
18238 schedGroup = (queue == mFgBroadcastQueue)
18239 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18240 app.adjType = "broadcast";
18241 procState = ActivityManager.PROCESS_STATE_RECEIVER;
18242 } else if (app.executingServices.size() > 0) {
18243 // An app that is currently executing a service callback also
18244 // counts as being in the foreground.
18245 adj = ProcessList.FOREGROUND_APP_ADJ;
18246 schedGroup = app.execServicesFg ?
18247 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
18248 app.adjType = "exec-service";
18249 procState = ActivityManager.PROCESS_STATE_SERVICE;
18250 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18252 // As far as we know the process is empty. We may change our mind later.
18253 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18254 // At this point we don't actually know the adjustment. Use the cached adj
18255 // value that the caller wants us to.
18257 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18260 app.adjType = "cch-empty";
18263 // Examine all activities if not already foreground.
18264 if (!foregroundActivities && activitiesSize > 0) {
18265 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18266 for (int j = 0; j < activitiesSize; j++) {
18267 final ActivityRecord r = app.activities.get(j);
18268 if (r.app != app) {
18269 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18270 + app + "?!? Using " + r.app + " instead.");
18274 // App has a visible activity; only upgrade adjustment.
18275 if (adj > ProcessList.VISIBLE_APP_ADJ) {
18276 adj = ProcessList.VISIBLE_APP_ADJ;
18277 app.adjType = "visible";
18279 if (procState > PROCESS_STATE_CUR_TOP) {
18280 procState = PROCESS_STATE_CUR_TOP;
18282 schedGroup = Process.THREAD_GROUP_DEFAULT;
18283 app.cached = false;
18285 foregroundActivities = true;
18286 if (r.task != null && minLayer > 0) {
18287 final int layer = r.task.mLayerRank;
18288 if (layer >= 0 && minLayer > layer) {
18293 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18294 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18295 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18296 app.adjType = "pausing";
18298 if (procState > PROCESS_STATE_CUR_TOP) {
18299 procState = PROCESS_STATE_CUR_TOP;
18301 schedGroup = Process.THREAD_GROUP_DEFAULT;
18302 app.cached = false;
18304 foregroundActivities = true;
18305 } else if (r.state == ActivityState.STOPPING) {
18306 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18307 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18308 app.adjType = "stopping";
18310 // For the process state, we will at this point consider the
18311 // process to be cached. It will be cached either as an activity
18312 // or empty depending on whether the activity is finishing. We do
18313 // this so that we can treat the process as cached for purposes of
18314 // memory trimming (determing current memory level, trim command to
18315 // send to process) since there can be an arbitrary number of stopping
18316 // processes and they should soon all go into the cached state.
18317 if (!r.finishing) {
18318 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18319 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18322 app.cached = false;
18324 foregroundActivities = true;
18326 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18327 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18328 app.adjType = "cch-act";
18332 if (adj == ProcessList.VISIBLE_APP_ADJ) {
18337 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18338 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18339 if (app.foregroundServices) {
18340 // The user is aware of this app, so make it visible.
18341 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18342 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18343 app.cached = false;
18344 app.adjType = "fg-service";
18345 schedGroup = Process.THREAD_GROUP_DEFAULT;
18346 } else if (app.forcingToForeground != null) {
18347 // The user is aware of this app, so make it visible.
18348 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18349 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18350 app.cached = false;
18351 app.adjType = "force-fg";
18352 app.adjSource = app.forcingToForeground;
18353 schedGroup = Process.THREAD_GROUP_DEFAULT;
18357 if (app == mHeavyWeightProcess) {
18358 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18359 // We don't want to kill the current heavy-weight process.
18360 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18361 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18362 app.cached = false;
18363 app.adjType = "heavy";
18365 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18366 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18370 if (app == mHomeProcess) {
18371 if (adj > ProcessList.HOME_APP_ADJ) {
18372 // This process is hosting what we currently consider to be the
18373 // home app, so we don't want to let it go into the background.
18374 adj = ProcessList.HOME_APP_ADJ;
18375 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18376 app.cached = false;
18377 app.adjType = "home";
18379 if (procState > ActivityManager.PROCESS_STATE_HOME) {
18380 procState = ActivityManager.PROCESS_STATE_HOME;
18384 if (app == mPreviousProcess && app.activities.size() > 0) {
18385 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18386 // This was the previous process that showed UI to the user.
18387 // We want to try to keep it around more aggressively, to give
18388 // a good experience around switching between two apps.
18389 adj = ProcessList.PREVIOUS_APP_ADJ;
18390 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18391 app.cached = false;
18392 app.adjType = "previous";
18394 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18395 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18399 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18400 + " reason=" + app.adjType);
18402 // By default, we use the computed adjustment. It may be changed if
18403 // there are applications dependent on our services or providers, but
18404 // this gives us a baseline and makes sure we don't get into an
18405 // infinite recursion.
18406 app.adjSeq = mAdjSeq;
18407 app.curRawAdj = adj;
18408 app.hasStartedServices = false;
18410 if (mBackupTarget != null && app == mBackupTarget.app) {
18411 // If possible we want to avoid killing apps while they're being backed up
18412 if (adj > ProcessList.BACKUP_APP_ADJ) {
18413 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18414 adj = ProcessList.BACKUP_APP_ADJ;
18415 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18416 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18418 app.adjType = "backup";
18419 app.cached = false;
18421 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18422 procState = ActivityManager.PROCESS_STATE_BACKUP;
18426 boolean mayBeTop = false;
18428 for (int is = app.services.size()-1;
18429 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18430 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18431 || procState > ActivityManager.PROCESS_STATE_TOP);
18433 ServiceRecord s = app.services.valueAt(is);
18434 if (s.startRequested) {
18435 app.hasStartedServices = true;
18436 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18437 procState = ActivityManager.PROCESS_STATE_SERVICE;
18439 if (app.hasShownUi && app != mHomeProcess) {
18440 // If this process has shown some UI, let it immediately
18441 // go to the LRU list because it may be pretty heavy with
18442 // UI stuff. We'll tag it with a label just to help
18443 // debug and understand what is going on.
18444 if (adj > ProcessList.SERVICE_ADJ) {
18445 app.adjType = "cch-started-ui-services";
18448 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18449 // This service has seen some activity within
18450 // recent memory, so we will keep its process ahead
18451 // of the background processes.
18452 if (adj > ProcessList.SERVICE_ADJ) {
18453 adj = ProcessList.SERVICE_ADJ;
18454 app.adjType = "started-services";
18455 app.cached = false;
18458 // If we have let the service slide into the background
18459 // state, still have some text describing what it is doing
18460 // even though the service no longer has an impact.
18461 if (adj > ProcessList.SERVICE_ADJ) {
18462 app.adjType = "cch-started-services";
18466 for (int conni = s.connections.size()-1;
18467 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18468 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18469 || procState > ActivityManager.PROCESS_STATE_TOP);
18471 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18473 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18474 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18475 || procState > ActivityManager.PROCESS_STATE_TOP);
18477 // XXX should compute this based on the max of
18478 // all connected clients.
18479 ConnectionRecord cr = clist.get(i);
18480 if (cr.binding.client == app) {
18481 // Binding to ourself is not interesting.
18484 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18485 ProcessRecord client = cr.binding.client;
18486 int clientAdj = computeOomAdjLocked(client, cachedAdj,
18487 TOP_APP, doingAll, now);
18488 int clientProcState = client.curProcState;
18489 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18490 // If the other app is cached for any reason, for purposes here
18491 // we are going to consider it empty. The specific cached state
18492 // doesn't propagate except under certain conditions.
18493 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18495 String adjType = null;
18496 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18497 // Not doing bind OOM management, so treat
18498 // this guy more like a started service.
18499 if (app.hasShownUi && app != mHomeProcess) {
18500 // If this process has shown some UI, let it immediately
18501 // go to the LRU list because it may be pretty heavy with
18502 // UI stuff. We'll tag it with a label just to help
18503 // debug and understand what is going on.
18504 if (adj > clientAdj) {
18505 adjType = "cch-bound-ui-services";
18507 app.cached = false;
18509 clientProcState = procState;
18511 if (now >= (s.lastActivity
18512 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18513 // This service has not seen activity within
18514 // recent memory, so allow it to drop to the
18515 // LRU list if there is no other reason to keep
18516 // it around. We'll also tag it with a label just
18517 // to help debug and undertand what is going on.
18518 if (adj > clientAdj) {
18519 adjType = "cch-bound-services";
18525 if (adj > clientAdj) {
18526 // If this process has recently shown UI, and
18527 // the process that is binding to it is less
18528 // important than being visible, then we don't
18529 // care about the binding as much as we care
18530 // about letting this process get into the LRU
18531 // list to be killed and restarted if needed for
18533 if (app.hasShownUi && app != mHomeProcess
18534 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18535 adjType = "cch-bound-ui-services";
18537 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18538 |Context.BIND_IMPORTANT)) != 0) {
18539 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18540 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18541 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18542 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18543 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18544 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18545 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18548 if (adj > ProcessList.VISIBLE_APP_ADJ) {
18549 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18552 if (!client.cached) {
18553 app.cached = false;
18555 adjType = "service";
18558 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18559 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18560 schedGroup = Process.THREAD_GROUP_DEFAULT;
18562 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18563 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18564 // Special handling of clients who are in the top state.
18565 // We *may* want to consider this process to be in the
18566 // top state as well, but only if there is not another
18567 // reason for it to be running. Being on the top is a
18568 // special state, meaning you are specifically running
18569 // for the current top app. If the process is already
18570 // running in the background for some other reason, it
18571 // is more important to continue considering it to be
18572 // in the background state.
18574 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18576 // Special handling for above-top states (persistent
18577 // processes). These should not bring the current process
18578 // into the top state, since they are not on top. Instead
18579 // give them the best state after that.
18580 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18582 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18583 } else if (mWakefulness
18584 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18585 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18588 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18591 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18596 if (clientProcState <
18597 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18599 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18602 if (procState > clientProcState) {
18603 procState = clientProcState;
18605 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18606 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18607 app.pendingUiClean = true;
18609 if (adjType != null) {
18610 app.adjType = adjType;
18611 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18612 .REASON_SERVICE_IN_USE;
18613 app.adjSource = cr.binding.client;
18614 app.adjSourceProcState = clientProcState;
18615 app.adjTarget = s.name;
18618 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18619 app.treatLikeActivity = true;
18621 final ActivityRecord a = cr.activity;
18622 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18623 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18624 (a.visible || a.state == ActivityState.RESUMED
18625 || a.state == ActivityState.PAUSING)) {
18626 adj = ProcessList.FOREGROUND_APP_ADJ;
18627 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18628 schedGroup = Process.THREAD_GROUP_DEFAULT;
18630 app.cached = false;
18631 app.adjType = "service";
18632 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18633 .REASON_SERVICE_IN_USE;
18635 app.adjSourceProcState = procState;
18636 app.adjTarget = s.name;
18643 for (int provi = app.pubProviders.size()-1;
18644 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18645 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18646 || procState > ActivityManager.PROCESS_STATE_TOP);
18648 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18649 for (int i = cpr.connections.size()-1;
18650 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18651 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18652 || procState > ActivityManager.PROCESS_STATE_TOP);
18654 ContentProviderConnection conn = cpr.connections.get(i);
18655 ProcessRecord client = conn.client;
18656 if (client == app) {
18657 // Being our own client is not interesting.
18660 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18661 int clientProcState = client.curProcState;
18662 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18663 // If the other app is cached for any reason, for purposes here
18664 // we are going to consider it empty.
18665 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18667 if (adj > clientAdj) {
18668 if (app.hasShownUi && app != mHomeProcess
18669 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18670 app.adjType = "cch-ui-provider";
18672 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18673 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18674 app.adjType = "provider";
18676 app.cached &= client.cached;
18677 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18678 .REASON_PROVIDER_IN_USE;
18679 app.adjSource = client;
18680 app.adjSourceProcState = clientProcState;
18681 app.adjTarget = cpr.name;
18683 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18684 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18685 // Special handling of clients who are in the top state.
18686 // We *may* want to consider this process to be in the
18687 // top state as well, but only if there is not another
18688 // reason for it to be running. Being on the top is a
18689 // special state, meaning you are specifically running
18690 // for the current top app. If the process is already
18691 // running in the background for some other reason, it
18692 // is more important to continue considering it to be
18693 // in the background state.
18695 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18697 // Special handling for above-top states (persistent
18698 // processes). These should not bring the current process
18699 // into the top state, since they are not on top. Instead
18700 // give them the best state after that.
18702 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18705 if (procState > clientProcState) {
18706 procState = clientProcState;
18708 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18709 schedGroup = Process.THREAD_GROUP_DEFAULT;
18712 // If the provider has external (non-framework) process
18713 // dependencies, ensure that its adjustment is at least
18714 // FOREGROUND_APP_ADJ.
18715 if (cpr.hasExternalProcessHandles()) {
18716 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18717 adj = ProcessList.FOREGROUND_APP_ADJ;
18718 schedGroup = Process.THREAD_GROUP_DEFAULT;
18719 app.cached = false;
18720 app.adjType = "provider";
18721 app.adjTarget = cpr.name;
18723 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18724 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18729 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18730 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18731 adj = ProcessList.PREVIOUS_APP_ADJ;
18732 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18733 app.cached = false;
18734 app.adjType = "provider";
18736 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18737 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18741 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18742 // A client of one of our services or providers is in the top state. We
18743 // *may* want to be in the top state, but not if we are already running in
18744 // the background for some other reason. For the decision here, we are going
18745 // to pick out a few specific states that we want to remain in when a client
18746 // is top (states that tend to be longer-term) and otherwise allow it to go
18747 // to the top state.
18748 switch (procState) {
18749 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18750 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18751 case ActivityManager.PROCESS_STATE_SERVICE:
18752 // These all are longer-term states, so pull them up to the top
18753 // of the background states, but not all the way to the top state.
18754 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18757 // Otherwise, top is a better choice, so take it.
18758 procState = ActivityManager.PROCESS_STATE_TOP;
18763 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18764 if (app.hasClientActivities) {
18765 // This is a cached process, but with client activities. Mark it so.
18766 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18767 app.adjType = "cch-client-act";
18768 } else if (app.treatLikeActivity) {
18769 // This is a cached process, but somebody wants us to treat it like it has
18770 // an activity, okay!
18771 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18772 app.adjType = "cch-as-act";
18776 if (adj == ProcessList.SERVICE_ADJ) {
18778 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18779 mNewNumServiceProcs++;
18780 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18781 if (!app.serviceb) {
18782 // This service isn't far enough down on the LRU list to
18783 // normally be a B service, but if we are low on RAM and it
18784 // is large we want to force it down since we would prefer to
18785 // keep launcher over it.
18786 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18787 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18788 app.serviceHighRam = true;
18789 app.serviceb = true;
18790 //Slog.i(TAG, "ADJ " + app + " high ram!");
18792 mNewNumAServiceProcs++;
18793 //Slog.i(TAG, "ADJ " + app + " not high ram!");
18796 app.serviceHighRam = false;
18799 if (app.serviceb) {
18800 adj = ProcessList.SERVICE_B_ADJ;
18804 app.curRawAdj = adj;
18806 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18807 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18808 if (adj > app.maxAdj) {
18810 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18811 schedGroup = Process.THREAD_GROUP_DEFAULT;
18815 // Do final modification to adj. Everything we do between here and applying
18816 // the final setAdj must be done in this function, because we will also use
18817 // it when computing the final cached adj later. Note that we don't need to
18818 // worry about this for max adj above, since max adj will always be used to
18819 // keep it out of the cached vaues.
18820 app.curAdj = app.modifyRawOomAdj(adj);
18821 app.curSchedGroup = schedGroup;
18822 app.curProcState = procState;
18823 app.foregroundActivities = foregroundActivities;
18825 return app.curRawAdj;
18829 * Record new PSS sample for a process.
18831 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18832 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18833 proc.lastPssTime = now;
18834 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18835 if (DEBUG_PSS) Slog.d(TAG_PSS,
18836 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18837 + " state=" + ProcessList.makeProcStateString(procState));
18838 if (proc.initialIdlePss == 0) {
18839 proc.initialIdlePss = pss;
18841 proc.lastPss = pss;
18842 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18843 proc.lastCachedPss = pss;
18846 final SparseArray<Pair<Long, String>> watchUids
18847 = mMemWatchProcesses.getMap().get(proc.processName);
18849 if (watchUids != null) {
18850 Pair<Long, String> val = watchUids.get(proc.uid);
18852 val = watchUids.get(0);
18858 if (check != null) {
18859 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18860 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18861 if (!isDebuggable) {
18862 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18863 isDebuggable = true;
18866 if (isDebuggable) {
18867 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18868 final ProcessRecord myProc = proc;
18869 final File heapdumpFile = DumpHeapProvider.getJavaFile();
18870 mMemWatchDumpProcName = proc.processName;
18871 mMemWatchDumpFile = heapdumpFile.toString();
18872 mMemWatchDumpPid = proc.pid;
18873 mMemWatchDumpUid = proc.uid;
18874 BackgroundThread.getHandler().post(new Runnable() {
18876 public void run() {
18877 revokeUriPermission(ActivityThread.currentActivityThread()
18878 .getApplicationThread(),
18879 DumpHeapActivity.JAVA_URI,
18880 Intent.FLAG_GRANT_READ_URI_PERMISSION
18881 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18882 UserHandle.myUserId());
18883 ParcelFileDescriptor fd = null;
18885 heapdumpFile.delete();
18886 fd = ParcelFileDescriptor.open(heapdumpFile,
18887 ParcelFileDescriptor.MODE_CREATE |
18888 ParcelFileDescriptor.MODE_TRUNCATE |
18889 ParcelFileDescriptor.MODE_WRITE_ONLY |
18890 ParcelFileDescriptor.MODE_APPEND);
18891 IApplicationThread thread = myProc.thread;
18892 if (thread != null) {
18894 if (DEBUG_PSS) Slog.d(TAG_PSS,
18895 "Requesting dump heap from "
18896 + myProc + " to " + heapdumpFile);
18897 thread.dumpHeap(true, heapdumpFile.toString(), fd);
18898 } catch (RemoteException e) {
18901 } catch (FileNotFoundException e) {
18902 e.printStackTrace();
18907 } catch (IOException e) {
18914 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18915 + ", but debugging not enabled");
18922 * Schedule PSS collection of a process.
18924 void requestPssLocked(ProcessRecord proc, int procState) {
18925 if (mPendingPssProcesses.contains(proc)) {
18928 if (mPendingPssProcesses.size() == 0) {
18929 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18931 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18932 proc.pssProcState = procState;
18933 mPendingPssProcesses.add(proc);
18937 * Schedule PSS collection of all processes.
18939 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18941 if (now < (mLastFullPssTime +
18942 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18946 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
18947 mLastFullPssTime = now;
18948 mFullPssPending = true;
18949 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18950 mPendingPssProcesses.clear();
18951 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18952 ProcessRecord app = mLruProcesses.get(i);
18953 if (app.thread == null
18954 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18957 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18958 app.pssProcState = app.setProcState;
18959 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18960 mTestPssMode, isSleeping(), now);
18961 mPendingPssProcesses.add(app);
18964 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18967 public void setTestPssMode(boolean enabled) {
18968 synchronized (this) {
18969 mTestPssMode = enabled;
18971 // Whenever we enable the mode, we want to take a snapshot all of current
18972 // process mem use.
18973 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18979 * Ask a given process to GC right now.
18981 final void performAppGcLocked(ProcessRecord app) {
18983 app.lastRequestedGc = SystemClock.uptimeMillis();
18984 if (app.thread != null) {
18985 if (app.reportLowMemory) {
18986 app.reportLowMemory = false;
18987 app.thread.scheduleLowMemory();
18989 app.thread.processInBackground();
18992 } catch (Exception e) {
18998 * Returns true if things are idle enough to perform GCs.
19000 private final boolean canGcNowLocked() {
19001 boolean processingBroadcasts = false;
19002 for (BroadcastQueue q : mBroadcastQueues) {
19003 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19004 processingBroadcasts = true;
19007 return !processingBroadcasts
19008 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19012 * Perform GCs on all processes that are waiting for it, but only
19013 * if things are idle.
19015 final void performAppGcsLocked() {
19016 final int N = mProcessesToGc.size();
19020 if (canGcNowLocked()) {
19021 while (mProcessesToGc.size() > 0) {
19022 ProcessRecord proc = mProcessesToGc.remove(0);
19023 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19024 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19025 <= SystemClock.uptimeMillis()) {
19026 // To avoid spamming the system, we will GC processes one
19027 // at a time, waiting a few seconds between each.
19028 performAppGcLocked(proc);
19029 scheduleAppGcsLocked();
19032 // It hasn't been long enough since we last GCed this
19033 // process... put it in the list to wait for its time.
19034 addProcessToGcListLocked(proc);
19040 scheduleAppGcsLocked();
19045 * If all looks good, perform GCs on all processes waiting for them.
19047 final void performAppGcsIfAppropriateLocked() {
19048 if (canGcNowLocked()) {
19049 performAppGcsLocked();
19052 // Still not idle, wait some more.
19053 scheduleAppGcsLocked();
19057 * Schedule the execution of all pending app GCs.
19059 final void scheduleAppGcsLocked() {
19060 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19062 if (mProcessesToGc.size() > 0) {
19063 // Schedule a GC for the time to the next process.
19064 ProcessRecord proc = mProcessesToGc.get(0);
19065 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19067 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19068 long now = SystemClock.uptimeMillis();
19069 if (when < (now+GC_TIMEOUT)) {
19070 when = now + GC_TIMEOUT;
19072 mHandler.sendMessageAtTime(msg, when);
19077 * Add a process to the array of processes waiting to be GCed. Keeps the
19078 * list in sorted order by the last GC time. The process can't already be
19081 final void addProcessToGcListLocked(ProcessRecord proc) {
19082 boolean added = false;
19083 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19084 if (mProcessesToGc.get(i).lastRequestedGc <
19085 proc.lastRequestedGc) {
19087 mProcessesToGc.add(i+1, proc);
19092 mProcessesToGc.add(0, proc);
19097 * Set up to ask a process to GC itself. This will either do it
19098 * immediately, or put it on the list of processes to gc the next
19099 * time things are idle.
19101 final void scheduleAppGcLocked(ProcessRecord app) {
19102 long now = SystemClock.uptimeMillis();
19103 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19106 if (!mProcessesToGc.contains(app)) {
19107 addProcessToGcListLocked(app);
19108 scheduleAppGcsLocked();
19112 final void checkExcessivePowerUsageLocked(boolean doKills) {
19113 updateCpuStatsNow();
19115 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19116 boolean doWakeKills = doKills;
19117 boolean doCpuKills = doKills;
19118 if (mLastPowerCheckRealtime == 0) {
19119 doWakeKills = false;
19121 if (mLastPowerCheckUptime == 0) {
19122 doCpuKills = false;
19124 if (stats.isScreenOn()) {
19125 doWakeKills = false;
19127 final long curRealtime = SystemClock.elapsedRealtime();
19128 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19129 final long curUptime = SystemClock.uptimeMillis();
19130 final long uptimeSince = curUptime - mLastPowerCheckUptime;
19131 mLastPowerCheckRealtime = curRealtime;
19132 mLastPowerCheckUptime = curUptime;
19133 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19134 doWakeKills = false;
19136 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19137 doCpuKills = false;
19139 int i = mLruProcesses.size();
19142 ProcessRecord app = mLruProcesses.get(i);
19143 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19145 synchronized (stats) {
19146 wtime = stats.getProcessWakeTime(app.info.uid,
19147 app.pid, curRealtime);
19149 long wtimeUsed = wtime - app.lastWakeTime;
19150 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19152 StringBuilder sb = new StringBuilder(128);
19153 sb.append("Wake for ");
19154 app.toShortString(sb);
19155 sb.append(": over ");
19156 TimeUtils.formatDuration(realtimeSince, sb);
19157 sb.append(" used ");
19158 TimeUtils.formatDuration(wtimeUsed, sb);
19160 sb.append((wtimeUsed*100)/realtimeSince);
19162 Slog.i(TAG_POWER, sb.toString());
19164 sb.append("CPU for ");
19165 app.toShortString(sb);
19166 sb.append(": over ");
19167 TimeUtils.formatDuration(uptimeSince, sb);
19168 sb.append(" used ");
19169 TimeUtils.formatDuration(cputimeUsed, sb);
19171 sb.append((cputimeUsed*100)/uptimeSince);
19173 Slog.i(TAG_POWER, sb.toString());
19175 // If a process has held a wake lock for more
19176 // than 50% of the time during this period,
19177 // that sounds bad. Kill!
19178 if (doWakeKills && realtimeSince > 0
19179 && ((wtimeUsed*100)/realtimeSince) >= 50) {
19180 synchronized (stats) {
19181 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19182 realtimeSince, wtimeUsed);
19184 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19185 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19186 } else if (doCpuKills && uptimeSince > 0
19187 && ((cputimeUsed*100)/uptimeSince) >= 25) {
19188 synchronized (stats) {
19189 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19190 uptimeSince, cputimeUsed);
19192 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19193 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19195 app.lastWakeTime = wtime;
19196 app.lastCpuTime = app.curCpuTime;
19202 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19204 boolean success = true;
19206 if (app.curRawAdj != app.setRawAdj) {
19207 app.setRawAdj = app.curRawAdj;
19212 if (app.curAdj != app.setAdj) {
19213 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19214 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19215 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19217 app.setAdj = app.curAdj;
19220 if (app.setSchedGroup != app.curSchedGroup) {
19221 app.setSchedGroup = app.curSchedGroup;
19222 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19223 "Setting process group of " + app.processName
19224 + " to " + app.curSchedGroup);
19225 if (app.waitingToKill != null && app.curReceiver == null
19226 && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
19227 app.kill(app.waitingToKill, true);
19231 long oldId = Binder.clearCallingIdentity();
19233 Process.setProcessGroup(app.pid, app.curSchedGroup);
19234 } catch (Exception e) {
19235 Slog.w(TAG, "Failed setting process group of " + app.pid
19236 + " to " + app.curSchedGroup);
19237 e.printStackTrace();
19239 Binder.restoreCallingIdentity(oldId);
19242 if (app.thread != null) {
19244 app.thread.setSchedulingGroup(app.curSchedGroup);
19245 } catch (RemoteException e) {
19251 if (app.repForegroundActivities != app.foregroundActivities) {
19252 app.repForegroundActivities = app.foregroundActivities;
19253 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19255 if (app.repProcState != app.curProcState) {
19256 app.repProcState = app.curProcState;
19257 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19258 if (app.thread != null) {
19261 //RuntimeException h = new RuntimeException("here");
19262 Slog.i(TAG, "Sending new process state " + app.repProcState
19263 + " to " + app /*, h*/);
19265 app.thread.setProcessState(app.repProcState);
19266 } catch (RemoteException e) {
19270 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19271 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19272 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19273 // Experimental code to more aggressively collect pss while
19274 // running test... the problem is that this tends to collect
19275 // the data right when a process is transitioning between process
19276 // states, which well tend to give noisy data.
19277 long start = SystemClock.uptimeMillis();
19278 long pss = Debug.getPss(app.pid, mTmpLong, null);
19279 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
19280 mPendingPssProcesses.remove(app);
19281 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19282 + " to " + app.curProcState + ": "
19283 + (SystemClock.uptimeMillis()-start) + "ms");
19285 app.lastStateTime = now;
19286 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19287 mTestPssMode, isSleeping(), now);
19288 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19289 + ProcessList.makeProcStateString(app.setProcState) + " to "
19290 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19291 + (app.nextPssTime-now) + ": " + app);
19293 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19294 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19296 requestPssLocked(app, app.setProcState);
19297 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19298 mTestPssMode, isSleeping(), now);
19299 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19300 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19302 if (app.setProcState != app.curProcState) {
19303 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19304 "Proc state change of " + app.processName
19305 + " to " + app.curProcState);
19306 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19307 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19308 if (setImportant && !curImportant) {
19309 // This app is no longer something we consider important enough to allow to
19310 // use arbitrary amounts of battery power. Note
19311 // its current wake lock time to later know to kill it if
19312 // it is not behaving well.
19313 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19314 synchronized (stats) {
19315 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19316 app.pid, nowElapsed);
19318 app.lastCpuTime = app.curCpuTime;
19321 // Inform UsageStats of important process state change
19322 // Must be called before updating setProcState
19323 maybeUpdateUsageStatsLocked(app, nowElapsed);
19325 app.setProcState = app.curProcState;
19326 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19327 app.notCachedSinceIdle = false;
19330 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19332 app.procStateChanged = true;
19334 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19335 > USAGE_STATS_INTERACTION_INTERVAL) {
19336 // For apps that sit around for a long time in the interactive state, we need
19337 // to report this at least once a day so they don't go idle.
19338 maybeUpdateUsageStatsLocked(app, nowElapsed);
19341 if (changes != 0) {
19342 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19343 "Changes in " + app + ": " + changes);
19344 int i = mPendingProcessChanges.size()-1;
19345 ProcessChangeItem item = null;
19347 item = mPendingProcessChanges.get(i);
19348 if (item.pid == app.pid) {
19349 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19350 "Re-using existing item: " + item);
19356 // No existing item in pending changes; need a new one.
19357 final int NA = mAvailProcessChanges.size();
19359 item = mAvailProcessChanges.remove(NA-1);
19360 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19361 "Retrieving available item: " + item);
19363 item = new ProcessChangeItem();
19364 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19365 "Allocating new item: " + item);
19368 item.pid = app.pid;
19369 item.uid = app.info.uid;
19370 if (mPendingProcessChanges.size() == 0) {
19371 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19372 "*** Enqueueing dispatch processes changed!");
19373 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19375 mPendingProcessChanges.add(item);
19377 item.changes |= changes;
19378 item.processState = app.repProcState;
19379 item.foregroundActivities = app.repForegroundActivities;
19380 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19381 "Item " + Integer.toHexString(System.identityHashCode(item))
19382 + " " + app.toShortString() + ": changes=" + item.changes
19383 + " procState=" + item.processState
19384 + " foreground=" + item.foregroundActivities
19385 + " type=" + app.adjType + " source=" + app.adjSource
19386 + " target=" + app.adjTarget);
19392 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19393 final UidRecord.ChangeItem pendingChange;
19394 if (uidRec == null || uidRec.pendingChange == null) {
19395 if (mPendingUidChanges.size() == 0) {
19396 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19397 "*** Enqueueing dispatch uid changed!");
19398 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19400 final int NA = mAvailUidChanges.size();
19402 pendingChange = mAvailUidChanges.remove(NA-1);
19403 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19404 "Retrieving available item: " + pendingChange);
19406 pendingChange = new UidRecord.ChangeItem();
19407 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19408 "Allocating new item: " + pendingChange);
19410 if (uidRec != null) {
19411 uidRec.pendingChange = pendingChange;
19412 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19413 // If this uid is going away, and we haven't yet reported it is gone,
19415 change = UidRecord.CHANGE_GONE_IDLE;
19417 } else if (uid < 0) {
19418 throw new IllegalArgumentException("No UidRecord or uid");
19420 pendingChange.uidRecord = uidRec;
19421 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19422 mPendingUidChanges.add(pendingChange);
19424 pendingChange = uidRec.pendingChange;
19425 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19426 change = UidRecord.CHANGE_GONE_IDLE;
19429 pendingChange.change = change;
19430 pendingChange.processState = uidRec != null
19431 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19434 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19435 String authority) {
19436 if (app == null) return;
19437 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19438 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19439 if (userState == null) return;
19440 final long now = SystemClock.elapsedRealtime();
19441 Long lastReported = userState.mProviderLastReportedFg.get(authority);
19442 if (lastReported == null || lastReported < now - 60 * 1000L) {
19443 mUsageStatsService.reportContentProviderUsage(
19444 authority, providerPkgName, app.userId);
19445 userState.mProviderLastReportedFg.put(authority, now);
19450 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19451 if (DEBUG_USAGE_STATS) {
19452 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19453 + "] state changes: old = " + app.setProcState + ", new = "
19454 + app.curProcState);
19456 if (mUsageStatsService == null) {
19459 boolean isInteraction;
19460 // To avoid some abuse patterns, we are going to be careful about what we consider
19461 // to be an app interaction. Being the top activity doesn't count while the display
19462 // is sleeping, nor do short foreground services.
19463 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19464 isInteraction = true;
19465 app.fgInteractionTime = 0;
19466 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19467 if (app.fgInteractionTime == 0) {
19468 app.fgInteractionTime = nowElapsed;
19469 isInteraction = false;
19471 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19474 isInteraction = app.curProcState
19475 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19476 app.fgInteractionTime = 0;
19478 if (isInteraction && (!app.reportedInteraction
19479 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19480 app.interactionEventTime = nowElapsed;
19481 String[] packages = app.getPackageList();
19482 if (packages != null) {
19483 for (int i = 0; i < packages.length; i++) {
19484 mUsageStatsService.reportEvent(packages[i], app.userId,
19485 UsageEvents.Event.SYSTEM_INTERACTION);
19489 app.reportedInteraction = isInteraction;
19490 if (!isInteraction) {
19491 app.interactionEventTime = 0;
19495 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19496 if (proc.thread != null) {
19497 if (proc.baseProcessTracker != null) {
19498 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19500 if (proc.repProcState >= 0) {
19501 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
19502 proc.repProcState);
19507 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19508 ProcessRecord TOP_APP, boolean doingAll, long now) {
19509 if (app.thread == null) {
19513 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19515 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19518 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19520 if (isForeground != proc.foregroundServices) {
19521 proc.foregroundServices = isForeground;
19522 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19524 if (isForeground) {
19525 if (curProcs == null) {
19526 curProcs = new ArrayList<ProcessRecord>();
19527 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19529 if (!curProcs.contains(proc)) {
19530 curProcs.add(proc);
19531 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19532 proc.info.packageName, proc.info.uid);
19535 if (curProcs != null) {
19536 if (curProcs.remove(proc)) {
19537 mBatteryStatsService.noteEvent(
19538 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19539 proc.info.packageName, proc.info.uid);
19540 if (curProcs.size() <= 0) {
19541 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19547 updateOomAdjLocked();
19552 private final ActivityRecord resumedAppLocked() {
19553 ActivityRecord act = mStackSupervisor.resumedAppLocked();
19557 pkg = act.packageName;
19558 uid = act.info.applicationInfo.uid;
19563 // Has the UID or resumed package name changed?
19564 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19565 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19566 if (mCurResumedPackage != null) {
19567 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19568 mCurResumedPackage, mCurResumedUid);
19570 mCurResumedPackage = pkg;
19571 mCurResumedUid = uid;
19572 if (mCurResumedPackage != null) {
19573 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19574 mCurResumedPackage, mCurResumedUid);
19580 final boolean updateOomAdjLocked(ProcessRecord app) {
19581 final ActivityRecord TOP_ACT = resumedAppLocked();
19582 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19583 final boolean wasCached = app.cached;
19587 // This is the desired cached adjusment we want to tell it to use.
19588 // If our app is currently cached, we know it, and that is it. Otherwise,
19589 // we don't know it yet, and it needs to now be cached we will then
19590 // need to do a complete oom adj.
19591 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19592 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19593 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19594 SystemClock.uptimeMillis());
19595 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19596 // Changed to/from cached state, so apps after it in the LRU
19597 // list may also be changed.
19598 updateOomAdjLocked();
19603 final void updateOomAdjLocked() {
19604 final ActivityRecord TOP_ACT = resumedAppLocked();
19605 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19606 final long now = SystemClock.uptimeMillis();
19607 final long nowElapsed = SystemClock.elapsedRealtime();
19608 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19609 final int N = mLruProcesses.size();
19612 RuntimeException e = new RuntimeException();
19613 e.fillInStackTrace();
19614 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19617 // Reset state in all uid records.
19618 for (int i=mActiveUids.size()-1; i>=0; i--) {
19619 final UidRecord uidRec = mActiveUids.valueAt(i);
19620 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19621 "Starting update of " + uidRec);
19625 mStackSupervisor.rankTaskLayersIfNeeded();
19628 mNewNumServiceProcs = 0;
19629 mNewNumAServiceProcs = 0;
19631 final int emptyProcessLimit;
19632 final int cachedProcessLimit;
19633 if (mProcessLimit <= 0) {
19634 emptyProcessLimit = cachedProcessLimit = 0;
19635 } else if (mProcessLimit == 1) {
19636 emptyProcessLimit = 1;
19637 cachedProcessLimit = 0;
19639 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19640 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19643 // Let's determine how many processes we have running vs.
19644 // how many slots we have for background processes; we may want
19645 // to put multiple processes in a slot of there are enough of
19647 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19648 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19649 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19650 if (numEmptyProcs > cachedProcessLimit) {
19651 // If there are more empty processes than our limit on cached
19652 // processes, then use the cached process limit for the factor.
19653 // This ensures that the really old empty processes get pushed
19654 // down to the bottom, so if we are running low on memory we will
19655 // have a better chance at keeping around more cached processes
19656 // instead of a gazillion empty processes.
19657 numEmptyProcs = cachedProcessLimit;
19659 int emptyFactor = numEmptyProcs/numSlots;
19660 if (emptyFactor < 1) emptyFactor = 1;
19661 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19662 if (cachedFactor < 1) cachedFactor = 1;
19663 int stepCached = 0;
19667 int numTrimming = 0;
19669 mNumNonCachedProcs = 0;
19670 mNumCachedHiddenProcs = 0;
19672 // First update the OOM adjustment for each of the
19673 // application processes based on their current state.
19674 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19675 int nextCachedAdj = curCachedAdj+1;
19676 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19677 int nextEmptyAdj = curEmptyAdj+2;
19678 for (int i=N-1; i>=0; i--) {
19679 ProcessRecord app = mLruProcesses.get(i);
19680 if (!app.killedByAm && app.thread != null) {
19681 app.procStateChanged = false;
19682 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19684 // If we haven't yet assigned the final cached adj
19685 // to the process, do that now.
19686 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19687 switch (app.curProcState) {
19688 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19689 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19690 // This process is a cached process holding activities...
19691 // assign it the next cached value for that type, and then
19692 // step that cached level.
19693 app.curRawAdj = curCachedAdj;
19694 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19695 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19696 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19698 if (curCachedAdj != nextCachedAdj) {
19700 if (stepCached >= cachedFactor) {
19702 curCachedAdj = nextCachedAdj;
19703 nextCachedAdj += 2;
19704 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19705 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19711 // For everything else, assign next empty cached process
19712 // level and bump that up. Note that this means that
19713 // long-running services that have dropped down to the
19714 // cached level will be treated as empty (since their process
19715 // state is still as a service), which is what we want.
19716 app.curRawAdj = curEmptyAdj;
19717 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19718 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19719 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19721 if (curEmptyAdj != nextEmptyAdj) {
19723 if (stepEmpty >= emptyFactor) {
19725 curEmptyAdj = nextEmptyAdj;
19727 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19728 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19736 applyOomAdjLocked(app, true, now, nowElapsed);
19738 // Count the number of process types.
19739 switch (app.curProcState) {
19740 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19741 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19742 mNumCachedHiddenProcs++;
19744 if (numCached > cachedProcessLimit) {
19745 app.kill("cached #" + numCached, true);
19748 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19749 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19750 && app.lastActivityTime < oldTime) {
19751 app.kill("empty for "
19752 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19753 / 1000) + "s", true);
19756 if (numEmpty > emptyProcessLimit) {
19757 app.kill("empty #" + numEmpty, true);
19762 mNumNonCachedProcs++;
19766 if (app.isolated && app.services.size() <= 0) {
19767 // If this is an isolated process, and there are no
19768 // services running in it, then the process is no longer
19769 // needed. We agressively kill these because we can by
19770 // definition not re-use the same process again, and it is
19771 // good to avoid having whatever code was running in them
19772 // left sitting around after no longer needed.
19773 app.kill("isolated not needed", true);
19775 // Keeping this process, update its uid.
19776 final UidRecord uidRec = app.uidRecord;
19777 if (uidRec != null && uidRec.curProcState > app.curProcState) {
19778 uidRec.curProcState = app.curProcState;
19782 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19783 && !app.killedByAm) {
19789 mNumServiceProcs = mNewNumServiceProcs;
19791 // Now determine the memory trimming level of background processes.
19792 // Unfortunately we need to start at the back of the list to do this
19793 // properly. We only do this if the number of background apps we
19794 // are managing to keep around is less than half the maximum we desire;
19795 // if we are keeping a good number around, we'll let them use whatever
19796 // memory they want.
19797 final int numCachedAndEmpty = numCached + numEmpty;
19799 if (numCached <= ProcessList.TRIM_CACHED_APPS
19800 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19801 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19802 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19803 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19804 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19806 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19809 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19811 // We always allow the memory level to go up (better). We only allow it to go
19812 // down if we are in a state where that is allowed, *and* the total number of processes
19813 // has gone down since last time.
19814 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19815 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19816 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19817 if (memFactor > mLastMemoryLevel) {
19818 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19819 memFactor = mLastMemoryLevel;
19820 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19823 mLastMemoryLevel = memFactor;
19824 mLastNumProcesses = mLruProcesses.size();
19825 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19826 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19827 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19828 if (mLowRamStartTime == 0) {
19829 mLowRamStartTime = now;
19833 switch (memFactor) {
19834 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19835 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19837 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19838 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19841 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19844 int factor = numTrimming/3;
19846 if (mHomeProcess != null) minFactor++;
19847 if (mPreviousProcess != null) minFactor++;
19848 if (factor < minFactor) factor = minFactor;
19849 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19850 for (int i=N-1; i>=0; i--) {
19851 ProcessRecord app = mLruProcesses.get(i);
19852 if (allChanged || app.procStateChanged) {
19853 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19854 app.procStateChanged = false;
19856 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19857 && !app.killedByAm) {
19858 if (app.trimMemoryLevel < curLevel && app.thread != null) {
19860 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19861 "Trimming memory of " + app.processName + " to " + curLevel);
19862 app.thread.scheduleTrimMemory(curLevel);
19863 } catch (RemoteException e) {
19866 // For now we won't do this; our memory trimming seems
19867 // to be good enough at this point that destroying
19868 // activities causes more harm than good.
19869 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19870 && app != mHomeProcess && app != mPreviousProcess) {
19871 // Need to do this on its own message because the stack may not
19872 // be in a consistent state at this point.
19873 // For these apps we will also finish their activities
19874 // to help them free memory.
19875 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19879 app.trimMemoryLevel = curLevel;
19881 if (step >= factor) {
19883 switch (curLevel) {
19884 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19885 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19887 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19888 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19892 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19893 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19894 && app.thread != null) {
19896 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19897 "Trimming memory of heavy-weight " + app.processName
19898 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19899 app.thread.scheduleTrimMemory(
19900 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19901 } catch (RemoteException e) {
19904 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19906 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19907 || app.systemNoUi) && app.pendingUiClean) {
19908 // If this application is now in the background and it
19909 // had done UI, then give it the special trim level to
19910 // have it free UI resources.
19911 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19912 if (app.trimMemoryLevel < level && app.thread != null) {
19914 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19915 "Trimming memory of bg-ui " + app.processName
19917 app.thread.scheduleTrimMemory(level);
19918 } catch (RemoteException e) {
19921 app.pendingUiClean = false;
19923 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19925 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19926 "Trimming memory of fg " + app.processName
19927 + " to " + fgTrimLevel);
19928 app.thread.scheduleTrimMemory(fgTrimLevel);
19929 } catch (RemoteException e) {
19932 app.trimMemoryLevel = fgTrimLevel;
19936 if (mLowRamStartTime != 0) {
19937 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19938 mLowRamStartTime = 0;
19940 for (int i=N-1; i>=0; i--) {
19941 ProcessRecord app = mLruProcesses.get(i);
19942 if (allChanged || app.procStateChanged) {
19943 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19944 app.procStateChanged = false;
19946 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19947 || app.systemNoUi) && app.pendingUiClean) {
19948 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19949 && app.thread != null) {
19951 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19952 "Trimming memory of ui hidden " + app.processName
19953 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19954 app.thread.scheduleTrimMemory(
19955 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19956 } catch (RemoteException e) {
19959 app.pendingUiClean = false;
19961 app.trimMemoryLevel = 0;
19965 if (mAlwaysFinishActivities) {
19966 // Need to do this on its own message because the stack may not
19967 // be in a consistent state at this point.
19968 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19972 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19975 // Update from any uid changes.
19976 for (int i=mActiveUids.size()-1; i>=0; i--) {
19977 final UidRecord uidRec = mActiveUids.valueAt(i);
19978 int uidChange = UidRecord.CHANGE_PROCSTATE;
19979 if (uidRec.setProcState != uidRec.curProcState) {
19980 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19981 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19982 + " to " + uidRec.curProcState);
19983 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
19984 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
19985 uidRec.lastBackgroundTime = nowElapsed;
19986 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
19987 // Note: the background settle time is in elapsed realtime, while
19988 // the handler time base is uptime. All this means is that we may
19989 // stop background uids later than we had intended, but that only
19990 // happens because the device was sleeping so we are okay anyway.
19991 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
19996 uidChange = UidRecord.CHANGE_ACTIVE;
19997 uidRec.idle = false;
19999 uidRec.lastBackgroundTime = 0;
20001 uidRec.setProcState = uidRec.curProcState;
20002 enqueueUidChangeLocked(uidRec, -1, uidChange);
20006 if (mProcessStats.shouldWriteNowLocked(now)) {
20007 mHandler.post(new Runnable() {
20008 @Override public void run() {
20009 synchronized (ActivityManagerService.this) {
20010 mProcessStats.writeStateAsyncLocked();
20016 if (DEBUG_OOM_ADJ) {
20017 final long duration = SystemClock.uptimeMillis() - now;
20019 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20020 new RuntimeException("here").fillInStackTrace());
20022 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20027 final void idleUids() {
20028 synchronized (this) {
20029 final long nowElapsed = SystemClock.elapsedRealtime();
20030 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20032 for (int i=mActiveUids.size()-1; i>=0; i--) {
20033 final UidRecord uidRec = mActiveUids.valueAt(i);
20034 final long bgTime = uidRec.lastBackgroundTime;
20035 if (bgTime > 0 && !uidRec.idle) {
20036 if (bgTime <= maxBgTime) {
20037 uidRec.idle = true;
20038 doStopUidLocked(uidRec.uid, uidRec);
20040 if (nextTime == 0 || nextTime > bgTime) {
20046 if (nextTime > 0) {
20047 mHandler.removeMessages(IDLE_UIDS_MSG);
20048 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20049 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20054 final void runInBackgroundDisabled(int uid) {
20055 synchronized (this) {
20056 UidRecord uidRec = mActiveUids.get(uid);
20057 if (uidRec != null) {
20058 // This uid is actually running... should it be considered background now?
20060 doStopUidLocked(uidRec.uid, uidRec);
20063 // This uid isn't actually running... still send a report about it being "stopped".
20064 doStopUidLocked(uid, null);
20069 final void doStopUidLocked(int uid, final UidRecord uidRec) {
20070 mServices.stopInBackgroundLocked(uid);
20071 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20074 final void trimApplications() {
20075 synchronized (this) {
20078 // First remove any unused application processes whose package
20079 // has been removed.
20080 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20081 final ProcessRecord app = mRemovedProcesses.get(i);
20082 if (app.activities.size() == 0
20083 && app.curReceiver == null && app.services.size() == 0) {
20085 TAG, "Exiting empty application process "
20086 + app.processName + " ("
20087 + (app.thread != null ? app.thread.asBinder() : null)
20089 if (app.pid > 0 && app.pid != MY_PID) {
20090 app.kill("empty", false);
20093 app.thread.scheduleExit();
20094 } catch (Exception e) {
20095 // Ignore exceptions.
20098 cleanUpApplicationRecordLocked(app, false, true, -1);
20099 mRemovedProcesses.remove(i);
20101 if (app.persistent) {
20102 addAppLocked(app.info, false, null /* ABI override */);
20107 // Now update the oom adj for all processes.
20108 updateOomAdjLocked();
20112 /** This method sends the specified signal to each of the persistent apps */
20113 public void signalPersistentProcesses(int sig) throws RemoteException {
20114 if (sig != Process.SIGNAL_USR1) {
20115 throw new SecurityException("Only SIGNAL_USR1 is allowed");
20118 synchronized (this) {
20119 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20120 != PackageManager.PERMISSION_GRANTED) {
20121 throw new SecurityException("Requires permission "
20122 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20125 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20126 ProcessRecord r = mLruProcesses.get(i);
20127 if (r.thread != null && r.persistent) {
20128 Process.sendSignal(r.pid, sig);
20134 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20135 if (proc == null || proc == mProfileProc) {
20136 proc = mProfileProc;
20137 profileType = mProfileType;
20138 clearProfilerLocked();
20140 if (proc == null) {
20144 proc.thread.profilerControl(false, null, profileType);
20145 } catch (RemoteException e) {
20146 throw new IllegalStateException("Process disappeared");
20150 private void clearProfilerLocked() {
20151 if (mProfileFd != null) {
20153 mProfileFd.close();
20154 } catch (IOException e) {
20157 mProfileApp = null;
20158 mProfileProc = null;
20159 mProfileFile = null;
20161 mAutoStopProfiler = false;
20162 mSamplingInterval = 0;
20165 public boolean profileControl(String process, int userId, boolean start,
20166 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20169 synchronized (this) {
20170 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20171 // its own permission.
20172 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20173 != PackageManager.PERMISSION_GRANTED) {
20174 throw new SecurityException("Requires permission "
20175 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20178 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20179 throw new IllegalArgumentException("null profile info or fd");
20182 ProcessRecord proc = null;
20183 if (process != null) {
20184 proc = findProcessLocked(process, userId, "profileControl");
20187 if (start && (proc == null || proc.thread == null)) {
20188 throw new IllegalArgumentException("Unknown process: " + process);
20192 stopProfilerLocked(null, 0);
20193 setProfileApp(proc.info, proc.processName, profilerInfo);
20194 mProfileProc = proc;
20195 mProfileType = profileType;
20196 ParcelFileDescriptor fd = profilerInfo.profileFd;
20199 } catch (IOException e) {
20202 profilerInfo.profileFd = fd;
20203 proc.thread.profilerControl(start, profilerInfo, profileType);
20207 stopProfilerLocked(proc, profileType);
20208 if (profilerInfo != null && profilerInfo.profileFd != null) {
20210 profilerInfo.profileFd.close();
20211 } catch (IOException e) {
20218 } catch (RemoteException e) {
20219 throw new IllegalStateException("Process disappeared");
20221 if (profilerInfo != null && profilerInfo.profileFd != null) {
20223 profilerInfo.profileFd.close();
20224 } catch (IOException e) {
20230 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20231 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20232 userId, true, ALLOW_FULL_ONLY, callName, null);
20233 ProcessRecord proc = null;
20235 int pid = Integer.parseInt(process);
20236 synchronized (mPidsSelfLocked) {
20237 proc = mPidsSelfLocked.get(pid);
20239 } catch (NumberFormatException e) {
20242 if (proc == null) {
20243 ArrayMap<String, SparseArray<ProcessRecord>> all
20244 = mProcessNames.getMap();
20245 SparseArray<ProcessRecord> procs = all.get(process);
20246 if (procs != null && procs.size() > 0) {
20247 proc = procs.valueAt(0);
20248 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20249 for (int i=1; i<procs.size(); i++) {
20250 ProcessRecord thisProc = procs.valueAt(i);
20251 if (thisProc.userId == userId) {
20263 public boolean dumpHeap(String process, int userId, boolean managed,
20264 String path, ParcelFileDescriptor fd) throws RemoteException {
20267 synchronized (this) {
20268 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20269 // its own permission (same as profileControl).
20270 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20271 != PackageManager.PERMISSION_GRANTED) {
20272 throw new SecurityException("Requires permission "
20273 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20277 throw new IllegalArgumentException("null fd");
20280 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20281 if (proc == null || proc.thread == null) {
20282 throw new IllegalArgumentException("Unknown process: " + process);
20285 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20286 if (!isDebuggable) {
20287 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20288 throw new SecurityException("Process not debuggable: " + proc);
20292 proc.thread.dumpHeap(managed, path, fd);
20296 } catch (RemoteException e) {
20297 throw new IllegalStateException("Process disappeared");
20302 } catch (IOException e) {
20309 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20310 String reportPackage) {
20311 if (processName != null) {
20312 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20313 "setDumpHeapDebugLimit()");
20315 synchronized (mPidsSelfLocked) {
20316 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20317 if (proc == null) {
20318 throw new SecurityException("No process found for calling pid "
20319 + Binder.getCallingPid());
20321 if (!Build.IS_DEBUGGABLE
20322 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20323 throw new SecurityException("Not running a debuggable build");
20325 processName = proc.processName;
20327 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20328 throw new SecurityException("Package " + reportPackage + " is not running in "
20333 synchronized (this) {
20334 if (maxMemSize > 0) {
20335 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20338 mMemWatchProcesses.remove(processName, uid);
20340 mMemWatchProcesses.getMap().remove(processName);
20347 public void dumpHeapFinished(String path) {
20348 synchronized (this) {
20349 if (Binder.getCallingPid() != mMemWatchDumpPid) {
20350 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20351 + " does not match last pid " + mMemWatchDumpPid);
20354 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20355 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20356 + " does not match last path " + mMemWatchDumpFile);
20359 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20360 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20364 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20365 public void monitor() {
20366 synchronized (this) { }
20369 void onCoreSettingsChange(Bundle settings) {
20370 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20371 ProcessRecord processRecord = mLruProcesses.get(i);
20373 if (processRecord.thread != null) {
20374 processRecord.thread.setCoreSettings(settings);
20376 } catch (RemoteException re) {
20382 // Multi-user methods
20385 * Start user, if its not already running, but don't bring it to foreground.
20388 public boolean startUserInBackground(final int userId) {
20389 return mUserController.startUser(userId, /* foreground */ false);
20393 public boolean unlockUser(int userId, byte[] token) {
20394 return mUserController.unlockUser(userId, token);
20398 public boolean switchUser(final int targetUserId) {
20399 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20400 UserInfo currentUserInfo;
20401 UserInfo targetUserInfo;
20402 synchronized (this) {
20403 int currentUserId = mUserController.getCurrentUserIdLocked();
20404 currentUserInfo = mUserController.getUserInfo(currentUserId);
20405 targetUserInfo = mUserController.getUserInfo(targetUserId);
20406 if (targetUserInfo == null) {
20407 Slog.w(TAG, "No user info for user #" + targetUserId);
20410 if (targetUserInfo.isManagedProfile()) {
20411 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20414 mUserController.setTargetUserIdLocked(targetUserId);
20416 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20417 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20418 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20422 void scheduleStartProfilesLocked() {
20423 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20424 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20425 DateUtils.SECOND_IN_MILLIS);
20430 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20431 return mUserController.stopUser(userId, force, callback);
20434 void onUserRemovedLocked(int userId) {
20435 mRecentTasks.removeTasksForUserLocked(userId);
20439 public UserInfo getCurrentUser() {
20440 return mUserController.getCurrentUser();
20444 public boolean isUserRunning(int userId, int flags) {
20445 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20446 != PackageManager.PERMISSION_GRANTED) {
20447 String msg = "Permission Denial: isUserRunning() from pid="
20448 + Binder.getCallingPid()
20449 + ", uid=" + Binder.getCallingUid()
20450 + " requires " + INTERACT_ACROSS_USERS;
20452 throw new SecurityException(msg);
20454 synchronized (this) {
20455 return mUserController.isUserRunningLocked(userId, flags);
20460 public int[] getRunningUserIds() {
20461 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20462 != PackageManager.PERMISSION_GRANTED) {
20463 String msg = "Permission Denial: isUserRunning() from pid="
20464 + Binder.getCallingPid()
20465 + ", uid=" + Binder.getCallingUid()
20466 + " requires " + INTERACT_ACROSS_USERS;
20468 throw new SecurityException(msg);
20470 synchronized (this) {
20471 return mUserController.getStartedUserArrayLocked();
20476 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20477 mUserController.registerUserSwitchObserver(observer);
20481 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20482 mUserController.unregisterUserSwitchObserver(observer);
20485 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20486 if (info == null) return null;
20487 ApplicationInfo newInfo = new ApplicationInfo(info);
20488 newInfo.initForUser(userId);
20492 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20494 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20498 ActivityInfo info = new ActivityInfo(aInfo);
20499 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20503 private boolean processSanityChecksLocked(ProcessRecord process) {
20504 if (process == null || process.thread == null) {
20508 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20509 if (!isDebuggable) {
20510 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20518 public boolean startBinderTracking() throws RemoteException {
20519 synchronized (this) {
20520 mBinderTransactionTrackingEnabled = true;
20521 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20522 // permission (same as profileControl).
20523 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20524 != PackageManager.PERMISSION_GRANTED) {
20525 throw new SecurityException("Requires permission "
20526 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20529 for (int i = 0; i < mLruProcesses.size(); i++) {
20530 ProcessRecord process = mLruProcesses.get(i);
20531 if (!processSanityChecksLocked(process)) {
20535 process.thread.startBinderTracking();
20536 } catch (RemoteException e) {
20537 Log.v(TAG, "Process disappared");
20544 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20546 synchronized (this) {
20547 mBinderTransactionTrackingEnabled = false;
20548 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20549 // permission (same as profileControl).
20550 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20551 != PackageManager.PERMISSION_GRANTED) {
20552 throw new SecurityException("Requires permission "
20553 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20557 throw new IllegalArgumentException("null fd");
20560 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20561 pw.println("Binder transaction traces for all processes.\n");
20562 for (ProcessRecord process : mLruProcesses) {
20563 if (!processSanityChecksLocked(process)) {
20567 pw.println("Traces for process: " + process.processName);
20570 TransferPipe tp = new TransferPipe();
20572 process.thread.stopBinderTrackingAndDump(
20573 tp.getWriteFd().getFileDescriptor());
20574 tp.go(fd.getFileDescriptor());
20578 } catch (IOException e) {
20579 pw.println("Failure while dumping IPC traces from " + process +
20580 ". Exception: " + e);
20582 } catch (RemoteException e) {
20583 pw.println("Got a RemoteException while dumping IPC traces from " +
20584 process + ". Exception: " + e);
20595 } catch (IOException e) {
20601 void stopReportingCrashesLocked(ProcessRecord proc) {
20602 if (mAppsNotReportingCrashes == null) {
20603 mAppsNotReportingCrashes = new ArraySet<>();
20605 mAppsNotReportingCrashes.add(proc.info.packageName);
20608 private final class LocalService extends ActivityManagerInternal {
20610 public void onWakefulnessChanged(int wakefulness) {
20611 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20615 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20616 String processName, String abiOverride, int uid, Runnable crashHandler) {
20617 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20618 processName, abiOverride, uid, crashHandler);
20622 public SleepToken acquireSleepToken(String tag) {
20623 Preconditions.checkNotNull(tag);
20625 synchronized (ActivityManagerService.this) {
20626 SleepTokenImpl token = new SleepTokenImpl(tag);
20627 mSleepTokens.add(token);
20628 updateSleepIfNeededLocked();
20634 public ComponentName getHomeActivityForUser(int userId) {
20635 synchronized (ActivityManagerService.this) {
20636 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20637 return homeActivity == null ? null : homeActivity.realActivity;
20642 public void onUserRemoved(int userId) {
20643 synchronized (ActivityManagerService.this) {
20644 ActivityManagerService.this.onUserRemovedLocked(userId);
20649 private final class SleepTokenImpl extends SleepToken {
20650 private final String mTag;
20651 private final long mAcquireTime;
20653 public SleepTokenImpl(String tag) {
20655 mAcquireTime = SystemClock.uptimeMillis();
20659 public void release() {
20660 synchronized (ActivityManagerService.this) {
20661 if (mSleepTokens.remove(this)) {
20662 updateSleepIfNeededLocked();
20668 public String toString() {
20669 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20674 * An implementation of IAppTask, that allows an app to manage its own tasks via
20675 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
20676 * only the process that calls getAppTasks() can call the AppTask methods.
20678 class AppTaskImpl extends IAppTask.Stub {
20679 private int mTaskId;
20680 private int mCallingUid;
20682 public AppTaskImpl(int taskId, int callingUid) {
20684 mCallingUid = callingUid;
20687 private void checkCaller() {
20688 if (mCallingUid != Binder.getCallingUid()) {
20689 throw new SecurityException("Caller " + mCallingUid
20690 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20695 public void finishAndRemoveTask() {
20698 synchronized (ActivityManagerService.this) {
20699 long origId = Binder.clearCallingIdentity();
20701 // We remove the task from recents to preserve backwards
20702 if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
20703 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20706 Binder.restoreCallingIdentity(origId);
20712 public ActivityManager.RecentTaskInfo getTaskInfo() {
20715 synchronized (ActivityManagerService.this) {
20716 long origId = Binder.clearCallingIdentity();
20718 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20720 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20722 return createRecentTaskInfoFromTaskRecord(tr);
20724 Binder.restoreCallingIdentity(origId);
20730 public void moveToFront() {
20732 // Will bring task to front if it already has a root activity.
20733 startActivityFromRecentsInner(mTaskId, INVALID_STACK_ID, null);
20737 public int startActivity(IBinder whoThread, String callingPackage,
20738 Intent intent, String resolvedType, Bundle bOptions) {
20741 int callingUser = UserHandle.getCallingUserId();
20743 IApplicationThread appThread;
20744 synchronized (ActivityManagerService.this) {
20745 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20747 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20749 appThread = ApplicationThreadNative.asInterface(whoThread);
20750 if (appThread == null) {
20751 throw new IllegalArgumentException("Bad app thread " + appThread);
20754 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20755 resolvedType, null, null, null, null, 0, 0, null, null,
20756 null, bOptions, false, callingUser, null, tr);
20760 public void setExcludeFromRecents(boolean exclude) {
20763 synchronized (ActivityManagerService.this) {
20764 long origId = Binder.clearCallingIdentity();
20766 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20768 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20770 Intent intent = tr.getBaseIntent();
20772 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20774 intent.setFlags(intent.getFlags()
20775 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20778 Binder.restoreCallingIdentity(origId);