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.ActivityStackSupervisor.HOME_STACK_ID;
32 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
33 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
34 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
35 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
36 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
37 import static org.xmlpull.v1.XmlPullParser.START_TAG;
39 import android.Manifest;
40 import android.app.AppOpsManager;
41 import android.app.ApplicationThreadNative;
42 import android.app.BroadcastOptions;
43 import android.app.IActivityContainer;
44 import android.app.IActivityContainerCallback;
45 import android.app.IAppTask;
46 import android.app.ITaskStackListener;
47 import android.app.ProfilerInfo;
48 import android.app.assist.AssistContent;
49 import android.app.assist.AssistStructure;
50 import android.app.usage.UsageEvents;
51 import android.app.usage.UsageStatsManagerInternal;
52 import android.appwidget.AppWidgetManager;
53 import android.content.pm.PermissionInfo;
54 import android.content.res.Resources;
55 import android.graphics.Bitmap;
56 import android.graphics.Point;
57 import android.graphics.Rect;
58 import android.os.BatteryStats;
59 import android.os.PersistableBundle;
60 import android.os.PowerManager;
61 import android.os.Trace;
62 import android.os.TransactionTooLargeException;
63 import android.os.WorkSource;
64 import android.os.storage.IMountService;
65 import android.os.storage.MountServiceInternal;
66 import android.os.storage.StorageManager;
67 import android.service.voice.IVoiceInteractionSession;
68 import android.service.voice.VoiceInteractionSession;
69 import android.util.ArrayMap;
70 import android.util.ArraySet;
71 import android.util.DebugUtils;
72 import android.util.SparseIntArray;
73 import android.view.Display;
75 import com.android.internal.R;
76 import com.android.internal.annotations.GuardedBy;
77 import com.android.internal.app.AssistUtils;
78 import com.android.internal.app.DumpHeapActivity;
79 import com.android.internal.app.IAppOpsService;
80 import com.android.internal.app.IVoiceInteractor;
81 import com.android.internal.app.ProcessMap;
82 import com.android.internal.app.ProcessStats;
83 import com.android.internal.os.BackgroundThread;
84 import com.android.internal.os.BatteryStatsImpl;
85 import com.android.internal.os.IResultReceiver;
86 import com.android.internal.os.ProcessCpuTracker;
87 import com.android.internal.os.TransferPipe;
88 import com.android.internal.os.Zygote;
89 import com.android.internal.util.ArrayUtils;
90 import com.android.internal.util.FastPrintWriter;
91 import com.android.internal.util.FastXmlSerializer;
92 import com.android.internal.util.MemInfoReader;
93 import com.android.internal.util.Preconditions;
94 import com.android.server.AppOpsService;
95 import com.android.server.AttributeCache;
96 import com.android.server.DeviceIdleController;
97 import com.android.server.IntentResolver;
98 import com.android.server.LocalServices;
99 import com.android.server.ServiceThread;
100 import com.android.server.SystemService;
101 import com.android.server.SystemServiceManager;
102 import com.android.server.Watchdog;
103 import com.android.server.am.ActivityStack.ActivityState;
104 import com.android.server.firewall.IntentFirewall;
105 import com.android.server.pm.Installer;
106 import com.android.server.pm.UserManagerService;
107 import com.android.server.statusbar.StatusBarManagerInternal;
108 import com.android.server.wm.AppTransition;
109 import com.android.server.wm.WindowManagerService;
110 import com.google.android.collect.Lists;
111 import com.google.android.collect.Maps;
113 import libcore.io.IoUtils;
114 import libcore.util.EmptyArray;
116 import org.xmlpull.v1.XmlPullParser;
117 import org.xmlpull.v1.XmlPullParserException;
118 import org.xmlpull.v1.XmlSerializer;
120 import android.app.Activity;
121 import android.app.ActivityManager;
122 import android.app.ActivityManager.RunningTaskInfo;
123 import android.app.ActivityManager.StackInfo;
124 import android.app.ActivityManagerInternal;
125 import android.app.ActivityManagerInternal.SleepToken;
126 import android.app.ActivityManagerNative;
127 import android.app.ActivityOptions;
128 import android.app.ActivityThread;
129 import android.app.AlertDialog;
130 import android.app.AppGlobals;
131 import android.app.ApplicationErrorReport;
132 import android.app.Dialog;
133 import android.app.IActivityController;
134 import android.app.IApplicationThread;
135 import android.app.IInstrumentationWatcher;
136 import android.app.INotificationManager;
137 import android.app.IProcessObserver;
138 import android.app.IServiceConnection;
139 import android.app.IStopUserCallback;
140 import android.app.IUidObserver;
141 import android.app.IUiAutomationConnection;
142 import android.app.IUserSwitchObserver;
143 import android.app.Instrumentation;
144 import android.app.Notification;
145 import android.app.NotificationManager;
146 import android.app.PendingIntent;
147 import android.app.backup.IBackupManager;
148 import android.app.admin.DevicePolicyManager;
149 import android.content.ActivityNotFoundException;
150 import android.content.BroadcastReceiver;
151 import android.content.ClipData;
152 import android.content.ComponentCallbacks2;
153 import android.content.ComponentName;
154 import android.content.ContentProvider;
155 import android.content.ContentResolver;
156 import android.content.Context;
157 import android.content.DialogInterface;
158 import android.content.IContentProvider;
159 import android.content.IIntentReceiver;
160 import android.content.IIntentSender;
161 import android.content.Intent;
162 import android.content.IntentFilter;
163 import android.content.IntentSender;
164 import android.content.pm.ActivityInfo;
165 import android.content.pm.ApplicationInfo;
166 import android.content.pm.ConfigurationInfo;
167 import android.content.pm.IPackageDataObserver;
168 import android.content.pm.IPackageManager;
169 import android.content.pm.InstrumentationInfo;
170 import android.content.pm.PackageInfo;
171 import android.content.pm.PackageManager;
172 import android.content.pm.ParceledListSlice;
173 import android.content.pm.UserInfo;
174 import android.content.pm.PackageManager.NameNotFoundException;
175 import android.content.pm.PathPermission;
176 import android.content.pm.ProviderInfo;
177 import android.content.pm.ResolveInfo;
178 import android.content.pm.ServiceInfo;
179 import android.content.res.CompatibilityInfo;
180 import android.content.res.Configuration;
181 import android.net.Proxy;
182 import android.net.ProxyInfo;
183 import android.net.Uri;
184 import android.os.Binder;
185 import android.os.Build;
186 import android.os.Bundle;
187 import android.os.Debug;
188 import android.os.DropBoxManager;
189 import android.os.Environment;
190 import android.os.FactoryTest;
191 import android.os.FileObserver;
192 import android.os.FileUtils;
193 import android.os.Handler;
194 import android.os.IBinder;
195 import android.os.IPermissionController;
196 import android.os.IProcessInfoService;
197 import android.os.IRemoteCallback;
198 import android.os.IUserManager;
199 import android.os.Looper;
200 import android.os.Message;
201 import android.os.Parcel;
202 import android.os.ParcelFileDescriptor;
203 import android.os.PowerManagerInternal;
204 import android.os.Process;
205 import android.os.RemoteCallbackList;
206 import android.os.RemoteException;
207 import android.os.SELinux;
208 import android.os.ServiceManager;
209 import android.os.StrictMode;
210 import android.os.SystemClock;
211 import android.os.SystemProperties;
212 import android.os.UpdateLock;
213 import android.os.UserHandle;
214 import android.os.UserManager;
215 import android.provider.Downloads;
216 import android.provider.Settings;
217 import android.telecom.TelecomManager;
218 import android.text.format.DateUtils;
219 import android.text.format.Time;
220 import android.util.AtomicFile;
221 import android.util.EventLog;
222 import android.util.Log;
223 import android.util.Pair;
224 import android.util.PrintWriterPrinter;
225 import android.util.Slog;
226 import android.util.SparseArray;
227 import android.util.TimeUtils;
228 import android.util.Xml;
229 import android.view.Gravity;
230 import android.view.LayoutInflater;
231 import android.view.View;
232 import android.view.WindowManager;
234 import dalvik.system.VMRuntime;
236 import java.io.BufferedInputStream;
237 import java.io.BufferedOutputStream;
238 import java.io.DataInputStream;
239 import java.io.DataOutputStream;
241 import java.io.FileDescriptor;
242 import java.io.FileInputStream;
243 import java.io.FileNotFoundException;
244 import java.io.FileOutputStream;
245 import java.io.IOException;
246 import java.io.InputStreamReader;
247 import java.io.PrintWriter;
248 import java.io.StringWriter;
249 import java.lang.ref.WeakReference;
250 import java.nio.charset.StandardCharsets;
251 import java.util.ArrayList;
252 import java.util.Arrays;
253 import java.util.Collections;
254 import java.util.Comparator;
255 import java.util.HashMap;
256 import java.util.HashSet;
257 import java.util.Iterator;
258 import java.util.List;
259 import java.util.Locale;
260 import java.util.Map;
261 import java.util.Set;
262 import java.util.concurrent.atomic.AtomicBoolean;
263 import java.util.concurrent.atomic.AtomicLong;
265 public final class ActivityManagerService extends ActivityManagerNative
266 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
268 // File that stores last updated system version and called preboot receivers
269 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
271 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
272 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
273 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
274 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
275 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
276 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
277 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
278 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
279 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
280 private static final String TAG_LRU = TAG + POSTFIX_LRU;
281 private static final String TAG_MU = TAG + POSTFIX_MU;
282 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
283 private static final String TAG_POWER = TAG + POSTFIX_POWER;
284 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
285 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
286 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
287 private static final String TAG_PSS = TAG + POSTFIX_PSS;
288 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
289 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
290 private static final String TAG_STACK = TAG + POSTFIX_STACK;
291 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
292 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
293 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
294 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
295 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
297 /** Control over CPU and battery monitoring */
298 // write battery stats every 30 minutes.
299 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
300 static final boolean MONITOR_CPU_USAGE = true;
301 // don't sample cpu less than every 5 seconds.
302 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
303 // wait possibly forever for next cpu sample.
304 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
305 static final boolean MONITOR_THREAD_CPU_USAGE = false;
307 // The flags that are set for all calls we make to the package manager.
308 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
310 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
312 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
314 // Amount of time after a call to stopAppSwitches() during which we will
315 // prevent further untrusted switches from happening.
316 static final long APP_SWITCH_DELAY_TIME = 5*1000;
318 // How long we wait for a launched process to attach to the activity manager
319 // before we decide it's never going to come up for real.
320 static final int PROC_START_TIMEOUT = 10*1000;
322 // How long we wait for a launched process to attach to the activity manager
323 // before we decide it's never going to come up for real, when the process was
324 // started with a wrapper for instrumentation (such as Valgrind) because it
325 // could take much longer than usual.
326 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
328 // How long to wait after going idle before forcing apps to GC.
329 static final int GC_TIMEOUT = 5*1000;
331 // The minimum amount of time between successive GC requests for a process.
332 static final int GC_MIN_INTERVAL = 60*1000;
334 // The minimum amount of time between successive PSS requests for a process.
335 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
337 // The minimum amount of time between successive PSS requests for a process
338 // when the request is due to the memory state being lowered.
339 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
341 // The rate at which we check for apps using excessive power -- 15 mins.
342 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
344 // The minimum sample duration we will allow before deciding we have
345 // enough data on wake locks to start killing things.
346 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
348 // The minimum sample duration we will allow before deciding we have
349 // enough data on CPU usage to start killing things.
350 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
352 // How long we allow a receiver to run before giving up on it.
353 static final int BROADCAST_FG_TIMEOUT = 10*1000;
354 static final int BROADCAST_BG_TIMEOUT = 60*1000;
356 // How long we wait until we timeout on key dispatching.
357 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
359 // How long we wait until we timeout on key dispatching during instrumentation.
360 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
362 // Amount of time we wait for observers to handle a user switch before
363 // giving up on them and unfreezing the screen.
364 static final int USER_SWITCH_TIMEOUT = 2*1000;
366 // This is the amount of time an app needs to be running a foreground service before
367 // we will consider it to be doing interaction for usage stats.
368 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
370 // Maximum number of users we allow to be running at a time.
371 static final int MAX_RUNNING_USERS = 3;
373 // How long to wait in getAssistContextExtras for the activity and foreground services
374 // to respond with the result.
375 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
377 // How long top wait when going through the modern assist (which doesn't need to block
378 // on getting this result before starting to launch its UI).
379 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
381 // Maximum number of persisted Uri grants a package is allowed
382 static final int MAX_PERSISTED_URI_GRANTS = 128;
384 static final int MY_PID = Process.myPid();
386 static final String[] EMPTY_STRING_ARRAY = new String[0];
388 // How many bytes to write into the dropbox log before truncating
389 static final int DROPBOX_MAX_SIZE = 256 * 1024;
391 // Access modes for handleIncomingUser.
392 static final int ALLOW_NON_FULL = 0;
393 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
394 static final int ALLOW_FULL_ONLY = 2;
396 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
398 // Delay in notifying task stack change listeners (in millis)
399 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
401 // Necessary ApplicationInfo flags to mark an app as persistent
402 private static final int PERSISTENT_MASK =
403 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
405 /** All system services */
406 SystemServiceManager mSystemServiceManager;
408 private Installer mInstaller;
410 /** Run all ActivityStacks through this */
411 ActivityStackSupervisor mStackSupervisor;
413 /** Task stack change listeners. */
414 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
415 new RemoteCallbackList<ITaskStackListener>();
417 public IntentFirewall mIntentFirewall;
419 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
420 // default actuion automatically. Important for devices without direct input
422 private boolean mShowDialogs = true;
424 BroadcastQueue mFgBroadcastQueue;
425 BroadcastQueue mBgBroadcastQueue;
426 // Convenient for easy iteration over the queues. Foreground is first
427 // so that dispatch of foreground broadcasts gets precedence.
428 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
430 BroadcastQueue broadcastQueueForIntent(Intent intent) {
431 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
432 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
433 "Broadcast intent " + intent + " on "
434 + (isFg ? "foreground" : "background") + " queue");
435 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
439 * Activity we have told the window manager to have key focus.
441 ActivityRecord mFocusedActivity = null;
444 * User id of the last activity mFocusedActivity was set to.
446 private int mLastFocusedUserId;
449 * If non-null, we are tracking the time the user spends in the currently focused app.
451 private AppTimeTracker mCurAppTimeTracker;
454 * List of intents that were used to start the most recent tasks.
456 private final RecentTasks mRecentTasks;
459 * For addAppTask: cached of the last activity component that was added.
461 ComponentName mLastAddedTaskComponent;
464 * For addAppTask: cached of the last activity uid that was added.
466 int mLastAddedTaskUid;
469 * For addAppTask: cached of the last ActivityInfo that was added.
471 ActivityInfo mLastAddedTaskActivity;
474 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
476 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
479 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
481 String mDeviceOwnerName;
483 public class PendingAssistExtras extends Binder implements Runnable {
484 public final ActivityRecord activity;
485 public final Bundle extras;
486 public final Intent intent;
487 public final String hint;
488 public final IResultReceiver receiver;
489 public final int userHandle;
490 public boolean haveResult = false;
491 public Bundle result = null;
492 public AssistStructure structure = null;
493 public AssistContent content = null;
494 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
495 String _hint, IResultReceiver _receiver, int _userHandle) {
496 activity = _activity;
500 receiver = _receiver;
501 userHandle = _userHandle;
505 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
506 synchronized (this) {
510 pendingAssistExtrasTimedOut(this);
514 final ArrayList<PendingAssistExtras> mPendingAssistExtras
515 = new ArrayList<PendingAssistExtras>();
518 * Process management.
520 final ProcessList mProcessList = new ProcessList();
523 * All of the applications we currently have running organized by name.
524 * The keys are strings of the application package name (as
525 * returned by the package manager), and the keys are ApplicationRecord
528 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
531 * Tracking long-term execution of processes to look for abuse and other
534 final ProcessStatsService mProcessStats;
537 * The currently running isolated processes.
539 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
542 * Counter for assigning isolated process uids, to avoid frequently reusing the
545 int mNextIsolatedProcessUid = 0;
548 * The currently running heavy-weight process, if any.
550 ProcessRecord mHeavyWeightProcess = null;
553 * The last time that various processes have crashed.
555 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
558 * Information about a process that is currently marked as bad.
560 static final class BadProcessInfo {
561 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
563 this.shortMsg = shortMsg;
564 this.longMsg = longMsg;
569 final String shortMsg;
570 final String longMsg;
575 * Set of applications that we consider to be bad, and will reject
576 * incoming broadcasts from (which the user has no control over).
577 * Processes are added to this set when they have crashed twice within
578 * a minimum amount of time; they are removed from it when they are
579 * later restarted (hopefully due to some user action). The value is the
580 * time it was added to the list.
582 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
585 * All of the processes we currently have running organized by pid.
586 * The keys are the pid running the application.
588 * <p>NOTE: This object is protected by its own lock, NOT the global
589 * activity manager lock!
591 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
594 * All of the processes that have been forced to be foreground. The key
595 * is the pid of the caller who requested it (we hold a death
598 abstract class ForegroundToken implements IBinder.DeathRecipient {
602 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
605 * List of records for processes that someone had tried to start before the
606 * system was ready. We don't start them at that point, but ensure they
607 * are started by the time booting is complete.
609 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
612 * List of persistent applications that are in the process
615 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
618 * Processes that are being forcibly torn down.
620 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
623 * List of running applications, sorted by recent usage.
624 * The first entry in the list is the least recently used.
626 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
629 * Where in mLruProcesses that the processes hosting activities start.
631 int mLruProcessActivityStart = 0;
634 * Where in mLruProcesses that the processes hosting services start.
635 * This is after (lower index) than mLruProcessesActivityStart.
637 int mLruProcessServiceStart = 0;
640 * List of processes that should gc as soon as things are idle.
642 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
645 * Processes we want to collect PSS data from.
647 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
650 * Last time we requested PSS data of all processes.
652 long mLastFullPssTime = SystemClock.uptimeMillis();
655 * If set, the next time we collect PSS data we should do a full collection
656 * with data from native processes and the kernel.
658 boolean mFullPssPending = false;
661 * This is the process holding what we currently consider to be
662 * the "home" activity.
664 ProcessRecord mHomeProcess;
667 * This is the process holding the activity the user last visited that
668 * is in a different process from the one they are currently in.
670 ProcessRecord mPreviousProcess;
673 * The time at which the previous process was last visible.
675 long mPreviousProcessVisibleTime;
678 * Track all uids that have actively running processes.
680 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
683 * Which users have been started, so are allowed to run code.
685 final SparseArray<UserState> mStartedUsers = new SparseArray<>();
688 * LRU list of history of current users. Most recently current is at the end.
690 final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
693 * Constant array of the users that are currently started.
695 int[] mStartedUserArray = new int[] { 0 };
698 * Registered observers of the user switching mechanics.
700 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
701 = new RemoteCallbackList<IUserSwitchObserver>();
704 * Currently active user switch.
706 Object mCurUserSwitchCallback;
709 * Packages that the user has asked to have run in screen size
710 * compatibility mode instead of filling the screen.
712 final CompatModePackages mCompatModePackages;
715 * Set of IntentSenderRecord objects that are currently active.
717 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
718 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
721 * Fingerprints (hashCode()) of stack traces that we've
722 * already logged DropBox entries for. Guarded by itself. If
723 * something (rogue user app) forces this over
724 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
726 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
727 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
730 * Strict Mode background batched logging state.
732 * The string buffer is guarded by itself, and its lock is also
733 * used to determine if another batched write is already
736 private final StringBuilder mStrictModeBuffer = new StringBuilder();
739 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
740 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
742 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
745 * Resolver for broadcast intents to registered receivers.
746 * Holds BroadcastFilter (subclass of IntentFilter).
748 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
749 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
751 protected boolean allowFilterResult(
752 BroadcastFilter filter, List<BroadcastFilter> dest) {
753 IBinder target = filter.receiverList.receiver.asBinder();
754 for (int i = dest.size() - 1; i >= 0; i--) {
755 if (dest.get(i).receiverList.receiver.asBinder() == target) {
763 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
764 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
765 || userId == filter.owningUserId) {
766 return super.newResult(filter, match, userId);
772 protected BroadcastFilter[] newArray(int size) {
773 return new BroadcastFilter[size];
777 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
778 return packageName.equals(filter.packageName);
783 * State of all active sticky broadcasts per user. Keys are the action of the
784 * sticky Intent, values are an ArrayList of all broadcasted intents with
785 * that action (which should usually be one). The SparseArray is keyed
786 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
787 * for stickies that are sent to all users.
789 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
790 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
792 final ActiveServices mServices;
794 final static class Association {
795 final int mSourceUid;
796 final String mSourceProcess;
797 final int mTargetUid;
798 final ComponentName mTargetComponent;
799 final String mTargetProcess;
807 Association(int sourceUid, String sourceProcess, int targetUid,
808 ComponentName targetComponent, String targetProcess) {
809 mSourceUid = sourceUid;
810 mSourceProcess = sourceProcess;
811 mTargetUid = targetUid;
812 mTargetComponent = targetComponent;
813 mTargetProcess = targetProcess;
818 * When service association tracking is enabled, this is all of the associations we
819 * have seen. Mapping is target uid -> target component -> source uid -> source process name
820 * -> association data.
822 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
823 mAssociations = new SparseArray<>();
824 boolean mTrackingAssociations;
827 * Backup/restore process management
829 String mBackupAppName = null;
830 BackupRecord mBackupTarget = null;
832 final ProviderMap mProviderMap;
835 * List of content providers who have clients waiting for them. The
836 * application is currently being launched and the provider will be
837 * removed from this list once it is published.
839 final ArrayList<ContentProviderRecord> mLaunchingProviders
840 = new ArrayList<ContentProviderRecord>();
843 * File storing persisted {@link #mGrantedUriPermissions}.
845 private final AtomicFile mGrantFile;
847 /** XML constants used in {@link #mGrantFile} */
848 private static final String TAG_URI_GRANTS = "uri-grants";
849 private static final String TAG_URI_GRANT = "uri-grant";
850 private static final String ATTR_USER_HANDLE = "userHandle";
851 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
852 private static final String ATTR_TARGET_USER_ID = "targetUserId";
853 private static final String ATTR_SOURCE_PKG = "sourcePkg";
854 private static final String ATTR_TARGET_PKG = "targetPkg";
855 private static final String ATTR_URI = "uri";
856 private static final String ATTR_MODE_FLAGS = "modeFlags";
857 private static final String ATTR_CREATED_TIME = "createdTime";
858 private static final String ATTR_PREFIX = "prefix";
861 * Global set of specific {@link Uri} permissions that have been granted.
862 * This optimized lookup structure maps from {@link UriPermission#targetUid}
863 * to {@link UriPermission#uri} to {@link UriPermission}.
866 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
867 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
869 public static class GrantUri {
870 public final int sourceUserId;
871 public final Uri uri;
872 public boolean prefix;
874 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
875 this.sourceUserId = sourceUserId;
877 this.prefix = prefix;
881 public int hashCode() {
883 hashCode = 31 * hashCode + sourceUserId;
884 hashCode = 31 * hashCode + uri.hashCode();
885 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
890 public boolean equals(Object o) {
891 if (o instanceof GrantUri) {
892 GrantUri other = (GrantUri) o;
893 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
894 && prefix == other.prefix;
900 public String toString() {
901 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
902 if (prefix) result += " [prefix]";
906 public String toSafeString() {
907 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
908 if (prefix) result += " [prefix]";
912 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
913 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
914 ContentProvider.getUriWithoutUserId(uri), false);
918 CoreSettingsObserver mCoreSettingsObserver;
921 * Thread-local storage used to carry caller permissions over through
922 * indirect content-provider access.
924 private class Identity {
925 public final IBinder token;
926 public final int pid;
927 public final int uid;
929 Identity(IBinder _token, int _pid, int _uid) {
936 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
939 * All information we have collected about the runtime performance of
940 * any user id that can impact battery performance.
942 final BatteryStatsService mBatteryStatsService;
945 * Information about component usage
947 UsageStatsManagerInternal mUsageStatsService;
950 * Access to DeviceIdleController service.
952 DeviceIdleController.LocalService mLocalDeviceIdleController;
955 * Information about and control over application operations
957 final AppOpsService mAppOpsService;
960 * Save recent tasks information across reboots.
962 final TaskPersister mTaskPersister;
965 * Current configuration information. HistoryRecord objects are given
966 * a reference to this object to indicate which configuration they are
967 * currently running in, so this object must be kept immutable.
969 Configuration mConfiguration = new Configuration();
972 * Current sequencing integer of the configuration, for skipping old
975 int mConfigurationSeq = 0;
978 * Hardware-reported OpenGLES version.
980 final int GL_ES_VERSION;
983 * List of initialization arguments to pass to all processes when binding applications to them.
984 * For example, references to the commonly used services.
986 HashMap<String, IBinder> mAppBindArgs;
987 HashMap<String, IBinder> mIsolatedAppBindArgs;
990 * Temporary to avoid allocations. Protected by main lock.
992 final StringBuilder mStringBuilder = new StringBuilder(256);
995 * Used to control how we initialize the service.
997 ComponentName mTopComponent;
998 String mTopAction = Intent.ACTION_MAIN;
1000 boolean mProcessesReady = false;
1001 boolean mSystemReady = false;
1002 boolean mBooting = false;
1003 boolean mCallFinishBooting = false;
1004 boolean mBootAnimationComplete = false;
1005 boolean mWaitingUpdate = false;
1006 boolean mDidUpdate = false;
1007 boolean mOnBattery = false;
1008 boolean mLaunchWarningShown = false;
1014 boolean mCheckedForSetup;
1017 * The time at which we will allow normal application switches again,
1018 * after a call to {@link #stopAppSwitches()}.
1020 long mAppSwitchesAllowedTime;
1023 * This is set to true after the first switch after mAppSwitchesAllowedTime
1024 * is set; any switches after that will clear the time.
1026 boolean mDidAppSwitch;
1029 * Last time (in realtime) at which we checked for power usage.
1031 long mLastPowerCheckRealtime;
1034 * Last time (in uptime) at which we checked for power usage.
1036 long mLastPowerCheckUptime;
1039 * Set while we are wanting to sleep, to prevent any
1040 * activities from being started/resumed.
1042 private boolean mSleeping = false;
1045 * The process state used for processes that are running the top activities.
1046 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1048 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1051 * Set while we are running a voice interaction. This overrides
1052 * sleeping while it is active.
1054 private IVoiceInteractionSession mRunningVoice;
1057 * For some direct access we need to power manager.
1059 PowerManagerInternal mLocalPowerManager;
1062 * We want to hold a wake lock while running a voice interaction session, since
1063 * this may happen with the screen off and we need to keep the CPU running to
1064 * be able to continue to interact with the user.
1066 PowerManager.WakeLock mVoiceWakeLock;
1069 * State of external calls telling us if the device is awake or asleep.
1071 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1074 * A list of tokens that cause the top activity to be put to sleep.
1075 * They are used by components that may hide and block interaction with underlying
1078 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1080 static final int LOCK_SCREEN_HIDDEN = 0;
1081 static final int LOCK_SCREEN_LEAVING = 1;
1082 static final int LOCK_SCREEN_SHOWN = 2;
1084 * State of external call telling us if the lock screen is shown.
1086 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1089 * Set if we are shutting down the system, similar to sleeping.
1091 boolean mShuttingDown = false;
1094 * Current sequence id for oom_adj computation traversal.
1099 * Current sequence id for process LRU updating.
1104 * Keep track of the non-cached/empty process we last found, to help
1105 * determine how to distribute cached/empty processes next time.
1107 int mNumNonCachedProcs = 0;
1110 * Keep track of the number of cached hidden procs, to balance oom adj
1111 * distribution between those and empty procs.
1113 int mNumCachedHiddenProcs = 0;
1116 * Keep track of the number of service processes we last found, to
1117 * determine on the next iteration which should be B services.
1119 int mNumServiceProcs = 0;
1120 int mNewNumAServiceProcs = 0;
1121 int mNewNumServiceProcs = 0;
1124 * Allow the current computed overall memory level of the system to go down?
1125 * This is set to false when we are killing processes for reasons other than
1126 * memory management, so that the now smaller process list will not be taken as
1127 * an indication that memory is tighter.
1129 boolean mAllowLowerMemLevel = false;
1132 * The last computed memory level, for holding when we are in a state that
1133 * processes are going away for other reasons.
1135 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1138 * The last total number of process we have, to determine if changes actually look
1139 * like a shrinking number of process due to lower RAM.
1141 int mLastNumProcesses;
1144 * The uptime of the last time we performed idle maintenance.
1146 long mLastIdleTime = SystemClock.uptimeMillis();
1149 * Total time spent with RAM that has been added in the past since the last idle time.
1151 long mLowRamTimeSinceLastIdle = 0;
1154 * If RAM is currently low, when that horrible situation started.
1156 long mLowRamStartTime = 0;
1159 * For reporting to battery stats the current top application.
1161 private String mCurResumedPackage = null;
1162 private int mCurResumedUid = -1;
1165 * For reporting to battery stats the apps currently running foreground
1166 * service. The ProcessMap is package/uid tuples; each of these contain
1167 * an array of the currently foreground processes.
1169 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1170 = new ProcessMap<ArrayList<ProcessRecord>>();
1173 * This is set if we had to do a delayed dexopt of an app before launching
1174 * it, to increase the ANR timeouts in that case.
1179 * Set if the systemServer made a call to enterSafeMode.
1184 * If true, we are running under a test environment so will sample PSS from processes
1185 * much more rapidly to try to collect better data when the tests are rapidly
1186 * running through apps.
1188 boolean mTestPssMode = false;
1190 String mDebugApp = null;
1191 boolean mWaitForDebugger = false;
1192 boolean mDebugTransient = false;
1193 String mOrigDebugApp = null;
1194 boolean mOrigWaitForDebugger = false;
1195 boolean mAlwaysFinishActivities = false;
1196 IActivityController mController = null;
1197 String mProfileApp = null;
1198 ProcessRecord mProfileProc = null;
1199 String mProfileFile;
1200 ParcelFileDescriptor mProfileFd;
1201 int mSamplingInterval = 0;
1202 boolean mAutoStopProfiler = false;
1203 int mProfileType = 0;
1204 String mOpenGlTraceApp = null;
1205 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1206 String mMemWatchDumpProcName;
1207 String mMemWatchDumpFile;
1208 int mMemWatchDumpPid;
1209 int mMemWatchDumpUid;
1211 final long[] mTmpLong = new long[1];
1213 static final class ProcessChangeItem {
1214 static final int CHANGE_ACTIVITIES = 1<<0;
1215 static final int CHANGE_PROCESS_STATE = 1<<1;
1220 boolean foregroundActivities;
1223 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1224 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1226 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1227 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1229 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1230 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1232 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1233 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1236 * Runtime CPU use collection thread. This object's lock is used to
1237 * perform synchronization with the thread (notifying it to run).
1239 final Thread mProcessCpuThread;
1242 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1243 * Must acquire this object's lock when accessing it.
1244 * NOTE: this lock will be held while doing long operations (trawling
1245 * through all processes in /proc), so it should never be acquired by
1246 * any critical paths such as when holding the main activity manager lock.
1248 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1249 MONITOR_THREAD_CPU_USAGE);
1250 final AtomicLong mLastCpuTime = new AtomicLong(0);
1251 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1253 long mLastWriteTime = 0;
1256 * Used to retain an update lock when the foreground activity is in
1259 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1262 * Set to true after the system has finished booting.
1264 boolean mBooted = false;
1266 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1267 int mProcessLimitOverride = -1;
1269 WindowManagerService mWindowManager;
1271 final ActivityThread mSystemThread;
1273 // Holds the current foreground user's id
1274 int mCurrentUserId = 0;
1275 // Holds the target user's id during a user switch
1276 int mTargetUserId = UserHandle.USER_NULL;
1277 // If there are multiple profiles for the current user, their ids are here
1278 // Currently only the primary user can have managed profiles
1279 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1282 * Mapping from each known user ID to the profile group ID it is associated with.
1284 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1286 private UserManagerService mUserManager;
1288 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1289 final ProcessRecord mApp;
1291 final IApplicationThread mAppThread;
1293 AppDeathRecipient(ProcessRecord app, int pid,
1294 IApplicationThread thread) {
1295 if (DEBUG_ALL) Slog.v(
1296 TAG, "New death recipient " + this
1297 + " for thread " + thread.asBinder());
1300 mAppThread = thread;
1304 public void binderDied() {
1305 if (DEBUG_ALL) Slog.v(
1306 TAG, "Death received in " + this
1307 + " for thread " + mAppThread.asBinder());
1308 synchronized(ActivityManagerService.this) {
1309 appDiedLocked(mApp, mPid, mAppThread, true);
1314 static final int SHOW_ERROR_MSG = 1;
1315 static final int SHOW_NOT_RESPONDING_MSG = 2;
1316 static final int SHOW_FACTORY_ERROR_MSG = 3;
1317 static final int UPDATE_CONFIGURATION_MSG = 4;
1318 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1319 static final int WAIT_FOR_DEBUGGER_MSG = 6;
1320 static final int SERVICE_TIMEOUT_MSG = 12;
1321 static final int UPDATE_TIME_ZONE = 13;
1322 static final int SHOW_UID_ERROR_MSG = 14;
1323 static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1324 static final int PROC_START_TIMEOUT_MSG = 20;
1325 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1326 static final int KILL_APPLICATION_MSG = 22;
1327 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1328 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1329 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1330 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1331 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1332 static final int CLEAR_DNS_CACHE_MSG = 28;
1333 static final int UPDATE_HTTP_PROXY_MSG = 29;
1334 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1335 static final int DISPATCH_PROCESSES_CHANGED = 31;
1336 static final int DISPATCH_PROCESS_DIED = 32;
1337 static final int REPORT_MEM_USAGE_MSG = 33;
1338 static final int REPORT_USER_SWITCH_MSG = 34;
1339 static final int CONTINUE_USER_SWITCH_MSG = 35;
1340 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1341 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1342 static final int PERSIST_URI_GRANTS_MSG = 38;
1343 static final int REQUEST_ALL_PSS_MSG = 39;
1344 static final int START_PROFILES_MSG = 40;
1345 static final int UPDATE_TIME = 41;
1346 static final int SYSTEM_USER_START_MSG = 42;
1347 static final int SYSTEM_USER_CURRENT_MSG = 43;
1348 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1349 static final int FINISH_BOOTING_MSG = 45;
1350 static final int START_USER_SWITCH_MSG = 46;
1351 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1352 static final int DISMISS_DIALOG_MSG = 48;
1353 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1354 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1355 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1356 static final int DELETE_DUMPHEAP_MSG = 52;
1357 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1358 static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1359 static final int REPORT_TIME_TRACKER_MSG = 55;
1360 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1361 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1363 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1364 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1365 static final int FIRST_COMPAT_MODE_MSG = 300;
1366 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1368 CompatModeDialog mCompatModeDialog;
1369 long mLastMemUsageReportTime = 0;
1372 * Flag whether the current user is a "monkey", i.e. whether
1373 * the UI is driven by a UI automation tool.
1375 private boolean mUserIsMonkey;
1377 /** Flag whether the device has a Recents UI */
1378 boolean mHasRecents;
1380 /** The dimensions of the thumbnails in the Recents UI. */
1381 int mThumbnailWidth;
1382 int mThumbnailHeight;
1384 final ServiceThread mHandlerThread;
1385 final MainHandler mHandler;
1386 final UiHandler mUiHandler;
1388 final class UiHandler extends Handler {
1389 public UiHandler() {
1390 super(com.android.server.UiThread.get().getLooper(), null, true);
1394 public void handleMessage(Message msg) {
1396 case SHOW_ERROR_MSG: {
1397 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1398 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1399 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1400 synchronized (ActivityManagerService.this) {
1401 ProcessRecord proc = (ProcessRecord)data.get("app");
1402 AppErrorResult res = (AppErrorResult) data.get("result");
1403 if (proc != null && proc.crashDialog != null) {
1404 Slog.e(TAG, "App already has crash dialog: " + proc);
1410 boolean isBackground = (UserHandle.getAppId(proc.uid)
1411 >= Process.FIRST_APPLICATION_UID
1412 && proc.pid != MY_PID);
1413 for (int userId : mCurrentProfileIds) {
1414 isBackground &= (proc.userId != userId);
1416 if (isBackground && !showBackground) {
1417 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1423 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1424 Dialog d = new AppErrorDialog(mContext,
1425 ActivityManagerService.this, res, proc);
1427 proc.crashDialog = d;
1429 // The device is asleep, so just pretend that the user
1430 // saw a crash dialog and hit "force quit".
1437 ensureBootCompleted();
1439 case SHOW_NOT_RESPONDING_MSG: {
1440 synchronized (ActivityManagerService.this) {
1441 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1442 ProcessRecord proc = (ProcessRecord)data.get("app");
1443 if (proc != null && proc.anrDialog != null) {
1444 Slog.e(TAG, "App already has anr dialog: " + proc);
1448 Intent intent = new Intent("android.intent.action.ANR");
1449 if (!mProcessesReady) {
1450 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1451 | Intent.FLAG_RECEIVER_FOREGROUND);
1453 broadcastIntentLocked(null, null, intent,
1454 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1455 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1458 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1459 mContext, proc, (ActivityRecord)data.get("activity"),
1464 // Just kill the app if there is no dialog to be shown.
1465 killAppAtUsersRequest(proc, null);
1469 ensureBootCompleted();
1471 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1472 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1473 synchronized (ActivityManagerService.this) {
1474 ProcessRecord proc = (ProcessRecord) data.get("app");
1476 Slog.e(TAG, "App not found when showing strict mode dialog.");
1479 if (proc.crashDialog != null) {
1480 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1483 AppErrorResult res = (AppErrorResult) data.get("result");
1484 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1485 Dialog d = new StrictModeViolationDialog(mContext,
1486 ActivityManagerService.this, res, proc);
1488 proc.crashDialog = d;
1490 // The device is asleep, so just pretend that the user
1491 // saw a crash dialog and hit "force quit".
1495 ensureBootCompleted();
1497 case SHOW_FACTORY_ERROR_MSG: {
1498 Dialog d = new FactoryErrorDialog(
1499 mContext, msg.getData().getCharSequence("msg"));
1501 ensureBootCompleted();
1503 case WAIT_FOR_DEBUGGER_MSG: {
1504 synchronized (ActivityManagerService.this) {
1505 ProcessRecord app = (ProcessRecord)msg.obj;
1506 if (msg.arg1 != 0) {
1507 if (!app.waitedForDebugger) {
1508 Dialog d = new AppWaitingForDebuggerDialog(
1509 ActivityManagerService.this,
1512 app.waitedForDebugger = true;
1516 if (app.waitDialog != null) {
1517 app.waitDialog.dismiss();
1518 app.waitDialog = null;
1523 case SHOW_UID_ERROR_MSG: {
1525 AlertDialog d = new BaseErrorDialog(mContext);
1526 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1527 d.setCancelable(false);
1528 d.setTitle(mContext.getText(R.string.android_system_label));
1529 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1530 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1531 obtainMessage(DISMISS_DIALOG_MSG, d));
1535 case SHOW_FINGERPRINT_ERROR_MSG: {
1537 AlertDialog d = new BaseErrorDialog(mContext);
1538 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1539 d.setCancelable(false);
1540 d.setTitle(mContext.getText(R.string.android_system_label));
1541 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1542 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1543 obtainMessage(DISMISS_DIALOG_MSG, d));
1547 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1548 synchronized (ActivityManagerService.this) {
1549 ActivityRecord ar = (ActivityRecord) msg.obj;
1550 if (mCompatModeDialog != null) {
1551 if (mCompatModeDialog.mAppInfo.packageName.equals(
1552 ar.info.applicationInfo.packageName)) {
1555 mCompatModeDialog.dismiss();
1556 mCompatModeDialog = null;
1558 if (ar != null && false) {
1559 if (mCompatModePackages.getPackageAskCompatModeLocked(
1561 int mode = mCompatModePackages.computeCompatModeLocked(
1562 ar.info.applicationInfo);
1563 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1564 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1565 mCompatModeDialog = new CompatModeDialog(
1566 ActivityManagerService.this, mContext,
1567 ar.info.applicationInfo);
1568 mCompatModeDialog.show();
1575 case START_USER_SWITCH_MSG: {
1576 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1579 case DISMISS_DIALOG_MSG: {
1580 final Dialog d = (Dialog) msg.obj;
1584 case DISPATCH_PROCESSES_CHANGED: {
1585 dispatchProcessesChanged();
1588 case DISPATCH_PROCESS_DIED: {
1589 final int pid = msg.arg1;
1590 final int uid = msg.arg2;
1591 dispatchProcessDied(pid, uid);
1594 case DISPATCH_UIDS_CHANGED_MSG: {
1595 dispatchUidsChanged();
1601 final class MainHandler extends Handler {
1602 public MainHandler(Looper looper) {
1603 super(looper, null, true);
1607 public void handleMessage(Message msg) {
1609 case UPDATE_CONFIGURATION_MSG: {
1610 final ContentResolver resolver = mContext.getContentResolver();
1611 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1613 case GC_BACKGROUND_PROCESSES_MSG: {
1614 synchronized (ActivityManagerService.this) {
1615 performAppGcsIfAppropriateLocked();
1618 case SERVICE_TIMEOUT_MSG: {
1621 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1623 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1626 mServices.serviceTimeout((ProcessRecord)msg.obj);
1628 case UPDATE_TIME_ZONE: {
1629 synchronized (ActivityManagerService.this) {
1630 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1631 ProcessRecord r = mLruProcesses.get(i);
1632 if (r.thread != null) {
1634 r.thread.updateTimeZone();
1635 } catch (RemoteException ex) {
1636 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1642 case CLEAR_DNS_CACHE_MSG: {
1643 synchronized (ActivityManagerService.this) {
1644 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1645 ProcessRecord r = mLruProcesses.get(i);
1646 if (r.thread != null) {
1648 r.thread.clearDnsCache();
1649 } catch (RemoteException ex) {
1650 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1656 case UPDATE_HTTP_PROXY_MSG: {
1657 ProxyInfo proxy = (ProxyInfo)msg.obj;
1660 String exclList = "";
1661 Uri pacFileUrl = Uri.EMPTY;
1662 if (proxy != null) {
1663 host = proxy.getHost();
1664 port = Integer.toString(proxy.getPort());
1665 exclList = proxy.getExclusionListAsString();
1666 pacFileUrl = proxy.getPacFileUrl();
1668 synchronized (ActivityManagerService.this) {
1669 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1670 ProcessRecord r = mLruProcesses.get(i);
1671 if (r.thread != null) {
1673 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1674 } catch (RemoteException ex) {
1675 Slog.w(TAG, "Failed to update http proxy for: " +
1676 r.info.processName);
1682 case PROC_START_TIMEOUT_MSG: {
1685 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1687 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1690 ProcessRecord app = (ProcessRecord)msg.obj;
1691 synchronized (ActivityManagerService.this) {
1692 processStartTimedOutLocked(app);
1695 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1696 synchronized (ActivityManagerService.this) {
1697 mStackSupervisor.doPendingActivityLaunchesLocked(true);
1700 case KILL_APPLICATION_MSG: {
1701 synchronized (ActivityManagerService.this) {
1702 int appid = msg.arg1;
1703 boolean restart = (msg.arg2 == 1);
1704 Bundle bundle = (Bundle)msg.obj;
1705 String pkg = bundle.getString("pkg");
1706 String reason = bundle.getString("reason");
1707 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1708 false, UserHandle.USER_ALL, reason);
1711 case FINALIZE_PENDING_INTENT_MSG: {
1712 ((PendingIntentRecord)msg.obj).completeFinalize();
1714 case POST_HEAVY_NOTIFICATION_MSG: {
1715 INotificationManager inm = NotificationManager.getService();
1720 ActivityRecord root = (ActivityRecord)msg.obj;
1721 ProcessRecord process = root.app;
1722 if (process == null) {
1727 Context context = mContext.createPackageContext(process.info.packageName, 0);
1728 String text = mContext.getString(R.string.heavy_weight_notification,
1729 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1730 Notification notification = new Notification.Builder(context)
1731 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1735 .setColor(mContext.getColor(
1736 com.android.internal.R.color.system_notification_accent_color))
1737 .setContentTitle(text)
1739 mContext.getText(R.string.heavy_weight_notification_detail))
1740 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1741 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1742 new UserHandle(root.userId)))
1745 int[] outId = new int[1];
1746 inm.enqueueNotificationWithTag("android", "android", null,
1747 R.string.heavy_weight_notification,
1748 notification, outId, root.userId);
1749 } catch (RuntimeException e) {
1750 Slog.w(ActivityManagerService.TAG,
1751 "Error showing notification for heavy-weight app", e);
1752 } catch (RemoteException e) {
1754 } catch (NameNotFoundException e) {
1755 Slog.w(TAG, "Unable to create context for heavy notification", e);
1758 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1759 INotificationManager inm = NotificationManager.getService();
1764 inm.cancelNotificationWithTag("android", null,
1765 R.string.heavy_weight_notification, msg.arg1);
1766 } catch (RuntimeException e) {
1767 Slog.w(ActivityManagerService.TAG,
1768 "Error canceling notification for service", e);
1769 } catch (RemoteException e) {
1772 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1773 synchronized (ActivityManagerService.this) {
1774 checkExcessivePowerUsageLocked(true);
1775 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1776 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1777 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1780 case REPORT_MEM_USAGE_MSG: {
1781 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1782 Thread thread = new Thread() {
1783 @Override public void run() {
1784 reportMemUsage(memInfos);
1790 case REPORT_USER_SWITCH_MSG: {
1791 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1794 case CONTINUE_USER_SWITCH_MSG: {
1795 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1798 case USER_SWITCH_TIMEOUT_MSG: {
1799 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1802 case IMMERSIVE_MODE_LOCK_MSG: {
1803 final boolean nextState = (msg.arg1 != 0);
1804 if (mUpdateLock.isHeld() != nextState) {
1805 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1806 "Applying new update lock state '" + nextState
1807 + "' for " + (ActivityRecord)msg.obj);
1809 mUpdateLock.acquire();
1811 mUpdateLock.release();
1816 case PERSIST_URI_GRANTS_MSG: {
1817 writeGrantedUriPermissions();
1820 case REQUEST_ALL_PSS_MSG: {
1821 synchronized (ActivityManagerService.this) {
1822 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1826 case START_PROFILES_MSG: {
1827 synchronized (ActivityManagerService.this) {
1828 startProfilesLocked();
1833 synchronized (ActivityManagerService.this) {
1834 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1835 ProcessRecord r = mLruProcesses.get(i);
1836 if (r.thread != null) {
1838 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1839 } catch (RemoteException ex) {
1840 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1847 case SYSTEM_USER_START_MSG: {
1848 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1849 Integer.toString(msg.arg1), msg.arg1);
1850 mSystemServiceManager.startUser(msg.arg1);
1853 case SYSTEM_USER_CURRENT_MSG: {
1854 mBatteryStatsService.noteEvent(
1855 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1856 Integer.toString(msg.arg2), msg.arg2);
1857 mBatteryStatsService.noteEvent(
1858 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1859 Integer.toString(msg.arg1), msg.arg1);
1860 mSystemServiceManager.switchUser(msg.arg1);
1863 case ENTER_ANIMATION_COMPLETE_MSG: {
1864 synchronized (ActivityManagerService.this) {
1865 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1866 if (r != null && r.app != null && r.app.thread != null) {
1868 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1869 } catch (RemoteException e) {
1875 case FINISH_BOOTING_MSG: {
1876 if (msg.arg1 != 0) {
1879 if (msg.arg2 != 0) {
1880 enableScreenAfterBoot();
1884 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1886 Locale l = (Locale) msg.obj;
1887 IBinder service = ServiceManager.getService("mount");
1888 IMountService mountService = IMountService.Stub.asInterface(service);
1889 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1890 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1891 } catch (RemoteException e) {
1892 Log.e(TAG, "Error storing locale for decryption UI", e);
1896 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1897 synchronized (ActivityManagerService.this) {
1898 int i = mTaskStackListeners.beginBroadcast();
1902 // Make a one-way callback to the listener
1903 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1904 } catch (RemoteException e){
1905 // Handled by the RemoteCallbackList
1908 mTaskStackListeners.finishBroadcast();
1912 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1913 final int uid = msg.arg1;
1914 final byte[] firstPacket = (byte[]) msg.obj;
1916 synchronized (mPidsSelfLocked) {
1917 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1918 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1921 p.thread.notifyCleartextNetwork(firstPacket);
1922 } catch (RemoteException ignored) {
1929 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1930 final String procName;
1932 final long memLimit;
1933 final String reportPackage;
1934 synchronized (ActivityManagerService.this) {
1935 procName = mMemWatchDumpProcName;
1936 uid = mMemWatchDumpUid;
1937 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1939 val = mMemWatchProcesses.get(procName, 0);
1942 memLimit = val.first;
1943 reportPackage = val.second;
1946 reportPackage = null;
1949 if (procName == null) {
1953 if (DEBUG_PSS) Slog.d(TAG_PSS,
1954 "Showing dump heap notification from " + procName + "/" + uid);
1956 INotificationManager inm = NotificationManager.getService();
1961 String text = mContext.getString(R.string.dump_heap_notification, procName);
1964 Intent deleteIntent = new Intent();
1965 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1966 Intent intent = new Intent();
1967 intent.setClassName("android", DumpHeapActivity.class.getName());
1968 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1969 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1970 if (reportPackage != null) {
1971 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1973 int userId = UserHandle.getUserId(uid);
1974 Notification notification = new Notification.Builder(mContext)
1975 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1978 .setAutoCancel(true)
1980 .setColor(mContext.getColor(
1981 com.android.internal.R.color.system_notification_accent_color))
1982 .setContentTitle(text)
1984 mContext.getText(R.string.dump_heap_notification_detail))
1985 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1986 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1987 new UserHandle(userId)))
1988 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1989 deleteIntent, 0, UserHandle.OWNER))
1993 int[] outId = new int[1];
1994 inm.enqueueNotificationWithTag("android", "android", null,
1995 R.string.dump_heap_notification,
1996 notification, outId, userId);
1997 } catch (RuntimeException e) {
1998 Slog.w(ActivityManagerService.TAG,
1999 "Error showing notification for dump heap", e);
2000 } catch (RemoteException e) {
2003 case DELETE_DUMPHEAP_MSG: {
2004 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2005 DumpHeapActivity.JAVA_URI,
2006 Intent.FLAG_GRANT_READ_URI_PERMISSION
2007 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2008 UserHandle.myUserId());
2009 synchronized (ActivityManagerService.this) {
2010 mMemWatchDumpFile = null;
2011 mMemWatchDumpProcName = null;
2012 mMemWatchDumpPid = -1;
2013 mMemWatchDumpUid = -1;
2016 case FOREGROUND_PROFILE_CHANGED_MSG: {
2017 dispatchForegroundProfileChanged(msg.arg1);
2019 case REPORT_TIME_TRACKER_MSG: {
2020 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2021 tracker.deliverResult(mContext);
2023 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2024 dispatchUserSwitchComplete(msg.arg1);
2026 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2027 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2029 connection.shutdown();
2030 } catch (RemoteException e) {
2031 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2033 // Only a UiAutomation can set this flag and now that
2034 // it is finished we make sure it is reset to its default.
2035 mUserIsMonkey = false;
2041 static final int COLLECT_PSS_BG_MSG = 1;
2043 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2045 public void handleMessage(Message msg) {
2047 case COLLECT_PSS_BG_MSG: {
2048 long start = SystemClock.uptimeMillis();
2049 MemInfoReader memInfo = null;
2050 synchronized (ActivityManagerService.this) {
2051 if (mFullPssPending) {
2052 mFullPssPending = false;
2053 memInfo = new MemInfoReader();
2056 if (memInfo != null) {
2057 updateCpuStatsNow();
2058 long nativeTotalPss = 0;
2059 synchronized (mProcessCpuTracker) {
2060 final int N = mProcessCpuTracker.countStats();
2061 for (int j=0; j<N; j++) {
2062 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2063 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2064 // This is definitely an application process; skip it.
2067 synchronized (mPidsSelfLocked) {
2068 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2069 // This is one of our own processes; skip it.
2073 nativeTotalPss += Debug.getPss(st.pid, null, null);
2076 memInfo.readMemInfo();
2077 synchronized (ActivityManagerService.this) {
2078 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2079 + (SystemClock.uptimeMillis()-start) + "ms");
2080 final long cachedKb = memInfo.getCachedSizeKb();
2081 final long freeKb = memInfo.getFreeSizeKb();
2082 final long zramKb = memInfo.getZramTotalSizeKb();
2083 final long kernelKb = memInfo.getKernelUsedSizeKb();
2084 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2085 kernelKb*1024, nativeTotalPss*1024);
2086 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2092 long[] tmp = new long[1];
2098 synchronized (ActivityManagerService.this) {
2099 if (mPendingPssProcesses.size() <= 0) {
2100 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2101 "Collected PSS of " + num + " processes in "
2102 + (SystemClock.uptimeMillis() - start) + "ms");
2103 mPendingPssProcesses.clear();
2106 proc = mPendingPssProcesses.remove(0);
2107 procState = proc.pssProcState;
2108 lastPssTime = proc.lastPssTime;
2109 if (proc.thread != null && procState == proc.setProcState
2110 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2111 < SystemClock.uptimeMillis()) {
2119 long pss = Debug.getPss(pid, tmp, null);
2120 synchronized (ActivityManagerService.this) {
2121 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2122 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2124 recordPssSampleLocked(proc, procState, pss, tmp[0],
2125 SystemClock.uptimeMillis());
2135 public void setSystemProcess() {
2137 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2138 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2139 ServiceManager.addService("meminfo", new MemBinder(this));
2140 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2141 ServiceManager.addService("dbinfo", new DbBinder(this));
2142 if (MONITOR_CPU_USAGE) {
2143 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2145 ServiceManager.addService("permission", new PermissionController(this));
2146 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2148 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2149 "android", STOCK_PM_FLAGS);
2150 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2152 synchronized (this) {
2153 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2154 app.persistent = true;
2156 app.maxAdj = ProcessList.SYSTEM_ADJ;
2157 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2158 synchronized (mPidsSelfLocked) {
2159 mPidsSelfLocked.put(app.pid, app);
2161 updateLruProcessLocked(app, false, null);
2162 updateOomAdjLocked();
2164 } catch (PackageManager.NameNotFoundException e) {
2165 throw new RuntimeException(
2166 "Unable to find android system package", e);
2170 public void setWindowManager(WindowManagerService wm) {
2171 mWindowManager = wm;
2172 mStackSupervisor.setWindowManager(wm);
2175 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2176 mUsageStatsService = usageStatsManager;
2179 public void startObservingNativeCrashes() {
2180 final NativeCrashListener ncl = new NativeCrashListener(this);
2184 public IAppOpsService getAppOpsService() {
2185 return mAppOpsService;
2188 static class MemBinder extends Binder {
2189 ActivityManagerService mActivityManagerService;
2190 MemBinder(ActivityManagerService activityManagerService) {
2191 mActivityManagerService = activityManagerService;
2195 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2196 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2197 != PackageManager.PERMISSION_GRANTED) {
2198 pw.println("Permission Denial: can't dump meminfo from from pid="
2199 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2200 + " without permission " + android.Manifest.permission.DUMP);
2204 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2208 static class GraphicsBinder extends Binder {
2209 ActivityManagerService mActivityManagerService;
2210 GraphicsBinder(ActivityManagerService activityManagerService) {
2211 mActivityManagerService = activityManagerService;
2215 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2216 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2217 != PackageManager.PERMISSION_GRANTED) {
2218 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2219 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2220 + " without permission " + android.Manifest.permission.DUMP);
2224 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2228 static class DbBinder extends Binder {
2229 ActivityManagerService mActivityManagerService;
2230 DbBinder(ActivityManagerService activityManagerService) {
2231 mActivityManagerService = activityManagerService;
2235 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2236 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2237 != PackageManager.PERMISSION_GRANTED) {
2238 pw.println("Permission Denial: can't dump dbinfo from from pid="
2239 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2240 + " without permission " + android.Manifest.permission.DUMP);
2244 mActivityManagerService.dumpDbInfo(fd, pw, args);
2248 static class CpuBinder extends Binder {
2249 ActivityManagerService mActivityManagerService;
2250 CpuBinder(ActivityManagerService activityManagerService) {
2251 mActivityManagerService = activityManagerService;
2255 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2256 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2257 != PackageManager.PERMISSION_GRANTED) {
2258 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2259 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2260 + " without permission " + android.Manifest.permission.DUMP);
2264 synchronized (mActivityManagerService.mProcessCpuTracker) {
2265 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2266 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2267 SystemClock.uptimeMillis()));
2272 public static final class Lifecycle extends SystemService {
2273 private final ActivityManagerService mService;
2275 public Lifecycle(Context context) {
2277 mService = new ActivityManagerService(context);
2281 public void onStart() {
2285 public ActivityManagerService getService() {
2290 // Note: This method is invoked on the main thread but may need to attach various
2291 // handlers to other threads. So take care to be explicit about the looper.
2292 public ActivityManagerService(Context systemContext) {
2293 mContext = systemContext;
2294 mFactoryTest = FactoryTest.getMode();
2295 mSystemThread = ActivityThread.currentActivityThread();
2297 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2299 mHandlerThread = new ServiceThread(TAG,
2300 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2301 mHandlerThread.start();
2302 mHandler = new MainHandler(mHandlerThread.getLooper());
2303 mUiHandler = new UiHandler();
2305 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2306 "foreground", BROADCAST_FG_TIMEOUT, false);
2307 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2308 "background", BROADCAST_BG_TIMEOUT, true);
2309 mBroadcastQueues[0] = mFgBroadcastQueue;
2310 mBroadcastQueues[1] = mBgBroadcastQueue;
2312 mServices = new ActiveServices(this);
2313 mProviderMap = new ProviderMap(this);
2315 // TODO: Move creation of battery stats service outside of activity manager service.
2316 File dataDir = Environment.getDataDirectory();
2317 File systemDir = new File(dataDir, "system");
2319 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2320 mBatteryStatsService.getActiveStatistics().readLocked();
2321 mBatteryStatsService.scheduleWriteToDisk();
2322 mOnBattery = DEBUG_POWER ? true
2323 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2324 mBatteryStatsService.getActiveStatistics().setCallback(this);
2326 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2328 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2330 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2332 // User 0 is the first and only user that runs at boot.
2333 mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2334 mUserLru.add(UserHandle.USER_OWNER);
2335 updateStartedUserArrayLocked();
2337 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2338 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2340 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2342 mConfiguration.setToDefaults();
2343 mConfiguration.setLocale(Locale.getDefault());
2345 mConfigurationSeq = mConfiguration.seq = 1;
2346 mProcessCpuTracker.init();
2348 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2349 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2350 mRecentTasks = new RecentTasks(this);
2351 mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2352 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2354 mProcessCpuThread = new Thread("CpuTracker") {
2360 synchronized(this) {
2361 final long now = SystemClock.uptimeMillis();
2362 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2363 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2364 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2365 // + ", write delay=" + nextWriteDelay);
2366 if (nextWriteDelay < nextCpuDelay) {
2367 nextCpuDelay = nextWriteDelay;
2369 if (nextCpuDelay > 0) {
2370 mProcessCpuMutexFree.set(true);
2371 this.wait(nextCpuDelay);
2374 } catch (InterruptedException e) {
2376 updateCpuStatsNow();
2377 } catch (Exception e) {
2378 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2384 Watchdog.getInstance().addMonitor(this);
2385 Watchdog.getInstance().addThread(mHandler);
2388 public void setSystemServiceManager(SystemServiceManager mgr) {
2389 mSystemServiceManager = mgr;
2392 public void setInstaller(Installer installer) {
2393 mInstaller = installer;
2396 private void start() {
2397 Process.removeAllProcessGroups();
2398 mProcessCpuThread.start();
2400 mBatteryStatsService.publish(mContext);
2401 mAppOpsService.publish(mContext);
2402 Slog.d("AppOps", "AppOpsService published");
2403 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2406 public void initPowerManagement() {
2407 mStackSupervisor.initPowerManagement();
2408 mBatteryStatsService.initPowerManagement();
2409 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2410 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2411 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2412 mVoiceWakeLock.setReferenceCounted(false);
2416 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2417 throws RemoteException {
2418 if (code == SYSPROPS_TRANSACTION) {
2419 // We need to tell all apps about the system property change.
2420 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2421 synchronized(this) {
2422 final int NP = mProcessNames.getMap().size();
2423 for (int ip=0; ip<NP; ip++) {
2424 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2425 final int NA = apps.size();
2426 for (int ia=0; ia<NA; ia++) {
2427 ProcessRecord app = apps.valueAt(ia);
2428 if (app.thread != null) {
2429 procs.add(app.thread.asBinder());
2435 int N = procs.size();
2436 for (int i=0; i<N; i++) {
2437 Parcel data2 = Parcel.obtain();
2439 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2440 } catch (RemoteException e) {
2446 return super.onTransact(code, data, reply, flags);
2447 } catch (RuntimeException e) {
2448 // The activity manager only throws security exceptions, so let's
2450 if (!(e instanceof SecurityException)) {
2451 Slog.wtf(TAG, "Activity Manager Crash", e);
2457 void updateCpuStats() {
2458 final long now = SystemClock.uptimeMillis();
2459 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2462 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2463 synchronized (mProcessCpuThread) {
2464 mProcessCpuThread.notify();
2469 void updateCpuStatsNow() {
2470 synchronized (mProcessCpuTracker) {
2471 mProcessCpuMutexFree.set(false);
2472 final long now = SystemClock.uptimeMillis();
2473 boolean haveNewCpuStats = false;
2475 if (MONITOR_CPU_USAGE &&
2476 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2477 mLastCpuTime.set(now);
2478 mProcessCpuTracker.update();
2479 if (mProcessCpuTracker.hasGoodLastStats()) {
2480 haveNewCpuStats = true;
2481 //Slog.i(TAG, mProcessCpu.printCurrentState());
2482 //Slog.i(TAG, "Total CPU usage: "
2483 // + mProcessCpu.getTotalCpuPercent() + "%");
2485 // Slog the cpu usage if the property is set.
2486 if ("true".equals(SystemProperties.get("events.cpu"))) {
2487 int user = mProcessCpuTracker.getLastUserTime();
2488 int system = mProcessCpuTracker.getLastSystemTime();
2489 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2490 int irq = mProcessCpuTracker.getLastIrqTime();
2491 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2492 int idle = mProcessCpuTracker.getLastIdleTime();
2494 int total = user + system + iowait + irq + softIrq + idle;
2495 if (total == 0) total = 1;
2497 EventLog.writeEvent(EventLogTags.CPU,
2498 ((user+system+iowait+irq+softIrq) * 100) / total,
2499 (user * 100) / total,
2500 (system * 100) / total,
2501 (iowait * 100) / total,
2502 (irq * 100) / total,
2503 (softIrq * 100) / total);
2508 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2509 synchronized(bstats) {
2510 synchronized(mPidsSelfLocked) {
2511 if (haveNewCpuStats) {
2512 if (bstats.startAddingCpuLocked()) {
2515 final int N = mProcessCpuTracker.countStats();
2516 for (int i=0; i<N; i++) {
2517 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2521 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2522 totalUTime += st.rel_utime;
2523 totalSTime += st.rel_stime;
2525 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2526 if (ps == null || !ps.isActive()) {
2527 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2528 pr.info.uid, pr.processName);
2530 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2531 pr.curCpuTime += st.rel_utime + st.rel_stime;
2533 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2534 if (ps == null || !ps.isActive()) {
2535 st.batteryStats = ps = bstats.getProcessStatsLocked(
2536 bstats.mapUid(st.uid), st.name);
2538 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2541 final int userTime = mProcessCpuTracker.getLastUserTime();
2542 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2543 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2544 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2545 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2546 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2547 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2548 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2553 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2554 mLastWriteTime = now;
2555 mBatteryStatsService.scheduleWriteToDisk();
2562 public void batteryNeedsCpuUpdate() {
2563 updateCpuStatsNow();
2567 public void batteryPowerChanged(boolean onBattery) {
2568 // When plugging in, update the CPU stats first before changing
2570 updateCpuStatsNow();
2571 synchronized (this) {
2572 synchronized(mPidsSelfLocked) {
2573 mOnBattery = DEBUG_POWER ? true : onBattery;
2579 public void batterySendBroadcast(Intent intent) {
2580 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2581 AppOpsManager.OP_NONE, null, false, false,
2582 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2586 * Initialize the application bind args. These are passed to each
2587 * process when the bindApplication() IPC is sent to the process. They're
2588 * lazily setup to make sure the services are running when they're asked for.
2590 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2591 // Isolated processes won't get this optimization, so that we don't
2592 // violate the rules about which services they have access to.
2594 if (mIsolatedAppBindArgs == null) {
2595 mIsolatedAppBindArgs = new HashMap<>();
2596 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2598 return mIsolatedAppBindArgs;
2601 if (mAppBindArgs == null) {
2602 mAppBindArgs = new HashMap<>();
2604 // Setup the application init args
2605 mAppBindArgs.put("package", ServiceManager.getService("package"));
2606 mAppBindArgs.put("window", ServiceManager.getService("window"));
2607 mAppBindArgs.put(Context.ALARM_SERVICE,
2608 ServiceManager.getService(Context.ALARM_SERVICE));
2610 return mAppBindArgs;
2613 final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2614 if (r != null && mFocusedActivity != r) {
2615 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2616 ActivityRecord last = mFocusedActivity;
2617 mFocusedActivity = r;
2618 if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2619 && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2620 if (mCurAppTimeTracker != r.appTimeTracker) {
2621 // We are switching app tracking. Complete the current one.
2622 if (mCurAppTimeTracker != null) {
2623 mCurAppTimeTracker.stop();
2624 mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2625 mCurAppTimeTracker).sendToTarget();
2626 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2627 mCurAppTimeTracker = null;
2629 if (r.appTimeTracker != null) {
2630 mCurAppTimeTracker = r.appTimeTracker;
2631 startTimeTrackingFocusedActivityLocked();
2634 startTimeTrackingFocusedActivityLocked();
2637 r.appTimeTracker = null;
2639 if (r.task != null && r.task.voiceInteractor != null) {
2640 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2642 finishRunningVoiceLocked();
2643 if (last != null && last.task.voiceSession != null) {
2644 // We had been in a voice interaction session, but now focused has
2645 // move to something different. Just finish the session, we can't
2646 // return to it and retain the proper state and synchronization with
2647 // the voice interaction service.
2648 finishVoiceTask(last.task.voiceSession);
2651 if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2652 mWindowManager.setFocusedApp(r.appToken, true);
2654 applyUpdateLockStateLocked(r);
2655 if (mFocusedActivity.userId != mLastFocusedUserId) {
2656 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2657 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2658 mFocusedActivity.userId, 0));
2659 mLastFocusedUserId = mFocusedActivity.userId;
2662 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2663 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2664 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2667 final void clearFocusedActivity(ActivityRecord r) {
2668 if (mFocusedActivity == r) {
2669 ActivityStack stack = mStackSupervisor.getFocusedStack();
2670 if (stack != null) {
2671 ActivityRecord top = stack.topActivity();
2672 if (top != null && top.userId != mLastFocusedUserId) {
2673 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2674 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2676 mLastFocusedUserId = top.userId;
2679 mFocusedActivity = null;
2680 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2685 public void setFocusedStack(int stackId) {
2686 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2687 synchronized (ActivityManagerService.this) {
2688 ActivityStack stack = mStackSupervisor.getStack(stackId);
2689 if (stack != null) {
2690 ActivityRecord r = stack.topRunningActivityLocked(null);
2692 setFocusedActivityLocked(r, "setFocusedStack");
2693 mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2699 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2701 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2702 synchronized (ActivityManagerService.this) {
2703 if (listener != null) {
2704 mTaskStackListeners.register(listener);
2710 public void notifyActivityDrawn(IBinder token) {
2711 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2712 synchronized (this) {
2713 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2715 r.task.stack.notifyActivityDrawnLocked(r);
2720 final void applyUpdateLockStateLocked(ActivityRecord r) {
2721 // Modifications to the UpdateLock state are done on our handler, outside
2722 // the activity manager's locks. The new state is determined based on the
2723 // state *now* of the relevant activity record. The object is passed to
2724 // the handler solely for logging detail, not to be consulted/modified.
2725 final boolean nextState = r != null && r.immersive;
2726 mHandler.sendMessage(
2727 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2730 final void showAskCompatModeDialogLocked(ActivityRecord r) {
2731 Message msg = Message.obtain();
2732 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2733 msg.obj = r.task.askedCompatMode ? null : r;
2734 mUiHandler.sendMessage(msg);
2737 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2738 String what, Object obj, ProcessRecord srcApp) {
2739 app.lastActivityTime = now;
2741 if (app.activities.size() > 0) {
2742 // Don't want to touch dependent processes that are hosting activities.
2746 int lrui = mLruProcesses.lastIndexOf(app);
2748 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2749 + what + " " + obj + " from " + srcApp);
2753 if (lrui >= index) {
2754 // Don't want to cause this to move dependent processes *back* in the
2755 // list as if they were less frequently used.
2759 if (lrui >= mLruProcessActivityStart) {
2760 // Don't want to touch dependent processes that are hosting activities.
2764 mLruProcesses.remove(lrui);
2768 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2769 + " in LRU list: " + app);
2770 mLruProcesses.add(index, app);
2774 private static void killProcessGroup(int uid, int pid) {
2775 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2776 Process.killProcessGroup(uid, pid);
2777 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2780 final void removeLruProcessLocked(ProcessRecord app) {
2781 int lrui = mLruProcesses.lastIndexOf(app);
2784 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2785 Process.killProcessQuiet(app.pid);
2786 killProcessGroup(app.uid, app.pid);
2788 if (lrui <= mLruProcessActivityStart) {
2789 mLruProcessActivityStart--;
2791 if (lrui <= mLruProcessServiceStart) {
2792 mLruProcessServiceStart--;
2794 mLruProcesses.remove(lrui);
2798 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2799 ProcessRecord client) {
2800 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2801 || app.treatLikeActivity;
2802 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2803 if (!activityChange && hasActivity) {
2804 // The process has activities, so we are only allowing activity-based adjustments
2805 // to move it. It should be kept in the front of the list with other
2806 // processes that have activities, and we don't want those to change their
2807 // order except due to activity operations.
2812 final long now = SystemClock.uptimeMillis();
2813 app.lastActivityTime = now;
2815 // First a quick reject: if the app is already at the position we will
2816 // put it, then there is nothing to do.
2818 final int N = mLruProcesses.size();
2819 if (N > 0 && mLruProcesses.get(N-1) == app) {
2820 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2824 if (mLruProcessServiceStart > 0
2825 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2826 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2831 int lrui = mLruProcesses.lastIndexOf(app);
2833 if (app.persistent && lrui >= 0) {
2834 // We don't care about the position of persistent processes, as long as
2835 // they are in the list.
2836 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2840 /* In progress: compute new position first, so we can avoid doing work
2841 if the process is not actually going to move. Not yet working.
2844 boolean inActivity = false, inService = false;
2846 // Process has activities, put it at the very tipsy-top.
2847 addIndex = mLruProcesses.size();
2848 nextIndex = mLruProcessServiceStart;
2850 } else if (hasService) {
2851 // Process has services, put it at the top of the service list.
2852 addIndex = mLruProcessActivityStart;
2853 nextIndex = mLruProcessServiceStart;
2857 // Process not otherwise of interest, it goes to the top of the non-service area.
2858 addIndex = mLruProcessServiceStart;
2859 if (client != null) {
2860 int clientIndex = mLruProcesses.lastIndexOf(client);
2861 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2863 if (clientIndex >= 0 && addIndex > clientIndex) {
2864 addIndex = clientIndex;
2867 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2870 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2871 + mLruProcessActivityStart + "): " + app);
2875 if (lrui < mLruProcessActivityStart) {
2876 mLruProcessActivityStart--;
2878 if (lrui < mLruProcessServiceStart) {
2879 mLruProcessServiceStart--;
2882 if (addIndex > lrui) {
2885 if (nextIndex > lrui) {
2889 mLruProcesses.remove(lrui);
2893 mLruProcesses.add(addIndex, app);
2895 mLruProcessActivityStart++;
2898 mLruProcessActivityStart++;
2904 final int N = mLruProcesses.size();
2905 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2906 // Process doesn't have activities, but has clients with
2907 // activities... move it up, but one below the top (the top
2908 // should always have a real activity).
2909 if (DEBUG_LRU) Slog.d(TAG_LRU,
2910 "Adding to second-top of LRU activity list: " + app);
2911 mLruProcesses.add(N - 1, app);
2912 // To keep it from spamming the LRU list (by making a bunch of clients),
2913 // we will push down any other entries owned by the app.
2914 final int uid = app.info.uid;
2915 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2916 ProcessRecord subProc = mLruProcesses.get(i);
2917 if (subProc.info.uid == uid) {
2918 // We want to push this one down the list. If the process after
2919 // it is for the same uid, however, don't do so, because we don't
2920 // want them internally to be re-ordered.
2921 if (mLruProcesses.get(i - 1).info.uid != uid) {
2922 if (DEBUG_LRU) Slog.d(TAG_LRU,
2923 "Pushing uid " + uid + " swapping at " + i + ": "
2924 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2925 ProcessRecord tmp = mLruProcesses.get(i);
2926 mLruProcesses.set(i, mLruProcesses.get(i - 1));
2927 mLruProcesses.set(i - 1, tmp);
2931 // A gap, we can stop here.
2936 // Process has activities, put it at the very tipsy-top.
2937 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2938 mLruProcesses.add(app);
2940 nextIndex = mLruProcessServiceStart;
2941 } else if (hasService) {
2942 // Process has services, put it at the top of the service list.
2943 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2944 mLruProcesses.add(mLruProcessActivityStart, app);
2945 nextIndex = mLruProcessServiceStart;
2946 mLruProcessActivityStart++;
2948 // Process not otherwise of interest, it goes to the top of the non-service area.
2949 int index = mLruProcessServiceStart;
2950 if (client != null) {
2951 // If there is a client, don't allow the process to be moved up higher
2952 // in the list than that client.
2953 int clientIndex = mLruProcesses.lastIndexOf(client);
2954 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2955 + " when updating " + app);
2956 if (clientIndex <= lrui) {
2957 // Don't allow the client index restriction to push it down farther in the
2958 // list than it already is.
2961 if (clientIndex >= 0 && index > clientIndex) {
2962 index = clientIndex;
2965 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2966 mLruProcesses.add(index, app);
2967 nextIndex = index-1;
2968 mLruProcessActivityStart++;
2969 mLruProcessServiceStart++;
2972 // If the app is currently using a content provider or service,
2973 // bump those processes as well.
2974 for (int j=app.connections.size()-1; j>=0; j--) {
2975 ConnectionRecord cr = app.connections.valueAt(j);
2976 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2977 && cr.binding.service.app != null
2978 && cr.binding.service.app.lruSeq != mLruSeq
2979 && !cr.binding.service.app.persistent) {
2980 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2981 "service connection", cr, app);
2984 for (int j=app.conProviders.size()-1; j>=0; j--) {
2985 ContentProviderRecord cpr = app.conProviders.get(j).provider;
2986 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2987 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2988 "provider reference", cpr, app);
2993 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2994 if (uid == Process.SYSTEM_UID) {
2995 // The system gets to run in any process. If there are multiple
2996 // processes with the same uid, just pick the first (this
2997 // should never happen).
2998 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2999 if (procs == null) return null;
3000 final int procCount = procs.size();
3001 for (int i = 0; i < procCount; i++) {
3002 final int procUid = procs.keyAt(i);
3003 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3004 // Don't use an app process or different user process for system component.
3007 return procs.valueAt(i);
3010 ProcessRecord proc = mProcessNames.get(processName, uid);
3011 if (false && proc != null && !keepIfLarge
3012 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3013 && proc.lastCachedPss >= 4000) {
3014 // Turn this condition on to cause killing to happen regularly, for testing.
3015 if (proc.baseProcessTracker != null) {
3016 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3018 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3019 } else if (proc != null && !keepIfLarge
3020 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3021 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3022 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3023 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3024 if (proc.baseProcessTracker != null) {
3025 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3027 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3033 void ensurePackageDexOpt(String packageName) {
3034 IPackageManager pm = AppGlobals.getPackageManager();
3036 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3039 } catch (RemoteException e) {
3043 boolean isNextTransitionForward() {
3044 int transit = mWindowManager.getPendingAppTransition();
3045 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3046 || transit == AppTransition.TRANSIT_TASK_OPEN
3047 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3050 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3051 String processName, String abiOverride, int uid, Runnable crashHandler) {
3052 synchronized(this) {
3053 ApplicationInfo info = new ApplicationInfo();
3054 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3055 // For isolated processes, the former contains the parent's uid and the latter the
3056 // actual uid of the isolated process.
3057 // In the special case introduced by this method (which is, starting an isolated
3058 // process directly from the SystemServer without an actual parent app process) the
3059 // closest thing to a parent's uid is SYSTEM_UID.
3060 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3061 // the |isolated| logic in the ProcessRecord constructor.
3062 info.uid = Process.SYSTEM_UID;
3063 info.processName = processName;
3064 info.className = entryPoint;
3065 info.packageName = "android";
3066 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3067 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3068 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3069 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3071 return proc != null ? proc.pid : 0;
3075 final ProcessRecord startProcessLocked(String processName,
3076 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3077 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3078 boolean isolated, boolean keepIfLarge) {
3079 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3080 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3081 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3082 null /* crashHandler */);
3085 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3086 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3087 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3088 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3089 long startTime = SystemClock.elapsedRealtime();
3092 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3093 checkTime(startTime, "startProcess: after getProcessRecord");
3095 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3096 // If we are in the background, then check to see if this process
3097 // is bad. If so, we will just silently fail.
3098 if (mBadProcesses.get(info.processName, info.uid) != null) {
3099 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3100 + "/" + info.processName);
3104 // When the user is explicitly starting a process, then clear its
3105 // crash count so that we won't make it bad until they see at
3106 // least one crash dialog again, and make the process good again
3107 // if it had been bad.
3108 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3109 + "/" + info.processName);
3110 mProcessCrashTimes.remove(info.processName, info.uid);
3111 if (mBadProcesses.get(info.processName, info.uid) != null) {
3112 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3113 UserHandle.getUserId(info.uid), info.uid,
3115 mBadProcesses.remove(info.processName, info.uid);
3122 // If this is an isolated process, it can't re-use an existing process.
3126 // We don't have to do anything more if:
3127 // (1) There is an existing application record; and
3128 // (2) The caller doesn't think it is dead, OR there is no thread
3129 // object attached to it so we know it couldn't have crashed; and
3130 // (3) There is a pid assigned to it, so it is either starting or
3132 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3133 + " app=" + app + " knownToBeDead=" + knownToBeDead
3134 + " thread=" + (app != null ? app.thread : null)
3135 + " pid=" + (app != null ? app.pid : -1));
3136 if (app != null && app.pid > 0) {
3137 if (!knownToBeDead || app.thread == null) {
3138 // We already have the app running, or are waiting for it to
3139 // come up (we have a pid but not yet its thread), so keep it.
3140 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3141 // If this is a new package in the process, add the package to the list
3142 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3143 checkTime(startTime, "startProcess: done, added package to proc");
3147 // An application record is attached to a previous process,
3149 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3150 checkTime(startTime, "startProcess: bad proc running, killing");
3151 killProcessGroup(app.uid, app.pid);
3152 handleAppDiedLocked(app, true, true);
3153 checkTime(startTime, "startProcess: done killing old proc");
3156 String hostingNameStr = hostingName != null
3157 ? hostingName.flattenToShortString() : null;
3160 checkTime(startTime, "startProcess: creating new process record");
3161 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3163 Slog.w(TAG, "Failed making new process record for "
3164 + processName + "/" + info.uid + " isolated=" + isolated);
3167 app.crashHandler = crashHandler;
3168 checkTime(startTime, "startProcess: done creating new process record");
3170 // If this is a new package in the process, add the package to the list
3171 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3172 checkTime(startTime, "startProcess: added package to existing proc");
3175 // If the system is not ready yet, then hold off on starting this
3176 // process until it is.
3177 if (!mProcessesReady
3178 && !isAllowedWhileBooting(info)
3179 && !allowWhileBooting) {
3180 if (!mProcessesOnHold.contains(app)) {
3181 mProcessesOnHold.add(app);
3183 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3184 "System not ready, putting on hold: " + app);
3185 checkTime(startTime, "startProcess: returning with proc on hold");
3189 checkTime(startTime, "startProcess: stepping in to startProcess");
3191 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3192 checkTime(startTime, "startProcess: done starting proc!");
3193 return (app.pid != 0) ? app : null;
3196 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3197 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3200 private final void startProcessLocked(ProcessRecord app,
3201 String hostingType, String hostingNameStr) {
3202 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3203 null /* entryPoint */, null /* entryPointArgs */);
3206 private final void startProcessLocked(ProcessRecord app, String hostingType,
3207 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3208 long startTime = SystemClock.elapsedRealtime();
3209 if (app.pid > 0 && app.pid != MY_PID) {
3210 checkTime(startTime, "startProcess: removing from pids map");
3211 synchronized (mPidsSelfLocked) {
3212 mPidsSelfLocked.remove(app.pid);
3213 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3215 checkTime(startTime, "startProcess: done removing from pids map");
3219 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3220 "startProcessLocked removing on hold: " + app);
3221 mProcessesOnHold.remove(app);
3223 checkTime(startTime, "startProcess: starting to update cpu stats");
3225 checkTime(startTime, "startProcess: done updating cpu stats");
3229 if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3230 // This is caught below as if we had failed to fork zygote
3231 throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3233 } catch (RemoteException e) {
3234 throw e.rethrowAsRuntimeException();
3239 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3240 if (!app.isolated) {
3241 int[] permGids = null;
3243 checkTime(startTime, "startProcess: getting gids from package manager");
3244 final IPackageManager pm = AppGlobals.getPackageManager();
3245 permGids = pm.getPackageGids(app.info.packageName, app.userId);
3246 MountServiceInternal mountServiceInternal = LocalServices.getService(
3247 MountServiceInternal.class);
3248 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3249 app.info.packageName);
3250 } catch (RemoteException e) {
3251 throw e.rethrowAsRuntimeException();
3255 * Add shared application and profile GIDs so applications can share some
3256 * resources like shared libraries and access user-wide resources
3258 if (ArrayUtils.isEmpty(permGids)) {
3261 gids = new int[permGids.length + 2];
3262 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3264 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3265 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3267 checkTime(startTime, "startProcess: building args");
3268 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3269 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3270 && mTopComponent != null
3271 && app.processName.equals(mTopComponent.getPackageName())) {
3274 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3275 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3280 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3281 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3282 // Also turn on CheckJNI for debuggable apps. It's quite
3283 // awkward to turn on otherwise.
3284 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3286 // Run the app in safe mode if its manifest requests so or the
3287 // system is booted in safe mode.
3288 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3289 mSafeMode == true) {
3290 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3292 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3293 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3295 String jitDebugProperty = SystemProperties.get("debug.usejit");
3296 if ("true".equals(jitDebugProperty)) {
3297 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3298 } else if (!"false".equals(jitDebugProperty)) {
3299 // If we didn't force disable by setting false, defer to the dalvik vm options.
3300 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3301 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3304 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3305 if ("true".equals(genDebugInfoProperty)) {
3306 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3308 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3309 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3311 if ("1".equals(SystemProperties.get("debug.assert"))) {
3312 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3315 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3316 if (requiredAbi == null) {
3317 requiredAbi = Build.SUPPORTED_ABIS[0];
3320 String instructionSet = null;
3321 if (app.info.primaryCpuAbi != null) {
3322 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3326 app.requiredAbi = requiredAbi;
3327 app.instructionSet = instructionSet;
3329 // Start the process. It will either succeed and return a result containing
3330 // the PID of the new process, or else throw a RuntimeException.
3331 boolean isActivityProcess = (entryPoint == null);
3332 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3333 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3335 checkTime(startTime, "startProcess: asking zygote to start proc");
3336 Process.ProcessStartResult startResult = Process.start(entryPoint,
3337 app.processName, uid, uid, gids, debugFlags, mountExternal,
3338 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3339 app.info.dataDir, entryPointArgs);
3340 checkTime(startTime, "startProcess: returned from zygote!");
3341 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3344 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3346 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3347 checkTime(startTime, "startProcess: done updating battery stats");
3349 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3350 UserHandle.getUserId(uid), startResult.pid, uid,
3351 app.processName, hostingType,
3352 hostingNameStr != null ? hostingNameStr : "");
3354 if (app.persistent) {
3355 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3358 checkTime(startTime, "startProcess: building log message");
3359 StringBuilder buf = mStringBuilder;
3361 buf.append("Start proc ");
3362 buf.append(startResult.pid);
3364 buf.append(app.processName);
3366 UserHandle.formatUid(buf, uid);
3367 if (!isActivityProcess) {
3369 buf.append(entryPoint);
3372 buf.append(" for ");
3373 buf.append(hostingType);
3374 if (hostingNameStr != null) {
3376 buf.append(hostingNameStr);
3378 Slog.i(TAG, buf.toString());
3379 app.setPid(startResult.pid);
3380 app.usingWrapper = startResult.usingWrapper;
3381 app.removed = false;
3383 app.killedByAm = false;
3384 checkTime(startTime, "startProcess: starting to update pids map");
3385 ProcessRecord oldApp;
3386 synchronized (mPidsSelfLocked) {
3387 oldApp = mPidsSelfLocked.get(startResult.pid);
3389 // If there is already an app occupying that pid that hasn't been cleaned up
3390 if (oldApp != null && !app.isolated) {
3391 // Clean up anything relating to this pid first
3392 Slog.w(TAG, "Reusing pid " + startResult.pid
3393 + " while app is still mapped to it");
3394 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3395 true /*replacingPid*/);
3397 synchronized (mPidsSelfLocked) {
3398 this.mPidsSelfLocked.put(startResult.pid, app);
3399 if (isActivityProcess) {
3400 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3402 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3403 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3406 checkTime(startTime, "startProcess: done updating pids map");
3407 } catch (RuntimeException e) {
3408 // XXX do better error recovery.
3410 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3412 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3414 Slog.e(TAG, "Failure starting process " + app.processName, e);
3418 void updateUsageStats(ActivityRecord component, boolean resumed) {
3419 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3420 "updateUsageStats: comp=" + component + "res=" + resumed);
3421 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3423 if (mUsageStatsService != null) {
3424 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3425 UsageEvents.Event.MOVE_TO_FOREGROUND);
3427 synchronized (stats) {
3428 stats.noteActivityResumedLocked(component.app.uid);
3431 if (mUsageStatsService != null) {
3432 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3433 UsageEvents.Event.MOVE_TO_BACKGROUND);
3435 synchronized (stats) {
3436 stats.noteActivityPausedLocked(component.app.uid);
3441 Intent getHomeIntent() {
3442 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3443 intent.setComponent(mTopComponent);
3444 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3445 intent.addCategory(Intent.CATEGORY_HOME);
3450 boolean startHomeActivityLocked(int userId, String reason) {
3451 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3452 && mTopAction == null) {
3453 // We are running in factory test mode, but unable to find
3454 // the factory test app, so just sit around displaying the
3455 // error message and don't try to start anything.
3458 Intent intent = getHomeIntent();
3459 ActivityInfo aInfo =
3460 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3461 if (aInfo != null) {
3462 intent.setComponent(new ComponentName(
3463 aInfo.applicationInfo.packageName, aInfo.name));
3464 // Don't do this if the home app is currently being
3466 aInfo = new ActivityInfo(aInfo);
3467 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3468 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3469 aInfo.applicationInfo.uid, true);
3470 if (app == null || app.instrumentationClass == null) {
3471 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3472 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3479 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3480 ActivityInfo ai = null;
3481 ComponentName comp = intent.getComponent();
3485 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3487 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3489 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3493 ai = info.activityInfo;
3496 } catch (RemoteException e) {
3504 * Starts the "new version setup screen" if appropriate.
3506 void startSetupActivityLocked() {
3507 // Only do this once per boot.
3508 if (mCheckedForSetup) {
3512 // We will show this screen if the current one is a different
3513 // version than the last one shown, and we are not running in
3514 // low-level factory test mode.
3515 final ContentResolver resolver = mContext.getContentResolver();
3516 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3517 Settings.Global.getInt(resolver,
3518 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3519 mCheckedForSetup = true;
3521 // See if we should be showing the platform update setup UI.
3522 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3523 List<ResolveInfo> ris = mContext.getPackageManager()
3524 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3526 // We don't allow third party apps to replace this.
3527 ResolveInfo ri = null;
3528 for (int i=0; ris != null && i<ris.size(); i++) {
3529 if ((ris.get(i).activityInfo.applicationInfo.flags
3530 & ApplicationInfo.FLAG_SYSTEM) != 0) {
3537 String vers = ri.activityInfo.metaData != null
3538 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3540 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3541 vers = ri.activityInfo.applicationInfo.metaData.getString(
3542 Intent.METADATA_SETUP_VERSION);
3544 String lastVers = Settings.Secure.getString(
3545 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3546 if (vers != null && !vers.equals(lastVers)) {
3547 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3548 intent.setComponent(new ComponentName(
3549 ri.activityInfo.packageName, ri.activityInfo.name));
3550 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3551 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3558 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3559 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3562 void enforceNotIsolatedCaller(String caller) {
3563 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3564 throw new SecurityException("Isolated process not allowed to call " + caller);
3568 void enforceShellRestriction(String restriction, int userHandle) {
3569 if (Binder.getCallingUid() == Process.SHELL_UID) {
3571 || mUserManager.hasUserRestriction(restriction, userHandle)) {
3572 throw new SecurityException("Shell does not have permission to access user "
3579 public int getFrontActivityScreenCompatMode() {
3580 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3581 synchronized (this) {
3582 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3587 public void setFrontActivityScreenCompatMode(int mode) {
3588 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3589 "setFrontActivityScreenCompatMode");
3590 synchronized (this) {
3591 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3596 public int getPackageScreenCompatMode(String packageName) {
3597 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3598 synchronized (this) {
3599 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3604 public void setPackageScreenCompatMode(String packageName, int mode) {
3605 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3606 "setPackageScreenCompatMode");
3607 synchronized (this) {
3608 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3613 public boolean getPackageAskScreenCompat(String packageName) {
3614 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3615 synchronized (this) {
3616 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3621 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3622 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3623 "setPackageAskScreenCompat");
3624 synchronized (this) {
3625 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3629 private boolean hasUsageStatsPermission(String callingPackage) {
3630 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3631 Binder.getCallingUid(), callingPackage);
3632 if (mode == AppOpsManager.MODE_DEFAULT) {
3633 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3634 == PackageManager.PERMISSION_GRANTED;
3636 return mode == AppOpsManager.MODE_ALLOWED;
3640 public int getPackageProcessState(String packageName, String callingPackage) {
3641 if (!hasUsageStatsPermission(callingPackage)) {
3642 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3643 "getPackageProcessState");
3646 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3647 synchronized (this) {
3648 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3649 final ProcessRecord proc = mLruProcesses.get(i);
3650 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3651 || procState > proc.setProcState) {
3652 boolean found = false;
3653 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3654 if (proc.pkgList.keyAt(j).equals(packageName)) {
3655 procState = proc.setProcState;
3659 if (proc.pkgDeps != null && !found) {
3660 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3661 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3662 procState = proc.setProcState;
3674 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3675 synchronized (this) {
3676 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3680 if (app.trimMemoryLevel < level && app.thread != null &&
3681 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3682 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3684 app.thread.scheduleTrimMemory(level);
3685 app.trimMemoryLevel = level;
3687 } catch (RemoteException e) {
3688 // Fallthrough to failure case.
3695 private void dispatchProcessesChanged() {
3697 synchronized (this) {
3698 N = mPendingProcessChanges.size();
3699 if (mActiveProcessChanges.length < N) {
3700 mActiveProcessChanges = new ProcessChangeItem[N];
3702 mPendingProcessChanges.toArray(mActiveProcessChanges);
3703 mPendingProcessChanges.clear();
3704 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3705 "*** Delivering " + N + " process changes");
3708 int i = mProcessObservers.beginBroadcast();
3711 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3712 if (observer != null) {
3714 for (int j=0; j<N; j++) {
3715 ProcessChangeItem item = mActiveProcessChanges[j];
3716 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3717 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3718 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3719 + item.uid + ": " + item.foregroundActivities);
3720 observer.onForegroundActivitiesChanged(item.pid, item.uid,
3721 item.foregroundActivities);
3723 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3724 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3725 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3726 + ": " + item.processState);
3727 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3730 } catch (RemoteException e) {
3734 mProcessObservers.finishBroadcast();
3736 synchronized (this) {
3737 for (int j=0; j<N; j++) {
3738 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3743 private void dispatchProcessDied(int pid, int uid) {
3744 int i = mProcessObservers.beginBroadcast();
3747 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3748 if (observer != null) {
3750 observer.onProcessDied(pid, uid);
3751 } catch (RemoteException e) {
3755 mProcessObservers.finishBroadcast();
3758 private void dispatchUidsChanged() {
3760 synchronized (this) {
3761 N = mPendingUidChanges.size();
3762 if (mActiveUidChanges.length < N) {
3763 mActiveUidChanges = new UidRecord.ChangeItem[N];
3765 for (int i=0; i<N; i++) {
3766 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3767 mActiveUidChanges[i] = change;
3768 change.uidRecord.pendingChange = null;
3769 change.uidRecord = null;
3771 mPendingUidChanges.clear();
3772 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3773 "*** Delivering " + N + " uid changes");
3776 if (mLocalPowerManager != null) {
3777 for (int j=0; j<N; j++) {
3778 UidRecord.ChangeItem item = mActiveUidChanges[j];
3780 mLocalPowerManager.uidGone(item.uid);
3782 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3787 int i = mUidObservers.beginBroadcast();
3790 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3791 if (observer != null) {
3793 for (int j=0; j<N; j++) {
3794 UidRecord.ChangeItem item = mActiveUidChanges[j];
3796 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3797 "UID gone uid=" + item.uid);
3798 observer.onUidGone(item.uid);
3800 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3801 "UID CHANGED uid=" + item.uid
3802 + ": " + item.processState);
3803 observer.onUidStateChanged(item.uid, item.processState);
3806 } catch (RemoteException e) {
3810 mUidObservers.finishBroadcast();
3812 synchronized (this) {
3813 for (int j=0; j<N; j++) {
3814 mAvailUidChanges.add(mActiveUidChanges[j]);
3820 public final int startActivity(IApplicationThread caller, String callingPackage,
3821 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3822 int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3823 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3824 resultWho, requestCode, startFlags, profilerInfo, options,
3825 UserHandle.getCallingUserId());
3829 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3830 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3831 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3832 enforceNotIsolatedCaller("startActivity");
3833 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3834 false, ALLOW_FULL_ONLY, "startActivity", null);
3835 // TODO: Switch to user app stacks here.
3836 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3837 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3838 profilerInfo, null, null, options, false, userId, null, null);
3842 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3843 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3844 int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3847 // This is very dangerous -- it allows you to perform a start activity (including
3848 // permission grants) as any app that may launch one of your own activities. So
3849 // we will only allow this to be done from activities that are part of the core framework,
3850 // and then only when they are running as the system.
3851 final ActivityRecord sourceRecord;
3852 final int targetUid;
3853 final String targetPackage;
3854 synchronized (this) {
3855 if (resultTo == null) {
3856 throw new SecurityException("Must be called from an activity");
3858 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3859 if (sourceRecord == null) {
3860 throw new SecurityException("Called with bad activity token: " + resultTo);
3862 if (!sourceRecord.info.packageName.equals("android")) {
3863 throw new SecurityException(
3864 "Must be called from an activity that is declared in the android package");
3866 if (sourceRecord.app == null) {
3867 throw new SecurityException("Called without a process attached to activity");
3869 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3870 // This is still okay, as long as this activity is running under the
3871 // uid of the original calling activity.
3872 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3873 throw new SecurityException(
3874 "Calling activity in uid " + sourceRecord.app.uid
3875 + " must be system uid or original calling uid "
3876 + sourceRecord.launchedFromUid);
3879 if (ignoreTargetSecurity) {
3880 if (intent.getComponent() == null) {
3881 throw new SecurityException(
3882 "Component must be specified with ignoreTargetSecurity");
3884 if (intent.getSelector() != null) {
3885 throw new SecurityException(
3886 "Selector not allowed with ignoreTargetSecurity");
3889 targetUid = sourceRecord.launchedFromUid;
3890 targetPackage = sourceRecord.launchedFromPackage;
3893 if (userId == UserHandle.USER_NULL) {
3894 userId = UserHandle.getUserId(sourceRecord.app.uid);
3897 // TODO: Switch to user app stacks here.
3899 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3900 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3901 null, null, options, ignoreTargetSecurity, userId, null, null);
3903 } catch (SecurityException e) {
3904 // XXX need to figure out how to propagate to original app.
3905 // A SecurityException here is generally actually a fault of the original
3906 // calling activity (such as a fairly granting permissions), so propagate it
3909 StringBuilder msg = new StringBuilder();
3910 msg.append("While launching");
3911 msg.append(intent.toString());
3913 msg.append(e.getMessage());
3920 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3921 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3922 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3923 enforceNotIsolatedCaller("startActivityAndWait");
3924 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3925 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3926 WaitResult res = new WaitResult();
3927 // TODO: Switch to user app stacks here.
3928 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3929 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3930 options, false, userId, null, null);
3935 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3936 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3937 int startFlags, Configuration config, Bundle options, int userId) {
3938 enforceNotIsolatedCaller("startActivityWithConfig");
3939 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3940 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3941 // TODO: Switch to user app stacks here.
3942 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3943 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3944 null, null, config, options, false, userId, null, null);
3949 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3950 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3951 int requestCode, int flagsMask, int flagsValues, Bundle options)
3952 throws TransactionTooLargeException {
3953 enforceNotIsolatedCaller("startActivityIntentSender");
3954 // Refuse possible leaked file descriptors
3955 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3956 throw new IllegalArgumentException("File descriptors passed in Intent");
3959 IIntentSender sender = intent.getTarget();
3960 if (!(sender instanceof PendingIntentRecord)) {
3961 throw new IllegalArgumentException("Bad PendingIntent object");
3964 PendingIntentRecord pir = (PendingIntentRecord)sender;
3966 synchronized (this) {
3967 // If this is coming from the currently resumed activity, it is
3968 // effectively saying that app switches are allowed at this point.
3969 final ActivityStack stack = getFocusedStack();
3970 if (stack.mResumedActivity != null &&
3971 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3972 mAppSwitchesAllowedTime = 0;
3975 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3976 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3981 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3982 Intent intent, String resolvedType, IVoiceInteractionSession session,
3983 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3984 Bundle options, int userId) {
3985 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3986 != PackageManager.PERMISSION_GRANTED) {
3987 String msg = "Permission Denial: startVoiceActivity() from pid="
3988 + Binder.getCallingPid()
3989 + ", uid=" + Binder.getCallingUid()
3990 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3992 throw new SecurityException(msg);
3994 if (session == null || interactor == null) {
3995 throw new NullPointerException("null session or interactor");
3997 userId = handleIncomingUser(callingPid, callingUid, userId,
3998 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3999 // TODO: Switch to user app stacks here.
4000 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4001 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4002 null, options, false, userId, null, null);
4006 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4007 synchronized (this) {
4008 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4010 mVoiceWakeLock.acquire();
4012 mVoiceWakeLock.release();
4019 public boolean startNextMatchingActivity(IBinder callingActivity,
4020 Intent intent, Bundle options) {
4021 // Refuse possible leaked file descriptors
4022 if (intent != null && intent.hasFileDescriptors() == true) {
4023 throw new IllegalArgumentException("File descriptors passed in Intent");
4026 synchronized (this) {
4027 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4029 ActivityOptions.abort(options);
4032 if (r.app == null || r.app.thread == null) {
4033 // The caller is not running... d'oh!
4034 ActivityOptions.abort(options);
4037 intent = new Intent(intent);
4038 // The caller is not allowed to change the data.
4039 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4040 // And we are resetting to find the next component...
4041 intent.setComponent(null);
4043 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4045 ActivityInfo aInfo = null;
4047 List<ResolveInfo> resolves =
4048 AppGlobals.getPackageManager().queryIntentActivities(
4049 intent, r.resolvedType,
4050 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4051 UserHandle.getCallingUserId());
4053 // Look for the original activity in the list...
4054 final int N = resolves != null ? resolves.size() : 0;
4055 for (int i=0; i<N; i++) {
4056 ResolveInfo rInfo = resolves.get(i);
4057 if (rInfo.activityInfo.packageName.equals(r.packageName)
4058 && rInfo.activityInfo.name.equals(r.info.name)) {
4059 // We found the current one... the next matching is
4063 aInfo = resolves.get(i).activityInfo;
4066 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4067 + "/" + r.info.name);
4068 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4069 + "/" + aInfo.name);
4074 } catch (RemoteException e) {
4077 if (aInfo == null) {
4078 // Nobody who is next!
4079 ActivityOptions.abort(options);
4080 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4084 intent.setComponent(new ComponentName(
4085 aInfo.applicationInfo.packageName, aInfo.name));
4086 intent.setFlags(intent.getFlags()&~(
4087 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4088 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4089 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4090 Intent.FLAG_ACTIVITY_NEW_TASK));
4092 // Okay now we need to start the new activity, replacing the
4093 // currently running activity. This is a little tricky because
4094 // we want to start the new one as if the current one is finished,
4095 // but not finish the current one first so that there is no flicker.
4097 final boolean wasFinishing = r.finishing;
4100 // Propagate reply information over to the new activity.
4101 final ActivityRecord resultTo = r.resultTo;
4102 final String resultWho = r.resultWho;
4103 final int requestCode = r.requestCode;
4105 if (resultTo != null) {
4106 resultTo.removeResultsLocked(r, resultWho, requestCode);
4109 final long origId = Binder.clearCallingIdentity();
4110 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4111 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4112 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4113 -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4114 Binder.restoreCallingIdentity(origId);
4116 r.finishing = wasFinishing;
4117 if (res != ActivityManager.START_SUCCESS) {
4125 public final int startActivityFromRecents(int taskId, Bundle options) {
4126 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4127 String msg = "Permission Denial: startActivityFromRecents called without " +
4128 START_TASKS_FROM_RECENTS;
4130 throw new SecurityException(msg);
4132 return startActivityFromRecentsInner(taskId, options);
4135 final int startActivityFromRecentsInner(int taskId, Bundle options) {
4136 final TaskRecord task;
4137 final int callingUid;
4138 final String callingPackage;
4139 final Intent intent;
4141 synchronized (this) {
4142 task = mStackSupervisor.anyTaskForIdLocked(taskId);
4144 throw new IllegalArgumentException("Task " + taskId + " not found.");
4146 if (task.getRootActivity() != null) {
4147 moveTaskToFrontLocked(task.taskId, 0, null);
4148 return ActivityManager.START_TASK_TO_FRONT;
4150 callingUid = task.mCallingUid;
4151 callingPackage = task.mCallingPackage;
4152 intent = task.intent;
4153 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4154 userId = task.userId;
4156 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4157 options, userId, null, task);
4160 final int startActivityInPackage(int uid, String callingPackage,
4161 Intent intent, String resolvedType, IBinder resultTo,
4162 String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4163 IActivityContainer container, TaskRecord inTask) {
4165 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4166 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4168 // TODO: Switch to user app stacks here.
4169 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4170 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4171 null, null, null, options, false, userId, container, inTask);
4176 public final int startActivities(IApplicationThread caller, String callingPackage,
4177 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4179 enforceNotIsolatedCaller("startActivities");
4180 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4181 false, ALLOW_FULL_ONLY, "startActivity", null);
4182 // TODO: Switch to user app stacks here.
4183 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4184 resolvedTypes, resultTo, options, userId);
4188 final int startActivitiesInPackage(int uid, String callingPackage,
4189 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4190 Bundle options, int userId) {
4192 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4193 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4194 // TODO: Switch to user app stacks here.
4195 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4196 resultTo, options, userId);
4201 public void reportActivityFullyDrawn(IBinder token) {
4202 synchronized (this) {
4203 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4207 r.reportFullyDrawnLocked();
4212 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4213 synchronized (this) {
4214 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4218 if (r.task != null && r.task.mResizeable) {
4219 // Fixed screen orientation isn't supported with resizeable activities.
4222 final long origId = Binder.clearCallingIdentity();
4223 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4224 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4225 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4226 if (config != null) {
4227 r.frozenBeforeDestroy = true;
4228 if (!updateConfigurationLocked(config, r, false, false)) {
4229 mStackSupervisor.resumeTopActivitiesLocked();
4232 Binder.restoreCallingIdentity(origId);
4237 public int getRequestedOrientation(IBinder token) {
4238 synchronized (this) {
4239 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4241 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4243 return mWindowManager.getAppOrientation(r.appToken);
4248 * This is the internal entry point for handling Activity.finish().
4250 * @param token The Binder token referencing the Activity we want to finish.
4251 * @param resultCode Result code, if any, from this Activity.
4252 * @param resultData Result data (Intent), if any, from this Activity.
4253 * @param finishTask Whether to finish the task associated with this Activity. Only applies to
4254 * the root Activity in the task.
4256 * @return Returns true if the activity successfully finished, or false if it is still running.
4259 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4260 boolean finishTask) {
4261 // Refuse possible leaked file descriptors
4262 if (resultData != null && resultData.hasFileDescriptors() == true) {
4263 throw new IllegalArgumentException("File descriptors passed in Intent");
4266 synchronized(this) {
4267 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4271 // Keep track of the root activity of the task before we finish it
4272 TaskRecord tr = r.task;
4273 ActivityRecord rootR = tr.getRootActivity();
4274 if (rootR == null) {
4275 Slog.w(TAG, "Finishing task with all activities already finished");
4277 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4279 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4280 mStackSupervisor.isLastLockedTask(tr)) {
4281 Slog.i(TAG, "Not finishing task in lock task mode");
4282 mStackSupervisor.showLockTaskToast();
4285 if (mController != null) {
4286 // Find the first activity that is not finishing.
4287 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4289 // ask watcher if this is allowed
4290 boolean resumeOK = true;
4292 resumeOK = mController.activityResuming(next.packageName);
4293 } catch (RemoteException e) {
4295 Watchdog.getInstance().setActivityController(null);
4299 Slog.i(TAG, "Not finishing activity because controller resumed");
4304 final long origId = Binder.clearCallingIdentity();
4307 if (finishTask && r == rootR) {
4308 // If requested, remove the task that is associated to this activity only if it
4309 // was the root activity in the task. The result code and data is ignored
4310 // because we don't support returning them across task boundaries.
4311 res = removeTaskByIdLocked(tr.taskId, false);
4313 Slog.i(TAG, "Removing task failed to finish activity");
4316 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4317 resultData, "app-request", true);
4319 Slog.i(TAG, "Failed to finish by app-request");
4324 Binder.restoreCallingIdentity(origId);
4330 public final void finishHeavyWeightApp() {
4331 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4332 != PackageManager.PERMISSION_GRANTED) {
4333 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4334 + Binder.getCallingPid()
4335 + ", uid=" + Binder.getCallingUid()
4336 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4338 throw new SecurityException(msg);
4341 synchronized(this) {
4342 if (mHeavyWeightProcess == null) {
4346 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4347 for (int i = 0; i < activities.size(); i++) {
4348 ActivityRecord r = activities.get(i);
4349 if (!r.finishing && r.isInStackLocked()) {
4350 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4351 null, "finish-heavy", true);
4355 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4356 mHeavyWeightProcess.userId, 0));
4357 mHeavyWeightProcess = null;
4362 public void crashApplication(int uid, int initialPid, String packageName,
4364 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4365 != PackageManager.PERMISSION_GRANTED) {
4366 String msg = "Permission Denial: crashApplication() from pid="
4367 + Binder.getCallingPid()
4368 + ", uid=" + Binder.getCallingUid()
4369 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4371 throw new SecurityException(msg);
4374 synchronized(this) {
4375 ProcessRecord proc = null;
4377 // Figure out which process to kill. We don't trust that initialPid
4378 // still has any relation to current pids, so must scan through the
4380 synchronized (mPidsSelfLocked) {
4381 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4382 ProcessRecord p = mPidsSelfLocked.valueAt(i);
4386 if (p.pid == initialPid) {
4390 if (p.pkgList.containsKey(packageName)) {
4397 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4398 + " initialPid=" + initialPid
4399 + " packageName=" + packageName);
4403 if (proc.thread != null) {
4404 if (proc.pid == Process.myPid()) {
4405 Log.w(TAG, "crashApplication: trying to crash self!");
4408 long ident = Binder.clearCallingIdentity();
4410 proc.thread.scheduleCrash(message);
4411 } catch (RemoteException e) {
4413 Binder.restoreCallingIdentity(ident);
4419 public final void finishSubActivity(IBinder token, String resultWho,
4421 synchronized(this) {
4422 final long origId = Binder.clearCallingIdentity();
4423 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4425 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4427 Binder.restoreCallingIdentity(origId);
4432 public boolean finishActivityAffinity(IBinder token) {
4433 synchronized(this) {
4434 final long origId = Binder.clearCallingIdentity();
4436 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4441 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4443 final TaskRecord task = r.task;
4444 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4445 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4446 mStackSupervisor.showLockTaskToast();
4449 return task.stack.finishActivityAffinityLocked(r);
4451 Binder.restoreCallingIdentity(origId);
4457 public void finishVoiceTask(IVoiceInteractionSession session) {
4458 synchronized(this) {
4459 final long origId = Binder.clearCallingIdentity();
4461 mStackSupervisor.finishVoiceTask(session);
4463 Binder.restoreCallingIdentity(origId);
4470 public boolean releaseActivityInstance(IBinder token) {
4471 synchronized(this) {
4472 final long origId = Binder.clearCallingIdentity();
4474 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4478 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4480 Binder.restoreCallingIdentity(origId);
4486 public void releaseSomeActivities(IApplicationThread appInt) {
4487 synchronized(this) {
4488 final long origId = Binder.clearCallingIdentity();
4490 ProcessRecord app = getRecordForAppLocked(appInt);
4491 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4493 Binder.restoreCallingIdentity(origId);
4499 public boolean willActivityBeVisible(IBinder token) {
4500 synchronized(this) {
4501 ActivityStack stack = ActivityRecord.getStackLocked(token);
4502 if (stack != null) {
4503 return stack.willActivityBeVisibleLocked(token);
4510 public void overridePendingTransition(IBinder token, String packageName,
4511 int enterAnim, int exitAnim) {
4512 synchronized(this) {
4513 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4518 final long origId = Binder.clearCallingIdentity();
4520 if (self.state == ActivityState.RESUMED
4521 || self.state == ActivityState.PAUSING) {
4522 mWindowManager.overridePendingAppTransition(packageName,
4523 enterAnim, exitAnim, null);
4526 Binder.restoreCallingIdentity(origId);
4531 * Main function for removing an existing process from the activity manager
4532 * as a result of that process going away. Clears out all connections
4535 private final void handleAppDiedLocked(ProcessRecord app,
4536 boolean restarting, boolean allowRestart) {
4538 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
4539 false /*replacingPid*/);
4540 if (!kept && !restarting) {
4541 removeLruProcessLocked(app);
4543 ProcessList.remove(pid);
4547 if (mProfileProc == app) {
4548 clearProfilerLocked();
4551 // Remove this application's activities from active lists.
4552 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4554 app.activities.clear();
4556 if (app.instrumentationClass != null) {
4557 Slog.w(TAG, "Crash of app " + app.processName
4558 + " running instrumentation " + app.instrumentationClass);
4559 Bundle info = new Bundle();
4560 info.putString("shortMsg", "Process crashed.");
4561 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4564 if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4565 // If there was nothing to resume, and we are not already
4566 // restarting this process, but there is a visible activity that
4567 // is hosted by the process... then make sure all visible
4568 // activities are running, taking care of restarting this
4570 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4574 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4575 IBinder threadBinder = thread.asBinder();
4576 // Find the application record.
4577 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4578 ProcessRecord rec = mLruProcesses.get(i);
4579 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4586 final ProcessRecord getRecordForAppLocked(
4587 IApplicationThread thread) {
4588 if (thread == null) {
4592 int appIndex = getLRURecordIndexForAppLocked(thread);
4593 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4596 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4597 // If there are no longer any background processes running,
4598 // and the app that died was not running instrumentation,
4599 // then tell everyone we are now low on memory.
4600 boolean haveBg = false;
4601 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4602 ProcessRecord rec = mLruProcesses.get(i);
4603 if (rec.thread != null
4604 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4611 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4613 long now = SystemClock.uptimeMillis();
4614 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4617 mLastMemUsageReportTime = now;
4620 final ArrayList<ProcessMemInfo> memInfos
4621 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4622 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4623 long now = SystemClock.uptimeMillis();
4624 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4625 ProcessRecord rec = mLruProcesses.get(i);
4626 if (rec == dyingProc || rec.thread == null) {
4630 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4631 rec.setProcState, rec.adjType, rec.makeAdjReason()));
4633 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4634 // The low memory report is overriding any current
4635 // state for a GC request. Make sure to do
4636 // heavy/important/visible/foreground processes first.
4637 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4638 rec.lastRequestedGc = 0;
4640 rec.lastRequestedGc = rec.lastLowMemory;
4642 rec.reportLowMemory = true;
4643 rec.lastLowMemory = now;
4644 mProcessesToGc.remove(rec);
4645 addProcessToGcListLocked(rec);
4649 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4650 mHandler.sendMessage(msg);
4652 scheduleAppGcsLocked();
4656 final void appDiedLocked(ProcessRecord app) {
4657 appDiedLocked(app, app.pid, app.thread, false);
4660 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4661 boolean fromBinderDied) {
4662 // First check if this ProcessRecord is actually active for the pid.
4663 synchronized (mPidsSelfLocked) {
4664 ProcessRecord curProc = mPidsSelfLocked.get(pid);
4665 if (curProc != app) {
4666 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4671 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4672 synchronized (stats) {
4673 stats.noteProcessDiedLocked(app.info.uid, pid);
4677 if (!fromBinderDied) {
4678 Process.killProcessQuiet(pid);
4680 killProcessGroup(app.uid, pid);
4684 // Clean up already done if the process has been re-started.
4685 if (app.pid == pid && app.thread != null &&
4686 app.thread.asBinder() == thread.asBinder()) {
4687 boolean doLowMem = app.instrumentationClass == null;
4688 boolean doOomAdj = doLowMem;
4689 if (!app.killedByAm) {
4690 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4692 mAllowLowerMemLevel = true;
4694 // Note that we always want to do oom adj to update our state with the
4695 // new number of procs.
4696 mAllowLowerMemLevel = false;
4699 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4700 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4701 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4702 handleAppDiedLocked(app, false, true);
4705 updateOomAdjLocked();
4708 doLowMemReportIfNeededLocked(app);
4710 } else if (app.pid != pid) {
4711 // A new process has already been started.
4712 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4713 + ") has died and restarted (pid " + app.pid + ").");
4714 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4715 } else if (DEBUG_PROCESSES) {
4716 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4717 + thread.asBinder());
4722 * If a stack trace dump file is configured, dump process stack traces.
4723 * @param clearTraces causes the dump file to be erased prior to the new
4724 * traces being written, if true; when false, the new traces will be
4725 * appended to any existing file content.
4726 * @param firstPids of dalvik VM processes to dump stack traces for first
4727 * @param lastPids of dalvik VM processes to dump stack traces for last
4728 * @param nativeProcs optional list of native process names to dump stack crawls
4729 * @return file containing stack traces, or null if no dump file is configured
4731 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4732 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4733 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4734 if (tracesPath == null || tracesPath.length() == 0) {
4738 File tracesFile = new File(tracesPath);
4740 File tracesDir = tracesFile.getParentFile();
4741 if (!tracesDir.exists()) {
4743 if (!SELinux.restorecon(tracesDir)) {
4747 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4749 if (clearTraces && tracesFile.exists()) tracesFile.delete();
4750 tracesFile.createNewFile();
4751 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4752 } catch (IOException e) {
4753 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4757 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4761 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4762 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4763 // Use a FileObserver to detect when traces finish writing.
4764 // The order of traces is considered important to maintain for legibility.
4765 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4767 public synchronized void onEvent(int event, String path) { notify(); }
4771 observer.startWatching();
4773 // First collect all of the stacks of the most important pids.
4774 if (firstPids != null) {
4776 int num = firstPids.size();
4777 for (int i = 0; i < num; i++) {
4778 synchronized (observer) {
4779 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4780 observer.wait(200); // Wait for write-close, give up after 200msec
4783 } catch (InterruptedException e) {
4788 // Next collect the stacks of the native pids
4789 if (nativeProcs != null) {
4790 int[] pids = Process.getPidsForCommands(nativeProcs);
4792 for (int pid : pids) {
4793 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4798 // Lastly, measure CPU usage.
4799 if (processCpuTracker != null) {
4800 processCpuTracker.init();
4802 processCpuTracker.update();
4804 synchronized (processCpuTracker) {
4805 processCpuTracker.wait(500); // measure over 1/2 second.
4807 } catch (InterruptedException e) {
4809 processCpuTracker.update();
4811 // We'll take the stack crawls of just the top apps using CPU.
4812 final int N = processCpuTracker.countWorkingStats();
4814 for (int i=0; i<N && numProcs<5; i++) {
4815 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4816 if (lastPids.indexOfKey(stats.pid) >= 0) {
4819 synchronized (observer) {
4820 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4821 observer.wait(200); // Wait for write-close, give up after 200msec
4823 } catch (InterruptedException e) {
4831 observer.stopWatching();
4835 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4836 if (true || IS_USER_BUILD) {
4839 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4840 if (tracesPath == null || tracesPath.length() == 0) {
4844 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4845 StrictMode.allowThreadDiskWrites();
4847 final File tracesFile = new File(tracesPath);
4848 final File tracesDir = tracesFile.getParentFile();
4849 final File tracesTmp = new File(tracesDir, "__tmp__");
4851 if (!tracesDir.exists()) {
4853 if (!SELinux.restorecon(tracesDir.getPath())) {
4857 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4859 if (tracesFile.exists()) {
4861 tracesFile.renameTo(tracesTmp);
4863 StringBuilder sb = new StringBuilder();
4864 Time tobj = new Time();
4865 tobj.set(System.currentTimeMillis());
4866 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4868 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4869 sb.append(" since ");
4871 FileOutputStream fos = new FileOutputStream(tracesFile);
4872 fos.write(sb.toString().getBytes());
4874 fos.write("\n*** No application process!".getBytes());
4877 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4878 } catch (IOException e) {
4879 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4884 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4885 firstPids.add(app.pid);
4886 dumpStackTraces(tracesPath, firstPids, null, null, null);
4889 File lastTracesFile = null;
4890 File curTracesFile = null;
4891 for (int i=9; i>=0; i--) {
4892 String name = String.format(Locale.US, "slow%02d.txt", i);
4893 curTracesFile = new File(tracesDir, name);
4894 if (curTracesFile.exists()) {
4895 if (lastTracesFile != null) {
4896 curTracesFile.renameTo(lastTracesFile);
4898 curTracesFile.delete();
4901 lastTracesFile = curTracesFile;
4903 tracesFile.renameTo(curTracesFile);
4904 if (tracesTmp.exists()) {
4905 tracesTmp.renameTo(tracesFile);
4908 StrictMode.setThreadPolicy(oldPolicy);
4912 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4913 ActivityRecord parent, boolean aboveSystem, final String annotation) {
4914 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4915 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4917 if (mController != null) {
4919 // 0 == continue, -1 = kill process immediately
4920 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4921 if (res < 0 && app.pid != MY_PID) {
4922 app.kill("anr", true);
4924 } catch (RemoteException e) {
4926 Watchdog.getInstance().setActivityController(null);
4930 long anrTime = SystemClock.uptimeMillis();
4931 if (MONITOR_CPU_USAGE) {
4932 updateCpuStatsNow();
4935 synchronized (this) {
4936 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4937 if (mShuttingDown) {
4938 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4940 } else if (app.notResponding) {
4941 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4943 } else if (app.crashing) {
4944 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4948 // In case we come through here for the same app before completing
4949 // this one, mark as anring now so we will bail out.
4950 app.notResponding = true;
4952 // Log the ANR to the event log.
4953 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4954 app.processName, app.info.flags, annotation);
4956 // Dump thread traces as quickly as we can, starting with "interesting" processes.
4957 firstPids.add(app.pid);
4959 int parentPid = app.pid;
4960 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4961 if (parentPid != app.pid) firstPids.add(parentPid);
4963 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4965 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4966 ProcessRecord r = mLruProcesses.get(i);
4967 if (r != null && r.thread != null) {
4969 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4973 lastPids.put(pid, Boolean.TRUE);
4980 // Log the ANR to the main log.
4981 StringBuilder info = new StringBuilder();
4983 info.append("ANR in ").append(app.processName);
4984 if (activity != null && activity.shortComponentName != null) {
4985 info.append(" (").append(activity.shortComponentName).append(")");
4988 info.append("PID: ").append(app.pid).append("\n");
4989 if (annotation != null) {
4990 info.append("Reason: ").append(annotation).append("\n");
4992 if (parent != null && parent != activity) {
4993 info.append("Parent: ").append(parent.shortComponentName).append("\n");
4996 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4998 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4999 NATIVE_STACKS_OF_INTEREST);
5001 String cpuInfo = null;
5002 if (MONITOR_CPU_USAGE) {
5003 updateCpuStatsNow();
5004 synchronized (mProcessCpuTracker) {
5005 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5007 info.append(processCpuTracker.printCurrentLoad());
5008 info.append(cpuInfo);
5011 info.append(processCpuTracker.printCurrentState(anrTime));
5013 Slog.e(TAG, info.toString());
5014 if (tracesFile == null) {
5015 // There is no trace file, so dump (only) the alleged culprit's threads to the log
5016 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5019 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5020 cpuInfo, tracesFile, null);
5022 if (mController != null) {
5024 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5025 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5027 if (res < 0 && app.pid != MY_PID) {
5028 app.kill("anr", true);
5030 synchronized (this) {
5031 mServices.scheduleServiceTimeoutLocked(app);
5036 } catch (RemoteException e) {
5038 Watchdog.getInstance().setActivityController(null);
5042 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5043 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5044 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5046 synchronized (this) {
5047 mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5049 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5050 app.kill("bg anr", true);
5054 // Set the app's notResponding state, and look up the errorReportReceiver
5055 makeAppNotRespondingLocked(app,
5056 activity != null ? activity.shortComponentName : null,
5057 annotation != null ? "ANR " + annotation : "ANR",
5060 // Bring up the infamous App Not Responding dialog
5061 Message msg = Message.obtain();
5062 HashMap<String, Object> map = new HashMap<String, Object>();
5063 msg.what = SHOW_NOT_RESPONDING_MSG;
5065 msg.arg1 = aboveSystem ? 1 : 0;
5066 map.put("app", app);
5067 if (activity != null) {
5068 map.put("activity", activity);
5071 mUiHandler.sendMessage(msg);
5075 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5076 if (!mLaunchWarningShown) {
5077 mLaunchWarningShown = true;
5078 mUiHandler.post(new Runnable() {
5081 synchronized (ActivityManagerService.this) {
5082 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5084 mUiHandler.postDelayed(new Runnable() {
5087 synchronized (ActivityManagerService.this) {
5089 mLaunchWarningShown = false;
5100 public boolean clearApplicationUserData(final String packageName,
5101 final IPackageDataObserver observer, int userId) {
5102 enforceNotIsolatedCaller("clearApplicationUserData");
5103 if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5104 throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5106 int uid = Binder.getCallingUid();
5107 int pid = Binder.getCallingPid();
5108 userId = handleIncomingUser(pid, uid,
5109 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5110 long callingId = Binder.clearCallingIdentity();
5112 IPackageManager pm = AppGlobals.getPackageManager();
5114 synchronized(this) {
5116 pkgUid = pm.getPackageUid(packageName, userId);
5117 } catch (RemoteException e) {
5120 Slog.w(TAG, "Invalid packageName: " + packageName);
5121 if (observer != null) {
5123 observer.onRemoveCompleted(packageName, false);
5124 } catch (RemoteException e) {
5125 Slog.i(TAG, "Observer no longer exists.");
5130 if (uid == pkgUid || checkComponentPermission(
5131 android.Manifest.permission.CLEAR_APP_USER_DATA,
5133 == PackageManager.PERMISSION_GRANTED) {
5134 forceStopPackageLocked(packageName, pkgUid, "clear data");
5136 throw new SecurityException("PID " + pid + " does not have permission "
5137 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5138 + " of package " + packageName);
5141 // Remove all tasks match the cleared application package and user
5142 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5143 final TaskRecord tr = mRecentTasks.get(i);
5144 final String taskPackageName =
5145 tr.getBaseIntent().getComponent().getPackageName();
5146 if (tr.userId != userId) continue;
5147 if (!taskPackageName.equals(packageName)) continue;
5148 removeTaskByIdLocked(tr.taskId, false);
5153 // Clear application user data
5154 pm.clearApplicationUserData(packageName, observer, userId);
5156 synchronized(this) {
5157 // Remove all permissions granted from/to this package
5158 removeUriPermissionsForPackageLocked(packageName, userId, true);
5161 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5162 Uri.fromParts("package", packageName, null));
5163 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5164 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5165 null, null, 0, null, null, null, null, false, false, userId);
5166 } catch (RemoteException e) {
5169 Binder.restoreCallingIdentity(callingId);
5175 public void killBackgroundProcesses(final String packageName, int userId) {
5176 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5177 != PackageManager.PERMISSION_GRANTED &&
5178 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5179 != PackageManager.PERMISSION_GRANTED) {
5180 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5181 + Binder.getCallingPid()
5182 + ", uid=" + Binder.getCallingUid()
5183 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5185 throw new SecurityException(msg);
5188 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5189 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5190 long callingId = Binder.clearCallingIdentity();
5192 IPackageManager pm = AppGlobals.getPackageManager();
5193 synchronized(this) {
5196 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5197 } catch (RemoteException e) {
5200 Slog.w(TAG, "Invalid packageName: " + packageName);
5203 killPackageProcessesLocked(packageName, appId, userId,
5204 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5207 Binder.restoreCallingIdentity(callingId);
5212 public void killAllBackgroundProcesses() {
5213 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5214 != PackageManager.PERMISSION_GRANTED) {
5215 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5216 + Binder.getCallingPid()
5217 + ", uid=" + Binder.getCallingUid()
5218 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5220 throw new SecurityException(msg);
5223 long callingId = Binder.clearCallingIdentity();
5225 synchronized(this) {
5226 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5227 final int NP = mProcessNames.getMap().size();
5228 for (int ip=0; ip<NP; ip++) {
5229 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5230 final int NA = apps.size();
5231 for (int ia=0; ia<NA; ia++) {
5232 ProcessRecord app = apps.valueAt(ia);
5233 if (app.persistent) {
5234 // we don't kill persistent processes
5239 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5246 int N = procs.size();
5247 for (int i=0; i<N; i++) {
5248 removeProcessLocked(procs.get(i), false, true, "kill all background");
5250 mAllowLowerMemLevel = true;
5251 updateOomAdjLocked();
5252 doLowMemReportIfNeededLocked(null);
5255 Binder.restoreCallingIdentity(callingId);
5260 public void forceStopPackage(final String packageName, int userId) {
5261 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5262 != PackageManager.PERMISSION_GRANTED) {
5263 String msg = "Permission Denial: forceStopPackage() from pid="
5264 + Binder.getCallingPid()
5265 + ", uid=" + Binder.getCallingUid()
5266 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5268 throw new SecurityException(msg);
5270 final int callingPid = Binder.getCallingPid();
5271 userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5272 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5273 long callingId = Binder.clearCallingIdentity();
5275 IPackageManager pm = AppGlobals.getPackageManager();
5276 synchronized(this) {
5277 int[] users = userId == UserHandle.USER_ALL
5278 ? getUsersLocked() : new int[] { userId };
5279 for (int user : users) {
5282 pkgUid = pm.getPackageUid(packageName, user);
5283 } catch (RemoteException e) {
5286 Slog.w(TAG, "Invalid packageName: " + packageName);
5290 pm.setPackageStoppedState(packageName, true, user);
5291 } catch (RemoteException e) {
5292 } catch (IllegalArgumentException e) {
5293 Slog.w(TAG, "Failed trying to unstop package "
5294 + packageName + ": " + e);
5296 if (isUserRunningLocked(user, false)) {
5297 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5302 Binder.restoreCallingIdentity(callingId);
5307 public void addPackageDependency(String packageName) {
5308 synchronized (this) {
5309 int callingPid = Binder.getCallingPid();
5310 if (callingPid == Process.myPid()) {
5315 synchronized (mPidsSelfLocked) {
5316 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5319 if (proc.pkgDeps == null) {
5320 proc.pkgDeps = new ArraySet<String>(1);
5322 proc.pkgDeps.add(packageName);
5328 * The pkg name and app id have to be specified.
5331 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5335 // Make sure the uid is valid.
5337 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5340 int callerUid = Binder.getCallingUid();
5341 // Only the system server can kill an application
5342 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5343 // Post an aysnc message to kill the application
5344 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5347 Bundle bundle = new Bundle();
5348 bundle.putString("pkg", pkg);
5349 bundle.putString("reason", reason);
5351 mHandler.sendMessage(msg);
5353 throw new SecurityException(callerUid + " cannot kill pkg: " +
5359 public void closeSystemDialogs(String reason) {
5360 enforceNotIsolatedCaller("closeSystemDialogs");
5362 final int pid = Binder.getCallingPid();
5363 final int uid = Binder.getCallingUid();
5364 final long origId = Binder.clearCallingIdentity();
5366 synchronized (this) {
5367 // Only allow this from foreground processes, so that background
5368 // applications can't abuse it to prevent system UI from being shown.
5369 if (uid >= Process.FIRST_APPLICATION_UID) {
5371 synchronized (mPidsSelfLocked) {
5372 proc = mPidsSelfLocked.get(pid);
5374 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5375 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5376 + " from background process " + proc);
5380 closeSystemDialogsLocked(reason);
5383 Binder.restoreCallingIdentity(origId);
5387 void closeSystemDialogsLocked(String reason) {
5388 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5389 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5390 | Intent.FLAG_RECEIVER_FOREGROUND);
5391 if (reason != null) {
5392 intent.putExtra("reason", reason);
5394 mWindowManager.closeSystemDialogs(reason);
5396 mStackSupervisor.closeSystemDialogsLocked();
5398 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5399 AppOpsManager.OP_NONE, null, false, false,
5400 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5404 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5405 enforceNotIsolatedCaller("getProcessMemoryInfo");
5406 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5407 for (int i=pids.length-1; i>=0; i--) {
5410 synchronized (this) {
5411 synchronized (mPidsSelfLocked) {
5412 proc = mPidsSelfLocked.get(pids[i]);
5413 oomAdj = proc != null ? proc.setAdj : 0;
5416 infos[i] = new Debug.MemoryInfo();
5417 Debug.getMemoryInfo(pids[i], infos[i]);
5419 synchronized (this) {
5420 if (proc.thread != null && proc.setAdj == oomAdj) {
5421 // Record this for posterity if the process has been stable.
5422 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5423 infos[i].getTotalUss(), false, proc.pkgList);
5432 public long[] getProcessPss(int[] pids) {
5433 enforceNotIsolatedCaller("getProcessPss");
5434 long[] pss = new long[pids.length];
5435 for (int i=pids.length-1; i>=0; i--) {
5438 synchronized (this) {
5439 synchronized (mPidsSelfLocked) {
5440 proc = mPidsSelfLocked.get(pids[i]);
5441 oomAdj = proc != null ? proc.setAdj : 0;
5444 long[] tmpUss = new long[1];
5445 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5447 synchronized (this) {
5448 if (proc.thread != null && proc.setAdj == oomAdj) {
5449 // Record this for posterity if the process has been stable.
5450 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5459 public void killApplicationProcess(String processName, int uid) {
5460 if (processName == null) {
5464 int callerUid = Binder.getCallingUid();
5465 // Only the system server can kill an application
5466 if (callerUid == Process.SYSTEM_UID) {
5467 synchronized (this) {
5468 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5469 if (app != null && app.thread != null) {
5471 app.thread.scheduleSuicide();
5472 } catch (RemoteException e) {
5473 // If the other end already died, then our work here is done.
5476 Slog.w(TAG, "Process/uid not found attempting kill of "
5477 + processName + " / " + uid);
5481 throw new SecurityException(callerUid + " cannot kill app process: " +
5486 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5487 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5488 false, true, false, false, UserHandle.getUserId(uid), reason);
5489 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5490 Uri.fromParts("package", packageName, null));
5491 if (!mProcessesReady) {
5492 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5493 | Intent.FLAG_RECEIVER_FOREGROUND);
5495 intent.putExtra(Intent.EXTRA_UID, uid);
5496 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5497 broadcastIntentLocked(null, null, intent,
5498 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5499 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5502 private void forceStopUserLocked(int userId, String reason) {
5503 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5504 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5505 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5506 | Intent.FLAG_RECEIVER_FOREGROUND);
5507 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5508 broadcastIntentLocked(null, null, intent,
5509 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5510 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5513 private final boolean killPackageProcessesLocked(String packageName, int appId,
5514 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5515 boolean doit, boolean evenPersistent, String reason) {
5516 ArrayList<ProcessRecord> procs = new ArrayList<>();
5518 // Remove all processes this package may have touched: all with the
5519 // same UID (except for the system or root user), and all whose name
5520 // matches the package name.
5521 final int NP = mProcessNames.getMap().size();
5522 for (int ip=0; ip<NP; ip++) {
5523 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5524 final int NA = apps.size();
5525 for (int ia=0; ia<NA; ia++) {
5526 ProcessRecord app = apps.valueAt(ia);
5527 if (app.persistent && !evenPersistent) {
5528 // we don't kill persistent processes
5538 // Skip process if it doesn't meet our oom adj requirement.
5539 if (app.setAdj < minOomAdj) {
5543 // If no package is specified, we call all processes under the
5545 if (packageName == null) {
5546 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5549 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5552 // Package has been specified, we want to hit all processes
5553 // that match it. We need to qualify this by the processes
5554 // that are running under the specified app and user ID.
5556 final boolean isDep = app.pkgDeps != null
5557 && app.pkgDeps.contains(packageName);
5558 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5561 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5564 if (!app.pkgList.containsKey(packageName) && !isDep) {
5569 // Process has passed all conditions, kill it!
5578 int N = procs.size();
5579 for (int i=0; i<N; i++) {
5580 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5582 updateOomAdjLocked();
5586 private void cleanupDisabledPackageComponentsLocked(
5587 String packageName, int userId, boolean killProcess, String[] changedClasses) {
5589 Set<String> disabledClasses = null;
5590 boolean packageDisabled = false;
5591 IPackageManager pm = AppGlobals.getPackageManager();
5593 if (changedClasses == null) {
5594 // Nothing changed...
5598 // Determine enable/disable state of the package and its components.
5599 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5600 for (int i = changedClasses.length - 1; i >= 0; i--) {
5601 final String changedClass = changedClasses[i];
5603 if (changedClass.equals(packageName)) {
5605 // Entire package setting changed
5606 enabled = pm.getApplicationEnabledSetting(packageName,
5607 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5608 } catch (Exception e) {
5609 // No such package/component; probably racing with uninstall. In any
5610 // event it means we have nothing further to do here.
5613 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5614 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5615 if (packageDisabled) {
5616 // Entire package is disabled.
5617 // No need to continue to check component states.
5618 disabledClasses = null;
5623 enabled = pm.getComponentEnabledSetting(
5624 new ComponentName(packageName, changedClass),
5625 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5626 } catch (Exception e) {
5627 // As above, probably racing with uninstall.
5630 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5631 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5632 if (disabledClasses == null) {
5633 disabledClasses = new ArraySet<>(changedClasses.length);
5635 disabledClasses.add(changedClass);
5640 if (!packageDisabled && disabledClasses == null) {
5641 // Nothing to do here...
5645 // Clean-up disabled activities.
5646 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5647 packageName, disabledClasses, true, false, userId) && mBooted) {
5648 mStackSupervisor.resumeTopActivitiesLocked();
5649 mStackSupervisor.scheduleIdleLocked();
5652 // Clean-up disabled tasks
5653 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5655 // Clean-up disabled services.
5656 mServices.bringDownDisabledPackageServicesLocked(
5657 packageName, disabledClasses, userId, false, killProcess, true);
5659 // Clean-up disabled providers.
5660 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5661 mProviderMap.collectPackageProvidersLocked(
5662 packageName, disabledClasses, true, false, userId, providers);
5663 for (int i = providers.size() - 1; i >= 0; i--) {
5664 removeDyingProviderLocked(null, providers.get(i), true);
5667 // Clean-up disabled broadcast receivers.
5668 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5669 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5670 packageName, disabledClasses, userId, true);
5675 private final boolean forceStopPackageLocked(String packageName, int appId,
5676 boolean callerWillRestart, boolean purgeCache, boolean doit,
5677 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5680 if (userId == UserHandle.USER_ALL && packageName == null) {
5681 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5684 if (appId < 0 && packageName != null) {
5686 appId = UserHandle.getAppId(
5687 AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5688 } catch (RemoteException e) {
5693 if (packageName != null) {
5694 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5695 + " user=" + userId + ": " + reason);
5697 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5700 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5701 for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5702 SparseArray<Long> ba = pmap.valueAt(ip);
5703 for (i = ba.size() - 1; i >= 0; i--) {
5704 boolean remove = false;
5705 final int entUid = ba.keyAt(i);
5706 if (packageName != null) {
5707 if (userId == UserHandle.USER_ALL) {
5708 if (UserHandle.getAppId(entUid) == appId) {
5712 if (entUid == UserHandle.getUid(userId, appId)) {
5716 } else if (UserHandle.getUserId(entUid) == userId) {
5723 if (ba.size() == 0) {
5729 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5730 -100, callerWillRestart, true, doit, evenPersistent,
5731 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5733 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5734 packageName, null, doit, evenPersistent, userId)) {
5738 didSomething = true;
5741 if (mServices.bringDownDisabledPackageServicesLocked(
5742 packageName, null, userId, evenPersistent, true, doit)) {
5746 didSomething = true;
5749 if (packageName == null) {
5750 // Remove all sticky broadcasts from this user.
5751 mStickyBroadcasts.remove(userId);
5754 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5755 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5756 userId, providers)) {
5760 didSomething = true;
5762 for (i = providers.size() - 1; i >= 0; i--) {
5763 removeDyingProviderLocked(null, providers.get(i), true);
5766 // Remove transient permissions granted from/to this package/user
5767 removeUriPermissionsForPackageLocked(packageName, userId, false);
5770 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5771 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5772 packageName, null, userId, doit);
5776 if (packageName == null || uninstalling) {
5777 // Remove pending intents. For now we only do this when force
5778 // stopping users, because we have some problems when doing this
5779 // for packages -- app widgets are not currently cleaned up for
5780 // such packages, so they can be left with bad pending intents.
5781 if (mIntentSenderRecords.size() > 0) {
5782 Iterator<WeakReference<PendingIntentRecord>> it
5783 = mIntentSenderRecords.values().iterator();
5784 while (it.hasNext()) {
5785 WeakReference<PendingIntentRecord> wpir = it.next();
5790 PendingIntentRecord pir = wpir.get();
5795 if (packageName == null) {
5796 // Stopping user, remove all objects for the user.
5797 if (pir.key.userId != userId) {
5798 // Not the same user, skip it.
5802 if (UserHandle.getAppId(pir.uid) != appId) {
5803 // Different app id, skip it.
5806 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5807 // Different user, skip it.
5810 if (!pir.key.packageName.equals(packageName)) {
5811 // Different package, skip it.
5818 didSomething = true;
5820 pir.canceled = true;
5821 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5822 pir.key.activity.pendingResults.remove(pir.ref);
5829 if (purgeCache && packageName != null) {
5830 AttributeCache ac = AttributeCache.instance();
5832 ac.removePackage(packageName);
5836 mStackSupervisor.resumeTopActivitiesLocked();
5837 mStackSupervisor.scheduleIdleLocked();
5841 return didSomething;
5844 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5845 ProcessRecord old = mProcessNames.remove(name, uid);
5847 old.uidRecord.numProcs--;
5848 if (old.uidRecord.numProcs == 0) {
5849 // No more processes using this uid, tell clients it is gone.
5850 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5851 "No more processes in " + old.uidRecord);
5852 enqueueUidChangeLocked(old.uidRecord, true);
5853 mActiveUids.remove(uid);
5855 old.uidRecord = null;
5857 mIsolatedProcesses.remove(uid);
5861 private final void addProcessNameLocked(ProcessRecord proc) {
5862 // We shouldn't already have a process under this name, but just in case we
5863 // need to clean up whatever may be there now.
5864 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5865 if (old == proc && proc.persistent) {
5866 // We are re-adding a persistent process. Whatevs! Just leave it there.
5867 Slog.w(TAG, "Re-adding persistent process " + proc);
5868 } else if (old != null) {
5869 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5871 UidRecord uidRec = mActiveUids.get(proc.uid);
5872 if (uidRec == null) {
5873 uidRec = new UidRecord(proc.uid);
5874 // This is the first appearance of the uid, report it now!
5875 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5876 "Creating new process uid: " + uidRec);
5877 mActiveUids.put(proc.uid, uidRec);
5878 enqueueUidChangeLocked(uidRec, false);
5880 proc.uidRecord = uidRec;
5882 mProcessNames.put(proc.processName, proc.uid, proc);
5883 if (proc.isolated) {
5884 mIsolatedProcesses.put(proc.uid, proc);
5888 private final boolean removeProcessLocked(ProcessRecord app,
5889 boolean callerWillRestart, boolean allowRestart, String reason) {
5890 final String name = app.processName;
5891 final int uid = app.uid;
5892 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5893 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5895 removeProcessNameLocked(name, uid);
5896 if (mHeavyWeightProcess == app) {
5897 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5898 mHeavyWeightProcess.userId, 0));
5899 mHeavyWeightProcess = null;
5901 boolean needRestart = false;
5902 if (app.pid > 0 && app.pid != MY_PID) {
5904 synchronized (mPidsSelfLocked) {
5905 mPidsSelfLocked.remove(pid);
5906 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5908 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5910 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5912 boolean willRestart = false;
5913 if (app.persistent && !app.isolated) {
5914 if (!callerWillRestart) {
5920 app.kill(reason, true);
5921 handleAppDiedLocked(app, willRestart, allowRestart);
5923 removeLruProcessLocked(app);
5924 addAppLocked(app.info, false, null /* ABI override */);
5927 mRemovedProcesses.add(app);
5933 private final void processStartTimedOutLocked(ProcessRecord app) {
5934 final int pid = app.pid;
5935 boolean gone = false;
5936 synchronized (mPidsSelfLocked) {
5937 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5938 if (knownApp != null && knownApp.thread == null) {
5939 mPidsSelfLocked.remove(pid);
5945 Slog.w(TAG, "Process " + app + " failed to attach");
5946 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5947 pid, app.uid, app.processName);
5948 removeProcessNameLocked(app.processName, app.uid);
5949 if (mHeavyWeightProcess == app) {
5950 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5951 mHeavyWeightProcess.userId, 0));
5952 mHeavyWeightProcess = null;
5954 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5956 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5958 // Take care of any launching providers waiting for this process.
5959 checkAppInLaunchingProvidersLocked(app, true);
5960 // Take care of any services that are waiting for the process.
5961 mServices.processStartTimedOutLocked(app);
5962 app.kill("start timeout", true);
5963 removeLruProcessLocked(app);
5964 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5965 Slog.w(TAG, "Unattached app died before backup, skipping");
5967 IBackupManager bm = IBackupManager.Stub.asInterface(
5968 ServiceManager.getService(Context.BACKUP_SERVICE));
5969 bm.agentDisconnected(app.info.packageName);
5970 } catch (RemoteException e) {
5971 // Can't happen; the backup manager is local
5974 if (isPendingBroadcastProcessLocked(pid)) {
5975 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5976 skipPendingBroadcastLocked(pid);
5979 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5983 private final boolean attachApplicationLocked(IApplicationThread thread,
5986 // Find the application record that is being attached... either via
5987 // the pid if we are running in multiple processes, or just pull the
5988 // next app record if we are emulating process with anonymous threads.
5990 if (pid != MY_PID && pid >= 0) {
5991 synchronized (mPidsSelfLocked) {
5992 app = mPidsSelfLocked.get(pid);
5999 Slog.w(TAG, "No pending application record for pid " + pid
6000 + " (IApplicationThread " + thread + "); dropping process");
6001 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6002 if (pid > 0 && pid != MY_PID) {
6003 Process.killProcessQuiet(pid);
6004 //TODO: killProcessGroup(app.info.uid, pid);
6007 thread.scheduleExit();
6008 } catch (Exception e) {
6009 // Ignore exceptions.
6015 // If this application record is still attached to a previous
6016 // process, clean it up now.
6017 if (app.thread != null) {
6018 handleAppDiedLocked(app, true, true);
6021 // Tell the process all about itself.
6023 if (DEBUG_ALL) Slog.v(
6024 TAG, "Binding process pid " + pid + " to record " + app);
6026 final String processName = app.processName;
6028 AppDeathRecipient adr = new AppDeathRecipient(
6030 thread.asBinder().linkToDeath(adr, 0);
6031 app.deathRecipient = adr;
6032 } catch (RemoteException e) {
6033 app.resetPackageList(mProcessStats);
6034 startProcessLocked(app, "link fail", processName);
6038 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6040 app.makeActive(thread, mProcessStats);
6041 app.curAdj = app.setAdj = -100;
6042 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6043 app.forcingToForeground = null;
6044 updateProcessForegroundLocked(app, false, false);
6045 app.hasShownUi = false;
6046 app.debugging = false;
6048 app.killedByAm = false;
6050 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6052 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6053 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6056 Slog.i(TAG, "Launching preboot mode app: " + app);
6059 if (DEBUG_ALL) Slog.v(
6060 TAG, "New app record " + app
6061 + " thread=" + thread.asBinder() + " pid=" + pid);
6063 int testMode = IApplicationThread.DEBUG_OFF;
6064 if (mDebugApp != null && mDebugApp.equals(processName)) {
6065 testMode = mWaitForDebugger
6066 ? IApplicationThread.DEBUG_WAIT
6067 : IApplicationThread.DEBUG_ON;
6068 app.debugging = true;
6069 if (mDebugTransient) {
6070 mDebugApp = mOrigDebugApp;
6071 mWaitForDebugger = mOrigWaitForDebugger;
6074 String profileFile = app.instrumentationProfileFile;
6075 ParcelFileDescriptor profileFd = null;
6076 int samplingInterval = 0;
6077 boolean profileAutoStop = false;
6078 if (mProfileApp != null && mProfileApp.equals(processName)) {
6080 profileFile = mProfileFile;
6081 profileFd = mProfileFd;
6082 samplingInterval = mSamplingInterval;
6083 profileAutoStop = mAutoStopProfiler;
6085 boolean enableOpenGlTrace = false;
6086 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6087 enableOpenGlTrace = true;
6088 mOpenGlTraceApp = null;
6091 // If the app is being launched for restore or full backup, set it up specially
6092 boolean isRestrictedBackupMode = false;
6093 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6094 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6095 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6096 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6099 ensurePackageDexOpt(app.instrumentationInfo != null
6100 ? app.instrumentationInfo.packageName
6101 : app.info.packageName);
6102 if (app.instrumentationClass != null) {
6103 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6105 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6106 + processName + " with config " + mConfiguration);
6107 ApplicationInfo appInfo = app.instrumentationInfo != null
6108 ? app.instrumentationInfo : app.info;
6109 app.compat = compatibilityInfoForPackageLocked(appInfo);
6110 if (profileFd != null) {
6111 profileFd = profileFd.dup();
6113 ProfilerInfo profilerInfo = profileFile == null ? null
6114 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6115 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6116 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6117 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6118 isRestrictedBackupMode || !normalMode, app.persistent,
6119 new Configuration(mConfiguration), app.compat,
6120 getCommonServicesLocked(app.isolated),
6121 mCoreSettingsObserver.getCoreSettingsLocked());
6122 updateLruProcessLocked(app, false, null);
6123 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6124 } catch (Exception e) {
6125 // todo: Yikes! What should we do? For now we will try to
6126 // start another process, but that could easily get us in
6127 // an infinite loop of restarting processes...
6128 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6130 app.resetPackageList(mProcessStats);
6131 app.unlinkDeathRecipient();
6132 startProcessLocked(app, "bind fail", processName);
6136 // Remove this record from the list of starting applications.
6137 mPersistentStartingProcesses.remove(app);
6138 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6139 "Attach application locked removing on hold: " + app);
6140 mProcessesOnHold.remove(app);
6142 boolean badApp = false;
6143 boolean didSomething = false;
6145 // See if the top visible activity is waiting to run in this process...
6148 if (mStackSupervisor.attachApplicationLocked(app)) {
6149 didSomething = true;
6151 } catch (Exception e) {
6152 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6157 // Find any services that should be running in this process...
6160 didSomething |= mServices.attachApplicationLocked(app, processName);
6161 } catch (Exception e) {
6162 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6167 // Check if a next-broadcast receiver is in this process...
6168 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6170 didSomething |= sendPendingBroadcastsLocked(app);
6171 } catch (Exception e) {
6172 // If the app died trying to launch the receiver we declare it 'bad'
6173 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6178 // Check whether the next backup agent is in this process...
6179 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6180 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6181 "New app is backup target, launching agent for " + app);
6182 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6184 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6185 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6186 mBackupTarget.backupMode);
6187 } catch (Exception e) {
6188 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6194 app.kill("error during init", true);
6195 handleAppDiedLocked(app, false, true);
6199 if (!didSomething) {
6200 updateOomAdjLocked();
6207 public final void attachApplication(IApplicationThread thread) {
6208 synchronized (this) {
6209 int callingPid = Binder.getCallingPid();
6210 final long origId = Binder.clearCallingIdentity();
6211 attachApplicationLocked(thread, callingPid);
6212 Binder.restoreCallingIdentity(origId);
6217 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6218 final long origId = Binder.clearCallingIdentity();
6219 synchronized (this) {
6220 ActivityStack stack = ActivityRecord.getStackLocked(token);
6221 if (stack != null) {
6223 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6224 if (stopProfiling) {
6225 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6228 } catch (IOException e) {
6230 clearProfilerLocked();
6235 Binder.restoreCallingIdentity(origId);
6238 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6239 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6240 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6243 void enableScreenAfterBoot() {
6244 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6245 SystemClock.uptimeMillis());
6246 mWindowManager.enableScreenAfterBoot();
6248 synchronized (this) {
6249 updateEventDispatchingLocked();
6254 public void showBootMessage(final CharSequence msg, final boolean always) {
6255 if (Binder.getCallingUid() != Process.myUid()) {
6256 // These days only the core system can call this, so apps can't get in
6257 // the way of what we show about running them.
6259 mWindowManager.showBootMessage(msg, always);
6263 public void keyguardWaitingForActivityDrawn() {
6264 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6265 final long token = Binder.clearCallingIdentity();
6267 synchronized (this) {
6268 if (DEBUG_LOCKSCREEN) logLockScreen("");
6269 mWindowManager.keyguardWaitingForActivityDrawn();
6270 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6271 mLockScreenShown = LOCK_SCREEN_LEAVING;
6272 updateSleepIfNeededLocked();
6276 Binder.restoreCallingIdentity(token);
6281 public void keyguardGoingAway(boolean disableWindowAnimations,
6282 boolean keyguardGoingToNotificationShade) {
6283 enforceNotIsolatedCaller("keyguardGoingAway");
6284 final long token = Binder.clearCallingIdentity();
6286 synchronized (this) {
6287 if (DEBUG_LOCKSCREEN) logLockScreen("");
6288 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6289 keyguardGoingToNotificationShade);
6290 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6291 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6292 updateSleepIfNeededLocked();
6296 Binder.restoreCallingIdentity(token);
6300 final void finishBooting() {
6301 synchronized (this) {
6302 if (!mBootAnimationComplete) {
6303 mCallFinishBooting = true;
6306 mCallFinishBooting = false;
6309 ArraySet<String> completedIsas = new ArraySet<String>();
6310 for (String abi : Build.SUPPORTED_ABIS) {
6311 Process.establishZygoteConnectionForAbi(abi);
6312 final String instructionSet = VMRuntime.getInstructionSet(abi);
6313 if (!completedIsas.contains(instructionSet)) {
6314 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6315 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6317 completedIsas.add(instructionSet);
6321 IntentFilter pkgFilter = new IntentFilter();
6322 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6323 pkgFilter.addDataScheme("package");
6324 mContext.registerReceiver(new BroadcastReceiver() {
6326 public void onReceive(Context context, Intent intent) {
6327 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6329 for (String pkg : pkgs) {
6330 synchronized (ActivityManagerService.this) {
6331 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6332 0, "query restart")) {
6333 setResultCode(Activity.RESULT_OK);
6342 IntentFilter dumpheapFilter = new IntentFilter();
6343 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6344 mContext.registerReceiver(new BroadcastReceiver() {
6346 public void onReceive(Context context, Intent intent) {
6347 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6348 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6350 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6355 // Let system services know.
6356 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6358 synchronized (this) {
6359 // Ensure that any processes we had put on hold are now started
6361 final int NP = mProcessesOnHold.size();
6363 ArrayList<ProcessRecord> procs =
6364 new ArrayList<ProcessRecord>(mProcessesOnHold);
6365 for (int ip=0; ip<NP; ip++) {
6366 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6368 startProcessLocked(procs.get(ip), "on-hold", null);
6372 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6373 // Start looking for apps that are abusing wake locks.
6374 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6375 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6376 // Tell anyone interested that we are done booting!
6377 SystemProperties.set("sys.boot_completed", "1");
6379 // And trigger dev.bootcomplete if we are not showing encryption progress
6380 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6381 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6382 SystemProperties.set("dev.bootcomplete", "1");
6384 for (int i=0; i<mStartedUsers.size(); i++) {
6385 UserState uss = mStartedUsers.valueAt(i);
6386 if (uss.mState == UserState.STATE_BOOTING) {
6387 uss.mState = UserState.STATE_RUNNING;
6388 final int userId = mStartedUsers.keyAt(i);
6389 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6390 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6391 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6392 broadcastIntentLocked(null, null, intent, null,
6393 new IIntentReceiver.Stub() {
6395 public void performReceive(Intent intent, int resultCode,
6396 String data, Bundle extras, boolean ordered,
6397 boolean sticky, int sendingUser) {
6398 synchronized (ActivityManagerService.this) {
6399 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6405 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6406 AppOpsManager.OP_NONE, null, true, false,
6407 MY_PID, Process.SYSTEM_UID, userId);
6410 scheduleStartProfilesLocked();
6416 public void bootAnimationComplete() {
6417 final boolean callFinishBooting;
6418 synchronized (this) {
6419 callFinishBooting = mCallFinishBooting;
6420 mBootAnimationComplete = true;
6422 if (callFinishBooting) {
6427 final void ensureBootCompleted() {
6429 boolean enableScreen;
6430 synchronized (this) {
6433 enableScreen = !mBooted;
6442 enableScreenAfterBoot();
6447 public final void activityResumed(IBinder token) {
6448 final long origId = Binder.clearCallingIdentity();
6449 synchronized(this) {
6450 ActivityStack stack = ActivityRecord.getStackLocked(token);
6451 if (stack != null) {
6452 ActivityRecord.activityResumedLocked(token);
6455 Binder.restoreCallingIdentity(origId);
6459 public final void activityPaused(IBinder token) {
6460 final long origId = Binder.clearCallingIdentity();
6461 synchronized(this) {
6462 ActivityStack stack = ActivityRecord.getStackLocked(token);
6463 if (stack != null) {
6464 stack.activityPausedLocked(token, false);
6467 Binder.restoreCallingIdentity(origId);
6471 public final void activityStopped(IBinder token, Bundle icicle,
6472 PersistableBundle persistentState, CharSequence description) {
6473 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6475 // Refuse possible leaked file descriptors
6476 if (icicle != null && icicle.hasFileDescriptors()) {
6477 throw new IllegalArgumentException("File descriptors passed in Bundle");
6480 final long origId = Binder.clearCallingIdentity();
6482 synchronized (this) {
6483 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6485 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6491 Binder.restoreCallingIdentity(origId);
6495 public final void activityDestroyed(IBinder token) {
6496 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6497 synchronized (this) {
6498 ActivityStack stack = ActivityRecord.getStackLocked(token);
6499 if (stack != null) {
6500 stack.activityDestroyedLocked(token, "activityDestroyed");
6506 public final void backgroundResourcesReleased(IBinder token) {
6507 final long origId = Binder.clearCallingIdentity();
6509 synchronized (this) {
6510 ActivityStack stack = ActivityRecord.getStackLocked(token);
6511 if (stack != null) {
6512 stack.backgroundResourcesReleased();
6516 Binder.restoreCallingIdentity(origId);
6521 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6522 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6526 public final void notifyEnterAnimationComplete(IBinder token) {
6527 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6531 public String getCallingPackage(IBinder token) {
6532 synchronized (this) {
6533 ActivityRecord r = getCallingRecordLocked(token);
6534 return r != null ? r.info.packageName : null;
6539 public ComponentName getCallingActivity(IBinder token) {
6540 synchronized (this) {
6541 ActivityRecord r = getCallingRecordLocked(token);
6542 return r != null ? r.intent.getComponent() : null;
6546 private ActivityRecord getCallingRecordLocked(IBinder token) {
6547 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6555 public ComponentName getActivityClassForToken(IBinder token) {
6556 synchronized(this) {
6557 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6561 return r.intent.getComponent();
6566 public String getPackageForToken(IBinder token) {
6567 synchronized(this) {
6568 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6572 return r.packageName;
6577 public boolean isRootVoiceInteraction(IBinder token) {
6578 synchronized(this) {
6579 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6583 return r.rootVoiceInteraction;
6588 public IIntentSender getIntentSender(int type,
6589 String packageName, IBinder token, String resultWho,
6590 int requestCode, Intent[] intents, String[] resolvedTypes,
6591 int flags, Bundle options, int userId) {
6592 enforceNotIsolatedCaller("getIntentSender");
6593 // Refuse possible leaked file descriptors
6594 if (intents != null) {
6595 if (intents.length < 1) {
6596 throw new IllegalArgumentException("Intents array length must be >= 1");
6598 for (int i=0; i<intents.length; i++) {
6599 Intent intent = intents[i];
6600 if (intent != null) {
6601 if (intent.hasFileDescriptors()) {
6602 throw new IllegalArgumentException("File descriptors passed in Intent");
6604 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6605 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6606 throw new IllegalArgumentException(
6607 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6609 intents[i] = new Intent(intent);
6612 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6613 throw new IllegalArgumentException(
6614 "Intent array length does not match resolvedTypes length");
6617 if (options != null) {
6618 if (options.hasFileDescriptors()) {
6619 throw new IllegalArgumentException("File descriptors passed in options");
6623 synchronized(this) {
6624 int callingUid = Binder.getCallingUid();
6625 int origUserId = userId;
6626 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6627 type == ActivityManager.INTENT_SENDER_BROADCAST,
6628 ALLOW_NON_FULL, "getIntentSender", null);
6629 if (origUserId == UserHandle.USER_CURRENT) {
6630 // We don't want to evaluate this until the pending intent is
6631 // actually executed. However, we do want to always do the
6632 // security checking for it above.
6633 userId = UserHandle.USER_CURRENT;
6636 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6637 int uid = AppGlobals.getPackageManager()
6638 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6639 if (!UserHandle.isSameApp(callingUid, uid)) {
6640 String msg = "Permission Denial: getIntentSender() from pid="
6641 + Binder.getCallingPid()
6642 + ", uid=" + Binder.getCallingUid()
6643 + ", (need uid=" + uid + ")"
6644 + " is not allowed to send as package " + packageName;
6646 throw new SecurityException(msg);
6650 return getIntentSenderLocked(type, packageName, callingUid, userId,
6651 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6653 } catch (RemoteException e) {
6654 throw new SecurityException(e);
6659 IIntentSender getIntentSenderLocked(int type, String packageName,
6660 int callingUid, int userId, IBinder token, String resultWho,
6661 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6663 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6664 ActivityRecord activity = null;
6665 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6666 activity = ActivityRecord.isInStackLocked(token);
6667 if (activity == null) {
6670 if (activity.finishing) {
6675 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6676 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6677 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6678 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6679 |PendingIntent.FLAG_UPDATE_CURRENT);
6681 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6682 type, packageName, activity, resultWho,
6683 requestCode, intents, resolvedTypes, flags, options, userId);
6684 WeakReference<PendingIntentRecord> ref;
6685 ref = mIntentSenderRecords.get(key);
6686 PendingIntentRecord rec = ref != null ? ref.get() : null;
6688 if (!cancelCurrent) {
6689 if (updateCurrent) {
6690 if (rec.key.requestIntent != null) {
6691 rec.key.requestIntent.replaceExtras(intents != null ?
6692 intents[intents.length - 1] : null);
6694 if (intents != null) {
6695 intents[intents.length-1] = rec.key.requestIntent;
6696 rec.key.allIntents = intents;
6697 rec.key.allResolvedTypes = resolvedTypes;
6699 rec.key.allIntents = null;
6700 rec.key.allResolvedTypes = null;
6705 rec.canceled = true;
6706 mIntentSenderRecords.remove(key);
6711 rec = new PendingIntentRecord(this, key, callingUid);
6712 mIntentSenderRecords.put(key, rec.ref);
6713 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6714 if (activity.pendingResults == null) {
6715 activity.pendingResults
6716 = new HashSet<WeakReference<PendingIntentRecord>>();
6718 activity.pendingResults.add(rec.ref);
6724 public void cancelIntentSender(IIntentSender sender) {
6725 if (!(sender instanceof PendingIntentRecord)) {
6728 synchronized(this) {
6729 PendingIntentRecord rec = (PendingIntentRecord)sender;
6731 int uid = AppGlobals.getPackageManager()
6732 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6733 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6734 String msg = "Permission Denial: cancelIntentSender() from pid="
6735 + Binder.getCallingPid()
6736 + ", uid=" + Binder.getCallingUid()
6737 + " is not allowed to cancel packges "
6738 + rec.key.packageName;
6740 throw new SecurityException(msg);
6742 } catch (RemoteException e) {
6743 throw new SecurityException(e);
6745 cancelIntentSenderLocked(rec, true);
6749 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6750 rec.canceled = true;
6751 mIntentSenderRecords.remove(rec.key);
6752 if (cleanActivity && rec.key.activity != null) {
6753 rec.key.activity.pendingResults.remove(rec.ref);
6758 public String getPackageForIntentSender(IIntentSender pendingResult) {
6759 if (!(pendingResult instanceof PendingIntentRecord)) {
6763 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6764 return res.key.packageName;
6765 } catch (ClassCastException e) {
6771 public int getUidForIntentSender(IIntentSender sender) {
6772 if (sender instanceof PendingIntentRecord) {
6774 PendingIntentRecord res = (PendingIntentRecord)sender;
6776 } catch (ClassCastException e) {
6783 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6784 if (!(pendingResult instanceof PendingIntentRecord)) {
6788 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6789 if (res.key.allIntents == null) {
6792 for (int i=0; i<res.key.allIntents.length; i++) {
6793 Intent intent = res.key.allIntents[i];
6794 if (intent.getPackage() != null && intent.getComponent() != null) {
6799 } catch (ClassCastException e) {
6805 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6806 if (!(pendingResult instanceof PendingIntentRecord)) {
6810 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6811 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6815 } catch (ClassCastException e) {
6821 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6822 if (!(pendingResult instanceof PendingIntentRecord)) {
6826 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6827 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6828 } catch (ClassCastException e) {
6834 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6835 if (!(pendingResult instanceof PendingIntentRecord)) {
6839 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6840 synchronized (this) {
6841 return getTagForIntentSenderLocked(res, prefix);
6843 } catch (ClassCastException e) {
6848 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6849 final Intent intent = res.key.requestIntent;
6850 if (intent != null) {
6851 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6852 || res.lastTagPrefix.equals(prefix))) {
6855 res.lastTagPrefix = prefix;
6856 final StringBuilder sb = new StringBuilder(128);
6857 if (prefix != null) {
6860 if (intent.getAction() != null) {
6861 sb.append(intent.getAction());
6862 } else if (intent.getComponent() != null) {
6863 intent.getComponent().appendShortString(sb);
6867 return res.lastTag = sb.toString();
6873 public void setProcessLimit(int max) {
6874 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6875 "setProcessLimit()");
6876 synchronized (this) {
6877 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6878 mProcessLimitOverride = max;
6884 public int getProcessLimit() {
6885 synchronized (this) {
6886 return mProcessLimitOverride;
6890 void foregroundTokenDied(ForegroundToken token) {
6891 synchronized (ActivityManagerService.this) {
6892 synchronized (mPidsSelfLocked) {
6894 = mForegroundProcesses.get(token.pid);
6898 mForegroundProcesses.remove(token.pid);
6899 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6903 pr.forcingToForeground = null;
6904 updateProcessForegroundLocked(pr, false, false);
6906 updateOomAdjLocked();
6911 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6912 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6913 "setProcessForeground()");
6914 synchronized(this) {
6915 boolean changed = false;
6917 synchronized (mPidsSelfLocked) {
6918 ProcessRecord pr = mPidsSelfLocked.get(pid);
6919 if (pr == null && isForeground) {
6920 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6923 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6924 if (oldToken != null) {
6925 oldToken.token.unlinkToDeath(oldToken, 0);
6926 mForegroundProcesses.remove(pid);
6928 pr.forcingToForeground = null;
6932 if (isForeground && token != null) {
6933 ForegroundToken newToken = new ForegroundToken() {
6935 public void binderDied() {
6936 foregroundTokenDied(this);
6940 newToken.token = token;
6942 token.linkToDeath(newToken, 0);
6943 mForegroundProcesses.put(pid, newToken);
6944 pr.forcingToForeground = token;
6946 } catch (RemoteException e) {
6947 // If the process died while doing this, we will later
6948 // do the cleanup with the process death link.
6954 updateOomAdjLocked();
6959 // =========================================================
6961 // =========================================================
6963 static class ProcessInfoService extends IProcessInfoService.Stub {
6964 final ActivityManagerService mActivityManagerService;
6965 ProcessInfoService(ActivityManagerService activityManagerService) {
6966 mActivityManagerService = activityManagerService;
6970 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6971 mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6976 * For each PID in the given input array, write the current process state
6977 * for that process into the output array, or -1 to indicate that no
6978 * process with the given PID exists.
6980 public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6982 throw new NullPointerException("pids");
6983 } else if (states == null) {
6984 throw new NullPointerException("states");
6985 } else if (pids.length != states.length) {
6986 throw new IllegalArgumentException("input and output arrays have different lengths!");
6989 synchronized (mPidsSelfLocked) {
6990 for (int i = 0; i < pids.length; i++) {
6991 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6992 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6998 // =========================================================
7000 // =========================================================
7002 static class PermissionController extends IPermissionController.Stub {
7003 ActivityManagerService mActivityManagerService;
7004 PermissionController(ActivityManagerService activityManagerService) {
7005 mActivityManagerService = activityManagerService;
7009 public boolean checkPermission(String permission, int pid, int uid) {
7010 return mActivityManagerService.checkPermission(permission, pid,
7011 uid) == PackageManager.PERMISSION_GRANTED;
7015 public String[] getPackagesForUid(int uid) {
7016 return mActivityManagerService.mContext.getPackageManager()
7017 .getPackagesForUid(uid);
7021 public boolean isRuntimePermission(String permission) {
7023 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7024 .getPermissionInfo(permission, 0);
7025 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7026 } catch (NameNotFoundException nnfe) {
7027 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7033 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7035 public int checkComponentPermission(String permission, int pid, int uid,
7036 int owningUid, boolean exported) {
7037 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7038 owningUid, exported);
7042 public Object getAMSLock() {
7043 return ActivityManagerService.this;
7048 * This can be called with or without the global lock held.
7050 int checkComponentPermission(String permission, int pid, int uid,
7051 int owningUid, boolean exported) {
7052 if (pid == MY_PID) {
7053 return PackageManager.PERMISSION_GRANTED;
7055 return ActivityManager.checkComponentPermission(permission, uid,
7056 owningUid, exported);
7060 * As the only public entry point for permissions checking, this method
7061 * can enforce the semantic that requesting a check on a null global
7062 * permission is automatically denied. (Internally a null permission
7063 * string is used when calling {@link #checkComponentPermission} in cases
7064 * when only uid-based security is needed.)
7066 * This can be called with or without the global lock held.
7069 public int checkPermission(String permission, int pid, int uid) {
7070 if (permission == null) {
7071 return PackageManager.PERMISSION_DENIED;
7073 return checkComponentPermission(permission, pid, uid, -1, true);
7077 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7078 if (permission == null) {
7079 return PackageManager.PERMISSION_DENIED;
7082 // We might be performing an operation on behalf of an indirect binder
7083 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7084 // client identity accordingly before proceeding.
7085 Identity tlsIdentity = sCallerIdentity.get();
7086 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7087 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7088 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7089 uid = tlsIdentity.uid;
7090 pid = tlsIdentity.pid;
7093 return checkComponentPermission(permission, pid, uid, -1, true);
7097 * Binder IPC calls go through the public entry point.
7098 * This can be called with or without the global lock held.
7100 int checkCallingPermission(String permission) {
7101 return checkPermission(permission,
7102 Binder.getCallingPid(),
7103 UserHandle.getAppId(Binder.getCallingUid()));
7107 * This can be called with or without the global lock held.
7109 void enforceCallingPermission(String permission, String func) {
7110 if (checkCallingPermission(permission)
7111 == PackageManager.PERMISSION_GRANTED) {
7115 String msg = "Permission Denial: " + func + " from pid="
7116 + Binder.getCallingPid()
7117 + ", uid=" + Binder.getCallingUid()
7118 + " requires " + permission;
7120 throw new SecurityException(msg);
7124 * Determine if UID is holding permissions required to access {@link Uri} in
7125 * the given {@link ProviderInfo}. Final permission checking is always done
7126 * in {@link ContentProvider}.
7128 private final boolean checkHoldingPermissionsLocked(
7129 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7130 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7131 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7132 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7133 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7134 != PERMISSION_GRANTED) {
7138 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7141 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7142 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7143 if (pi.applicationInfo.uid == uid) {
7145 } else if (!pi.exported) {
7149 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7150 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7152 // check if target holds top-level <provider> permissions
7153 if (!readMet && pi.readPermission != null && considerUidPermissions
7154 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7157 if (!writeMet && pi.writePermission != null && considerUidPermissions
7158 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7162 // track if unprotected read/write is allowed; any denied
7163 // <path-permission> below removes this ability
7164 boolean allowDefaultRead = pi.readPermission == null;
7165 boolean allowDefaultWrite = pi.writePermission == null;
7167 // check if target holds any <path-permission> that match uri
7168 final PathPermission[] pps = pi.pathPermissions;
7170 final String path = grantUri.uri.getPath();
7172 while (i > 0 && (!readMet || !writeMet)) {
7174 PathPermission pp = pps[i];
7175 if (pp.match(path)) {
7177 final String pprperm = pp.getReadPermission();
7178 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7179 "Checking read perm for " + pprperm + " for " + pp.getPath()
7180 + ": match=" + pp.match(path)
7181 + " check=" + pm.checkUidPermission(pprperm, uid));
7182 if (pprperm != null) {
7183 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7184 == PERMISSION_GRANTED) {
7187 allowDefaultRead = false;
7192 final String ppwperm = pp.getWritePermission();
7193 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7194 "Checking write perm " + ppwperm + " for " + pp.getPath()
7195 + ": match=" + pp.match(path)
7196 + " check=" + pm.checkUidPermission(ppwperm, uid));
7197 if (ppwperm != null) {
7198 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7199 == PERMISSION_GRANTED) {
7202 allowDefaultWrite = false;
7210 // grant unprotected <provider> read/write, if not blocked by
7211 // <path-permission> above
7212 if (allowDefaultRead) readMet = true;
7213 if (allowDefaultWrite) writeMet = true;
7215 } catch (RemoteException e) {
7219 return readMet && writeMet;
7222 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7223 ProviderInfo pi = null;
7224 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7229 pi = AppGlobals.getPackageManager().resolveContentProvider(
7230 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7231 } catch (RemoteException ex) {
7237 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7238 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7239 if (targetUris != null) {
7240 return targetUris.get(grantUri);
7245 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7246 String targetPkg, int targetUid, GrantUri grantUri) {
7247 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7248 if (targetUris == null) {
7249 targetUris = Maps.newArrayMap();
7250 mGrantedUriPermissions.put(targetUid, targetUris);
7253 UriPermission perm = targetUris.get(grantUri);
7255 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7256 targetUris.put(grantUri, perm);
7262 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7263 final int modeFlags) {
7264 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7265 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7266 : UriPermission.STRENGTH_OWNED;
7268 // Root gets to do everything.
7273 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7274 if (perms == null) return false;
7276 // First look for exact match
7277 final UriPermission exactPerm = perms.get(grantUri);
7278 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7282 // No exact match, look for prefixes
7283 final int N = perms.size();
7284 for (int i = 0; i < N; i++) {
7285 final UriPermission perm = perms.valueAt(i);
7286 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7287 && perm.getStrength(modeFlags) >= minStrength) {
7296 * @param uri This uri must NOT contain an embedded userId.
7297 * @param userId The userId in which the uri is to be resolved.
7300 public int checkUriPermission(Uri uri, int pid, int uid,
7301 final int modeFlags, int userId, IBinder callerToken) {
7302 enforceNotIsolatedCaller("checkUriPermission");
7304 // Another redirected-binder-call permissions check as in
7305 // {@link checkPermissionWithToken}.
7306 Identity tlsIdentity = sCallerIdentity.get();
7307 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7308 uid = tlsIdentity.uid;
7309 pid = tlsIdentity.pid;
7312 // Our own process gets to do everything.
7313 if (pid == MY_PID) {
7314 return PackageManager.PERMISSION_GRANTED;
7316 synchronized (this) {
7317 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7318 ? PackageManager.PERMISSION_GRANTED
7319 : PackageManager.PERMISSION_DENIED;
7324 * Check if the targetPkg can be granted permission to access uri by
7325 * the callingUid using the given modeFlags. Throws a security exception
7326 * if callingUid is not allowed to do this. Returns the uid of the target
7327 * if the URI permission grant should be performed; returns -1 if it is not
7328 * needed (for example targetPkg already has permission to access the URI).
7329 * If you already know the uid of the target, you can supply it in
7330 * lastTargetUid else set that to -1.
7332 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7333 final int modeFlags, int lastTargetUid) {
7334 if (!Intent.isAccessUriMode(modeFlags)) {
7338 if (targetPkg != null) {
7339 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7340 "Checking grant " + targetPkg + " permission to " + grantUri);
7343 final IPackageManager pm = AppGlobals.getPackageManager();
7345 // If this is not a content: uri, we can't do anything with it.
7346 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7347 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7348 "Can't grant URI permission for non-content URI: " + grantUri);
7352 final String authority = grantUri.uri.getAuthority();
7353 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7355 Slog.w(TAG, "No content provider found for permission check: " +
7356 grantUri.uri.toSafeString());
7360 int targetUid = lastTargetUid;
7361 if (targetUid < 0 && targetPkg != null) {
7363 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7364 if (targetUid < 0) {
7365 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7366 "Can't grant URI permission no uid for: " + targetPkg);
7369 } catch (RemoteException ex) {
7374 if (targetUid >= 0) {
7375 // First... does the target actually need this permission?
7376 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7377 // No need to grant the target this permission.
7378 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7379 "Target " + targetPkg + " already has full permission to " + grantUri);
7383 // First... there is no target package, so can anyone access it?
7384 boolean allowed = pi.exported;
7385 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7386 if (pi.readPermission != null) {
7390 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7391 if (pi.writePermission != null) {
7400 /* There is a special cross user grant if:
7401 * - The target is on another user.
7402 * - Apps on the current user can access the uri without any uid permissions.
7403 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7404 * grant uri permissions.
7406 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7407 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7408 modeFlags, false /*without considering the uid permissions*/);
7410 // Second... is the provider allowing granting of URI permissions?
7411 if (!specialCrossUserGrant) {
7412 if (!pi.grantUriPermissions) {
7413 throw new SecurityException("Provider " + pi.packageName
7415 + " does not allow granting of Uri permissions (uri "
7418 if (pi.uriPermissionPatterns != null) {
7419 final int N = pi.uriPermissionPatterns.length;
7420 boolean allowed = false;
7421 for (int i=0; i<N; i++) {
7422 if (pi.uriPermissionPatterns[i] != null
7423 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7429 throw new SecurityException("Provider " + pi.packageName
7431 + " does not allow granting of permission to path of Uri "
7437 // Third... does the caller itself have permission to access
7439 final int callingAppId = UserHandle.getAppId(callingUid);
7440 if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
7441 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
7442 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
7445 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7446 // Require they hold a strong enough Uri permission
7447 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7448 throw new SecurityException("Uid " + callingUid
7449 + " does not have permission to uri " + grantUri);
7457 * @param uri This uri must NOT contain an embedded userId.
7458 * @param userId The userId in which the uri is to be resolved.
7461 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7462 final int modeFlags, int userId) {
7463 enforceNotIsolatedCaller("checkGrantUriPermission");
7464 synchronized(this) {
7465 return checkGrantUriPermissionLocked(callingUid, targetPkg,
7466 new GrantUri(userId, uri, false), modeFlags, -1);
7470 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7471 final int modeFlags, UriPermissionOwner owner) {
7472 if (!Intent.isAccessUriMode(modeFlags)) {
7476 // So here we are: the caller has the assumed permission
7477 // to the uri, and the target doesn't. Let's now give this to
7480 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7481 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7483 final String authority = grantUri.uri.getAuthority();
7484 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7486 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7490 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7491 grantUri.prefix = true;
7493 final UriPermission perm = findOrCreateUriPermissionLocked(
7494 pi.packageName, targetPkg, targetUid, grantUri);
7495 perm.grantModes(modeFlags, owner);
7498 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7499 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7500 if (targetPkg == null) {
7501 throw new NullPointerException("targetPkg");
7504 final IPackageManager pm = AppGlobals.getPackageManager();
7506 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7507 } catch (RemoteException ex) {
7511 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7513 if (targetUid < 0) {
7517 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7521 static class NeededUriGrants extends ArrayList<GrantUri> {
7522 final String targetPkg;
7523 final int targetUid;
7526 NeededUriGrants(String targetPkg, int targetUid, int flags) {
7527 this.targetPkg = targetPkg;
7528 this.targetUid = targetUid;
7534 * Like checkGrantUriPermissionLocked, but takes an Intent.
7536 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7537 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7538 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7539 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7540 + " clip=" + (intent != null ? intent.getClipData() : null)
7541 + " from " + intent + "; flags=0x"
7542 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7544 if (targetPkg == null) {
7545 throw new NullPointerException("targetPkg");
7548 if (intent == null) {
7551 Uri data = intent.getData();
7552 ClipData clip = intent.getClipData();
7553 if (data == null && clip == null) {
7556 // Default userId for uris in the intent (if they don't specify it themselves)
7557 int contentUserHint = intent.getContentUserHint();
7558 if (contentUserHint == UserHandle.USER_CURRENT) {
7559 contentUserHint = UserHandle.getUserId(callingUid);
7561 final IPackageManager pm = AppGlobals.getPackageManager();
7563 if (needed != null) {
7564 targetUid = needed.targetUid;
7567 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7568 } catch (RemoteException ex) {
7571 if (targetUid < 0) {
7572 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7573 "Can't grant URI permission no uid for: " + targetPkg
7574 + " on user " + targetUserId);
7579 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7580 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7582 if (targetUid > 0) {
7583 if (needed == null) {
7584 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7586 needed.add(grantUri);
7590 for (int i=0; i<clip.getItemCount(); i++) {
7591 Uri uri = clip.getItemAt(i).getUri();
7593 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7594 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7596 if (targetUid > 0) {
7597 if (needed == null) {
7598 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7600 needed.add(grantUri);
7603 Intent clipIntent = clip.getItemAt(i).getIntent();
7604 if (clipIntent != null) {
7605 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7606 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7607 if (newNeeded != null) {
7619 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7621 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7622 UriPermissionOwner owner) {
7623 if (needed != null) {
7624 for (int i=0; i<needed.size(); i++) {
7625 GrantUri grantUri = needed.get(i);
7626 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7627 grantUri, needed.flags, owner);
7632 void grantUriPermissionFromIntentLocked(int callingUid,
7633 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7634 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7635 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7636 if (needed == null) {
7640 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7644 * @param uri This uri must NOT contain an embedded userId.
7645 * @param userId The userId in which the uri is to be resolved.
7648 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7649 final int modeFlags, int userId) {
7650 enforceNotIsolatedCaller("grantUriPermission");
7651 GrantUri grantUri = new GrantUri(userId, uri, false);
7652 synchronized(this) {
7653 final ProcessRecord r = getRecordForAppLocked(caller);
7655 throw new SecurityException("Unable to find app for caller "
7657 + " when granting permission to uri " + grantUri);
7659 if (targetPkg == null) {
7660 throw new IllegalArgumentException("null target");
7662 if (grantUri == null) {
7663 throw new IllegalArgumentException("null uri");
7666 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7667 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7668 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7669 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7671 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7672 UserHandle.getUserId(r.uid));
7676 void removeUriPermissionIfNeededLocked(UriPermission perm) {
7677 if (perm.modeFlags == 0) {
7678 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7680 if (perms != null) {
7681 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7682 "Removing " + perm.targetUid + " permission to " + perm.uri);
7684 perms.remove(perm.uri);
7685 if (perms.isEmpty()) {
7686 mGrantedUriPermissions.remove(perm.targetUid);
7692 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7693 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7694 "Revoking all granted permissions to " + grantUri);
7696 final IPackageManager pm = AppGlobals.getPackageManager();
7697 final String authority = grantUri.uri.getAuthority();
7698 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7700 Slog.w(TAG, "No content provider found for permission revoke: "
7701 + grantUri.toSafeString());
7705 // Does the caller have this permission on the URI?
7706 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7707 // If they don't have direct access to the URI, then revoke any
7708 // ownerless URI permissions that have been granted to them.
7709 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7710 if (perms != null) {
7711 boolean persistChanged = false;
7712 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7713 final UriPermission perm = it.next();
7714 if (perm.uri.sourceUserId == grantUri.sourceUserId
7715 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7716 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7717 "Revoking non-owned " + perm.targetUid
7718 + " permission to " + perm.uri);
7719 persistChanged |= perm.revokeModes(
7720 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7721 if (perm.modeFlags == 0) {
7726 if (perms.isEmpty()) {
7727 mGrantedUriPermissions.remove(callingUid);
7729 if (persistChanged) {
7730 schedulePersistUriGrants();
7736 boolean persistChanged = false;
7738 // Go through all of the permissions and remove any that match.
7739 int N = mGrantedUriPermissions.size();
7740 for (int i = 0; i < N; i++) {
7741 final int targetUid = mGrantedUriPermissions.keyAt(i);
7742 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7744 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7745 final UriPermission perm = it.next();
7746 if (perm.uri.sourceUserId == grantUri.sourceUserId
7747 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7748 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7749 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7750 persistChanged |= perm.revokeModes(
7751 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7752 if (perm.modeFlags == 0) {
7758 if (perms.isEmpty()) {
7759 mGrantedUriPermissions.remove(targetUid);
7765 if (persistChanged) {
7766 schedulePersistUriGrants();
7771 * @param uri This uri must NOT contain an embedded userId.
7772 * @param userId The userId in which the uri is to be resolved.
7775 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7777 enforceNotIsolatedCaller("revokeUriPermission");
7778 synchronized(this) {
7779 final ProcessRecord r = getRecordForAppLocked(caller);
7781 throw new SecurityException("Unable to find app for caller "
7783 + " when revoking permission to uri " + uri);
7786 Slog.w(TAG, "revokeUriPermission: null uri");
7790 if (!Intent.isAccessUriMode(modeFlags)) {
7794 final String authority = uri.getAuthority();
7795 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7797 Slog.w(TAG, "No content provider found for permission revoke: "
7798 + uri.toSafeString());
7802 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7807 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7810 * @param packageName Package name to match, or {@code null} to apply to all
7812 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7814 * @param persistable If persistable grants should be removed.
7816 private void removeUriPermissionsForPackageLocked(
7817 String packageName, int userHandle, boolean persistable) {
7818 if (userHandle == UserHandle.USER_ALL && packageName == null) {
7819 throw new IllegalArgumentException("Must narrow by either package or user");
7822 boolean persistChanged = false;
7824 int N = mGrantedUriPermissions.size();
7825 for (int i = 0; i < N; i++) {
7826 final int targetUid = mGrantedUriPermissions.keyAt(i);
7827 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7829 // Only inspect grants matching user
7830 if (userHandle == UserHandle.USER_ALL
7831 || userHandle == UserHandle.getUserId(targetUid)) {
7832 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7833 final UriPermission perm = it.next();
7835 // Only inspect grants matching package
7836 if (packageName == null || perm.sourcePkg.equals(packageName)
7837 || perm.targetPkg.equals(packageName)) {
7838 // Hacky solution as part of fixing a security bug; ignore
7839 // grants associated with DownloadManager so we don't have
7840 // to immediately launch it to regrant the permissions
7841 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
7842 && !persistable) continue;
7844 persistChanged |= perm.revokeModes(persistable
7845 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7847 // Only remove when no modes remain; any persisted grants
7848 // will keep this alive.
7849 if (perm.modeFlags == 0) {
7855 if (perms.isEmpty()) {
7856 mGrantedUriPermissions.remove(targetUid);
7863 if (persistChanged) {
7864 schedulePersistUriGrants();
7869 public IBinder newUriPermissionOwner(String name) {
7870 enforceNotIsolatedCaller("newUriPermissionOwner");
7871 synchronized(this) {
7872 UriPermissionOwner owner = new UriPermissionOwner(this, name);
7873 return owner.getExternalTokenLocked();
7878 * @param uri This uri must NOT contain an embedded userId.
7879 * @param sourceUserId The userId in which the uri is to be resolved.
7880 * @param targetUserId The userId of the app that receives the grant.
7883 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7884 final int modeFlags, int sourceUserId, int targetUserId) {
7885 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7886 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7887 synchronized(this) {
7888 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7889 if (owner == null) {
7890 throw new IllegalArgumentException("Unknown owner: " + token);
7892 if (fromUid != Binder.getCallingUid()) {
7893 if (Binder.getCallingUid() != Process.myUid()) {
7894 // Only system code can grant URI permissions on behalf
7896 throw new SecurityException("nice try");
7899 if (targetPkg == null) {
7900 throw new IllegalArgumentException("null target");
7903 throw new IllegalArgumentException("null uri");
7906 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7907 modeFlags, owner, targetUserId);
7912 * @param uri This uri must NOT contain an embedded userId.
7913 * @param userId The userId in which the uri is to be resolved.
7916 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7917 synchronized(this) {
7918 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7919 if (owner == null) {
7920 throw new IllegalArgumentException("Unknown owner: " + token);
7924 owner.removeUriPermissionsLocked(mode);
7926 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7931 private void schedulePersistUriGrants() {
7932 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7933 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7934 10 * DateUtils.SECOND_IN_MILLIS);
7938 private void writeGrantedUriPermissions() {
7939 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7941 // Snapshot permissions so we can persist without lock
7942 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7943 synchronized (this) {
7944 final int size = mGrantedUriPermissions.size();
7945 for (int i = 0; i < size; i++) {
7946 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7947 for (UriPermission perm : perms.values()) {
7948 if (perm.persistedModeFlags != 0) {
7949 persist.add(perm.snapshot());
7955 FileOutputStream fos = null;
7957 fos = mGrantFile.startWrite();
7959 XmlSerializer out = new FastXmlSerializer();
7960 out.setOutput(fos, StandardCharsets.UTF_8.name());
7961 out.startDocument(null, true);
7962 out.startTag(null, TAG_URI_GRANTS);
7963 for (UriPermission.Snapshot perm : persist) {
7964 out.startTag(null, TAG_URI_GRANT);
7965 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7966 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7967 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7968 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7969 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7970 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7971 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7972 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7973 out.endTag(null, TAG_URI_GRANT);
7975 out.endTag(null, TAG_URI_GRANTS);
7978 mGrantFile.finishWrite(fos);
7979 } catch (IOException e) {
7981 mGrantFile.failWrite(fos);
7986 private void readGrantedUriPermissionsLocked() {
7987 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7989 final long now = System.currentTimeMillis();
7991 FileInputStream fis = null;
7993 fis = mGrantFile.openRead();
7994 final XmlPullParser in = Xml.newPullParser();
7995 in.setInput(fis, StandardCharsets.UTF_8.name());
7998 while ((type = in.next()) != END_DOCUMENT) {
7999 final String tag = in.getName();
8000 if (type == START_TAG) {
8001 if (TAG_URI_GRANT.equals(tag)) {
8002 final int sourceUserId;
8003 final int targetUserId;
8004 final int userHandle = readIntAttribute(in,
8005 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8006 if (userHandle != UserHandle.USER_NULL) {
8007 // For backwards compatibility.
8008 sourceUserId = userHandle;
8009 targetUserId = userHandle;
8011 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8012 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8014 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8015 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8016 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8017 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8018 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8019 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8021 // Sanity check that provider still belongs to source package
8022 final ProviderInfo pi = getProviderInfoLocked(
8023 uri.getAuthority(), sourceUserId);
8024 if (pi != null && sourcePkg.equals(pi.packageName)) {
8027 targetUid = AppGlobals.getPackageManager()
8028 .getPackageUid(targetPkg, targetUserId);
8029 } catch (RemoteException e) {
8031 if (targetUid != -1) {
8032 final UriPermission perm = findOrCreateUriPermissionLocked(
8033 sourcePkg, targetPkg, targetUid,
8034 new GrantUri(sourceUserId, uri, prefix));
8035 perm.initPersistedModes(modeFlags, createdTime);
8038 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8039 + " but instead found " + pi);
8044 } catch (FileNotFoundException e) {
8045 // Missing grants is okay
8046 } catch (IOException e) {
8047 Slog.wtf(TAG, "Failed reading Uri grants", e);
8048 } catch (XmlPullParserException e) {
8049 Slog.wtf(TAG, "Failed reading Uri grants", e);
8051 IoUtils.closeQuietly(fis);
8056 * @param uri This uri must NOT contain an embedded userId.
8057 * @param userId The userId in which the uri is to be resolved.
8060 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8061 enforceNotIsolatedCaller("takePersistableUriPermission");
8063 Preconditions.checkFlagsArgument(modeFlags,
8064 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8066 synchronized (this) {
8067 final int callingUid = Binder.getCallingUid();
8068 boolean persistChanged = false;
8069 GrantUri grantUri = new GrantUri(userId, uri, false);
8071 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8072 new GrantUri(userId, uri, false));
8073 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8074 new GrantUri(userId, uri, true));
8076 final boolean exactValid = (exactPerm != null)
8077 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8078 final boolean prefixValid = (prefixPerm != null)
8079 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8081 if (!(exactValid || prefixValid)) {
8082 throw new SecurityException("No persistable permission grants found for UID "
8083 + callingUid + " and Uri " + grantUri.toSafeString());
8087 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8090 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8093 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8095 if (persistChanged) {
8096 schedulePersistUriGrants();
8102 * @param uri This uri must NOT contain an embedded userId.
8103 * @param userId The userId in which the uri is to be resolved.
8106 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8107 enforceNotIsolatedCaller("releasePersistableUriPermission");
8109 Preconditions.checkFlagsArgument(modeFlags,
8110 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8112 synchronized (this) {
8113 final int callingUid = Binder.getCallingUid();
8114 boolean persistChanged = false;
8116 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8117 new GrantUri(userId, uri, false));
8118 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8119 new GrantUri(userId, uri, true));
8120 if (exactPerm == null && prefixPerm == null) {
8121 throw new SecurityException("No permission grants found for UID " + callingUid
8122 + " and Uri " + uri.toSafeString());
8125 if (exactPerm != null) {
8126 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8127 removeUriPermissionIfNeededLocked(exactPerm);
8129 if (prefixPerm != null) {
8130 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8131 removeUriPermissionIfNeededLocked(prefixPerm);
8134 if (persistChanged) {
8135 schedulePersistUriGrants();
8141 * Prune any older {@link UriPermission} for the given UID until outstanding
8142 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8144 * @return if any mutations occured that require persisting.
8146 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8147 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8148 if (perms == null) return false;
8149 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8151 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8152 for (UriPermission perm : perms.values()) {
8153 if (perm.persistedModeFlags != 0) {
8154 persisted.add(perm);
8158 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8159 if (trimCount <= 0) return false;
8161 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8162 for (int i = 0; i < trimCount; i++) {
8163 final UriPermission perm = persisted.get(i);
8165 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8166 "Trimming grant created at " + perm.persistedCreateTime);
8168 perm.releasePersistableModes(~0);
8169 removeUriPermissionIfNeededLocked(perm);
8176 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8177 String packageName, boolean incoming) {
8178 enforceNotIsolatedCaller("getPersistedUriPermissions");
8179 Preconditions.checkNotNull(packageName, "packageName");
8181 final int callingUid = Binder.getCallingUid();
8182 final IPackageManager pm = AppGlobals.getPackageManager();
8184 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8185 if (packageUid != callingUid) {
8186 throw new SecurityException(
8187 "Package " + packageName + " does not belong to calling UID " + callingUid);
8189 } catch (RemoteException e) {
8190 throw new SecurityException("Failed to verify package name ownership");
8193 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8194 synchronized (this) {
8196 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8198 if (perms == null) {
8199 Slog.w(TAG, "No permission grants found for " + packageName);
8201 for (UriPermission perm : perms.values()) {
8202 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8203 result.add(perm.buildPersistedPublicApiObject());
8208 final int size = mGrantedUriPermissions.size();
8209 for (int i = 0; i < size; i++) {
8210 final ArrayMap<GrantUri, UriPermission> perms =
8211 mGrantedUriPermissions.valueAt(i);
8212 for (UriPermission perm : perms.values()) {
8213 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8214 result.add(perm.buildPersistedPublicApiObject());
8220 return new ParceledListSlice<android.content.UriPermission>(result);
8224 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8225 synchronized (this) {
8227 who != null ? getRecordForAppLocked(who) : null;
8228 if (app == null) return;
8230 Message msg = Message.obtain();
8231 msg.what = WAIT_FOR_DEBUGGER_MSG;
8233 msg.arg1 = waiting ? 1 : 0;
8234 mUiHandler.sendMessage(msg);
8239 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8240 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8241 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8242 outInfo.availMem = Process.getFreeMemory();
8243 outInfo.totalMem = Process.getTotalMemory();
8244 outInfo.threshold = homeAppMem;
8245 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8246 outInfo.hiddenAppThreshold = cachedAppMem;
8247 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8248 ProcessList.SERVICE_ADJ);
8249 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8250 ProcessList.VISIBLE_APP_ADJ);
8251 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8252 ProcessList.FOREGROUND_APP_ADJ);
8255 // =========================================================
8257 // =========================================================
8260 public List<IAppTask> getAppTasks(String callingPackage) {
8261 int callingUid = Binder.getCallingUid();
8262 long ident = Binder.clearCallingIdentity();
8264 synchronized(this) {
8265 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8267 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8269 final int N = mRecentTasks.size();
8270 for (int i = 0; i < N; i++) {
8271 TaskRecord tr = mRecentTasks.get(i);
8272 // Skip tasks that do not match the caller. We don't need to verify
8273 // callingPackage, because we are also limiting to callingUid and know
8274 // that will limit to the correct security sandbox.
8275 if (tr.effectiveUid != callingUid) {
8278 Intent intent = tr.getBaseIntent();
8279 if (intent == null ||
8280 !callingPackage.equals(intent.getComponent().getPackageName())) {
8283 ActivityManager.RecentTaskInfo taskInfo =
8284 createRecentTaskInfoFromTaskRecord(tr);
8285 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8289 Binder.restoreCallingIdentity(ident);
8296 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8297 final int callingUid = Binder.getCallingUid();
8298 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8300 synchronized(this) {
8301 if (DEBUG_ALL) Slog.v(
8302 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8304 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8307 // TODO: Improve with MRU list from all ActivityStacks.
8308 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8315 * Creates a new RecentTaskInfo from a TaskRecord.
8317 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8318 // Update the task description to reflect any changes in the task stack
8319 tr.updateTaskDescription();
8321 // Compose the recent task info
8322 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8323 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8324 rti.persistentId = tr.taskId;
8325 rti.baseIntent = new Intent(tr.getBaseIntent());
8326 rti.origActivity = tr.origActivity;
8327 rti.description = tr.lastDescription;
8328 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8329 rti.userId = tr.userId;
8330 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8331 rti.firstActiveTime = tr.firstActiveTime;
8332 rti.lastActiveTime = tr.lastActiveTime;
8333 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8334 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8335 rti.numActivities = 0;
8337 ActivityRecord base = null;
8338 ActivityRecord top = null;
8341 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8342 tmp = tr.mActivities.get(i);
8343 if (tmp.finishing) {
8347 if (top == null || (top.state == ActivityState.INITIALIZING)) {
8350 rti.numActivities++;
8353 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8354 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8359 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8360 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8361 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8363 if (checkPermission(android.Manifest.permission.GET_TASKS,
8364 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8365 // Temporary compatibility: some existing apps on the system image may
8366 // still be requesting the old permission and not switched to the new
8367 // one; if so, we'll still allow them full access. This means we need
8368 // to see if they are holding the old permission and are a system app.
8370 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8372 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8373 + " is using old GET_TASKS but privileged; allowing");
8375 } catch (RemoteException e) {
8380 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8381 + " does not hold REAL_GET_TASKS; limiting output");
8387 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8388 final int callingUid = Binder.getCallingUid();
8389 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8390 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8392 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8393 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8394 synchronized (this) {
8395 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8397 final boolean detailed = checkCallingPermission(
8398 android.Manifest.permission.GET_DETAILED_TASKS)
8399 == PackageManager.PERMISSION_GRANTED;
8401 final int recentsCount = mRecentTasks.size();
8402 ArrayList<ActivityManager.RecentTaskInfo> res =
8403 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8405 final Set<Integer> includedUsers;
8406 if (includeProfiles) {
8407 includedUsers = getProfileIdsLocked(userId);
8409 includedUsers = new HashSet<>();
8411 includedUsers.add(Integer.valueOf(userId));
8413 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8414 TaskRecord tr = mRecentTasks.get(i);
8415 // Only add calling user or related users recent tasks
8416 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8417 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8421 // Return the entry if desired by the caller. We always return
8422 // the first entry, because callers always expect this to be the
8423 // foreground app. We may filter others if the caller has
8424 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8425 // we should exclude the entry.
8429 || (tr.intent == null)
8430 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8433 // If the caller doesn't have the GET_TASKS permission, then only
8434 // allow them to see a small subset of tasks -- their own and home.
8435 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8436 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8440 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8441 if (tr.stack != null && tr.stack.isHomeStack()) {
8442 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8443 "Skipping, home stack task: " + tr);
8447 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8448 // Don't include auto remove tasks that are finished or finishing.
8449 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8450 "Skipping, auto-remove without activity: " + tr);
8453 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8454 && !tr.isAvailable) {
8455 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8456 "Skipping, unavail real act: " + tr);
8460 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8462 rti.baseIntent.replaceExtras((Bundle)null);
8474 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8475 synchronized (this) {
8476 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8477 "getTaskThumbnail()");
8478 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8480 return tr.getTaskThumbnailLocked();
8487 public int addAppTask(IBinder activityToken, Intent intent,
8488 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8489 final int callingUid = Binder.getCallingUid();
8490 final long callingIdent = Binder.clearCallingIdentity();
8493 synchronized (this) {
8494 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8496 throw new IllegalArgumentException("Activity does not exist; token="
8499 ComponentName comp = intent.getComponent();
8501 throw new IllegalArgumentException("Intent " + intent
8502 + " must specify explicit component");
8504 if (thumbnail.getWidth() != mThumbnailWidth
8505 || thumbnail.getHeight() != mThumbnailHeight) {
8506 throw new IllegalArgumentException("Bad thumbnail size: got "
8507 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8508 + mThumbnailWidth + "x" + mThumbnailHeight);
8510 if (intent.getSelector() != null) {
8511 intent.setSelector(null);
8513 if (intent.getSourceBounds() != null) {
8514 intent.setSourceBounds(null);
8516 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8517 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8518 // The caller has added this as an auto-remove task... that makes no
8519 // sense, so turn off auto-remove.
8520 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8522 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8523 // Must be a new task.
8524 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8526 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8527 mLastAddedTaskActivity = null;
8529 ActivityInfo ainfo = mLastAddedTaskActivity;
8530 if (ainfo == null) {
8531 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8532 comp, 0, UserHandle.getUserId(callingUid));
8533 if (ainfo.applicationInfo.uid != callingUid) {
8534 throw new SecurityException(
8535 "Can't add task for another application: target uid="
8536 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8540 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8541 intent, description);
8543 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8545 // If this would have caused a trim, then we'll abort because that
8546 // means it would be added at the end of the list but then just removed.
8547 return INVALID_TASK_ID;
8550 final int N = mRecentTasks.size();
8551 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8552 final TaskRecord tr = mRecentTasks.remove(N - 1);
8553 tr.removedFromRecents();
8556 task.inRecents = true;
8557 mRecentTasks.add(task);
8558 r.task.stack.addTask(task, false, false);
8560 task.setLastThumbnail(thumbnail);
8561 task.freeLastThumbnail();
8566 Binder.restoreCallingIdentity(callingIdent);
8571 public Point getAppTaskThumbnailSize() {
8572 synchronized (this) {
8573 return new Point(mThumbnailWidth, mThumbnailHeight);
8578 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8579 synchronized (this) {
8580 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8582 r.setTaskDescription(td);
8583 r.task.updateTaskDescription();
8589 public void setTaskResizeable(int taskId, boolean resizeable) {
8590 synchronized (this) {
8591 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8593 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8596 if (task.mResizeable != resizeable) {
8597 task.mResizeable = resizeable;
8598 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8599 mStackSupervisor.resumeTopActivitiesLocked();
8605 public void resizeTask(int taskId, Rect bounds) {
8606 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8608 long ident = Binder.clearCallingIdentity();
8610 synchronized (this) {
8611 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8613 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8616 mStackSupervisor.resizeTaskLocked(task, bounds);
8619 Binder.restoreCallingIdentity(ident);
8624 public Bitmap getTaskDescriptionIcon(String filename) {
8625 if (!FileUtils.isValidExtFilename(filename)
8626 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8627 throw new IllegalArgumentException("Bad filename: " + filename);
8629 return mTaskPersister.getTaskDescriptionIcon(filename);
8633 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8634 throws RemoteException {
8635 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8636 opts.getCustomInPlaceResId() == 0) {
8637 throw new IllegalArgumentException("Expected in-place ActivityOption " +
8638 "with valid animation");
8640 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8641 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8642 opts.getCustomInPlaceResId());
8643 mWindowManager.executeAppTransition();
8646 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8647 mRecentTasks.remove(tr);
8648 tr.removedFromRecents();
8649 ComponentName component = tr.getBaseIntent().getComponent();
8650 if (component == null) {
8651 Slog.w(TAG, "No component for base intent of task: " + tr);
8655 // Find any running services associated with this app and stop if needed.
8656 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8662 // Determine if the process(es) for this task should be killed.
8663 final String pkg = component.getPackageName();
8664 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8665 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8666 for (int i = 0; i < pmap.size(); i++) {
8668 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8669 for (int j = 0; j < uids.size(); j++) {
8670 ProcessRecord proc = uids.valueAt(j);
8671 if (proc.userId != tr.userId) {
8672 // Don't kill process for a different user.
8675 if (proc == mHomeProcess) {
8676 // Don't kill the home process along with tasks from the same package.
8679 if (!proc.pkgList.containsKey(pkg)) {
8680 // Don't kill process that is not associated with this task.
8684 for (int k = 0; k < proc.activities.size(); k++) {
8685 TaskRecord otherTask = proc.activities.get(k).task;
8686 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8687 // Don't kill process(es) that has an activity in a different task that is
8693 if (proc.foregroundServices) {
8694 // Don't kill process(es) with foreground service.
8698 // Add process to kill list.
8699 procsToKill.add(proc);
8703 // Kill the running processes.
8704 for (int i = 0; i < procsToKill.size(); i++) {
8705 ProcessRecord pr = procsToKill.get(i);
8706 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8707 && pr.curReceiver == null) {
8708 pr.kill("remove task", true);
8710 // We delay killing processes that are not in the background or running a receiver.
8711 pr.waitingToKill = "remove task";
8716 private void removeTasksByPackageNameLocked(String packageName, int userId) {
8717 // Remove all tasks with activities in the specified package from the list of recent tasks
8718 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8719 TaskRecord tr = mRecentTasks.get(i);
8720 if (tr.userId != userId) continue;
8722 ComponentName cn = tr.intent.getComponent();
8723 if (cn != null && cn.getPackageName().equals(packageName)) {
8724 // If the package name matches, remove the task.
8725 removeTaskByIdLocked(tr.taskId, true);
8730 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8733 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8734 TaskRecord tr = mRecentTasks.get(i);
8735 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8739 ComponentName cn = tr.intent.getComponent();
8740 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8741 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8742 if (sameComponent) {
8743 removeTaskByIdLocked(tr.taskId, false);
8749 * Removes the task with the specified task id.
8751 * @param taskId Identifier of the task to be removed.
8752 * @param killProcess Kill any process associated with the task if possible.
8753 * @return Returns true if the given task was found and removed.
8755 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8756 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8758 tr.removeTaskActivitiesLocked();
8759 cleanUpRemovedTaskLocked(tr, killProcess);
8760 if (tr.isPersistable) {
8761 notifyTaskPersisterLocked(null, true);
8765 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8770 public boolean removeTask(int taskId) {
8771 synchronized (this) {
8772 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8774 long ident = Binder.clearCallingIdentity();
8776 return removeTaskByIdLocked(taskId, true);
8778 Binder.restoreCallingIdentity(ident);
8784 * TODO: Add mController hook
8787 public void moveTaskToFront(int taskId, int flags, Bundle options) {
8788 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8790 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8791 synchronized(this) {
8792 moveTaskToFrontLocked(taskId, flags, options);
8796 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8797 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8798 Binder.getCallingUid(), -1, -1, "Task to front")) {
8799 ActivityOptions.abort(options);
8802 final long origId = Binder.clearCallingIdentity();
8804 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8806 Slog.d(TAG, "Could not find task for id: "+ taskId);
8809 if (mStackSupervisor.isLockTaskModeViolation(task)) {
8810 mStackSupervisor.showLockTaskToast();
8811 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8814 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8815 if (prev != null && prev.isRecentsActivity()) {
8816 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8818 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8820 Binder.restoreCallingIdentity(origId);
8822 ActivityOptions.abort(options);
8826 * Moves an activity, and all of the other activities within the same task, to the bottom
8827 * of the history stack. The activity's order within the task is unchanged.
8829 * @param token A reference to the activity we wish to move
8830 * @param nonRoot If false then this only works if the activity is the root
8831 * of a task; if true it will work for any activity in a task.
8832 * @return Returns true if the move completed, false if not.
8835 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8836 enforceNotIsolatedCaller("moveActivityTaskToBack");
8837 synchronized(this) {
8838 final long origId = Binder.clearCallingIdentity();
8840 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8841 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8843 if (mStackSupervisor.isLockedTask(task)) {
8844 mStackSupervisor.showLockTaskToast();
8847 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8850 Binder.restoreCallingIdentity(origId);
8857 public void moveTaskBackwards(int task) {
8858 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8859 "moveTaskBackwards()");
8861 synchronized(this) {
8862 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8863 Binder.getCallingUid(), -1, -1, "Task backwards")) {
8866 final long origId = Binder.clearCallingIdentity();
8867 moveTaskBackwardsLocked(task);
8868 Binder.restoreCallingIdentity(origId);
8872 private final void moveTaskBackwardsLocked(int task) {
8873 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8877 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8878 IActivityContainerCallback callback) throws RemoteException {
8879 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8880 "createActivityContainer()");
8881 synchronized (this) {
8882 if (parentActivityToken == null) {
8883 throw new IllegalArgumentException("parent token must not be null");
8885 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8889 if (callback == null) {
8890 throw new IllegalArgumentException("callback must not be null");
8892 return mStackSupervisor.createVirtualActivityContainer(r, callback);
8897 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8898 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8899 "deleteActivityContainer()");
8900 synchronized (this) {
8901 mStackSupervisor.deleteActivityContainer(container);
8906 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8907 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8908 "createStackOnDisplay()");
8909 synchronized (this) {
8910 final int stackId = mStackSupervisor.getNextStackId();
8911 final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8912 if (stack == null) {
8915 return stack.mActivityContainer;
8920 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8921 synchronized (this) {
8922 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8923 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8924 return stack.mActivityContainer.getDisplayId();
8926 return Display.DEFAULT_DISPLAY;
8931 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8932 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8933 "moveTaskToStack()");
8934 if (stackId == HOME_STACK_ID) {
8935 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8936 new RuntimeException("here").fillInStackTrace());
8938 synchronized (this) {
8939 long ident = Binder.clearCallingIdentity();
8941 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8942 + " to stackId=" + stackId + " toTop=" + toTop);
8943 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8945 Binder.restoreCallingIdentity(ident);
8951 public void resizeStack(int stackId, Rect bounds) {
8952 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8954 long ident = Binder.clearCallingIdentity();
8956 synchronized (this) {
8957 mStackSupervisor.resizeStackLocked(stackId, bounds);
8960 Binder.restoreCallingIdentity(ident);
8965 public List<StackInfo> getAllStackInfos() {
8966 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8967 "getAllStackInfos()");
8968 long ident = Binder.clearCallingIdentity();
8970 synchronized (this) {
8971 return mStackSupervisor.getAllStackInfosLocked();
8974 Binder.restoreCallingIdentity(ident);
8979 public StackInfo getStackInfo(int stackId) {
8980 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8982 long ident = Binder.clearCallingIdentity();
8984 synchronized (this) {
8985 return mStackSupervisor.getStackInfoLocked(stackId);
8988 Binder.restoreCallingIdentity(ident);
8993 public boolean isInHomeStack(int taskId) {
8994 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8996 long ident = Binder.clearCallingIdentity();
8998 synchronized (this) {
8999 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
9000 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9003 Binder.restoreCallingIdentity(ident);
9008 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9009 synchronized(this) {
9010 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9015 public void updateDeviceOwner(String packageName) {
9016 final int callingUid = Binder.getCallingUid();
9017 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9018 throw new SecurityException("updateDeviceOwner called from non-system process");
9020 synchronized (this) {
9021 mDeviceOwnerName = packageName;
9026 public void updateLockTaskPackages(int userId, String[] packages) {
9027 final int callingUid = Binder.getCallingUid();
9028 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9029 throw new SecurityException("updateLockTaskPackage called from non-system process");
9031 synchronized (this) {
9032 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9033 Arrays.toString(packages));
9034 mLockTaskPackages.put(userId, packages);
9035 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9040 void startLockTaskModeLocked(TaskRecord task) {
9041 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9042 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9046 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9047 // is initiated by system after the pinning request was shown and locked mode is initiated
9048 // by an authorized app directly
9049 final int callingUid = Binder.getCallingUid();
9050 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9051 long ident = Binder.clearCallingIdentity();
9053 final ActivityStack stack = mStackSupervisor.getFocusedStack();
9054 if (!isSystemInitiated) {
9055 task.mLockTaskUid = callingUid;
9056 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9057 // startLockTask() called by app and task mode is lockTaskModeDefault.
9058 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9059 StatusBarManagerInternal statusBarManager =
9060 LocalServices.getService(StatusBarManagerInternal.class);
9061 if (statusBarManager != null) {
9062 statusBarManager.showScreenPinningRequest();
9067 if (stack == null || task != stack.topTask()) {
9068 throw new IllegalArgumentException("Invalid task, not in foreground");
9071 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9073 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9074 ActivityManager.LOCK_TASK_MODE_PINNED :
9075 ActivityManager.LOCK_TASK_MODE_LOCKED,
9076 "startLockTask", true);
9078 Binder.restoreCallingIdentity(ident);
9083 public void startLockTaskMode(int taskId) {
9084 synchronized (this) {
9085 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9087 startLockTaskModeLocked(task);
9093 public void startLockTaskMode(IBinder token) {
9094 synchronized (this) {
9095 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9099 final TaskRecord task = r.task;
9101 startLockTaskModeLocked(task);
9107 public void startLockTaskModeOnCurrent() throws RemoteException {
9108 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9109 "startLockTaskModeOnCurrent");
9110 long ident = Binder.clearCallingIdentity();
9112 synchronized (this) {
9113 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9115 startLockTaskModeLocked(r.task);
9119 Binder.restoreCallingIdentity(ident);
9124 public void stopLockTaskMode() {
9125 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9126 if (lockTask == null) {
9127 // Our work here is done.
9131 final int callingUid = Binder.getCallingUid();
9132 final int lockTaskUid = lockTask.mLockTaskUid;
9133 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9134 // It is possible lockTaskMode was started by the system process because
9135 // android:lockTaskMode is set to a locking value in the application manifest instead of
9136 // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9137 // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9138 if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9139 callingUid != lockTaskUid
9140 && (lockTaskUid != 0
9141 || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9142 throw new SecurityException("Invalid uid, expected " + lockTaskUid
9143 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9146 long ident = Binder.clearCallingIdentity();
9148 Log.d(TAG, "stopLockTaskMode");
9150 synchronized (this) {
9151 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9152 "stopLockTask", true);
9154 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
9156 tm.showInCallScreen(false);
9159 Binder.restoreCallingIdentity(ident);
9164 public void stopLockTaskModeOnCurrent() throws RemoteException {
9165 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9166 "stopLockTaskModeOnCurrent");
9167 long ident = Binder.clearCallingIdentity();
9171 Binder.restoreCallingIdentity(ident);
9176 public boolean isInLockTaskMode() {
9177 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9181 public int getLockTaskModeState() {
9182 synchronized (this) {
9183 return mStackSupervisor.getLockTaskModeState();
9188 public void showLockTaskEscapeMessage(IBinder token) {
9189 synchronized (this) {
9190 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9194 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9198 // =========================================================
9199 // CONTENT PROVIDERS
9200 // =========================================================
9202 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9203 List<ProviderInfo> providers = null;
9205 ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9206 queryContentProviders(app.processName, app.uid,
9207 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9208 providers = slice != null ? slice.getList() : null;
9209 } catch (RemoteException ex) {
9211 if (DEBUG_MU) Slog.v(TAG_MU,
9212 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9213 int userId = app.userId;
9214 if (providers != null) {
9215 int N = providers.size();
9216 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9217 for (int i=0; i<N; i++) {
9219 (ProviderInfo)providers.get(i);
9220 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9221 cpi.name, cpi.flags);
9222 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9223 // This is a singleton provider, but a user besides the
9224 // default user is asking to initialize a process it runs
9225 // in... well, no, it doesn't actually run in this process,
9226 // it runs in the process of the default user. Get rid of it.
9227 providers.remove(i);
9233 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9234 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9236 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9237 mProviderMap.putProviderByClass(comp, cpr);
9239 if (DEBUG_MU) Slog.v(TAG_MU,
9240 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9241 app.pubProviders.put(cpi.name, cpr);
9242 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9243 // Don't add this if it is a platform component that is marked
9244 // to run in multiple processes, because this is actually
9245 // part of the framework so doesn't make sense to track as a
9246 // separate apk in the process.
9247 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9250 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9257 * Check if the calling UID has a possible chance at accessing the provider
9258 * at the given authority and user.
9260 public String checkContentProviderAccess(String authority, int userId) {
9261 if (userId == UserHandle.USER_ALL) {
9262 mContext.enforceCallingOrSelfPermission(
9263 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
9264 userId = UserHandle.getCallingUserId();
9267 ProviderInfo cpi = null;
9269 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
9270 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9271 } catch (RemoteException ignored) {
9274 // TODO: make this an outright failure in a future platform release;
9275 // until then anonymous content notifications are unprotected
9276 //return "Failed to find provider " + authority + " for user " + userId;
9280 ProcessRecord r = null;
9281 synchronized (mPidsSelfLocked) {
9282 r = mPidsSelfLocked.get(Binder.getCallingPid());
9285 return "Failed to find PID " + Binder.getCallingPid();
9288 synchronized (this) {
9289 return checkContentProviderPermissionLocked(cpi, r, userId, true);
9294 * Check if {@link ProcessRecord} has a possible chance at accessing the
9295 * given {@link ProviderInfo}. Final permission checking is always done
9296 * in {@link ContentProvider}.
9298 private final String checkContentProviderPermissionLocked(
9299 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9300 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9301 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9302 boolean checkedGrants = false;
9304 // Looking for cross-user grants before enforcing the typical cross-users permissions
9305 int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9306 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9307 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9310 checkedGrants = true;
9312 userId = handleIncomingUser(callingPid, callingUid, userId,
9313 false, ALLOW_NON_FULL,
9314 "checkContentProviderPermissionLocked " + cpi.authority, null);
9315 if (userId != tmpTargetUserId) {
9316 // When we actually went to determine the final targer user ID, this ended
9317 // up different than our initial check for the authority. This is because
9318 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9319 // SELF. So we need to re-check the grants again.
9320 checkedGrants = false;
9323 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9324 cpi.applicationInfo.uid, cpi.exported)
9325 == PackageManager.PERMISSION_GRANTED) {
9328 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9329 cpi.applicationInfo.uid, cpi.exported)
9330 == PackageManager.PERMISSION_GRANTED) {
9334 PathPermission[] pps = cpi.pathPermissions;
9339 PathPermission pp = pps[i];
9340 String pprperm = pp.getReadPermission();
9341 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9342 cpi.applicationInfo.uid, cpi.exported)
9343 == PackageManager.PERMISSION_GRANTED) {
9346 String ppwperm = pp.getWritePermission();
9347 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9348 cpi.applicationInfo.uid, cpi.exported)
9349 == PackageManager.PERMISSION_GRANTED) {
9354 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9359 if (!cpi.exported) {
9360 msg = "Permission Denial: opening provider " + cpi.name
9361 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9362 + ", uid=" + callingUid + ") that is not exported from uid "
9363 + cpi.applicationInfo.uid;
9365 msg = "Permission Denial: opening provider " + cpi.name
9366 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9367 + ", uid=" + callingUid + ") requires "
9368 + cpi.readPermission + " or " + cpi.writePermission;
9375 * Returns if the ContentProvider has granted a uri to callingUid
9377 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9378 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9379 if (perms != null) {
9380 for (int i=perms.size()-1; i>=0; i--) {
9381 GrantUri grantUri = perms.keyAt(i);
9382 if (grantUri.sourceUserId == userId || !checkUser) {
9383 if (matchesProvider(grantUri.uri, cpi)) {
9393 * Returns true if the uri authority is one of the authorities specified in the provider.
9395 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9396 String uriAuth = uri.getAuthority();
9397 String cpiAuth = cpi.authority;
9398 if (cpiAuth.indexOf(';') == -1) {
9399 return cpiAuth.equals(uriAuth);
9401 String[] cpiAuths = cpiAuth.split(";");
9402 int length = cpiAuths.length;
9403 for (int i = 0; i < length; i++) {
9404 if (cpiAuths[i].equals(uriAuth)) return true;
9409 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9410 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9412 for (int i=0; i<r.conProviders.size(); i++) {
9413 ContentProviderConnection conn = r.conProviders.get(i);
9414 if (conn.provider == cpr) {
9415 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9416 "Adding provider requested by "
9417 + r.processName + " from process "
9418 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9419 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9422 conn.numStableIncs++;
9424 conn.unstableCount++;
9425 conn.numUnstableIncs++;
9430 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9432 conn.stableCount = 1;
9433 conn.numStableIncs = 1;
9435 conn.unstableCount = 1;
9436 conn.numUnstableIncs = 1;
9438 cpr.connections.add(conn);
9439 r.conProviders.add(conn);
9440 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9443 cpr.addExternalProcessHandleLocked(externalProcessToken);
9447 boolean decProviderCountLocked(ContentProviderConnection conn,
9448 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9450 cpr = conn.provider;
9451 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9452 "Removing provider requested by "
9453 + conn.client.processName + " from process "
9454 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9455 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9459 conn.unstableCount--;
9461 if (conn.stableCount == 0 && conn.unstableCount == 0) {
9462 cpr.connections.remove(conn);
9463 conn.client.conProviders.remove(conn);
9464 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9469 cpr.removeExternalProcessHandleLocked(externalProcessToken);
9473 private void checkTime(long startTime, String where) {
9474 long now = SystemClock.elapsedRealtime();
9475 if ((now-startTime) > 1000) {
9476 // If we are taking more than a second, log about it.
9477 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9481 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9482 String name, IBinder token, boolean stable, int userId) {
9483 ContentProviderRecord cpr;
9484 ContentProviderConnection conn = null;
9485 ProviderInfo cpi = null;
9487 synchronized(this) {
9488 long startTime = SystemClock.elapsedRealtime();
9490 ProcessRecord r = null;
9491 if (caller != null) {
9492 r = getRecordForAppLocked(caller);
9494 throw new SecurityException(
9495 "Unable to find app for caller " + caller
9496 + " (pid=" + Binder.getCallingPid()
9497 + ") when getting content provider " + name);
9501 boolean checkCrossUser = true;
9503 checkTime(startTime, "getContentProviderImpl: getProviderByName");
9505 // First check if this content provider has been published...
9506 cpr = mProviderMap.getProviderByName(name, userId);
9507 // If that didn't work, check if it exists for user 0 and then
9508 // verify that it's a singleton provider before using it.
9509 if (cpr == null && userId != UserHandle.USER_OWNER) {
9510 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9513 if (isSingleton(cpi.processName, cpi.applicationInfo,
9514 cpi.name, cpi.flags)
9515 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9516 userId = UserHandle.USER_OWNER;
9517 checkCrossUser = false;
9525 boolean providerRunning = cpr != null;
9526 if (providerRunning) {
9529 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9530 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9532 throw new SecurityException(msg);
9534 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9536 if (r != null && cpr.canRunHere(r)) {
9537 // This provider has been published or is in the process
9538 // of being published... but it is also allowed to run
9539 // in the caller's process, so don't make a connection
9540 // and just let the caller instantiate its own instance.
9541 ContentProviderHolder holder = cpr.newHolder(null);
9542 // don't give caller the provider object, it needs
9544 holder.provider = null;
9548 final long origId = Binder.clearCallingIdentity();
9550 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9552 // In this case the provider instance already exists, so we can
9553 // return it right away.
9554 conn = incProviderCountLocked(r, cpr, token, stable);
9555 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9556 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9557 // If this is a perceptible app accessing the provider,
9558 // make sure to count it as being accessed and thus
9559 // back up on the LRU list. This is good because
9560 // content providers are often expensive to start.
9561 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9562 updateLruProcessLocked(cpr.proc, false, null);
9563 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9567 if (cpr.proc != null) {
9569 if (cpr.name.flattenToShortString().equals(
9570 "com.android.providers.calendar/.CalendarProvider2")) {
9571 Slog.v(TAG, "****************** KILLING "
9572 + cpr.name.flattenToShortString());
9573 Process.killProcess(cpr.proc.pid);
9576 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9577 boolean success = updateOomAdjLocked(cpr.proc);
9578 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9579 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9580 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9581 // NOTE: there is still a race here where a signal could be
9582 // pending on the process even though we managed to update its
9583 // adj level. Not sure what to do about this, but at least
9584 // the race is now smaller.
9586 // Uh oh... it looks like the provider's process
9587 // has been killed on us. We need to wait for a new
9588 // process to be started, and make sure its death
9589 // doesn't kill our process.
9590 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9591 + " is crashing; detaching " + r);
9592 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9593 checkTime(startTime, "getContentProviderImpl: before appDied");
9594 appDiedLocked(cpr.proc);
9595 checkTime(startTime, "getContentProviderImpl: after appDied");
9597 // This wasn't the last ref our process had on
9598 // the provider... we have now been killed, bail.
9601 providerRunning = false;
9606 Binder.restoreCallingIdentity(origId);
9610 if (!providerRunning) {
9612 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9613 cpi = AppGlobals.getPackageManager().
9614 resolveContentProvider(name,
9615 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9616 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9617 } catch (RemoteException ex) {
9622 // If the provider is a singleton AND
9623 // (it's a call within the same user || the provider is a
9625 // Then allow connecting to the singleton provider
9626 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9627 cpi.name, cpi.flags)
9628 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9630 userId = UserHandle.USER_OWNER;
9632 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9633 checkTime(startTime, "getContentProviderImpl: got app info for user");
9636 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9637 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9639 throw new SecurityException(msg);
9641 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9643 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9644 && !cpi.processName.equals("system")) {
9645 // If this content provider does not run in the system
9646 // process, and the system is not yet ready to run other
9647 // processes, then fail fast instead of hanging.
9648 throw new IllegalArgumentException(
9649 "Attempt to launch content provider before system ready");
9652 // Make sure that the user who owns this provider is running. If not,
9653 // we don't want to allow it to run.
9654 if (!isUserRunningLocked(userId, false)) {
9655 Slog.w(TAG, "Unable to launch app "
9656 + cpi.applicationInfo.packageName + "/"
9657 + cpi.applicationInfo.uid + " for provider "
9658 + name + ": user " + userId + " is stopped");
9662 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9663 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9664 cpr = mProviderMap.getProviderByClass(comp, userId);
9665 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9666 final boolean firstClass = cpr == null;
9668 final long ident = Binder.clearCallingIdentity();
9670 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9671 ApplicationInfo ai =
9672 AppGlobals.getPackageManager().
9674 cpi.applicationInfo.packageName,
9675 STOCK_PM_FLAGS, userId);
9676 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9678 Slog.w(TAG, "No package info for content provider "
9682 ai = getAppInfoForUser(ai, userId);
9683 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9684 } catch (RemoteException ex) {
9685 // pm is in same process, this will never happen.
9687 Binder.restoreCallingIdentity(ident);
9691 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9693 if (r != null && cpr.canRunHere(r)) {
9694 // If this is a multiprocess provider, then just return its
9695 // info and allow the caller to instantiate it. Only do
9696 // this if the provider is the same user as the caller's
9697 // process, or can run as root (so can be in any process).
9698 return cpr.newHolder(null);
9701 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9702 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9703 + cpr.info.name + " callers=" + Debug.getCallers(6));
9705 // This is single process, and our app is now connecting to it.
9706 // See if we are already in the process of launching this
9708 final int N = mLaunchingProviders.size();
9710 for (i = 0; i < N; i++) {
9711 if (mLaunchingProviders.get(i) == cpr) {
9716 // If the provider is not already being launched, then get it
9719 final long origId = Binder.clearCallingIdentity();
9722 // Content provider is now in use, its package can't be stopped.
9724 checkTime(startTime, "getContentProviderImpl: before set stopped state");
9725 AppGlobals.getPackageManager().setPackageStoppedState(
9726 cpr.appInfo.packageName, false, userId);
9727 checkTime(startTime, "getContentProviderImpl: after set stopped state");
9728 } catch (RemoteException e) {
9729 } catch (IllegalArgumentException e) {
9730 Slog.w(TAG, "Failed trying to unstop package "
9731 + cpr.appInfo.packageName + ": " + e);
9734 // Use existing process if already started
9735 checkTime(startTime, "getContentProviderImpl: looking for process record");
9736 ProcessRecord proc = getProcessRecordLocked(
9737 cpi.processName, cpr.appInfo.uid, false);
9738 if (proc != null && proc.thread != null) {
9739 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9740 "Installing in existing process " + proc);
9741 if (!proc.pubProviders.containsKey(cpi.name)) {
9742 checkTime(startTime, "getContentProviderImpl: scheduling install");
9743 proc.pubProviders.put(cpi.name, cpr);
9745 proc.thread.scheduleInstallProvider(cpi);
9746 } catch (RemoteException e) {
9750 checkTime(startTime, "getContentProviderImpl: before start process");
9751 proc = startProcessLocked(cpi.processName,
9752 cpr.appInfo, false, 0, "content provider",
9753 new ComponentName(cpi.applicationInfo.packageName,
9754 cpi.name), false, false, false);
9755 checkTime(startTime, "getContentProviderImpl: after start process");
9757 Slog.w(TAG, "Unable to launch app "
9758 + cpi.applicationInfo.packageName + "/"
9759 + cpi.applicationInfo.uid + " for provider "
9760 + name + ": process is bad");
9764 cpr.launchingApp = proc;
9765 mLaunchingProviders.add(cpr);
9767 Binder.restoreCallingIdentity(origId);
9771 checkTime(startTime, "getContentProviderImpl: updating data structures");
9773 // Make sure the provider is published (the same provider class
9774 // may be published under multiple names).
9776 mProviderMap.putProviderByClass(comp, cpr);
9779 mProviderMap.putProviderByName(name, cpr);
9780 conn = incProviderCountLocked(r, cpr, token, stable);
9782 conn.waiting = true;
9785 checkTime(startTime, "getContentProviderImpl: done!");
9788 // Wait for the provider to be published...
9789 synchronized (cpr) {
9790 while (cpr.provider == null) {
9791 if (cpr.launchingApp == null) {
9792 Slog.w(TAG, "Unable to launch app "
9793 + cpi.applicationInfo.packageName + "/"
9794 + cpi.applicationInfo.uid + " for provider "
9795 + name + ": launching app became null");
9796 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9797 UserHandle.getUserId(cpi.applicationInfo.uid),
9798 cpi.applicationInfo.packageName,
9799 cpi.applicationInfo.uid, name);
9803 if (DEBUG_MU) Slog.v(TAG_MU,
9804 "Waiting to start provider " + cpr
9805 + " launchingApp=" + cpr.launchingApp);
9807 conn.waiting = true;
9810 } catch (InterruptedException ex) {
9813 conn.waiting = false;
9818 return cpr != null ? cpr.newHolder(conn) : null;
9822 public final ContentProviderHolder getContentProvider(
9823 IApplicationThread caller, String name, int userId, boolean stable) {
9824 enforceNotIsolatedCaller("getContentProvider");
9825 if (caller == null) {
9826 String msg = "null IApplicationThread when getting content provider "
9829 throw new SecurityException(msg);
9831 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9832 // with cross-user grant.
9833 return getContentProviderImpl(caller, name, null, stable, userId);
9836 public ContentProviderHolder getContentProviderExternal(
9837 String name, int userId, IBinder token) {
9838 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9839 "Do not have permission in call getContentProviderExternal()");
9840 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9841 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9842 return getContentProviderExternalUnchecked(name, token, userId);
9845 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9846 IBinder token, int userId) {
9847 return getContentProviderImpl(null, name, token, true, userId);
9851 * Drop a content provider from a ProcessRecord's bookkeeping
9853 public void removeContentProvider(IBinder connection, boolean stable) {
9854 enforceNotIsolatedCaller("removeContentProvider");
9855 long ident = Binder.clearCallingIdentity();
9857 synchronized (this) {
9858 ContentProviderConnection conn;
9860 conn = (ContentProviderConnection)connection;
9861 } catch (ClassCastException e) {
9862 String msg ="removeContentProvider: " + connection
9863 + " not a ContentProviderConnection";
9865 throw new IllegalArgumentException(msg);
9868 throw new NullPointerException("connection is null");
9870 if (decProviderCountLocked(conn, null, null, stable)) {
9871 updateOomAdjLocked();
9875 Binder.restoreCallingIdentity(ident);
9879 public void removeContentProviderExternal(String name, IBinder token) {
9880 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9881 "Do not have permission in call removeContentProviderExternal()");
9882 int userId = UserHandle.getCallingUserId();
9883 long ident = Binder.clearCallingIdentity();
9885 removeContentProviderExternalUnchecked(name, token, userId);
9887 Binder.restoreCallingIdentity(ident);
9891 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9892 synchronized (this) {
9893 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9895 //remove from mProvidersByClass
9896 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9900 //update content provider record entry info
9901 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9902 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9903 if (localCpr.hasExternalProcessHandles()) {
9904 if (localCpr.removeExternalProcessHandleLocked(token)) {
9905 updateOomAdjLocked();
9907 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9908 + " with no external reference for token: "
9912 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9913 + " with no external references.");
9918 public final void publishContentProviders(IApplicationThread caller,
9919 List<ContentProviderHolder> providers) {
9920 if (providers == null) {
9924 enforceNotIsolatedCaller("publishContentProviders");
9925 synchronized (this) {
9926 final ProcessRecord r = getRecordForAppLocked(caller);
9927 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9929 throw new SecurityException(
9930 "Unable to find app for caller " + caller
9931 + " (pid=" + Binder.getCallingPid()
9932 + ") when publishing content providers");
9935 final long origId = Binder.clearCallingIdentity();
9937 final int N = providers.size();
9938 for (int i=0; i<N; i++) {
9939 ContentProviderHolder src = providers.get(i);
9940 if (src == null || src.info == null || src.provider == null) {
9943 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9944 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9946 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9947 mProviderMap.putProviderByClass(comp, dst);
9948 String names[] = dst.info.authority.split(";");
9949 for (int j = 0; j < names.length; j++) {
9950 mProviderMap.putProviderByName(names[j], dst);
9953 int NL = mLaunchingProviders.size();
9955 for (j=0; j<NL; j++) {
9956 if (mLaunchingProviders.get(j) == dst) {
9957 mLaunchingProviders.remove(j);
9962 synchronized (dst) {
9963 dst.provider = src.provider;
9967 updateOomAdjLocked(r);
9968 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9969 src.info.authority);
9973 Binder.restoreCallingIdentity(origId);
9977 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9978 ContentProviderConnection conn;
9980 conn = (ContentProviderConnection)connection;
9981 } catch (ClassCastException e) {
9982 String msg ="refContentProvider: " + connection
9983 + " not a ContentProviderConnection";
9985 throw new IllegalArgumentException(msg);
9988 throw new NullPointerException("connection is null");
9991 synchronized (this) {
9993 conn.numStableIncs += stable;
9995 stable = conn.stableCount + stable;
9997 throw new IllegalStateException("stableCount < 0: " + stable);
10000 if (unstable > 0) {
10001 conn.numUnstableIncs += unstable;
10003 unstable = conn.unstableCount + unstable;
10004 if (unstable < 0) {
10005 throw new IllegalStateException("unstableCount < 0: " + unstable);
10008 if ((stable+unstable) <= 0) {
10009 throw new IllegalStateException("ref counts can't go to zero here: stable="
10010 + stable + " unstable=" + unstable);
10012 conn.stableCount = stable;
10013 conn.unstableCount = unstable;
10018 public void unstableProviderDied(IBinder connection) {
10019 ContentProviderConnection conn;
10021 conn = (ContentProviderConnection)connection;
10022 } catch (ClassCastException e) {
10023 String msg ="refContentProvider: " + connection
10024 + " not a ContentProviderConnection";
10026 throw new IllegalArgumentException(msg);
10028 if (conn == null) {
10029 throw new NullPointerException("connection is null");
10032 // Safely retrieve the content provider associated with the connection.
10033 IContentProvider provider;
10034 synchronized (this) {
10035 provider = conn.provider.provider;
10038 if (provider == null) {
10039 // Um, yeah, we're way ahead of you.
10043 // Make sure the caller is being honest with us.
10044 if (provider.asBinder().pingBinder()) {
10045 // Er, no, still looks good to us.
10046 synchronized (this) {
10047 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10048 + " says " + conn + " died, but we don't agree");
10053 // Well look at that! It's dead!
10054 synchronized (this) {
10055 if (conn.provider.provider != provider) {
10056 // But something changed... good enough.
10060 ProcessRecord proc = conn.provider.proc;
10061 if (proc == null || proc.thread == null) {
10062 // Seems like the process is already cleaned up.
10066 // As far as we're concerned, this is just like receiving a
10067 // death notification... just a bit prematurely.
10068 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10069 + ") early provider death");
10070 final long ident = Binder.clearCallingIdentity();
10072 appDiedLocked(proc);
10074 Binder.restoreCallingIdentity(ident);
10080 public void appNotRespondingViaProvider(IBinder connection) {
10081 enforceCallingPermission(
10082 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10084 final ContentProviderConnection conn = (ContentProviderConnection) connection;
10085 if (conn == null) {
10086 Slog.w(TAG, "ContentProviderConnection is null");
10090 final ProcessRecord host = conn.provider.proc;
10091 if (host == null) {
10092 Slog.w(TAG, "Failed to find hosting ProcessRecord");
10096 final long token = Binder.clearCallingIdentity();
10098 appNotResponding(host, null, null, false, "ContentProvider not responding");
10100 Binder.restoreCallingIdentity(token);
10104 public final void installSystemProviders() {
10105 List<ProviderInfo> providers;
10106 synchronized (this) {
10107 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10108 providers = generateApplicationProvidersLocked(app);
10109 if (providers != null) {
10110 for (int i=providers.size()-1; i>=0; i--) {
10111 ProviderInfo pi = (ProviderInfo)providers.get(i);
10112 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10113 Slog.w(TAG, "Not installing system proc provider " + pi.name
10114 + ": not system .apk");
10115 providers.remove(i);
10120 if (providers != null) {
10121 mSystemThread.installSystemProviders(providers);
10124 mCoreSettingsObserver = new CoreSettingsObserver(this);
10126 //mUsageStatsService.monitorPackages();
10130 * Allows apps to retrieve the MIME type of a URI.
10131 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10132 * users, then it does not need permission to access the ContentProvider.
10133 * Either, it needs cross-user uri grants.
10135 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10137 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10138 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10140 public String getProviderMimeType(Uri uri, int userId) {
10141 enforceNotIsolatedCaller("getProviderMimeType");
10142 final String name = uri.getAuthority();
10143 int callingUid = Binder.getCallingUid();
10144 int callingPid = Binder.getCallingPid();
10146 boolean clearedIdentity = false;
10147 userId = unsafeConvertIncomingUser(userId);
10148 if (canClearIdentity(callingPid, callingUid, userId)) {
10149 clearedIdentity = true;
10150 ident = Binder.clearCallingIdentity();
10152 ContentProviderHolder holder = null;
10154 holder = getContentProviderExternalUnchecked(name, null, userId);
10155 if (holder != null) {
10156 return holder.provider.getType(uri);
10158 } catch (RemoteException e) {
10159 Log.w(TAG, "Content provider dead retrieving " + uri, e);
10162 // We need to clear the identity to call removeContentProviderExternalUnchecked
10163 if (!clearedIdentity) {
10164 ident = Binder.clearCallingIdentity();
10167 if (holder != null) {
10168 removeContentProviderExternalUnchecked(name, null, userId);
10171 Binder.restoreCallingIdentity(ident);
10178 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10179 if (UserHandle.getUserId(callingUid) == userId) {
10182 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10183 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10184 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10185 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10191 // =========================================================
10192 // GLOBAL MANAGEMENT
10193 // =========================================================
10195 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10196 boolean isolated, int isolatedUid) {
10197 String proc = customProcess != null ? customProcess : info.processName;
10198 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10199 final int userId = UserHandle.getUserId(info.uid);
10200 int uid = info.uid;
10202 if (isolatedUid == 0) {
10203 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10205 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10206 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10207 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10209 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10210 mNextIsolatedProcessUid++;
10211 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10212 // No process for this uid, use it.
10216 if (stepsLeft <= 0) {
10221 // Special case for startIsolatedProcess (internal only), where
10222 // the uid of the isolated process is specified by the caller.
10226 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10227 if (!mBooted && !mBooting
10228 && userId == UserHandle.USER_OWNER
10229 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10230 r.persistent = true;
10232 addProcessNameLocked(r);
10236 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10237 String abiOverride) {
10240 app = getProcessRecordLocked(info.processName, info.uid, true);
10246 app = newProcessRecordLocked(info, null, isolated, 0);
10247 updateLruProcessLocked(app, false, null);
10248 updateOomAdjLocked();
10251 // This package really, really can not be stopped.
10253 AppGlobals.getPackageManager().setPackageStoppedState(
10254 info.packageName, false, UserHandle.getUserId(app.uid));
10255 } catch (RemoteException e) {
10256 } catch (IllegalArgumentException e) {
10257 Slog.w(TAG, "Failed trying to unstop package "
10258 + info.packageName + ": " + e);
10261 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10262 app.persistent = true;
10263 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10265 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10266 mPersistentStartingProcesses.add(app);
10267 startProcessLocked(app, "added application", app.processName, abiOverride,
10268 null /* entryPoint */, null /* entryPointArgs */);
10274 public void unhandledBack() {
10275 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10276 "unhandledBack()");
10278 synchronized(this) {
10279 final long origId = Binder.clearCallingIdentity();
10281 getFocusedStack().unhandledBackLocked();
10283 Binder.restoreCallingIdentity(origId);
10288 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10289 enforceNotIsolatedCaller("openContentUri");
10290 final int userId = UserHandle.getCallingUserId();
10291 String name = uri.getAuthority();
10292 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10293 ParcelFileDescriptor pfd = null;
10295 // We record the binder invoker's uid in thread-local storage before
10296 // going to the content provider to open the file. Later, in the code
10297 // that handles all permissions checks, we look for this uid and use
10298 // that rather than the Activity Manager's own uid. The effect is that
10299 // we do the check against the caller's permissions even though it looks
10300 // to the content provider like the Activity Manager itself is making
10302 Binder token = new Binder();
10303 sCallerIdentity.set(new Identity(
10304 token, Binder.getCallingPid(), Binder.getCallingUid()));
10306 pfd = cph.provider.openFile(null, uri, "r", null, token);
10307 } catch (FileNotFoundException e) {
10308 // do nothing; pfd will be returned null
10310 // Ensure that whatever happens, we clean up the identity state
10311 sCallerIdentity.remove();
10312 // Ensure we're done with the provider.
10313 removeContentProviderExternalUnchecked(name, null, userId);
10316 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10321 // Actually is sleeping or shutting down or whatever else in the future
10322 // is an inactive state.
10323 public boolean isSleepingOrShuttingDown() {
10324 return isSleeping() || mShuttingDown;
10327 public boolean isSleeping() {
10331 void onWakefulnessChanged(int wakefulness) {
10332 synchronized(this) {
10333 mWakefulness = wakefulness;
10334 updateSleepIfNeededLocked();
10338 void finishRunningVoiceLocked() {
10339 if (mRunningVoice != null) {
10340 mRunningVoice = null;
10341 mVoiceWakeLock.release();
10342 updateSleepIfNeededLocked();
10346 void startTimeTrackingFocusedActivityLocked() {
10347 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10348 mCurAppTimeTracker.start(mFocusedActivity.packageName);
10352 void updateSleepIfNeededLocked() {
10353 if (mSleeping && !shouldSleepLocked()) {
10355 startTimeTrackingFocusedActivityLocked();
10356 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10357 mStackSupervisor.comeOutOfSleepIfNeededLocked();
10358 updateOomAdjLocked();
10359 } else if (!mSleeping && shouldSleepLocked()) {
10361 if (mCurAppTimeTracker != null) {
10362 mCurAppTimeTracker.stop();
10364 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10365 mStackSupervisor.goingToSleepLocked();
10366 updateOomAdjLocked();
10368 // Initialize the wake times of all processes.
10369 checkExcessivePowerUsageLocked(false);
10370 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10371 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10372 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10376 private boolean shouldSleepLocked() {
10377 // Resume applications while running a voice interactor.
10378 if (mRunningVoice != null) {
10382 // TODO: Transform the lock screen state into a sleep token instead.
10383 switch (mWakefulness) {
10384 case PowerManagerInternal.WAKEFULNESS_AWAKE:
10385 case PowerManagerInternal.WAKEFULNESS_DREAMING:
10386 case PowerManagerInternal.WAKEFULNESS_DOZING:
10387 // Pause applications whenever the lock screen is shown or any sleep
10388 // tokens have been acquired.
10389 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10390 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10392 // If we're asleep then pause applications unconditionally.
10397 /** Pokes the task persister. */
10398 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10399 if (task != null && task.stack != null && task.stack.isHomeStack()) {
10400 // Never persist the home stack.
10403 mTaskPersister.wakeup(task, flush);
10406 /** Notifies all listeners when the task stack has changed. */
10407 void notifyTaskStackChangedLocked() {
10408 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10409 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10410 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10414 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10415 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10419 public boolean shutdown(int timeout) {
10420 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10421 != PackageManager.PERMISSION_GRANTED) {
10422 throw new SecurityException("Requires permission "
10423 + android.Manifest.permission.SHUTDOWN);
10426 boolean timedout = false;
10428 synchronized(this) {
10429 mShuttingDown = true;
10430 updateEventDispatchingLocked();
10431 timedout = mStackSupervisor.shutdownLocked(timeout);
10434 mAppOpsService.shutdown();
10435 if (mUsageStatsService != null) {
10436 mUsageStatsService.prepareShutdown();
10438 mBatteryStatsService.shutdown();
10439 synchronized (this) {
10440 mProcessStats.shutdownLocked();
10441 notifyTaskPersisterLocked(null, true);
10447 public final void activitySlept(IBinder token) {
10448 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10450 final long origId = Binder.clearCallingIdentity();
10452 synchronized (this) {
10453 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10455 mStackSupervisor.activitySleptLocked(r);
10459 Binder.restoreCallingIdentity(origId);
10462 private String lockScreenShownToString() {
10463 switch (mLockScreenShown) {
10464 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10465 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10466 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10467 default: return "Unknown=" + mLockScreenShown;
10471 void logLockScreen(String msg) {
10472 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10473 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10474 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10475 + " mSleeping=" + mSleeping);
10478 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10479 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10480 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10481 boolean wasRunningVoice = mRunningVoice != null;
10482 mRunningVoice = session;
10483 if (!wasRunningVoice) {
10484 mVoiceWakeLock.acquire();
10485 updateSleepIfNeededLocked();
10490 private void updateEventDispatchingLocked() {
10491 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10494 public void setLockScreenShown(boolean shown) {
10495 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10496 != PackageManager.PERMISSION_GRANTED) {
10497 throw new SecurityException("Requires permission "
10498 + android.Manifest.permission.DEVICE_POWER);
10501 synchronized(this) {
10502 long ident = Binder.clearCallingIdentity();
10504 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10505 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10506 updateSleepIfNeededLocked();
10508 Binder.restoreCallingIdentity(ident);
10514 public void stopAppSwitches() {
10515 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10516 != PackageManager.PERMISSION_GRANTED) {
10517 throw new SecurityException("Requires permission "
10518 + android.Manifest.permission.STOP_APP_SWITCHES);
10521 synchronized(this) {
10522 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10523 + APP_SWITCH_DELAY_TIME;
10524 mDidAppSwitch = false;
10525 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10526 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10527 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10531 public void resumeAppSwitches() {
10532 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10533 != PackageManager.PERMISSION_GRANTED) {
10534 throw new SecurityException("Requires permission "
10535 + android.Manifest.permission.STOP_APP_SWITCHES);
10538 synchronized(this) {
10539 // Note that we don't execute any pending app switches... we will
10540 // let those wait until either the timeout, or the next start
10541 // activity request.
10542 mAppSwitchesAllowedTime = 0;
10546 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10547 int callingPid, int callingUid, String name) {
10548 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10552 int perm = checkComponentPermission(
10553 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10554 sourceUid, -1, true);
10555 if (perm == PackageManager.PERMISSION_GRANTED) {
10559 // If the actual IPC caller is different from the logical source, then
10560 // also see if they are allowed to control app switches.
10561 if (callingUid != -1 && callingUid != sourceUid) {
10562 perm = checkComponentPermission(
10563 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10564 callingUid, -1, true);
10565 if (perm == PackageManager.PERMISSION_GRANTED) {
10570 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10574 public void setDebugApp(String packageName, boolean waitForDebugger,
10575 boolean persistent) {
10576 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10579 long ident = Binder.clearCallingIdentity();
10581 // Note that this is not really thread safe if there are multiple
10582 // callers into it at the same time, but that's not a situation we
10585 final ContentResolver resolver = mContext.getContentResolver();
10586 Settings.Global.putString(
10587 resolver, Settings.Global.DEBUG_APP,
10589 Settings.Global.putInt(
10590 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10591 waitForDebugger ? 1 : 0);
10594 synchronized (this) {
10596 mOrigDebugApp = mDebugApp;
10597 mOrigWaitForDebugger = mWaitForDebugger;
10599 mDebugApp = packageName;
10600 mWaitForDebugger = waitForDebugger;
10601 mDebugTransient = !persistent;
10602 if (packageName != null) {
10603 forceStopPackageLocked(packageName, -1, false, false, true, true,
10604 false, UserHandle.USER_ALL, "set debug app");
10608 Binder.restoreCallingIdentity(ident);
10612 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10613 synchronized (this) {
10614 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10615 if (!isDebuggable) {
10616 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10617 throw new SecurityException("Process not debuggable: " + app.packageName);
10621 mOpenGlTraceApp = processName;
10625 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10626 synchronized (this) {
10627 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10628 if (!isDebuggable) {
10629 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10630 throw new SecurityException("Process not debuggable: " + app.packageName);
10633 mProfileApp = processName;
10634 mProfileFile = profilerInfo.profileFile;
10635 if (mProfileFd != null) {
10637 mProfileFd.close();
10638 } catch (IOException e) {
10642 mProfileFd = profilerInfo.profileFd;
10643 mSamplingInterval = profilerInfo.samplingInterval;
10644 mAutoStopProfiler = profilerInfo.autoStopProfiler;
10650 public void setAlwaysFinish(boolean enabled) {
10651 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10652 "setAlwaysFinish()");
10654 Settings.Global.putInt(
10655 mContext.getContentResolver(),
10656 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10658 synchronized (this) {
10659 mAlwaysFinishActivities = enabled;
10664 public void setActivityController(IActivityController controller) {
10665 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10666 "setActivityController()");
10667 synchronized (this) {
10668 mController = controller;
10669 Watchdog.getInstance().setActivityController(controller);
10674 public void setUserIsMonkey(boolean userIsMonkey) {
10675 synchronized (this) {
10676 synchronized (mPidsSelfLocked) {
10677 final int callingPid = Binder.getCallingPid();
10678 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10679 if (precessRecord == null) {
10680 throw new SecurityException("Unknown process: " + callingPid);
10682 if (precessRecord.instrumentationUiAutomationConnection == null) {
10683 throw new SecurityException("Only an instrumentation process "
10684 + "with a UiAutomation can call setUserIsMonkey");
10687 mUserIsMonkey = userIsMonkey;
10692 public boolean isUserAMonkey() {
10693 synchronized (this) {
10694 // If there is a controller also implies the user is a monkey.
10695 return (mUserIsMonkey || mController != null);
10699 public void requestBugReport() {
10700 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10701 SystemProperties.set("ctl.start", "bugreport");
10704 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10705 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10708 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10709 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10710 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10712 return KEY_DISPATCHING_TIMEOUT;
10716 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10717 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10718 != PackageManager.PERMISSION_GRANTED) {
10719 throw new SecurityException("Requires permission "
10720 + android.Manifest.permission.FILTER_EVENTS);
10722 ProcessRecord proc;
10724 synchronized (this) {
10725 synchronized (mPidsSelfLocked) {
10726 proc = mPidsSelfLocked.get(pid);
10728 timeout = getInputDispatchingTimeoutLocked(proc);
10731 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10739 * Handle input dispatching timeouts.
10740 * Returns whether input dispatching should be aborted or not.
10742 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10743 final ActivityRecord activity, final ActivityRecord parent,
10744 final boolean aboveSystem, String reason) {
10745 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10746 != PackageManager.PERMISSION_GRANTED) {
10747 throw new SecurityException("Requires permission "
10748 + android.Manifest.permission.FILTER_EVENTS);
10751 final String annotation;
10752 if (reason == null) {
10753 annotation = "Input dispatching timed out";
10755 annotation = "Input dispatching timed out (" + reason + ")";
10758 if (proc != null) {
10759 synchronized (this) {
10760 if (proc.debugging) {
10765 // Give more time since we were dexopting.
10766 mDidDexOpt = false;
10770 if (proc.instrumentationClass != null) {
10771 Bundle info = new Bundle();
10772 info.putString("shortMsg", "keyDispatchingTimedOut");
10773 info.putString("longMsg", annotation);
10774 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10778 mHandler.post(new Runnable() {
10780 public void run() {
10781 appNotResponding(proc, activity, parent, aboveSystem, annotation);
10790 public Bundle getAssistContextExtras(int requestType) {
10791 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10792 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10796 synchronized (pae) {
10797 while (!pae.haveResult) {
10800 } catch (InterruptedException e) {
10804 synchronized (this) {
10805 buildAssistBundleLocked(pae, pae.result);
10806 mPendingAssistExtras.remove(pae);
10807 mUiHandler.removeCallbacks(pae);
10813 public boolean isAssistDataAllowedOnCurrentActivity() {
10814 int userId = mCurrentUserId;
10815 synchronized (this) {
10816 ActivityRecord activity = getFocusedStack().topActivity();
10817 if (activity == null) {
10820 userId = activity.userId;
10822 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10823 Context.DEVICE_POLICY_SERVICE);
10824 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10828 public boolean showAssistFromActivity(IBinder token, Bundle args) {
10829 long ident = Binder.clearCallingIdentity();
10831 synchronized (this) {
10832 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10833 ActivityRecord top = getFocusedStack().topActivity();
10834 if (top != caller) {
10835 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10836 + " is not current top " + top);
10839 if (!top.nowVisible) {
10840 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10841 + " is not visible");
10845 AssistUtils utils = new AssistUtils(mContext);
10846 return utils.showSessionForActiveService(args,
10847 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10849 Binder.restoreCallingIdentity(ident);
10854 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10855 IBinder activityToken) {
10856 return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10857 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10860 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10861 IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10863 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10864 "enqueueAssistContext()");
10865 synchronized (this) {
10866 ActivityRecord activity = getFocusedStack().topActivity();
10867 if (activity == null) {
10868 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10871 if (activity.app == null || activity.app.thread == null) {
10872 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10875 if (activityToken != null) {
10876 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10877 if (activity != caller) {
10878 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10879 + " is not current top " + activity);
10883 PendingAssistExtras pae;
10884 Bundle extras = new Bundle();
10885 if (args != null) {
10886 extras.putAll(args);
10888 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10889 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10890 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10892 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10894 mPendingAssistExtras.add(pae);
10895 mUiHandler.postDelayed(pae, timeout);
10896 } catch (RemoteException e) {
10897 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10904 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10905 IResultReceiver receiver;
10906 synchronized (this) {
10907 mPendingAssistExtras.remove(pae);
10908 receiver = pae.receiver;
10910 if (receiver != null) {
10911 // Caller wants result sent back to them.
10913 pae.receiver.send(0, null);
10914 } catch (RemoteException e) {
10919 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10920 if (result != null) {
10921 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10923 if (pae.hint != null) {
10924 pae.extras.putBoolean(pae.hint, true);
10928 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10929 AssistContent content, Uri referrer) {
10930 PendingAssistExtras pae = (PendingAssistExtras)token;
10931 synchronized (pae) {
10932 pae.result = extras;
10933 pae.structure = structure;
10934 pae.content = content;
10935 if (referrer != null) {
10936 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10938 pae.haveResult = true;
10940 if (pae.intent == null && pae.receiver == null) {
10941 // Caller is just waiting for the result.
10946 // We are now ready to launch the assist activity.
10947 IResultReceiver sendReceiver = null;
10948 Bundle sendBundle = null;
10949 synchronized (this) {
10950 buildAssistBundleLocked(pae, extras);
10951 boolean exists = mPendingAssistExtras.remove(pae);
10952 mUiHandler.removeCallbacks(pae);
10957 if ((sendReceiver=pae.receiver) != null) {
10958 // Caller wants result sent back to them.
10959 sendBundle = new Bundle();
10960 sendBundle.putBundle("data", pae.extras);
10961 sendBundle.putParcelable("structure", pae.structure);
10962 sendBundle.putParcelable("content", pae.content);
10965 if (sendReceiver != null) {
10967 sendReceiver.send(0, sendBundle);
10968 } catch (RemoteException e) {
10973 long ident = Binder.clearCallingIdentity();
10975 pae.intent.replaceExtras(pae.extras);
10976 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10977 | Intent.FLAG_ACTIVITY_SINGLE_TOP
10978 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10979 closeSystemDialogs("assist");
10981 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10982 } catch (ActivityNotFoundException e) {
10983 Slog.w(TAG, "No activity to handle assist action.", e);
10986 Binder.restoreCallingIdentity(ident);
10990 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10992 return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10993 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10996 public void registerProcessObserver(IProcessObserver observer) {
10997 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10998 "registerProcessObserver()");
10999 synchronized (this) {
11000 mProcessObservers.register(observer);
11005 public void unregisterProcessObserver(IProcessObserver observer) {
11006 synchronized (this) {
11007 mProcessObservers.unregister(observer);
11011 public void registerUidObserver(IUidObserver observer) {
11012 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11013 "registerUidObserver()");
11014 synchronized (this) {
11015 mUidObservers.register(observer);
11020 public void unregisterUidObserver(IUidObserver observer) {
11021 synchronized (this) {
11022 mUidObservers.unregister(observer);
11027 public boolean convertFromTranslucent(IBinder token) {
11028 final long origId = Binder.clearCallingIdentity();
11030 synchronized (this) {
11031 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11035 final boolean translucentChanged = r.changeWindowTranslucency(true);
11036 if (translucentChanged) {
11037 r.task.stack.releaseBackgroundResources(r);
11038 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11040 mWindowManager.setAppFullscreen(token, true);
11041 return translucentChanged;
11044 Binder.restoreCallingIdentity(origId);
11049 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11050 final long origId = Binder.clearCallingIdentity();
11052 synchronized (this) {
11053 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11057 int index = r.task.mActivities.lastIndexOf(r);
11059 ActivityRecord under = r.task.mActivities.get(index - 1);
11060 under.returningOptions = options;
11062 final boolean translucentChanged = r.changeWindowTranslucency(false);
11063 if (translucentChanged) {
11064 r.task.stack.convertActivityToTranslucent(r);
11066 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11067 mWindowManager.setAppFullscreen(token, false);
11068 return translucentChanged;
11071 Binder.restoreCallingIdentity(origId);
11076 public boolean requestVisibleBehind(IBinder token, boolean visible) {
11077 final long origId = Binder.clearCallingIdentity();
11079 synchronized (this) {
11080 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11082 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11087 Binder.restoreCallingIdentity(origId);
11092 public boolean isBackgroundVisibleBehind(IBinder token) {
11093 final long origId = Binder.clearCallingIdentity();
11095 synchronized (this) {
11096 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11097 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11098 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11099 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11103 Binder.restoreCallingIdentity(origId);
11108 public ActivityOptions getActivityOptions(IBinder token) {
11109 final long origId = Binder.clearCallingIdentity();
11111 synchronized (this) {
11112 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11114 final ActivityOptions activityOptions = r.pendingOptions;
11115 r.pendingOptions = null;
11116 return activityOptions;
11121 Binder.restoreCallingIdentity(origId);
11126 public void setImmersive(IBinder token, boolean immersive) {
11127 synchronized(this) {
11128 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11130 throw new IllegalArgumentException();
11132 r.immersive = immersive;
11134 // update associated state if we're frontmost
11135 if (r == mFocusedActivity) {
11136 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11137 applyUpdateLockStateLocked(r);
11143 public boolean isImmersive(IBinder token) {
11144 synchronized (this) {
11145 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11147 throw new IllegalArgumentException();
11149 return r.immersive;
11153 public boolean isTopActivityImmersive() {
11154 enforceNotIsolatedCaller("startActivity");
11155 synchronized (this) {
11156 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11157 return (r != null) ? r.immersive : false;
11162 public boolean isTopOfTask(IBinder token) {
11163 synchronized (this) {
11164 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11166 throw new IllegalArgumentException();
11168 return r.task.getTopActivity() == r;
11172 public final void enterSafeMode() {
11173 synchronized(this) {
11174 // It only makes sense to do this before the system is ready
11175 // and started launching other packages.
11176 if (!mSystemReady) {
11178 AppGlobals.getPackageManager().enterSafeMode();
11179 } catch (RemoteException e) {
11187 public final void showSafeModeOverlay() {
11188 View v = LayoutInflater.from(mContext).inflate(
11189 com.android.internal.R.layout.safe_mode, null);
11190 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11191 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11192 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11193 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11194 lp.gravity = Gravity.BOTTOM | Gravity.START;
11195 lp.format = v.getBackground().getOpacity();
11196 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11197 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11198 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11199 ((WindowManager)mContext.getSystemService(
11200 Context.WINDOW_SERVICE)).addView(v, lp);
11203 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11204 if (!(sender instanceof PendingIntentRecord)) {
11207 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11208 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11209 synchronized (stats) {
11210 if (mBatteryStatsService.isOnBattery()) {
11211 mBatteryStatsService.enforceCallingPermission();
11212 int MY_UID = Binder.getCallingUid();
11213 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11214 BatteryStatsImpl.Uid.Pkg pkg =
11215 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11216 sourcePkg != null ? sourcePkg : rec.key.packageName);
11217 pkg.noteWakeupAlarmLocked(tag);
11222 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11223 if (!(sender instanceof PendingIntentRecord)) {
11226 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11227 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11228 synchronized (stats) {
11229 mBatteryStatsService.enforceCallingPermission();
11230 int MY_UID = Binder.getCallingUid();
11231 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11232 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11236 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11237 if (!(sender instanceof PendingIntentRecord)) {
11240 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11241 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11242 synchronized (stats) {
11243 mBatteryStatsService.enforceCallingPermission();
11244 int MY_UID = Binder.getCallingUid();
11245 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11246 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11250 public boolean killPids(int[] pids, String pReason, boolean secure) {
11251 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11252 throw new SecurityException("killPids only available to the system");
11254 String reason = (pReason == null) ? "Unknown" : pReason;
11255 // XXX Note: don't acquire main activity lock here, because the window
11256 // manager calls in with its locks held.
11258 boolean killed = false;
11259 synchronized (mPidsSelfLocked) {
11260 int[] types = new int[pids.length];
11262 for (int i=0; i<pids.length; i++) {
11263 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11264 if (proc != null) {
11265 int type = proc.setAdj;
11267 if (type > worstType) {
11273 // If the worst oom_adj is somewhere in the cached proc LRU range,
11274 // then constrain it so we will kill all cached procs.
11275 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11276 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11277 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11280 // If this is not a secure call, don't let it kill processes that
11282 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11283 worstType = ProcessList.SERVICE_ADJ;
11286 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11287 for (int i=0; i<pids.length; i++) {
11288 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11289 if (proc == null) {
11292 int adj = proc.setAdj;
11293 if (adj >= worstType && !proc.killedByAm) {
11294 proc.kill(reason, true);
11303 public void killUid(int appId, int userId, String reason) {
11304 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11305 synchronized (this) {
11306 final long identity = Binder.clearCallingIdentity();
11308 killPackageProcessesLocked(null, appId, userId,
11309 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11310 reason != null ? reason : "kill uid");
11312 Binder.restoreCallingIdentity(identity);
11318 public boolean killProcessesBelowForeground(String reason) {
11319 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11320 throw new SecurityException("killProcessesBelowForeground() only available to system");
11323 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11326 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11327 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11328 throw new SecurityException("killProcessesBelowAdj() only available to system");
11331 boolean killed = false;
11332 synchronized (mPidsSelfLocked) {
11333 final int size = mPidsSelfLocked.size();
11334 for (int i = 0; i < size; i++) {
11335 final int pid = mPidsSelfLocked.keyAt(i);
11336 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11337 if (proc == null) continue;
11339 final int adj = proc.setAdj;
11340 if (adj > belowAdj && !proc.killedByAm) {
11341 proc.kill(reason, true);
11350 public void hang(final IBinder who, boolean allowRestart) {
11351 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11352 != PackageManager.PERMISSION_GRANTED) {
11353 throw new SecurityException("Requires permission "
11354 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11357 final IBinder.DeathRecipient death = new DeathRecipient() {
11359 public void binderDied() {
11360 synchronized (this) {
11367 who.linkToDeath(death, 0);
11368 } catch (RemoteException e) {
11369 Slog.w(TAG, "hang: given caller IBinder is already dead.");
11373 synchronized (this) {
11374 Watchdog.getInstance().setAllowRestart(allowRestart);
11375 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11376 synchronized (death) {
11377 while (who.isBinderAlive()) {
11380 } catch (InterruptedException e) {
11384 Watchdog.getInstance().setAllowRestart(true);
11389 public void restart() {
11390 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11391 != PackageManager.PERMISSION_GRANTED) {
11392 throw new SecurityException("Requires permission "
11393 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11396 Log.i(TAG, "Sending shutdown broadcast...");
11398 BroadcastReceiver br = new BroadcastReceiver() {
11399 @Override public void onReceive(Context context, Intent intent) {
11400 // Now the broadcast is done, finish up the low-level shutdown.
11401 Log.i(TAG, "Shutting down activity manager...");
11403 Log.i(TAG, "Shutdown complete, restarting!");
11404 Process.killProcess(Process.myPid());
11409 // First send the high-level shut down broadcast.
11410 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11411 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11412 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11413 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11414 mContext.sendOrderedBroadcastAsUser(intent,
11415 UserHandle.ALL, null, br, mHandler, 0, null, null);
11417 br.onReceive(mContext, intent);
11420 private long getLowRamTimeSinceIdle(long now) {
11421 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11425 public void performIdleMaintenance() {
11426 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11427 != PackageManager.PERMISSION_GRANTED) {
11428 throw new SecurityException("Requires permission "
11429 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11432 synchronized (this) {
11433 final long now = SystemClock.uptimeMillis();
11434 final long timeSinceLastIdle = now - mLastIdleTime;
11435 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11436 mLastIdleTime = now;
11437 mLowRamTimeSinceLastIdle = 0;
11438 if (mLowRamStartTime != 0) {
11439 mLowRamStartTime = now;
11442 StringBuilder sb = new StringBuilder(128);
11443 sb.append("Idle maintenance over ");
11444 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11445 sb.append(" low RAM for ");
11446 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11447 Slog.i(TAG, sb.toString());
11449 // If at least 1/3 of our time since the last idle period has been spent
11450 // with RAM low, then we want to kill processes.
11451 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11453 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11454 ProcessRecord proc = mLruProcesses.get(i);
11455 if (proc.notCachedSinceIdle) {
11456 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11457 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11458 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11459 if (doKilling && proc.initialIdlePss != 0
11460 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11461 sb = new StringBuilder(128);
11463 sb.append(proc.processName);
11464 sb.append(" in idle maint: pss=");
11465 sb.append(proc.lastPss);
11466 sb.append(", initialPss=");
11467 sb.append(proc.initialIdlePss);
11468 sb.append(", period=");
11469 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11470 sb.append(", lowRamPeriod=");
11471 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11472 Slog.wtfQuiet(TAG, sb.toString());
11473 proc.kill("idle maint (pss " + proc.lastPss
11474 + " from " + proc.initialIdlePss + ")", true);
11477 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11478 proc.notCachedSinceIdle = true;
11479 proc.initialIdlePss = 0;
11480 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11481 mTestPssMode, isSleeping(), now);
11485 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11486 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11490 private void retrieveSettings() {
11491 final ContentResolver resolver = mContext.getContentResolver();
11492 String debugApp = Settings.Global.getString(
11493 resolver, Settings.Global.DEBUG_APP);
11494 boolean waitForDebugger = Settings.Global.getInt(
11495 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11496 boolean alwaysFinishActivities = Settings.Global.getInt(
11497 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11498 boolean forceRtl = Settings.Global.getInt(
11499 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11500 // Transfer any global setting for forcing RTL layout, into a System Property
11501 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11503 Configuration configuration = new Configuration();
11504 Settings.System.getConfiguration(resolver, configuration);
11506 // This will take care of setting the correct layout direction flags
11507 configuration.setLayoutDirection(configuration.locale);
11510 synchronized (this) {
11511 mDebugApp = mOrigDebugApp = debugApp;
11512 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11513 mAlwaysFinishActivities = alwaysFinishActivities;
11514 // This happens before any activities are started, so we can
11515 // change mConfiguration in-place.
11516 updateConfigurationLocked(configuration, null, false, true);
11517 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11518 "Initial config: " + mConfiguration);
11522 /** Loads resources after the current configuration has been set. */
11523 private void loadResourcesOnSystemReady() {
11524 final Resources res = mContext.getResources();
11525 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11526 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11527 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11530 public boolean testIsSystemReady() {
11531 // no need to synchronize(this) just to read & return the value
11532 return mSystemReady;
11535 private static File getCalledPreBootReceiversFile() {
11536 File dataDir = Environment.getDataDirectory();
11537 File systemDir = new File(dataDir, "system");
11538 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11542 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11543 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11544 File file = getCalledPreBootReceiversFile();
11545 FileInputStream fis = null;
11547 fis = new FileInputStream(file);
11548 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11549 int fvers = dis.readInt();
11550 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11551 String vers = dis.readUTF();
11552 String codename = dis.readUTF();
11553 String build = dis.readUTF();
11554 if (android.os.Build.VERSION.RELEASE.equals(vers)
11555 && android.os.Build.VERSION.CODENAME.equals(codename)
11556 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11557 int num = dis.readInt();
11560 String pkg = dis.readUTF();
11561 String cls = dis.readUTF();
11562 lastDoneReceivers.add(new ComponentName(pkg, cls));
11566 } catch (FileNotFoundException e) {
11567 } catch (IOException e) {
11568 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11573 } catch (IOException e) {
11577 return lastDoneReceivers;
11580 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11581 File file = getCalledPreBootReceiversFile();
11582 FileOutputStream fos = null;
11583 DataOutputStream dos = null;
11585 fos = new FileOutputStream(file);
11586 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11587 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11588 dos.writeUTF(android.os.Build.VERSION.RELEASE);
11589 dos.writeUTF(android.os.Build.VERSION.CODENAME);
11590 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11591 dos.writeInt(list.size());
11592 for (int i=0; i<list.size(); i++) {
11593 dos.writeUTF(list.get(i).getPackageName());
11594 dos.writeUTF(list.get(i).getClassName());
11596 } catch (IOException e) {
11597 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11600 FileUtils.sync(fos);
11604 } catch (IOException e) {
11605 // TODO Auto-generated catch block
11606 e.printStackTrace();
11612 final class PreBootContinuation extends IIntentReceiver.Stub {
11613 final Intent intent;
11614 final Runnable onFinishCallback;
11615 final ArrayList<ComponentName> doneReceivers;
11616 final List<ResolveInfo> ris;
11622 PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11623 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11625 onFinishCallback = _onFinishCallback;
11626 doneReceivers = _doneReceivers;
11632 if (lastRi != curRi) {
11633 ActivityInfo ai = ris.get(curRi).activityInfo;
11634 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11635 intent.setComponent(comp);
11636 doneReceivers.add(comp);
11638 CharSequence label = ai.loadLabel(mContext.getPackageManager());
11639 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11641 Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11642 + " for user " + users[curUser]);
11643 EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11644 broadcastIntentLocked(null, null, intent, null, this,
11645 0, null, null, null, AppOpsManager.OP_NONE,
11646 null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11649 public void performReceive(Intent intent, int resultCode,
11650 String data, Bundle extras, boolean ordered,
11651 boolean sticky, int sendingUser) {
11653 if (curUser >= users.length) {
11656 if (curRi >= ris.size()) {
11657 // All done sending broadcasts!
11658 if (onFinishCallback != null) {
11659 // The raw IIntentReceiver interface is called
11660 // with the AM lock held, so redispatch to
11661 // execute our code without the lock.
11662 mHandler.post(onFinishCallback);
11671 private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11672 ArrayList<ComponentName> doneReceivers, int userId) {
11673 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11674 List<ResolveInfo> ris = null;
11676 ris = AppGlobals.getPackageManager().queryIntentReceivers(
11677 intent, null, 0, userId);
11678 } catch (RemoteException e) {
11683 for (int i=ris.size()-1; i>=0; i--) {
11684 if ((ris.get(i).activityInfo.applicationInfo.flags
11685 &ApplicationInfo.FLAG_SYSTEM) == 0) {
11689 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11691 // For User 0, load the version number. When delivering to a new user, deliver
11692 // to all receivers.
11693 if (userId == UserHandle.USER_OWNER) {
11694 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11695 for (int i=0; i<ris.size(); i++) {
11696 ActivityInfo ai = ris.get(i).activityInfo;
11697 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11698 if (lastDoneReceivers.contains(comp)) {
11699 // We already did the pre boot receiver for this app with the current
11700 // platform version, so don't do it again...
11703 // ...however, do keep it as one that has been done, so we don't
11704 // forget about it when rewriting the file of last done receivers.
11705 doneReceivers.add(comp);
11710 if (ris.size() <= 0) {
11714 // If primary user, send broadcast to all available users, else just to userId
11715 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11716 : new int[] { userId };
11717 if (users.length <= 0) {
11721 PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11727 public void systemReady(final Runnable goingCallback) {
11728 synchronized(this) {
11729 if (mSystemReady) {
11730 // If we're done calling all the receivers, run the next "boot phase" passed in
11731 // by the SystemServer
11732 if (goingCallback != null) {
11733 goingCallback.run();
11738 mLocalDeviceIdleController
11739 = LocalServices.getService(DeviceIdleController.LocalService.class);
11741 // Make sure we have the current profile info, since it is needed for
11742 // security checks.
11743 updateCurrentProfileIdsLocked();
11745 mRecentTasks.clear();
11746 mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11747 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11748 mTaskPersister.startPersisting();
11750 // Check to see if there are any update receivers to run.
11752 if (mWaitingUpdate) {
11755 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11756 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11757 public void run() {
11758 synchronized (ActivityManagerService.this) {
11761 showBootMessage(mContext.getText(
11762 R.string.android_upgrading_complete),
11764 writeLastDonePreBootReceivers(doneReceivers);
11765 systemReady(goingCallback);
11767 }, doneReceivers, UserHandle.USER_OWNER);
11769 if (mWaitingUpdate) {
11775 mAppOpsService.systemReady();
11776 mSystemReady = true;
11779 ArrayList<ProcessRecord> procsToKill = null;
11780 synchronized(mPidsSelfLocked) {
11781 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11782 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11783 if (!isAllowedWhileBooting(proc.info)){
11784 if (procsToKill == null) {
11785 procsToKill = new ArrayList<ProcessRecord>();
11787 procsToKill.add(proc);
11792 synchronized(this) {
11793 if (procsToKill != null) {
11794 for (int i=procsToKill.size()-1; i>=0; i--) {
11795 ProcessRecord proc = procsToKill.get(i);
11796 Slog.i(TAG, "Removing system update proc: " + proc);
11797 removeProcessLocked(proc, true, false, "system update done");
11801 // Now that we have cleaned up any update processes, we
11802 // are ready to start launching real processes and know that
11803 // we won't trample on them any more.
11804 mProcessesReady = true;
11807 Slog.i(TAG, "System now ready");
11808 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11809 SystemClock.uptimeMillis());
11811 synchronized(this) {
11812 // Make sure we have no pre-ready processes sitting around.
11814 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11815 ResolveInfo ri = mContext.getPackageManager()
11816 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11818 CharSequence errorMsg = null;
11820 ActivityInfo ai = ri.activityInfo;
11821 ApplicationInfo app = ai.applicationInfo;
11822 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11823 mTopAction = Intent.ACTION_FACTORY_TEST;
11825 mTopComponent = new ComponentName(app.packageName,
11828 errorMsg = mContext.getResources().getText(
11829 com.android.internal.R.string.factorytest_not_system);
11832 errorMsg = mContext.getResources().getText(
11833 com.android.internal.R.string.factorytest_no_action);
11835 if (errorMsg != null) {
11838 mTopComponent = null;
11839 Message msg = Message.obtain();
11840 msg.what = SHOW_FACTORY_ERROR_MSG;
11841 msg.getData().putCharSequence("msg", errorMsg);
11842 mUiHandler.sendMessage(msg);
11847 retrieveSettings();
11848 loadResourcesOnSystemReady();
11850 synchronized (this) {
11851 readGrantedUriPermissionsLocked();
11854 if (goingCallback != null) goingCallback.run();
11856 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11857 Integer.toString(mCurrentUserId), mCurrentUserId);
11858 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11859 Integer.toString(mCurrentUserId), mCurrentUserId);
11860 mSystemServiceManager.startUser(mCurrentUserId);
11862 synchronized (this) {
11863 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11865 List apps = AppGlobals.getPackageManager().
11866 getPersistentApplications(STOCK_PM_FLAGS);
11867 if (apps != null) {
11868 int N = apps.size();
11870 for (i=0; i<N; i++) {
11871 ApplicationInfo info
11872 = (ApplicationInfo)apps.get(i);
11873 if (info != null &&
11874 !info.packageName.equals("android")) {
11875 addAppLocked(info, false, null /* ABI override */);
11879 } catch (RemoteException ex) {
11880 // pm is in same process, this will never happen.
11884 // Start up initial activity.
11886 startHomeActivityLocked(mCurrentUserId, "systemReady");
11889 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11890 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11891 + " data partition or your device will be unstable.");
11892 mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11894 } catch (RemoteException e) {
11897 if (!Build.isBuildConsistent()) {
11898 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11899 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11902 long ident = Binder.clearCallingIdentity();
11904 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11905 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11906 | Intent.FLAG_RECEIVER_FOREGROUND);
11907 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11908 broadcastIntentLocked(null, null, intent,
11909 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11910 null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11911 intent = new Intent(Intent.ACTION_USER_STARTING);
11912 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11913 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11914 broadcastIntentLocked(null, null, intent,
11915 null, new IIntentReceiver.Stub() {
11917 public void performReceive(Intent intent, int resultCode, String data,
11918 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11919 throws RemoteException {
11922 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11923 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11924 } catch (Throwable t) {
11925 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11927 Binder.restoreCallingIdentity(ident);
11929 mStackSupervisor.resumeTopActivitiesLocked();
11930 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11934 private boolean makeAppCrashingLocked(ProcessRecord app,
11935 String shortMsg, String longMsg, String stackTrace) {
11936 app.crashing = true;
11937 app.crashingReport = generateProcessError(app,
11938 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11939 startAppProblemLocked(app);
11940 app.stopFreezingAllLocked();
11941 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11944 private void makeAppNotRespondingLocked(ProcessRecord app,
11945 String activity, String shortMsg, String longMsg) {
11946 app.notResponding = true;
11947 app.notRespondingReport = generateProcessError(app,
11948 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11949 activity, shortMsg, longMsg, null);
11950 startAppProblemLocked(app);
11951 app.stopFreezingAllLocked();
11955 * Generate a process error record, suitable for attachment to a ProcessRecord.
11957 * @param app The ProcessRecord in which the error occurred.
11958 * @param condition Crashing, Application Not Responding, etc. Values are defined in
11959 * ActivityManager.AppErrorStateInfo
11960 * @param activity The activity associated with the crash, if known.
11961 * @param shortMsg Short message describing the crash.
11962 * @param longMsg Long message describing the crash.
11963 * @param stackTrace Full crash stack trace, may be null.
11965 * @return Returns a fully-formed AppErrorStateInfo record.
11967 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11968 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11969 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11971 report.condition = condition;
11972 report.processName = app.processName;
11973 report.pid = app.pid;
11974 report.uid = app.info.uid;
11975 report.tag = activity;
11976 report.shortMsg = shortMsg;
11977 report.longMsg = longMsg;
11978 report.stackTrace = stackTrace;
11983 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11984 synchronized (this) {
11985 app.crashing = false;
11986 app.crashingReport = null;
11987 app.notResponding = false;
11988 app.notRespondingReport = null;
11989 if (app.anrDialog == fromDialog) {
11990 app.anrDialog = null;
11992 if (app.waitDialog == fromDialog) {
11993 app.waitDialog = null;
11995 if (app.pid > 0 && app.pid != MY_PID) {
11996 handleAppCrashLocked(app, "user-terminated" /*reason*/,
11997 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11998 app.kill("user request after error", true);
12003 private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12004 String shortMsg, String longMsg, String stackTrace) {
12005 long now = SystemClock.uptimeMillis();
12008 if (!app.isolated) {
12009 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12013 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12014 // This process loses!
12015 Slog.w(TAG, "Process " + app.info.processName
12016 + " has crashed too many times: killing!");
12017 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12018 app.userId, app.info.processName, app.uid);
12019 mStackSupervisor.handleAppCrashLocked(app);
12020 if (!app.persistent) {
12021 // We don't want to start this process again until the user
12022 // explicitly does so... but for persistent process, we really
12023 // need to keep it running. If a persistent process is actually
12024 // repeatedly crashing, then badness for everyone.
12025 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12026 app.info.processName);
12027 if (!app.isolated) {
12028 // XXX We don't have a way to mark isolated processes
12029 // as bad, since they don't have a peristent identity.
12030 mBadProcesses.put(app.info.processName, app.uid,
12031 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12032 mProcessCrashTimes.remove(app.info.processName, app.uid);
12035 app.removed = true;
12036 // Don't let services in this process be restarted and potentially
12037 // annoy the user repeatedly. Unless it is persistent, since those
12038 // processes run critical code.
12039 removeProcessLocked(app, false, false, "crash");
12040 mStackSupervisor.resumeTopActivitiesLocked();
12043 mStackSupervisor.resumeTopActivitiesLocked();
12045 mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12048 // Bump up the crash count of any services currently running in the proc.
12049 for (int i=app.services.size()-1; i>=0; i--) {
12050 // Any services running in the application need to be placed
12051 // back in the pending list.
12052 ServiceRecord sr = app.services.valueAt(i);
12056 // If the crashing process is what we consider to be the "home process" and it has been
12057 // replaced by a third-party app, clear the package preferred activities from packages
12058 // with a home activity running in the process to prevent a repeatedly crashing app
12059 // from blocking the user to manually clear the list.
12060 final ArrayList<ActivityRecord> activities = app.activities;
12061 if (app == mHomeProcess && activities.size() > 0
12062 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12063 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12064 final ActivityRecord r = activities.get(activityNdx);
12065 if (r.isHomeActivity()) {
12066 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12068 ActivityThread.getPackageManager()
12069 .clearPackagePreferredActivities(r.packageName);
12070 } catch (RemoteException c) {
12071 // pm is in same process, this will never happen.
12077 if (!app.isolated) {
12078 // XXX Can't keep track of crash times for isolated processes,
12079 // because they don't have a perisistent identity.
12080 mProcessCrashTimes.put(app.info.processName, app.uid, now);
12083 if (app.crashHandler != null) mHandler.post(app.crashHandler);
12087 void startAppProblemLocked(ProcessRecord app) {
12088 // If this app is not running under the current user, then we
12089 // can't give it a report button because that would require
12090 // launching the report UI under a different user.
12091 app.errorReportReceiver = null;
12093 for (int userId : mCurrentProfileIds) {
12094 if (app.userId == userId) {
12095 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12096 mContext, app.info.packageName, app.info.flags);
12099 skipCurrentReceiverLocked(app);
12102 void skipCurrentReceiverLocked(ProcessRecord app) {
12103 for (BroadcastQueue queue : mBroadcastQueues) {
12104 queue.skipCurrentReceiverLocked(app);
12109 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12110 * The application process will exit immediately after this call returns.
12111 * @param app object of the crashing app, null for the system server
12112 * @param crashInfo describing the exception
12114 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12115 ProcessRecord r = findAppProcess(app, "Crash");
12116 final String processName = app == null ? "system_server"
12117 : (r == null ? "unknown" : r.processName);
12119 handleApplicationCrashInner("crash", r, processName, crashInfo);
12122 /* Native crash reporting uses this inner version because it needs to be somewhat
12123 * decoupled from the AM-managed cleanup lifecycle
12125 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12126 ApplicationErrorReport.CrashInfo crashInfo) {
12127 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12128 UserHandle.getUserId(Binder.getCallingUid()), processName,
12129 r == null ? -1 : r.info.flags,
12130 crashInfo.exceptionClassName,
12131 crashInfo.exceptionMessage,
12132 crashInfo.throwFileName,
12133 crashInfo.throwLineNumber);
12135 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12137 crashApplication(r, crashInfo);
12140 public void handleApplicationStrictModeViolation(
12143 StrictMode.ViolationInfo info) {
12144 ProcessRecord r = findAppProcess(app, "StrictMode");
12149 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12150 Integer stackFingerprint = info.hashCode();
12151 boolean logIt = true;
12152 synchronized (mAlreadyLoggedViolatedStacks) {
12153 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12155 // TODO: sub-sample into EventLog for these, with
12156 // the info.durationMillis? Then we'd get
12157 // the relative pain numbers, without logging all
12158 // the stack traces repeatedly. We'd want to do
12159 // likewise in the client code, which also does
12160 // dup suppression, before the Binder call.
12162 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12163 mAlreadyLoggedViolatedStacks.clear();
12165 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12169 logStrictModeViolationToDropBox(r, info);
12173 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12174 AppErrorResult result = new AppErrorResult();
12175 synchronized (this) {
12176 final long origId = Binder.clearCallingIdentity();
12178 Message msg = Message.obtain();
12179 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12180 HashMap<String, Object> data = new HashMap<String, Object>();
12181 data.put("result", result);
12182 data.put("app", r);
12183 data.put("violationMask", violationMask);
12184 data.put("info", info);
12186 mUiHandler.sendMessage(msg);
12188 Binder.restoreCallingIdentity(origId);
12190 int res = result.get();
12191 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12195 // Depending on the policy in effect, there could be a bunch of
12196 // these in quick succession so we try to batch these together to
12197 // minimize disk writes, number of dropbox entries, and maximize
12198 // compression, by having more fewer, larger records.
12199 private void logStrictModeViolationToDropBox(
12200 ProcessRecord process,
12201 StrictMode.ViolationInfo info) {
12202 if (info == null) {
12205 final boolean isSystemApp = process == null ||
12206 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12207 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12208 final String processName = process == null ? "unknown" : process.processName;
12209 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12210 final DropBoxManager dbox = (DropBoxManager)
12211 mContext.getSystemService(Context.DROPBOX_SERVICE);
12213 // Exit early if the dropbox isn't configured to accept this report type.
12214 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12216 boolean bufferWasEmpty;
12217 boolean needsFlush;
12218 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12219 synchronized (sb) {
12220 bufferWasEmpty = sb.length() == 0;
12221 appendDropBoxProcessHeaders(process, processName, sb);
12222 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12223 sb.append("System-App: ").append(isSystemApp).append("\n");
12224 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12225 if (info.violationNumThisLoop != 0) {
12226 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12228 if (info.numAnimationsRunning != 0) {
12229 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12231 if (info.broadcastIntentAction != null) {
12232 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12234 if (info.durationMillis != -1) {
12235 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12237 if (info.numInstances != -1) {
12238 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12240 if (info.tags != null) {
12241 for (String tag : info.tags) {
12242 sb.append("Span-Tag: ").append(tag).append("\n");
12246 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12247 sb.append(info.crashInfo.stackTrace);
12250 if (info.message != null) {
12251 sb.append(info.message);
12255 // Only buffer up to ~64k. Various logging bits truncate
12257 needsFlush = (sb.length() > 64 * 1024);
12260 // Flush immediately if the buffer's grown too large, or this
12261 // is a non-system app. Non-system apps are isolated with a
12262 // different tag & policy and not batched.
12264 // Batching is useful during internal testing with
12265 // StrictMode settings turned up high. Without batching,
12266 // thousands of separate files could be created on boot.
12267 if (!isSystemApp || needsFlush) {
12268 new Thread("Error dump: " + dropboxTag) {
12270 public void run() {
12272 synchronized (sb) {
12273 report = sb.toString();
12274 sb.delete(0, sb.length());
12277 if (report.length() != 0) {
12278 dbox.addText(dropboxTag, report);
12285 // System app batching:
12286 if (!bufferWasEmpty) {
12287 // An existing dropbox-writing thread is outstanding, so
12288 // we don't need to start it up. The existing thread will
12289 // catch the buffer appends we just did.
12293 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12294 // (After this point, we shouldn't access AMS internal data structures.)
12295 new Thread("Error dump: " + dropboxTag) {
12297 public void run() {
12298 // 5 second sleep to let stacks arrive and be batched together
12300 Thread.sleep(5000); // 5 seconds
12301 } catch (InterruptedException e) {}
12303 String errorReport;
12304 synchronized (mStrictModeBuffer) {
12305 errorReport = mStrictModeBuffer.toString();
12306 if (errorReport.length() == 0) {
12309 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12310 mStrictModeBuffer.trimToSize();
12312 dbox.addText(dropboxTag, errorReport);
12318 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12319 * @param app object of the crashing app, null for the system server
12320 * @param tag reported by the caller
12321 * @param system whether this wtf is coming from the system
12322 * @param crashInfo describing the context of the error
12323 * @return true if the process should exit immediately (WTF is fatal)
12325 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12326 final ApplicationErrorReport.CrashInfo crashInfo) {
12327 final int callingUid = Binder.getCallingUid();
12328 final int callingPid = Binder.getCallingPid();
12331 // If this is coming from the system, we could very well have low-level
12332 // system locks held, so we want to do this all asynchronously. And we
12333 // never want this to become fatal, so there is that too.
12334 mHandler.post(new Runnable() {
12335 @Override public void run() {
12336 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12342 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12345 if (r != null && r.pid != Process.myPid() &&
12346 Settings.Global.getInt(mContext.getContentResolver(),
12347 Settings.Global.WTF_IS_FATAL, 0) != 0) {
12348 crashApplication(r, crashInfo);
12355 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12356 final ApplicationErrorReport.CrashInfo crashInfo) {
12357 final ProcessRecord r = findAppProcess(app, "WTF");
12358 final String processName = app == null ? "system_server"
12359 : (r == null ? "unknown" : r.processName);
12361 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12362 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12364 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12370 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12371 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12373 private ProcessRecord findAppProcess(IBinder app, String reason) {
12378 synchronized (this) {
12379 final int NP = mProcessNames.getMap().size();
12380 for (int ip=0; ip<NP; ip++) {
12381 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12382 final int NA = apps.size();
12383 for (int ia=0; ia<NA; ia++) {
12384 ProcessRecord p = apps.valueAt(ia);
12385 if (p.thread != null && p.thread.asBinder() == app) {
12391 Slog.w(TAG, "Can't find mystery application for " + reason
12392 + " from pid=" + Binder.getCallingPid()
12393 + " uid=" + Binder.getCallingUid() + ": " + app);
12399 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12400 * to append various headers to the dropbox log text.
12402 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12403 StringBuilder sb) {
12404 // Watchdog thread ends up invoking this function (with
12405 // a null ProcessRecord) to add the stack file to dropbox.
12406 // Do not acquire a lock on this (am) in such cases, as it
12407 // could cause a potential deadlock, if and when watchdog
12408 // is invoked due to unavailability of lock on am and it
12409 // would prevent watchdog from killing system_server.
12410 if (process == null) {
12411 sb.append("Process: ").append(processName).append("\n");
12414 // Note: ProcessRecord 'process' is guarded by the service
12415 // instance. (notably process.pkgList, which could otherwise change
12416 // concurrently during execution of this method)
12417 synchronized (this) {
12418 sb.append("Process: ").append(processName).append("\n");
12419 int flags = process.info.flags;
12420 IPackageManager pm = AppGlobals.getPackageManager();
12421 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12422 for (int ip=0; ip<process.pkgList.size(); ip++) {
12423 String pkg = process.pkgList.keyAt(ip);
12424 sb.append("Package: ").append(pkg);
12426 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12428 sb.append(" v").append(pi.versionCode);
12429 if (pi.versionName != null) {
12430 sb.append(" (").append(pi.versionName).append(")");
12433 } catch (RemoteException e) {
12434 Slog.e(TAG, "Error getting package info: " + pkg, e);
12441 private static String processClass(ProcessRecord process) {
12442 if (process == null || process.pid == MY_PID) {
12443 return "system_server";
12444 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12445 return "system_app";
12452 * Write a description of an error (crash, WTF, ANR) to the drop box.
12453 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12454 * @param process which caused the error, null means the system server
12455 * @param activity which triggered the error, null if unknown
12456 * @param parent activity related to the error, null if unknown
12457 * @param subject line related to the error, null if absent
12458 * @param report in long form describing the error, null if absent
12459 * @param logFile to include in the report, null if none
12460 * @param crashInfo giving an application stack trace, null if absent
12462 public void addErrorToDropBox(String eventType,
12463 ProcessRecord process, String processName, ActivityRecord activity,
12464 ActivityRecord parent, String subject,
12465 final String report, final File logFile,
12466 final ApplicationErrorReport.CrashInfo crashInfo) {
12467 // NOTE -- this must never acquire the ActivityManagerService lock,
12468 // otherwise the watchdog may be prevented from resetting the system.
12470 final String dropboxTag = processClass(process) + "_" + eventType;
12471 final DropBoxManager dbox = (DropBoxManager)
12472 mContext.getSystemService(Context.DROPBOX_SERVICE);
12474 // Exit early if the dropbox isn't configured to accept this report type.
12475 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12477 final StringBuilder sb = new StringBuilder(1024);
12478 appendDropBoxProcessHeaders(process, processName, sb);
12479 if (activity != null) {
12480 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12482 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12483 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12485 if (parent != null && parent != activity) {
12486 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12488 if (subject != null) {
12489 sb.append("Subject: ").append(subject).append("\n");
12491 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12492 if (Debug.isDebuggerConnected()) {
12493 sb.append("Debugger: Connected\n");
12497 // Do the rest in a worker thread to avoid blocking the caller on I/O
12498 // (After this point, we shouldn't access AMS internal data structures.)
12499 Thread worker = new Thread("Error dump: " + dropboxTag) {
12501 public void run() {
12502 if (report != null) {
12505 if (logFile != null) {
12507 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12508 "\n\n[[TRUNCATED]]"));
12509 } catch (IOException e) {
12510 Slog.e(TAG, "Error reading " + logFile, e);
12513 if (crashInfo != null && crashInfo.stackTrace != null) {
12514 sb.append(crashInfo.stackTrace);
12517 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12518 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12522 // Merge several logcat streams, and take the last N lines
12523 InputStreamReader input = null;
12525 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12526 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12528 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12530 try { logcat.getOutputStream().close(); } catch (IOException e) {}
12531 try { logcat.getErrorStream().close(); } catch (IOException e) {}
12532 input = new InputStreamReader(logcat.getInputStream());
12535 char[] buf = new char[8192];
12536 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12537 } catch (IOException e) {
12538 Slog.e(TAG, "Error running logcat", e);
12540 if (input != null) try { input.close(); } catch (IOException e) {}
12544 dbox.addText(dropboxTag, sb.toString());
12548 if (process == null) {
12549 // If process is null, we are being called from some internal code
12550 // and may be about to die -- run this synchronously.
12558 * Bring up the "unexpected error" dialog box for a crashing app.
12559 * Deal with edge cases (intercepts from instrumented applications,
12560 * ActivityController, error intent receivers, that sort of thing).
12561 * @param r the application crashing
12562 * @param crashInfo describing the failure
12564 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12565 long timeMillis = System.currentTimeMillis();
12566 String shortMsg = crashInfo.exceptionClassName;
12567 String longMsg = crashInfo.exceptionMessage;
12568 String stackTrace = crashInfo.stackTrace;
12569 if (shortMsg != null && longMsg != null) {
12570 longMsg = shortMsg + ": " + longMsg;
12571 } else if (shortMsg != null) {
12572 longMsg = shortMsg;
12575 AppErrorResult result = new AppErrorResult();
12576 synchronized (this) {
12577 if (mController != null) {
12579 String name = r != null ? r.processName : null;
12580 int pid = r != null ? r.pid : Binder.getCallingPid();
12581 int uid = r != null ? r.info.uid : Binder.getCallingUid();
12582 if (!mController.appCrashed(name, pid,
12583 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12584 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12585 && "Native crash".equals(crashInfo.exceptionClassName)) {
12586 Slog.w(TAG, "Skip killing native crashed app " + name
12587 + "(" + pid + ") during testing");
12589 Slog.w(TAG, "Force-killing crashed app " + name
12590 + " at watcher's request");
12592 r.kill("crash", true);
12595 Process.killProcess(pid);
12596 killProcessGroup(uid, pid);
12601 } catch (RemoteException e) {
12602 mController = null;
12603 Watchdog.getInstance().setActivityController(null);
12607 final long origId = Binder.clearCallingIdentity();
12609 // If this process is running instrumentation, finish it.
12610 if (r != null && r.instrumentationClass != null) {
12611 Slog.w(TAG, "Error in app " + r.processName
12612 + " running instrumentation " + r.instrumentationClass + ":");
12613 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
12614 if (longMsg != null) Slog.w(TAG, " " + longMsg);
12615 Bundle info = new Bundle();
12616 info.putString("shortMsg", shortMsg);
12617 info.putString("longMsg", longMsg);
12618 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12619 Binder.restoreCallingIdentity(origId);
12623 // Log crash in battery stats.
12625 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12628 // If we can't identify the process or it's already exceeded its crash quota,
12629 // quit right away without showing a crash dialog.
12630 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12631 Binder.restoreCallingIdentity(origId);
12635 Message msg = Message.obtain();
12636 msg.what = SHOW_ERROR_MSG;
12637 HashMap data = new HashMap();
12638 data.put("result", result);
12639 data.put("app", r);
12641 mUiHandler.sendMessage(msg);
12643 Binder.restoreCallingIdentity(origId);
12646 int res = result.get();
12648 Intent appErrorIntent = null;
12649 synchronized (this) {
12650 if (r != null && !r.isolated) {
12651 // XXX Can't keep track of crash time for isolated processes,
12652 // since they don't have a persistent identity.
12653 mProcessCrashTimes.put(r.info.processName, r.uid,
12654 SystemClock.uptimeMillis());
12656 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12657 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12661 if (appErrorIntent != null) {
12663 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12664 } catch (ActivityNotFoundException e) {
12665 Slog.w(TAG, "bug report receiver dissappeared", e);
12670 Intent createAppErrorIntentLocked(ProcessRecord r,
12671 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12672 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12673 if (report == null) {
12676 Intent result = new Intent(Intent.ACTION_APP_ERROR);
12677 result.setComponent(r.errorReportReceiver);
12678 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12679 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12683 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12684 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12685 if (r.errorReportReceiver == null) {
12689 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12693 ApplicationErrorReport report = new ApplicationErrorReport();
12694 report.packageName = r.info.packageName;
12695 report.installerPackageName = r.errorReportReceiver.getPackageName();
12696 report.processName = r.processName;
12697 report.time = timeMillis;
12698 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12700 if (r.crashing || r.forceCrashReport) {
12701 report.type = ApplicationErrorReport.TYPE_CRASH;
12702 report.crashInfo = crashInfo;
12703 } else if (r.notResponding) {
12704 report.type = ApplicationErrorReport.TYPE_ANR;
12705 report.anrInfo = new ApplicationErrorReport.AnrInfo();
12707 report.anrInfo.activity = r.notRespondingReport.tag;
12708 report.anrInfo.cause = r.notRespondingReport.shortMsg;
12709 report.anrInfo.info = r.notRespondingReport.longMsg;
12715 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12716 enforceNotIsolatedCaller("getProcessesInErrorState");
12717 // assume our apps are happy - lazy create the list
12718 List<ActivityManager.ProcessErrorStateInfo> errList = null;
12720 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12721 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12722 int userId = UserHandle.getUserId(Binder.getCallingUid());
12724 synchronized (this) {
12726 // iterate across all processes
12727 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12728 ProcessRecord app = mLruProcesses.get(i);
12729 if (!allUsers && app.userId != userId) {
12732 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12733 // This one's in trouble, so we'll generate a report for it
12734 // crashes are higher priority (in case there's a crash *and* an anr)
12735 ActivityManager.ProcessErrorStateInfo report = null;
12736 if (app.crashing) {
12737 report = app.crashingReport;
12738 } else if (app.notResponding) {
12739 report = app.notRespondingReport;
12742 if (report != null) {
12743 if (errList == null) {
12744 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12746 errList.add(report);
12748 Slog.w(TAG, "Missing app error report, app = " + app.processName +
12749 " crashing = " + app.crashing +
12750 " notResponding = " + app.notResponding);
12759 static int procStateToImportance(int procState, int memAdj,
12760 ActivityManager.RunningAppProcessInfo currApp) {
12761 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12762 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12763 currApp.lru = memAdj;
12770 private void fillInProcMemInfo(ProcessRecord app,
12771 ActivityManager.RunningAppProcessInfo outInfo) {
12772 outInfo.pid = app.pid;
12773 outInfo.uid = app.info.uid;
12774 if (mHeavyWeightProcess == app) {
12775 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12777 if (app.persistent) {
12778 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12780 if (app.activities.size() > 0) {
12781 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12783 outInfo.lastTrimLevel = app.trimMemoryLevel;
12784 int adj = app.curAdj;
12785 int procState = app.curProcState;
12786 outInfo.importance = procStateToImportance(procState, adj, outInfo);
12787 outInfo.importanceReasonCode = app.adjTypeCode;
12788 outInfo.processState = app.curProcState;
12791 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12792 enforceNotIsolatedCaller("getRunningAppProcesses");
12794 final int callingUid = Binder.getCallingUid();
12796 // Lazy instantiation of list
12797 List<ActivityManager.RunningAppProcessInfo> runList = null;
12798 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12799 callingUid) == PackageManager.PERMISSION_GRANTED;
12800 final int userId = UserHandle.getUserId(callingUid);
12801 final boolean allUids = isGetTasksAllowed(
12802 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12804 synchronized (this) {
12805 // Iterate across all processes
12806 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12807 ProcessRecord app = mLruProcesses.get(i);
12808 if ((!allUsers && app.userId != userId)
12809 || (!allUids && app.uid != callingUid)) {
12812 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12813 // Generate process state info for running application
12814 ActivityManager.RunningAppProcessInfo currApp =
12815 new ActivityManager.RunningAppProcessInfo(app.processName,
12816 app.pid, app.getPackageList());
12817 fillInProcMemInfo(app, currApp);
12818 if (app.adjSource instanceof ProcessRecord) {
12819 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12820 currApp.importanceReasonImportance =
12821 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12822 app.adjSourceProcState);
12823 } else if (app.adjSource instanceof ActivityRecord) {
12824 ActivityRecord r = (ActivityRecord)app.adjSource;
12825 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12827 if (app.adjTarget instanceof ComponentName) {
12828 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12830 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12831 // + " lru=" + currApp.lru);
12832 if (runList == null) {
12833 runList = new ArrayList<>();
12835 runList.add(currApp);
12842 public List<ApplicationInfo> getRunningExternalApplications() {
12843 enforceNotIsolatedCaller("getRunningExternalApplications");
12844 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12845 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12846 if (runningApps != null && runningApps.size() > 0) {
12847 Set<String> extList = new HashSet<String>();
12848 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12849 if (app.pkgList != null) {
12850 for (String pkg : app.pkgList) {
12855 IPackageManager pm = AppGlobals.getPackageManager();
12856 for (String pkg : extList) {
12858 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12859 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12862 } catch (RemoteException e) {
12870 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12871 enforceNotIsolatedCaller("getMyMemoryState");
12872 synchronized (this) {
12873 ProcessRecord proc;
12874 synchronized (mPidsSelfLocked) {
12875 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12877 fillInProcMemInfo(proc, outInfo);
12882 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12883 if (checkCallingPermission(android.Manifest.permission.DUMP)
12884 != PackageManager.PERMISSION_GRANTED) {
12885 pw.println("Permission Denial: can't dump ActivityManager from from pid="
12886 + Binder.getCallingPid()
12887 + ", uid=" + Binder.getCallingUid()
12888 + " without permission "
12889 + android.Manifest.permission.DUMP);
12893 boolean dumpAll = false;
12894 boolean dumpClient = false;
12895 String dumpPackage = null;
12898 while (opti < args.length) {
12899 String opt = args[opti];
12900 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12904 if ("-a".equals(opt)) {
12906 } else if ("-c".equals(opt)) {
12908 } else if ("-p".equals(opt)) {
12909 if (opti < args.length) {
12910 dumpPackage = args[opti];
12913 pw.println("Error: -p option requires package argument");
12917 } else if ("-h".equals(opt)) {
12918 pw.println("Activity manager dump options:");
12919 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ...");
12920 pw.println(" cmd may be one of:");
12921 pw.println(" a[ctivities]: activity stack state");
12922 pw.println(" r[recents]: recent activities state");
12923 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12924 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
12925 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
12926 pw.println(" o[om]: out of memory management");
12927 pw.println(" perm[issions]: URI permission grant state");
12928 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
12929 pw.println(" provider [COMP_SPEC]: provider client-side state");
12930 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
12931 pw.println(" as[sociations]: tracked app associations");
12932 pw.println(" service [COMP_SPEC]: service client-side state");
12933 pw.println(" package [PACKAGE_NAME]: all state related to given package");
12934 pw.println(" all: dump all activities");
12935 pw.println(" top: dump the top activity");
12936 pw.println(" write: write all pending state to storage");
12937 pw.println(" track-associations: enable association tracking");
12938 pw.println(" untrack-associations: disable and clear association tracking");
12939 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
12940 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
12941 pw.println(" a partial substring in a component name, a");
12942 pw.println(" hex object identifier.");
12943 pw.println(" -a: include all available server state.");
12944 pw.println(" -c: include client state.");
12945 pw.println(" -p: limit output to given package.");
12948 pw.println("Unknown argument: " + opt + "; use -h for help");
12952 long origId = Binder.clearCallingIdentity();
12953 boolean more = false;
12954 // Is the caller requesting to dump a particular piece of data?
12955 if (opti < args.length) {
12956 String cmd = args[opti];
12958 if ("activities".equals(cmd) || "a".equals(cmd)) {
12959 synchronized (this) {
12960 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12962 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12963 synchronized (this) {
12964 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12966 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12969 if (opti >= args.length) {
12971 newArgs = EMPTY_STRING_ARRAY;
12973 dumpPackage = args[opti];
12975 newArgs = new String[args.length - opti];
12976 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12977 args.length - opti);
12979 synchronized (this) {
12980 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12982 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12985 if (opti >= args.length) {
12987 newArgs = EMPTY_STRING_ARRAY;
12989 dumpPackage = args[opti];
12991 newArgs = new String[args.length - opti];
12992 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12993 args.length - opti);
12995 synchronized (this) {
12996 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12998 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13001 if (opti >= args.length) {
13003 newArgs = EMPTY_STRING_ARRAY;
13005 dumpPackage = args[opti];
13007 newArgs = new String[args.length - opti];
13008 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13009 args.length - opti);
13011 synchronized (this) {
13012 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13014 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13015 synchronized (this) {
13016 dumpOomLocked(fd, pw, args, opti, true);
13018 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13019 synchronized (this) {
13020 dumpPermissionsLocked(fd, pw, args, opti, true, null);
13022 } else if ("provider".equals(cmd)) {
13025 if (opti >= args.length) {
13027 newArgs = EMPTY_STRING_ARRAY;
13031 newArgs = new String[args.length - opti];
13032 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13034 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13035 pw.println("No providers match: " + name);
13036 pw.println("Use -h for help.");
13038 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13039 synchronized (this) {
13040 dumpProvidersLocked(fd, pw, args, opti, true, null);
13042 } else if ("service".equals(cmd)) {
13045 if (opti >= args.length) {
13047 newArgs = EMPTY_STRING_ARRAY;
13051 newArgs = new String[args.length - opti];
13052 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13053 args.length - opti);
13055 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13056 pw.println("No services match: " + name);
13057 pw.println("Use -h for help.");
13059 } else if ("package".equals(cmd)) {
13061 if (opti >= args.length) {
13062 pw.println("package: no package name specified");
13063 pw.println("Use -h for help.");
13065 dumpPackage = args[opti];
13067 newArgs = new String[args.length - opti];
13068 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13069 args.length - opti);
13074 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13075 synchronized (this) {
13076 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13078 } else if ("services".equals(cmd) || "s".equals(cmd)) {
13079 synchronized (this) {
13080 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13082 } else if ("write".equals(cmd)) {
13083 mTaskPersister.flush();
13084 pw.println("All tasks persisted.");
13086 } else if ("track-associations".equals(cmd)) {
13087 synchronized (this) {
13088 if (!mTrackingAssociations) {
13089 mTrackingAssociations = true;
13090 pw.println("Association tracking started.");
13092 pw.println("Association tracking already enabled.");
13096 } else if ("untrack-associations".equals(cmd)) {
13097 synchronized (this) {
13098 if (mTrackingAssociations) {
13099 mTrackingAssociations = false;
13100 mAssociations.clear();
13101 pw.println("Association tracking stopped.");
13103 pw.println("Association tracking not running.");
13108 // Dumping a single activity?
13109 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13110 pw.println("Bad activity command, or no activities match: " + cmd);
13111 pw.println("Use -h for help.");
13115 Binder.restoreCallingIdentity(origId);
13120 // No piece of data specified, dump everything.
13121 synchronized (this) {
13122 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13125 pw.println("-------------------------------------------------------------------------------");
13127 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13130 pw.println("-------------------------------------------------------------------------------");
13132 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13135 pw.println("-------------------------------------------------------------------------------");
13137 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13140 pw.println("-------------------------------------------------------------------------------");
13142 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13145 pw.println("-------------------------------------------------------------------------------");
13147 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13150 pw.println("-------------------------------------------------------------------------------");
13152 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13153 if (mAssociations.size() > 0) {
13156 pw.println("-------------------------------------------------------------------------------");
13158 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13162 pw.println("-------------------------------------------------------------------------------");
13164 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13166 Binder.restoreCallingIdentity(origId);
13169 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13170 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13171 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13173 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13175 boolean needSep = printedAnything;
13177 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13178 dumpPackage, needSep, " mFocusedActivity: ");
13180 printedAnything = true;
13184 if (dumpPackage == null) {
13189 printedAnything = true;
13190 mStackSupervisor.dump(pw, " ");
13193 if (!printedAnything) {
13194 pw.println(" (nothing)");
13198 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13199 int opti, boolean dumpAll, String dumpPackage) {
13200 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13202 boolean printedAnything = false;
13204 if (mRecentTasks != null && mRecentTasks.size() > 0) {
13205 boolean printedHeader = false;
13207 final int N = mRecentTasks.size();
13208 for (int i=0; i<N; i++) {
13209 TaskRecord tr = mRecentTasks.get(i);
13210 if (dumpPackage != null) {
13211 if (tr.realActivity == null ||
13212 !dumpPackage.equals(tr.realActivity)) {
13216 if (!printedHeader) {
13217 pw.println(" Recent tasks:");
13218 printedHeader = true;
13219 printedAnything = true;
13221 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
13224 mRecentTasks.get(i).dump(pw, " ");
13229 if (!printedAnything) {
13230 pw.println(" (nothing)");
13234 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13235 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13236 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13239 if (dumpPackage != null) {
13240 IPackageManager pm = AppGlobals.getPackageManager();
13242 dumpUid = pm.getPackageUid(dumpPackage, 0);
13243 } catch (RemoteException e) {
13247 boolean printedAnything = false;
13249 final long now = SystemClock.uptimeMillis();
13251 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13252 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13253 = mAssociations.valueAt(i1);
13254 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13255 SparseArray<ArrayMap<String, Association>> sourceUids
13256 = targetComponents.valueAt(i2);
13257 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13258 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13259 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13260 Association ass = sourceProcesses.valueAt(i4);
13261 if (dumpPackage != null) {
13262 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13263 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13267 printedAnything = true;
13269 pw.print(ass.mTargetProcess);
13271 UserHandle.formatUid(pw, ass.mTargetUid);
13273 pw.print(ass.mSourceProcess);
13275 UserHandle.formatUid(pw, ass.mSourceUid);
13278 pw.print(ass.mTargetComponent.flattenToShortString());
13281 long dur = ass.mTime;
13282 if (ass.mNesting > 0) {
13283 dur += now - ass.mStartTime;
13285 TimeUtils.formatDuration(dur, pw);
13287 pw.print(ass.mCount);
13288 pw.println(" times)");
13289 if (ass.mNesting > 0) {
13291 pw.print(" Currently active: ");
13292 TimeUtils.formatDuration(now - ass.mStartTime, pw);
13301 if (!printedAnything) {
13302 pw.println(" (nothing)");
13306 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13307 int opti, boolean dumpAll, String dumpPackage) {
13308 boolean needSep = false;
13309 boolean printedAnything = false;
13312 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13315 final int NP = mProcessNames.getMap().size();
13316 for (int ip=0; ip<NP; ip++) {
13317 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13318 final int NA = procs.size();
13319 for (int ia=0; ia<NA; ia++) {
13320 ProcessRecord r = procs.valueAt(ia);
13321 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13325 pw.println(" All known processes:");
13327 printedAnything = true;
13329 pw.print(r.persistent ? " *PERS*" : " *APP*");
13330 pw.print(" UID "); pw.print(procs.keyAt(ia));
13331 pw.print(" "); pw.println(r);
13333 if (r.persistent) {
13340 if (mIsolatedProcesses.size() > 0) {
13341 boolean printed = false;
13342 for (int i=0; i<mIsolatedProcesses.size(); i++) {
13343 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13344 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13351 pw.println(" Isolated process list (sorted by uid):");
13352 printedAnything = true;
13356 pw.println(String.format("%sIsolated #%2d: %s",
13357 " ", i, r.toString()));
13361 if (mActiveUids.size() > 0) {
13365 pw.println(" UID states:");
13366 for (int i=0; i<mActiveUids.size(); i++) {
13367 UidRecord uidRec = mActiveUids.valueAt(i);
13368 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
13369 pw.print(": "); pw.println(uidRec);
13372 printedAnything = true;
13375 if (mLruProcesses.size() > 0) {
13379 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13380 pw.print(" total, non-act at ");
13381 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13382 pw.print(", non-svc at ");
13383 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13385 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
13387 printedAnything = true;
13390 if (dumpAll || dumpPackage != null) {
13391 synchronized (mPidsSelfLocked) {
13392 boolean printed = false;
13393 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13394 ProcessRecord r = mPidsSelfLocked.valueAt(i);
13395 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13399 if (needSep) pw.println();
13401 pw.println(" PID mappings:");
13403 printedAnything = true;
13405 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13406 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13411 if (mForegroundProcesses.size() > 0) {
13412 synchronized (mPidsSelfLocked) {
13413 boolean printed = false;
13414 for (int i=0; i<mForegroundProcesses.size(); i++) {
13415 ProcessRecord r = mPidsSelfLocked.get(
13416 mForegroundProcesses.valueAt(i).pid);
13417 if (dumpPackage != null && (r == null
13418 || !r.pkgList.containsKey(dumpPackage))) {
13422 if (needSep) pw.println();
13424 pw.println(" Foreground Processes:");
13426 printedAnything = true;
13428 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
13429 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13434 if (mPersistentStartingProcesses.size() > 0) {
13435 if (needSep) pw.println();
13437 printedAnything = true;
13438 pw.println(" Persisent processes that are starting:");
13439 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
13440 "Starting Norm", "Restarting PERS", dumpPackage);
13443 if (mRemovedProcesses.size() > 0) {
13444 if (needSep) pw.println();
13446 printedAnything = true;
13447 pw.println(" Processes that are being removed:");
13448 dumpProcessList(pw, this, mRemovedProcesses, " ",
13449 "Removed Norm", "Removed PERS", dumpPackage);
13452 if (mProcessesOnHold.size() > 0) {
13453 if (needSep) pw.println();
13455 printedAnything = true;
13456 pw.println(" Processes that are on old until the system is ready:");
13457 dumpProcessList(pw, this, mProcessesOnHold, " ",
13458 "OnHold Norm", "OnHold PERS", dumpPackage);
13461 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13463 if (mProcessCrashTimes.getMap().size() > 0) {
13464 boolean printed = false;
13465 long now = SystemClock.uptimeMillis();
13466 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13467 final int NP = pmap.size();
13468 for (int ip=0; ip<NP; ip++) {
13469 String pname = pmap.keyAt(ip);
13470 SparseArray<Long> uids = pmap.valueAt(ip);
13471 final int N = uids.size();
13472 for (int i=0; i<N; i++) {
13473 int puid = uids.keyAt(i);
13474 ProcessRecord r = mProcessNames.get(pname, puid);
13475 if (dumpPackage != null && (r == null
13476 || !r.pkgList.containsKey(dumpPackage))) {
13480 if (needSep) pw.println();
13482 pw.println(" Time since processes crashed:");
13484 printedAnything = true;
13486 pw.print(" Process "); pw.print(pname);
13487 pw.print(" uid "); pw.print(puid);
13488 pw.print(": last crashed ");
13489 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13490 pw.println(" ago");
13495 if (mBadProcesses.getMap().size() > 0) {
13496 boolean printed = false;
13497 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13498 final int NP = pmap.size();
13499 for (int ip=0; ip<NP; ip++) {
13500 String pname = pmap.keyAt(ip);
13501 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13502 final int N = uids.size();
13503 for (int i=0; i<N; i++) {
13504 int puid = uids.keyAt(i);
13505 ProcessRecord r = mProcessNames.get(pname, puid);
13506 if (dumpPackage != null && (r == null
13507 || !r.pkgList.containsKey(dumpPackage))) {
13511 if (needSep) pw.println();
13513 pw.println(" Bad processes:");
13514 printedAnything = true;
13516 BadProcessInfo info = uids.valueAt(i);
13517 pw.print(" Bad process "); pw.print(pname);
13518 pw.print(" uid "); pw.print(puid);
13519 pw.print(": crashed at time "); pw.println(info.time);
13520 if (info.shortMsg != null) {
13521 pw.print(" Short msg: "); pw.println(info.shortMsg);
13523 if (info.longMsg != null) {
13524 pw.print(" Long msg: "); pw.println(info.longMsg);
13526 if (info.stack != null) {
13527 pw.println(" Stack:");
13529 for (int pos=0; pos<info.stack.length(); pos++) {
13530 if (info.stack.charAt(pos) == '\n') {
13532 pw.write(info.stack, lastPos, pos-lastPos);
13537 if (lastPos < info.stack.length()) {
13539 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13547 if (dumpPackage == null) {
13550 pw.println(" mStartedUsers:");
13551 for (int i=0; i<mStartedUsers.size(); i++) {
13552 UserState uss = mStartedUsers.valueAt(i);
13553 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
13554 pw.print(": "); uss.dump("", pw);
13556 pw.print(" mStartedUserArray: [");
13557 for (int i=0; i<mStartedUserArray.length; i++) {
13558 if (i > 0) pw.print(", ");
13559 pw.print(mStartedUserArray[i]);
13562 pw.print(" mUserLru: [");
13563 for (int i=0; i<mUserLru.size(); i++) {
13564 if (i > 0) pw.print(", ");
13565 pw.print(mUserLru.get(i));
13569 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13571 synchronized (mUserProfileGroupIdsSelfLocked) {
13572 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13573 pw.println(" mUserProfileGroupIds:");
13574 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13575 pw.print(" User #");
13576 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13577 pw.print(" -> profile #");
13578 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13583 if (mHomeProcess != null && (dumpPackage == null
13584 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13589 pw.println(" mHomeProcess: " + mHomeProcess);
13591 if (mPreviousProcess != null && (dumpPackage == null
13592 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13597 pw.println(" mPreviousProcess: " + mPreviousProcess);
13600 StringBuilder sb = new StringBuilder(128);
13601 sb.append(" mPreviousProcessVisibleTime: ");
13602 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13605 if (mHeavyWeightProcess != null && (dumpPackage == null
13606 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13611 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13613 if (dumpPackage == null) {
13614 pw.println(" mConfiguration: " + mConfiguration);
13617 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13618 if (mCompatModePackages.getPackages().size() > 0) {
13619 boolean printed = false;
13620 for (Map.Entry<String, Integer> entry
13621 : mCompatModePackages.getPackages().entrySet()) {
13622 String pkg = entry.getKey();
13623 int mode = entry.getValue();
13624 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13628 pw.println(" mScreenCompatPackages:");
13631 pw.print(" "); pw.print(pkg); pw.print(": ");
13632 pw.print(mode); pw.println();
13636 if (dumpPackage == null) {
13637 pw.println(" mWakefulness="
13638 + PowerManagerInternal.wakefulnessToString(mWakefulness));
13639 pw.println(" mSleepTokens=" + mSleepTokens);
13640 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
13641 + lockScreenShownToString());
13642 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13643 if (mRunningVoice != null) {
13644 pw.println(" mRunningVoice=" + mRunningVoice);
13645 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
13648 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13649 || mOrigWaitForDebugger) {
13650 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13651 || dumpPackage.equals(mOrigDebugApp)) {
13656 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13657 + " mDebugTransient=" + mDebugTransient
13658 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13661 if (mCurAppTimeTracker != null) {
13662 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
13664 if (mMemWatchProcesses.getMap().size() > 0) {
13665 pw.println(" Mem watch processes:");
13666 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13667 = mMemWatchProcesses.getMap();
13668 for (int i=0; i<procs.size(); i++) {
13669 final String proc = procs.keyAt(i);
13670 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13671 for (int j=0; j<uids.size(); j++) {
13676 StringBuilder sb = new StringBuilder();
13677 sb.append(" ").append(proc).append('/');
13678 UserHandle.formatUid(sb, uids.keyAt(j));
13679 Pair<Long, String> val = uids.valueAt(j);
13680 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13681 if (val.second != null) {
13682 sb.append(", report to ").append(val.second);
13684 pw.println(sb.toString());
13687 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13688 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13689 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13690 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13692 if (mOpenGlTraceApp != null) {
13693 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13698 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
13701 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13702 || mProfileFd != null) {
13703 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13708 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13709 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13710 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13711 + mAutoStopProfiler);
13712 pw.println(" mProfileType=" + mProfileType);
13715 if (dumpPackage == null) {
13716 if (mAlwaysFinishActivities || mController != null) {
13717 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
13718 + " mController=" + mController);
13721 pw.println(" Total persistent processes: " + numPers);
13722 pw.println(" mProcessesReady=" + mProcessesReady
13723 + " mSystemReady=" + mSystemReady
13724 + " mBooted=" + mBooted
13725 + " mFactoryTest=" + mFactoryTest);
13726 pw.println(" mBooting=" + mBooting
13727 + " mCallFinishBooting=" + mCallFinishBooting
13728 + " mBootAnimationComplete=" + mBootAnimationComplete);
13729 pw.print(" mLastPowerCheckRealtime=");
13730 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13732 pw.print(" mLastPowerCheckUptime=");
13733 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13735 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13736 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13737 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13738 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
13739 + " (" + mLruProcesses.size() + " total)"
13740 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13741 + " mNumServiceProcs=" + mNumServiceProcs
13742 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13743 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
13744 + " mLastMemoryLevel" + mLastMemoryLevel
13745 + " mLastNumProcesses" + mLastNumProcesses);
13746 long now = SystemClock.uptimeMillis();
13747 pw.print(" mLastIdleTime=");
13748 TimeUtils.formatDuration(now, mLastIdleTime, pw);
13749 pw.print(" mLowRamSinceLastIdle=");
13750 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13755 if (!printedAnything) {
13756 pw.println(" (nothing)");
13760 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13761 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13762 if (mProcessesToGc.size() > 0) {
13763 boolean printed = false;
13764 long now = SystemClock.uptimeMillis();
13765 for (int i=0; i<mProcessesToGc.size(); i++) {
13766 ProcessRecord proc = mProcessesToGc.get(i);
13767 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13771 if (needSep) pw.println();
13773 pw.println(" Processes that are waiting to GC:");
13776 pw.print(" Process "); pw.println(proc);
13777 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
13778 pw.print(", last gced=");
13779 pw.print(now-proc.lastRequestedGc);
13780 pw.print(" ms ago, last lowMem=");
13781 pw.print(now-proc.lastLowMemory);
13782 pw.println(" ms ago");
13789 void printOomLevel(PrintWriter pw, String name, int adj) {
13793 if (adj < 10) pw.print(' ');
13795 if (adj > -10) pw.print(' ');
13801 pw.print(mProcessList.getMemLevel(adj)/1024);
13802 pw.println(" kB)");
13805 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13806 int opti, boolean dumpAll) {
13807 boolean needSep = false;
13809 if (mLruProcesses.size() > 0) {
13810 if (needSep) pw.println();
13812 pw.println(" OOM levels:");
13813 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13814 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13815 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13816 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13817 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13818 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13819 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13820 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13821 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13822 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13823 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13824 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13825 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13826 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13828 if (needSep) pw.println();
13829 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
13830 pw.print(" total, non-act at ");
13831 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13832 pw.print(", non-svc at ");
13833 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13835 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
13839 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13842 pw.println(" mHomeProcess: " + mHomeProcess);
13843 pw.println(" mPreviousProcess: " + mPreviousProcess);
13844 if (mHeavyWeightProcess != null) {
13845 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13852 * There are three ways to call this:
13853 * - no provider specified: dump all the providers
13854 * - a flattened component name that matched an existing provider was specified as the
13855 * first arg: dump that one provider
13856 * - the first arg isn't the flattened component name of an existing provider:
13857 * dump all providers whose component contains the first arg as a substring
13859 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13860 int opti, boolean dumpAll) {
13861 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13864 static class ItemMatcher {
13865 ArrayList<ComponentName> components;
13866 ArrayList<String> strings;
13867 ArrayList<Integer> objects;
13874 void build(String name) {
13875 ComponentName componentName = ComponentName.unflattenFromString(name);
13876 if (componentName != null) {
13877 if (components == null) {
13878 components = new ArrayList<ComponentName>();
13880 components.add(componentName);
13884 // Not a '/' separated full component name; maybe an object ID?
13886 objectId = Integer.parseInt(name, 16);
13887 if (objects == null) {
13888 objects = new ArrayList<Integer>();
13890 objects.add(objectId);
13892 } catch (RuntimeException e) {
13893 // Not an integer; just do string match.
13894 if (strings == null) {
13895 strings = new ArrayList<String>();
13903 int build(String[] args, int opti) {
13904 for (; opti<args.length; opti++) {
13905 String name = args[opti];
13906 if ("--".equals(name)) {
13914 boolean match(Object object, ComponentName comp) {
13918 if (components != null) {
13919 for (int i=0; i<components.size(); i++) {
13920 if (components.get(i).equals(comp)) {
13925 if (objects != null) {
13926 for (int i=0; i<objects.size(); i++) {
13927 if (System.identityHashCode(object) == objects.get(i)) {
13932 if (strings != null) {
13933 String flat = comp.flattenToString();
13934 for (int i=0; i<strings.size(); i++) {
13935 if (flat.contains(strings.get(i))) {
13945 * There are three things that cmd can be:
13946 * - a flattened component name that matches an existing activity
13947 * - the cmd arg isn't the flattened component name of an existing activity:
13948 * dump all activity whose component contains the cmd as a substring
13949 * - A hex number of the ActivityRecord object instance.
13951 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13952 int opti, boolean dumpAll) {
13953 ArrayList<ActivityRecord> activities;
13955 synchronized (this) {
13956 activities = mStackSupervisor.getDumpActivitiesLocked(name);
13959 if (activities.size() <= 0) {
13963 String[] newArgs = new String[args.length - opti];
13964 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13966 TaskRecord lastTask = null;
13967 boolean needSep = false;
13968 for (int i=activities.size()-1; i>=0; i--) {
13969 ActivityRecord r = activities.get(i);
13974 synchronized (this) {
13975 if (lastTask != r.task) {
13977 pw.print("TASK "); pw.print(lastTask.affinity);
13978 pw.print(" id="); pw.println(lastTask.taskId);
13980 lastTask.dump(pw, " ");
13984 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
13990 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13991 * there is a thread associated with the activity.
13993 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13994 final ActivityRecord r, String[] args, boolean dumpAll) {
13995 String innerPrefix = prefix + " ";
13996 synchronized (this) {
13997 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13998 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14000 if (r.app != null) pw.println(r.app.pid);
14001 else pw.println("(not running)");
14003 r.dump(pw, innerPrefix);
14006 if (r.app != null && r.app.thread != null) {
14007 // flush anything that is already in the PrintWriter since the thread is going
14008 // to write to the file descriptor directly
14011 TransferPipe tp = new TransferPipe();
14013 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14014 r.appToken, innerPrefix, args);
14019 } catch (IOException e) {
14020 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14021 } catch (RemoteException e) {
14022 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14027 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14028 int opti, boolean dumpAll, String dumpPackage) {
14029 boolean needSep = false;
14030 boolean onlyHistory = false;
14031 boolean printedAnything = false;
14033 if ("history".equals(dumpPackage)) {
14034 if (opti < args.length && "-s".equals(args[opti])) {
14037 onlyHistory = true;
14038 dumpPackage = null;
14041 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14042 if (!onlyHistory && dumpAll) {
14043 if (mRegisteredReceivers.size() > 0) {
14044 boolean printed = false;
14045 Iterator it = mRegisteredReceivers.values().iterator();
14046 while (it.hasNext()) {
14047 ReceiverList r = (ReceiverList)it.next();
14048 if (dumpPackage != null && (r.app == null ||
14049 !dumpPackage.equals(r.app.info.packageName))) {
14053 pw.println(" Registered Receivers:");
14056 printedAnything = true;
14058 pw.print(" * "); pw.println(r);
14063 if (mReceiverResolver.dump(pw, needSep ?
14064 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
14065 " ", dumpPackage, false, false)) {
14067 printedAnything = true;
14071 for (BroadcastQueue q : mBroadcastQueues) {
14072 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14073 printedAnything |= needSep;
14078 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14079 for (int user=0; user<mStickyBroadcasts.size(); user++) {
14084 printedAnything = true;
14085 pw.print(" Sticky broadcasts for user ");
14086 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14087 StringBuilder sb = new StringBuilder(128);
14088 for (Map.Entry<String, ArrayList<Intent>> ent
14089 : mStickyBroadcasts.valueAt(user).entrySet()) {
14090 pw.print(" * Sticky action "); pw.print(ent.getKey());
14093 ArrayList<Intent> intents = ent.getValue();
14094 final int N = intents.size();
14095 for (int i=0; i<N; i++) {
14097 sb.append(" Intent: ");
14098 intents.get(i).toShortString(sb, false, true, false, false);
14099 pw.println(sb.toString());
14100 Bundle bundle = intents.get(i).getExtras();
14101 if (bundle != null) {
14103 pw.println(bundle.toString());
14113 if (!onlyHistory && dumpAll) {
14115 for (BroadcastQueue queue : mBroadcastQueues) {
14116 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
14117 + queue.mBroadcastsScheduled);
14119 pw.println(" mHandler:");
14120 mHandler.dump(new PrintWriterPrinter(pw), " ");
14122 printedAnything = true;
14125 if (!printedAnything) {
14126 pw.println(" (nothing)");
14130 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14131 int opti, boolean dumpAll, String dumpPackage) {
14133 boolean printedAnything = false;
14135 ItemMatcher matcher = new ItemMatcher();
14136 matcher.build(args, opti);
14138 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14140 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14141 printedAnything |= needSep;
14143 if (mLaunchingProviders.size() > 0) {
14144 boolean printed = false;
14145 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14146 ContentProviderRecord r = mLaunchingProviders.get(i);
14147 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14151 if (needSep) pw.println();
14153 pw.println(" Launching content providers:");
14155 printedAnything = true;
14157 pw.print(" Launching #"); pw.print(i); pw.print(": ");
14162 if (!printedAnything) {
14163 pw.println(" (nothing)");
14167 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14168 int opti, boolean dumpAll, String dumpPackage) {
14169 boolean needSep = false;
14170 boolean printedAnything = false;
14172 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14174 if (mGrantedUriPermissions.size() > 0) {
14175 boolean printed = false;
14177 if (dumpPackage != null) {
14179 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14180 } catch (NameNotFoundException e) {
14184 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14185 int uid = mGrantedUriPermissions.keyAt(i);
14186 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14189 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14191 if (needSep) pw.println();
14193 pw.println(" Granted Uri Permissions:");
14195 printedAnything = true;
14197 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
14198 for (UriPermission perm : perms.values()) {
14199 pw.print(" "); pw.println(perm);
14201 perm.dump(pw, " ");
14207 if (!printedAnything) {
14208 pw.println(" (nothing)");
14212 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14213 int opti, boolean dumpAll, String dumpPackage) {
14214 boolean printed = false;
14216 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14218 if (mIntentSenderRecords.size() > 0) {
14219 Iterator<WeakReference<PendingIntentRecord>> it
14220 = mIntentSenderRecords.values().iterator();
14221 while (it.hasNext()) {
14222 WeakReference<PendingIntentRecord> ref = it.next();
14223 PendingIntentRecord rec = ref != null ? ref.get(): null;
14224 if (dumpPackage != null && (rec == null
14225 || !dumpPackage.equals(rec.key.packageName))) {
14230 pw.print(" * "); pw.println(rec);
14235 pw.print(" * "); pw.println(ref);
14241 pw.println(" (nothing)");
14245 private static final int dumpProcessList(PrintWriter pw,
14246 ActivityManagerService service, List list,
14247 String prefix, String normalLabel, String persistentLabel,
14248 String dumpPackage) {
14250 final int N = list.size()-1;
14251 for (int i=N; i>=0; i--) {
14252 ProcessRecord r = (ProcessRecord)list.get(i);
14253 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14256 pw.println(String.format("%s%s #%2d: %s",
14257 prefix, (r.persistent ? persistentLabel : normalLabel),
14259 if (r.persistent) {
14266 private static final boolean dumpProcessOomList(PrintWriter pw,
14267 ActivityManagerService service, List<ProcessRecord> origList,
14268 String prefix, String normalLabel, String persistentLabel,
14269 boolean inclDetails, String dumpPackage) {
14271 ArrayList<Pair<ProcessRecord, Integer>> list
14272 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14273 for (int i=0; i<origList.size(); i++) {
14274 ProcessRecord r = origList.get(i);
14275 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14278 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14281 if (list.size() <= 0) {
14285 Comparator<Pair<ProcessRecord, Integer>> comparator
14286 = new Comparator<Pair<ProcessRecord, Integer>>() {
14288 public int compare(Pair<ProcessRecord, Integer> object1,
14289 Pair<ProcessRecord, Integer> object2) {
14290 if (object1.first.setAdj != object2.first.setAdj) {
14291 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14293 if (object1.second.intValue() != object2.second.intValue()) {
14294 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14300 Collections.sort(list, comparator);
14302 final long curRealtime = SystemClock.elapsedRealtime();
14303 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14304 final long curUptime = SystemClock.uptimeMillis();
14305 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14307 for (int i=list.size()-1; i>=0; i--) {
14308 ProcessRecord r = list.get(i).first;
14309 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14311 switch (r.setSchedGroup) {
14312 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14315 case Process.THREAD_GROUP_DEFAULT:
14323 if (r.foregroundActivities) {
14325 } else if (r.foregroundServices) {
14330 String procState = ProcessList.makeProcStateString(r.curProcState);
14332 pw.print(r.persistent ? persistentLabel : normalLabel);
14334 int num = (origList.size()-1)-list.get(i).second;
14335 if (num < 10) pw.print(' ');
14340 pw.print(schedGroup);
14342 pw.print(foreground);
14344 pw.print(procState);
14346 if (r.trimMemoryLevel < 10) pw.print(' ');
14347 pw.print(r.trimMemoryLevel);
14349 pw.print(r.toShortString());
14351 pw.print(r.adjType);
14353 if (r.adjSource != null || r.adjTarget != null) {
14356 if (r.adjTarget instanceof ComponentName) {
14357 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14358 } else if (r.adjTarget != null) {
14359 pw.print(r.adjTarget.toString());
14361 pw.print("{null}");
14364 if (r.adjSource instanceof ProcessRecord) {
14366 pw.print(((ProcessRecord)r.adjSource).toShortString());
14368 } else if (r.adjSource != null) {
14369 pw.println(r.adjSource.toString());
14371 pw.println("{null}");
14377 pw.print("oom: max="); pw.print(r.maxAdj);
14378 pw.print(" curRaw="); pw.print(r.curRawAdj);
14379 pw.print(" setRaw="); pw.print(r.setRawAdj);
14380 pw.print(" cur="); pw.print(r.curAdj);
14381 pw.print(" set="); pw.println(r.setAdj);
14384 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14385 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14386 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14387 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14391 pw.print("cached="); pw.print(r.cached);
14392 pw.print(" empty="); pw.print(r.empty);
14393 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14395 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14396 if (r.lastWakeTime != 0) {
14398 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14399 synchronized (stats) {
14400 wtime = stats.getProcessWakeTime(r.info.uid,
14401 r.pid, curRealtime);
14403 long timeUsed = wtime - r.lastWakeTime;
14406 pw.print("keep awake over ");
14407 TimeUtils.formatDuration(realtimeSince, pw);
14408 pw.print(" used ");
14409 TimeUtils.formatDuration(timeUsed, pw);
14411 pw.print((timeUsed*100)/realtimeSince);
14414 if (r.lastCpuTime != 0) {
14415 long timeUsed = r.curCpuTime - r.lastCpuTime;
14418 pw.print("run cpu over ");
14419 TimeUtils.formatDuration(uptimeSince, pw);
14420 pw.print(" used ");
14421 TimeUtils.formatDuration(timeUsed, pw);
14423 pw.print((timeUsed*100)/uptimeSince);
14432 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14434 ArrayList<ProcessRecord> procs;
14435 synchronized (this) {
14436 if (args != null && args.length > start
14437 && args[start].charAt(0) != '-') {
14438 procs = new ArrayList<ProcessRecord>();
14441 pid = Integer.parseInt(args[start]);
14442 } catch (NumberFormatException e) {
14444 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14445 ProcessRecord proc = mLruProcesses.get(i);
14446 if (proc.pid == pid) {
14448 } else if (allPkgs && proc.pkgList != null
14449 && proc.pkgList.containsKey(args[start])) {
14451 } else if (proc.processName.equals(args[start])) {
14455 if (procs.size() <= 0) {
14459 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14465 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14466 PrintWriter pw, String[] args) {
14467 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14468 if (procs == null) {
14469 pw.println("No process found for: " + args[0]);
14473 long uptime = SystemClock.uptimeMillis();
14474 long realtime = SystemClock.elapsedRealtime();
14475 pw.println("Applications Graphics Acceleration Info:");
14476 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14478 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14479 ProcessRecord r = procs.get(i);
14480 if (r.thread != null) {
14481 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14484 TransferPipe tp = new TransferPipe();
14486 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14491 } catch (IOException e) {
14492 pw.println("Failure while dumping the app: " + r);
14494 } catch (RemoteException e) {
14495 pw.println("Got a RemoteException while dumping the app " + r);
14502 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14503 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14504 if (procs == null) {
14505 pw.println("No process found for: " + args[0]);
14509 pw.println("Applications Database Info:");
14511 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14512 ProcessRecord r = procs.get(i);
14513 if (r.thread != null) {
14514 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14517 TransferPipe tp = new TransferPipe();
14519 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14524 } catch (IOException e) {
14525 pw.println("Failure while dumping the app: " + r);
14527 } catch (RemoteException e) {
14528 pw.println("Got a RemoteException while dumping the app " + r);
14535 final static class MemItem {
14536 final boolean isProc;
14537 final String label;
14538 final String shortLabel;
14541 final boolean hasActivities;
14542 ArrayList<MemItem> subitems;
14544 public MemItem(String _label, String _shortLabel, long _pss, int _id,
14545 boolean _hasActivities) {
14548 shortLabel = _shortLabel;
14551 hasActivities = _hasActivities;
14554 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14557 shortLabel = _shortLabel;
14560 hasActivities = false;
14564 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14565 ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14566 if (sort && !isCompact) {
14567 Collections.sort(items, new Comparator<MemItem>() {
14569 public int compare(MemItem lhs, MemItem rhs) {
14570 if (lhs.pss < rhs.pss) {
14572 } else if (lhs.pss > rhs.pss) {
14580 for (int i=0; i<items.size(); i++) {
14581 MemItem mi = items.get(i);
14583 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14584 } else if (mi.isProc) {
14585 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14586 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14587 pw.println(mi.hasActivities ? ",a" : ",e");
14589 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14590 pw.println(mi.pss);
14592 if (mi.subitems != null) {
14593 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
14599 // These are in KB.
14600 static final long[] DUMP_MEM_BUCKETS = new long[] {
14601 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14602 120*1024, 160*1024, 200*1024,
14603 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14604 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14607 static final void appendMemBucket(StringBuilder out, long memKB, String label,
14608 boolean stackLike) {
14609 int start = label.lastIndexOf('.');
14610 if (start >= 0) start++;
14612 int end = label.length();
14613 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14614 if (DUMP_MEM_BUCKETS[i] >= memKB) {
14615 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14616 out.append(bucket);
14617 out.append(stackLike ? "MB." : "MB ");
14618 out.append(label, start, end);
14622 out.append(memKB/1024);
14623 out.append(stackLike ? "MB." : "MB ");
14624 out.append(label, start, end);
14627 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14628 ProcessList.NATIVE_ADJ,
14629 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14630 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14631 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14632 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14633 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14634 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14636 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14638 "System", "Persistent", "Persistent Service", "Foreground",
14639 "Visible", "Perceptible",
14640 "Heavy Weight", "Backup",
14641 "A Services", "Home",
14642 "Previous", "B Services", "Cached"
14644 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14646 "sys", "pers", "persvc", "fore",
14649 "servicea", "home",
14650 "prev", "serviceb", "cached"
14653 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14654 long realtime, boolean isCheckinRequest, boolean isCompact) {
14655 if (isCheckinRequest || isCompact) {
14656 // short checkin version
14657 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14659 pw.println("Applications Memory Usage (kB):");
14660 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14664 private static final int KSM_SHARED = 0;
14665 private static final int KSM_SHARING = 1;
14666 private static final int KSM_UNSHARED = 2;
14667 private static final int KSM_VOLATILE = 3;
14669 private final long[] getKsmInfo() {
14670 long[] longOut = new long[4];
14671 final int[] SINGLE_LONG_FORMAT = new int[] {
14672 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14674 long[] longTmp = new long[1];
14675 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14676 SINGLE_LONG_FORMAT, null, longTmp, null);
14677 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14679 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14680 SINGLE_LONG_FORMAT, null, longTmp, null);
14681 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14683 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14684 SINGLE_LONG_FORMAT, null, longTmp, null);
14685 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14687 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14688 SINGLE_LONG_FORMAT, null, longTmp, null);
14689 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14693 final void dumpApplicationMemoryUsage(FileDescriptor fd,
14694 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14695 boolean dumpDetails = false;
14696 boolean dumpFullDetails = false;
14697 boolean dumpDalvik = false;
14698 boolean dumpSummaryOnly = false;
14699 boolean oomOnly = false;
14700 boolean isCompact = false;
14701 boolean localOnly = false;
14702 boolean packages = false;
14705 while (opti < args.length) {
14706 String opt = args[opti];
14707 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14711 if ("-a".equals(opt)) {
14712 dumpDetails = true;
14713 dumpFullDetails = true;
14715 } else if ("-d".equals(opt)) {
14717 } else if ("-c".equals(opt)) {
14719 } else if ("-s".equals(opt)) {
14720 dumpDetails = true;
14721 dumpSummaryOnly = true;
14722 } else if ("--oom".equals(opt)) {
14724 } else if ("--local".equals(opt)) {
14726 } else if ("--package".equals(opt)) {
14728 } else if ("-h".equals(opt)) {
14729 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14730 pw.println(" -a: include all available information for each process.");
14731 pw.println(" -d: include dalvik details.");
14732 pw.println(" -c: dump in a compact machine-parseable representation.");
14733 pw.println(" -s: dump only summary of application memory usage.");
14734 pw.println(" --oom: only show processes organized by oom adj.");
14735 pw.println(" --local: only collect details locally, don't call process.");
14736 pw.println(" --package: interpret process arg as package, dumping all");
14737 pw.println(" processes that have loaded that package.");
14738 pw.println("If [process] is specified it can be the name or ");
14739 pw.println("pid of a specific process to dump.");
14742 pw.println("Unknown argument: " + opt + "; use -h for help");
14746 final boolean isCheckinRequest = scanArgs(args, "--checkin");
14747 long uptime = SystemClock.uptimeMillis();
14748 long realtime = SystemClock.elapsedRealtime();
14749 final long[] tmpLong = new long[1];
14751 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14752 if (procs == null) {
14753 // No Java processes. Maybe they want to print a native process.
14754 if (args != null && args.length > opti
14755 && args[opti].charAt(0) != '-') {
14756 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14757 = new ArrayList<ProcessCpuTracker.Stats>();
14758 updateCpuStatsNow();
14761 findPid = Integer.parseInt(args[opti]);
14762 } catch (NumberFormatException e) {
14764 synchronized (mProcessCpuTracker) {
14765 final int N = mProcessCpuTracker.countStats();
14766 for (int i=0; i<N; i++) {
14767 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14768 if (st.pid == findPid || (st.baseName != null
14769 && st.baseName.equals(args[opti]))) {
14770 nativeProcs.add(st);
14774 if (nativeProcs.size() > 0) {
14775 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14777 Debug.MemoryInfo mi = null;
14778 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14779 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14780 final int pid = r.pid;
14781 if (!isCheckinRequest && dumpDetails) {
14782 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14785 mi = new Debug.MemoryInfo();
14787 if (dumpDetails || (!brief && !oomOnly)) {
14788 Debug.getMemoryInfo(pid, mi);
14790 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14791 mi.dalvikPrivateDirty = (int)tmpLong[0];
14793 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14794 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14795 if (isCheckinRequest) {
14802 pw.println("No process found for: " + args[opti]);
14806 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14807 dumpDetails = true;
14810 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14812 String[] innerArgs = new String[args.length-opti];
14813 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14815 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14816 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14817 long nativePss = 0;
14818 long dalvikPss = 0;
14819 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14822 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14824 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14825 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14826 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14829 long cachedPss = 0;
14831 Debug.MemoryInfo mi = null;
14832 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14833 final ProcessRecord r = procs.get(i);
14834 final IApplicationThread thread;
14837 final boolean hasActivities;
14838 synchronized (this) {
14841 oomAdj = r.getSetAdjWithServices();
14842 hasActivities = r.activities.size() > 0;
14844 if (thread != null) {
14845 if (!isCheckinRequest && dumpDetails) {
14846 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14849 mi = new Debug.MemoryInfo();
14851 if (dumpDetails || (!brief && !oomOnly)) {
14852 Debug.getMemoryInfo(pid, mi);
14854 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14855 mi.dalvikPrivateDirty = (int)tmpLong[0];
14859 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14860 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14861 if (isCheckinRequest) {
14867 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14868 dumpDalvik, dumpSummaryOnly, innerArgs);
14869 } catch (RemoteException e) {
14870 if (!isCheckinRequest) {
14871 pw.println("Got RemoteException!");
14878 final long myTotalPss = mi.getTotalPss();
14879 final long myTotalUss = mi.getTotalUss();
14881 synchronized (this) {
14882 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14883 // Record this for posterity if the process has been stable.
14884 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14888 if (!isCheckinRequest && mi != null) {
14889 totalPss += myTotalPss;
14890 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14891 (hasActivities ? " / activities)" : ")"),
14892 r.processName, myTotalPss, pid, hasActivities);
14893 procMems.add(pssItem);
14894 procMemsMap.put(pid, pssItem);
14896 nativePss += mi.nativePss;
14897 dalvikPss += mi.dalvikPss;
14898 for (int j=0; j<dalvikSubitemPss.length; j++) {
14899 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14901 otherPss += mi.otherPss;
14902 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14903 long mem = mi.getOtherPss(j);
14908 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14909 cachedPss += myTotalPss;
14912 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14913 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14914 || oomIndex == (oomPss.length-1)) {
14915 oomPss[oomIndex] += myTotalPss;
14916 if (oomProcs[oomIndex] == null) {
14917 oomProcs[oomIndex] = new ArrayList<MemItem>();
14919 oomProcs[oomIndex].add(pssItem);
14927 long nativeProcTotalPss = 0;
14929 if (!isCheckinRequest && procs.size() > 1 && !packages) {
14930 // If we are showing aggregations, also look for native processes to
14931 // include so that our aggregations are more accurate.
14932 updateCpuStatsNow();
14934 synchronized (mProcessCpuTracker) {
14935 final int N = mProcessCpuTracker.countStats();
14936 for (int i=0; i<N; i++) {
14937 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14938 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14940 mi = new Debug.MemoryInfo();
14942 if (!brief && !oomOnly) {
14943 Debug.getMemoryInfo(st.pid, mi);
14945 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14946 mi.nativePrivateDirty = (int)tmpLong[0];
14949 final long myTotalPss = mi.getTotalPss();
14950 totalPss += myTotalPss;
14951 nativeProcTotalPss += myTotalPss;
14953 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14954 st.name, myTotalPss, st.pid, false);
14955 procMems.add(pssItem);
14957 nativePss += mi.nativePss;
14958 dalvikPss += mi.dalvikPss;
14959 for (int j=0; j<dalvikSubitemPss.length; j++) {
14960 dalvikSubitemPss[j] += mi.getOtherPss(
14961 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14963 otherPss += mi.otherPss;
14964 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14965 long mem = mi.getOtherPss(j);
14969 oomPss[0] += myTotalPss;
14970 if (oomProcs[0] == null) {
14971 oomProcs[0] = new ArrayList<MemItem>();
14973 oomProcs[0].add(pssItem);
14978 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14980 catMems.add(new MemItem("Native", "Native", nativePss, -1));
14981 final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14982 if (dalvikSubitemPss.length > 0) {
14983 dalvikItem.subitems = new ArrayList<MemItem>();
14984 for (int j=0; j<dalvikSubitemPss.length; j++) {
14985 final String name = Debug.MemoryInfo.getOtherLabel(
14986 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14987 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14990 catMems.add(dalvikItem);
14991 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14992 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14993 String label = Debug.MemoryInfo.getOtherLabel(j);
14994 catMems.add(new MemItem(label, label, miscPss[j], j));
14997 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14998 for (int j=0; j<oomPss.length; j++) {
14999 if (oomPss[j] != 0) {
15000 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15001 : DUMP_MEM_OOM_LABEL[j];
15002 MemItem item = new MemItem(label, label, oomPss[j],
15003 DUMP_MEM_OOM_ADJ[j]);
15004 item.subitems = oomProcs[j];
15009 if (!brief && !oomOnly && !isCompact) {
15011 pw.println("Total PSS by process:");
15012 dumpMemItems(pw, " ", "proc", procMems, true, isCompact);
15016 pw.println("Total PSS by OOM adjustment:");
15018 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact);
15019 if (!brief && !oomOnly) {
15020 PrintWriter out = categoryPw != null ? categoryPw : pw;
15023 out.println("Total PSS by category:");
15025 dumpMemItems(out, " ", "cat", catMems, true, isCompact);
15030 MemInfoReader memInfo = new MemInfoReader();
15031 memInfo.readMemInfo();
15032 if (nativeProcTotalPss > 0) {
15033 synchronized (this) {
15034 final long cachedKb = memInfo.getCachedSizeKb();
15035 final long freeKb = memInfo.getFreeSizeKb();
15036 final long zramKb = memInfo.getZramTotalSizeKb();
15037 final long kernelKb = memInfo.getKernelUsedSizeKb();
15038 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15039 kernelKb*1024, nativeProcTotalPss*1024);
15040 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15041 nativeProcTotalPss);
15046 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
15047 pw.print(" kB (status ");
15048 switch (mLastMemoryLevel) {
15049 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15050 pw.println("normal)");
15052 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15053 pw.println("moderate)");
15055 case ProcessStats.ADJ_MEM_FACTOR_LOW:
15056 pw.println("low)");
15058 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15059 pw.println("critical)");
15062 pw.print(mLastMemoryLevel);
15066 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
15067 + memInfo.getFreeSizeKb()); pw.print(" kB (");
15068 pw.print(cachedPss); pw.print(" cached pss + ");
15069 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
15070 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
15072 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15073 pw.print(cachedPss + memInfo.getCachedSizeKb()
15074 + memInfo.getFreeSizeKb()); pw.print(",");
15075 pw.println(totalPss - cachedPss);
15079 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15080 + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15081 pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15082 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15083 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15084 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15085 - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15088 if (memInfo.getZramTotalSizeKb() != 0) {
15090 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15091 pw.print(" kB physical used for ");
15092 pw.print(memInfo.getSwapTotalSizeKb()
15093 - memInfo.getSwapFreeSizeKb());
15094 pw.print(" kB in swap (");
15095 pw.print(memInfo.getSwapTotalSizeKb());
15096 pw.println(" kB total swap)");
15098 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15099 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15100 pw.println(memInfo.getSwapFreeSizeKb());
15103 final long[] ksm = getKsmInfo();
15105 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15106 || ksm[KSM_VOLATILE] != 0) {
15107 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]);
15108 pw.print(" kB saved from shared ");
15109 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15110 pw.print(" "); pw.print(ksm[KSM_UNSHARED]);
15111 pw.print(" kB unshared; ");
15112 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15114 pw.print(" Tuning: ");
15115 pw.print(ActivityManager.staticGetMemoryClass());
15116 pw.print(" (large ");
15117 pw.print(ActivityManager.staticGetLargeMemoryClass());
15118 pw.print("), oom ");
15119 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15121 pw.print(", restore limit ");
15122 pw.print(mProcessList.getCachedRestoreThresholdKb());
15124 if (ActivityManager.isLowRamDeviceStatic()) {
15125 pw.print(" (low-ram)");
15127 if (ActivityManager.isHighEndGfx()) {
15128 pw.print(" (high-end-gfx)");
15132 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15133 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15134 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15135 pw.print("tuning,");
15136 pw.print(ActivityManager.staticGetMemoryClass());
15138 pw.print(ActivityManager.staticGetLargeMemoryClass());
15140 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15141 if (ActivityManager.isLowRamDeviceStatic()) {
15142 pw.print(",low-ram");
15144 if (ActivityManager.isHighEndGfx()) {
15145 pw.print(",high-end-gfx");
15153 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15154 long memtrack, String name) {
15156 sb.append(ProcessList.makeOomAdjString(oomAdj));
15158 sb.append(ProcessList.makeProcStateString(procState));
15160 ProcessList.appendRamKb(sb, pss);
15161 sb.append(" kB: ");
15163 if (memtrack > 0) {
15165 sb.append(memtrack);
15166 sb.append(" kB memtrack)");
15170 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15171 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15172 sb.append(" (pid ");
15175 sb.append(mi.adjType);
15177 if (mi.adjReason != null) {
15179 sb.append(mi.adjReason);
15184 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15185 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15186 for (int i=0, N=memInfos.size(); i<N; i++) {
15187 ProcessMemInfo mi = memInfos.get(i);
15188 infoMap.put(mi.pid, mi);
15190 updateCpuStatsNow();
15191 long[] memtrackTmp = new long[1];
15192 synchronized (mProcessCpuTracker) {
15193 final int N = mProcessCpuTracker.countStats();
15194 for (int i=0; i<N; i++) {
15195 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15196 if (st.vsize > 0) {
15197 long pss = Debug.getPss(st.pid, null, memtrackTmp);
15199 if (infoMap.indexOfKey(st.pid) < 0) {
15200 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15201 ProcessList.NATIVE_ADJ, -1, "native", null);
15203 mi.memtrack = memtrackTmp[0];
15212 long totalMemtrack = 0;
15213 for (int i=0, N=memInfos.size(); i<N; i++) {
15214 ProcessMemInfo mi = memInfos.get(i);
15216 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15217 mi.memtrack = memtrackTmp[0];
15219 totalPss += mi.pss;
15220 totalMemtrack += mi.memtrack;
15222 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15223 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15224 if (lhs.oomAdj != rhs.oomAdj) {
15225 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15227 if (lhs.pss != rhs.pss) {
15228 return lhs.pss < rhs.pss ? 1 : -1;
15234 StringBuilder tag = new StringBuilder(128);
15235 StringBuilder stack = new StringBuilder(128);
15236 tag.append("Low on memory -- ");
15237 appendMemBucket(tag, totalPss, "total", false);
15238 appendMemBucket(stack, totalPss, "total", true);
15240 StringBuilder fullNativeBuilder = new StringBuilder(1024);
15241 StringBuilder shortNativeBuilder = new StringBuilder(1024);
15242 StringBuilder fullJavaBuilder = new StringBuilder(1024);
15244 boolean firstLine = true;
15245 int lastOomAdj = Integer.MIN_VALUE;
15246 long extraNativeRam = 0;
15247 long extraNativeMemtrack = 0;
15248 long cachedPss = 0;
15249 for (int i=0, N=memInfos.size(); i<N; i++) {
15250 ProcessMemInfo mi = memInfos.get(i);
15252 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15253 cachedPss += mi.pss;
15256 if (mi.oomAdj != ProcessList.NATIVE_ADJ
15257 && (mi.oomAdj < ProcessList.SERVICE_ADJ
15258 || mi.oomAdj == ProcessList.HOME_APP_ADJ
15259 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15260 if (lastOomAdj != mi.oomAdj) {
15261 lastOomAdj = mi.oomAdj;
15262 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15265 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15270 stack.append("\n\t at ");
15278 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15279 appendMemBucket(tag, mi.pss, mi.name, false);
15281 appendMemBucket(stack, mi.pss, mi.name, true);
15282 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15283 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15285 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15286 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15287 stack.append(DUMP_MEM_OOM_LABEL[k]);
15289 stack.append(DUMP_MEM_OOM_ADJ[k]);
15296 appendMemInfo(fullNativeBuilder, mi);
15297 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15298 // The short form only has native processes that are >= 512K.
15299 if (mi.pss >= 512) {
15300 appendMemInfo(shortNativeBuilder, mi);
15302 extraNativeRam += mi.pss;
15303 extraNativeMemtrack += mi.memtrack;
15306 // Short form has all other details, but if we have collected RAM
15307 // from smaller native processes let's dump a summary of that.
15308 if (extraNativeRam > 0) {
15309 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15310 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15311 shortNativeBuilder.append('\n');
15312 extraNativeRam = 0;
15314 appendMemInfo(fullJavaBuilder, mi);
15318 fullJavaBuilder.append(" ");
15319 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15320 fullJavaBuilder.append(" kB: TOTAL");
15321 if (totalMemtrack > 0) {
15322 fullJavaBuilder.append(" (");
15323 fullJavaBuilder.append(totalMemtrack);
15324 fullJavaBuilder.append(" kB memtrack)");
15327 fullJavaBuilder.append("\n");
15329 MemInfoReader memInfo = new MemInfoReader();
15330 memInfo.readMemInfo();
15331 final long[] infos = memInfo.getRawInfo();
15333 StringBuilder memInfoBuilder = new StringBuilder(1024);
15334 Debug.getMemInfo(infos);
15335 memInfoBuilder.append(" MemInfo: ");
15336 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15337 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15338 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15339 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15340 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15341 memInfoBuilder.append(" ");
15342 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15343 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15344 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15345 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15346 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15347 memInfoBuilder.append(" ZRAM: ");
15348 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15349 memInfoBuilder.append(" kB RAM, ");
15350 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15351 memInfoBuilder.append(" kB swap total, ");
15352 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15353 memInfoBuilder.append(" kB swap free\n");
15355 final long[] ksm = getKsmInfo();
15356 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15357 || ksm[KSM_VOLATILE] != 0) {
15358 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15359 memInfoBuilder.append(" kB saved from shared ");
15360 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15361 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15362 memInfoBuilder.append(" kB unshared; ");
15363 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15365 memInfoBuilder.append(" Free RAM: ");
15366 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15367 + memInfo.getFreeSizeKb());
15368 memInfoBuilder.append(" kB\n");
15369 memInfoBuilder.append(" Used RAM: ");
15370 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15371 memInfoBuilder.append(" kB\n");
15372 memInfoBuilder.append(" Lost RAM: ");
15373 memInfoBuilder.append(memInfo.getTotalSizeKb()
15374 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15375 - memInfo.getKernelUsedSizeKb());
15376 memInfoBuilder.append(" kB\n");
15377 Slog.i(TAG, "Low on memory:");
15378 Slog.i(TAG, shortNativeBuilder.toString());
15379 Slog.i(TAG, fullJavaBuilder.toString());
15380 Slog.i(TAG, memInfoBuilder.toString());
15382 StringBuilder dropBuilder = new StringBuilder(1024);
15384 StringWriter oomSw = new StringWriter();
15385 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15386 StringWriter catSw = new StringWriter();
15387 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15388 String[] emptyArgs = new String[] { };
15389 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
15391 String oomString = oomSw.toString();
15393 dropBuilder.append("Low on memory:");
15394 dropBuilder.append(stack);
15395 dropBuilder.append('\n');
15396 dropBuilder.append(fullNativeBuilder);
15397 dropBuilder.append(fullJavaBuilder);
15398 dropBuilder.append('\n');
15399 dropBuilder.append(memInfoBuilder);
15400 dropBuilder.append('\n');
15402 dropBuilder.append(oomString);
15403 dropBuilder.append('\n');
15405 StringWriter catSw = new StringWriter();
15406 synchronized (ActivityManagerService.this) {
15407 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15408 String[] emptyArgs = new String[] { };
15410 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15412 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15413 false, false, null);
15415 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15418 dropBuilder.append(catSw.toString());
15419 addErrorToDropBox("lowmem", null, "system_server", null,
15420 null, tag.toString(), dropBuilder.toString(), null, null);
15421 //Slog.i(TAG, "Sent to dropbox:");
15422 //Slog.i(TAG, dropBuilder.toString());
15423 synchronized (ActivityManagerService.this) {
15424 long now = SystemClock.uptimeMillis();
15425 if (mLastMemUsageReportTime < now) {
15426 mLastMemUsageReportTime = now;
15432 * Searches array of arguments for the specified string
15433 * @param args array of argument strings
15434 * @param value value to search for
15435 * @return true if the value is contained in the array
15437 private static boolean scanArgs(String[] args, String value) {
15438 if (args != null) {
15439 for (String arg : args) {
15440 if (value.equals(arg)) {
15448 private final boolean removeDyingProviderLocked(ProcessRecord proc,
15449 ContentProviderRecord cpr, boolean always) {
15450 final boolean inLaunching = mLaunchingProviders.contains(cpr);
15452 if (!inLaunching || always) {
15453 synchronized (cpr) {
15454 cpr.launchingApp = null;
15457 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15458 String names[] = cpr.info.authority.split(";");
15459 for (int j = 0; j < names.length; j++) {
15460 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15464 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15465 ContentProviderConnection conn = cpr.connections.get(i);
15466 if (conn.waiting) {
15467 // If this connection is waiting for the provider, then we don't
15468 // need to mess with its process unless we are always removing
15469 // or for some reason the provider is not currently launching.
15470 if (inLaunching && !always) {
15474 ProcessRecord capp = conn.client;
15476 if (conn.stableCount > 0) {
15477 if (!capp.persistent && capp.thread != null
15479 && capp.pid != MY_PID) {
15480 capp.kill("depends on provider "
15481 + cpr.name.flattenToShortString()
15482 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15484 } else if (capp.thread != null && conn.provider.provider != null) {
15486 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15487 } catch (RemoteException e) {
15489 // In the protocol here, we don't expect the client to correctly
15490 // clean up this connection, we'll just remove it.
15491 cpr.connections.remove(i);
15492 if (conn.client.conProviders.remove(conn)) {
15493 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15498 if (inLaunching && always) {
15499 mLaunchingProviders.remove(cpr);
15501 return inLaunching;
15505 * Main code for cleaning up a process when it has gone away. This is
15506 * called both as a result of the process dying, or directly when stopping
15507 * a process when running in single process mode.
15509 * @return Returns true if the given process has been restarted, so the
15510 * app that was passed in must remain on the process lists.
15512 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15513 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
15514 Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
15516 removeLruProcessLocked(app);
15517 ProcessList.remove(app.pid);
15520 mProcessesToGc.remove(app);
15521 mPendingPssProcesses.remove(app);
15523 // Dismiss any open dialogs.
15524 if (app.crashDialog != null && !app.forceCrashReport) {
15525 app.crashDialog.dismiss();
15526 app.crashDialog = null;
15528 if (app.anrDialog != null) {
15529 app.anrDialog.dismiss();
15530 app.anrDialog = null;
15532 if (app.waitDialog != null) {
15533 app.waitDialog.dismiss();
15534 app.waitDialog = null;
15537 app.crashing = false;
15538 app.notResponding = false;
15540 app.resetPackageList(mProcessStats);
15541 app.unlinkDeathRecipient();
15542 app.makeInactive(mProcessStats);
15543 app.waitingToKill = null;
15544 app.forcingToForeground = null;
15545 updateProcessForegroundLocked(app, false, false);
15546 app.foregroundActivities = false;
15547 app.hasShownUi = false;
15548 app.treatLikeActivity = false;
15549 app.hasAboveClient = false;
15550 app.hasClientActivities = false;
15552 mServices.killServicesLocked(app, allowRestart);
15554 boolean restart = false;
15556 // Remove published content providers.
15557 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15558 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15559 final boolean always = app.bad || !allowRestart;
15560 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15561 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15562 // We left the provider in the launching list, need to
15567 cpr.provider = null;
15570 app.pubProviders.clear();
15572 // Take care of any launching providers waiting for this process.
15573 if (checkAppInLaunchingProvidersLocked(app, false)) {
15577 // Unregister from connected content providers.
15578 if (!app.conProviders.isEmpty()) {
15579 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15580 ContentProviderConnection conn = app.conProviders.get(i);
15581 conn.provider.connections.remove(conn);
15582 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15583 conn.provider.name);
15585 app.conProviders.clear();
15588 // At this point there may be remaining entries in mLaunchingProviders
15589 // where we were the only one waiting, so they are no longer of use.
15590 // Look for these and clean up if found.
15591 // XXX Commented out for now. Trying to figure out a way to reproduce
15592 // the actual situation to identify what is actually going on.
15594 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15595 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15596 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15597 synchronized (cpr) {
15598 cpr.launchingApp = null;
15605 skipCurrentReceiverLocked(app);
15607 // Unregister any receivers.
15608 for (int i = app.receivers.size() - 1; i >= 0; i--) {
15609 removeReceiverLocked(app.receivers.valueAt(i));
15611 app.receivers.clear();
15613 // If the app is undergoing backup, tell the backup manager about it
15614 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15615 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15616 + mBackupTarget.appInfo + " died during backup");
15618 IBackupManager bm = IBackupManager.Stub.asInterface(
15619 ServiceManager.getService(Context.BACKUP_SERVICE));
15620 bm.agentDisconnected(app.info.packageName);
15621 } catch (RemoteException e) {
15622 // can't happen; backup manager is local
15626 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15627 ProcessChangeItem item = mPendingProcessChanges.get(i);
15628 if (item.pid == app.pid) {
15629 mPendingProcessChanges.remove(i);
15630 mAvailProcessChanges.add(item);
15633 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15635 // If the caller is restarting this app, then leave it in its
15636 // current lists and let the caller take care of it.
15641 if (!app.persistent || app.isolated) {
15642 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15643 "Removing non-persistent process during cleanup: " + app);
15644 if (!replacingPid) {
15645 removeProcessNameLocked(app.processName, app.uid);
15647 if (mHeavyWeightProcess == app) {
15648 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15649 mHeavyWeightProcess.userId, 0));
15650 mHeavyWeightProcess = null;
15652 } else if (!app.removed) {
15653 // This app is persistent, so we need to keep its record around.
15654 // If it is not already on the pending app list, add it there
15655 // and start a new process for it.
15656 if (mPersistentStartingProcesses.indexOf(app) < 0) {
15657 mPersistentStartingProcesses.add(app);
15661 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15662 TAG_CLEANUP, "Clean-up removing on hold: " + app);
15663 mProcessesOnHold.remove(app);
15665 if (app == mHomeProcess) {
15666 mHomeProcess = null;
15668 if (app == mPreviousProcess) {
15669 mPreviousProcess = null;
15672 if (restart && !app.isolated) {
15673 // We have components that still need to be running in the
15674 // process, so re-launch it.
15676 ProcessList.remove(app.pid);
15678 addProcessNameLocked(app);
15679 startProcessLocked(app, "restart", app.processName);
15681 } else if (app.pid > 0 && app.pid != MY_PID) {
15684 synchronized (mPidsSelfLocked) {
15685 mPidsSelfLocked.remove(app.pid);
15686 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15688 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15689 if (app.isolated) {
15690 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15697 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15698 // Look through the content providers we are waiting to have launched,
15699 // and if any run in this process then either schedule a restart of
15700 // the process or kill the client waiting for it if this process has
15702 boolean restart = false;
15703 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15704 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15705 if (cpr.launchingApp == app) {
15706 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15709 removeDyingProviderLocked(app, cpr, true);
15716 // =========================================================
15718 // =========================================================
15721 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15723 enforceNotIsolatedCaller("getServices");
15724 synchronized (this) {
15725 return mServices.getRunningServiceInfoLocked(maxNum, flags);
15730 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15731 enforceNotIsolatedCaller("getRunningServiceControlPanel");
15732 synchronized (this) {
15733 return mServices.getRunningServiceControlPanelLocked(name);
15738 public ComponentName startService(IApplicationThread caller, Intent service,
15739 String resolvedType, String callingPackage, int userId)
15740 throws TransactionTooLargeException {
15741 enforceNotIsolatedCaller("startService");
15742 // Refuse possible leaked file descriptors
15743 if (service != null && service.hasFileDescriptors() == true) {
15744 throw new IllegalArgumentException("File descriptors passed in Intent");
15747 if (callingPackage == null) {
15748 throw new IllegalArgumentException("callingPackage cannot be null");
15751 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15752 "startService: " + service + " type=" + resolvedType);
15753 synchronized(this) {
15754 final int callingPid = Binder.getCallingPid();
15755 final int callingUid = Binder.getCallingUid();
15756 final long origId = Binder.clearCallingIdentity();
15757 ComponentName res = mServices.startServiceLocked(caller, service,
15758 resolvedType, callingPid, callingUid, callingPackage, userId);
15759 Binder.restoreCallingIdentity(origId);
15764 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15765 String callingPackage, int userId)
15766 throws TransactionTooLargeException {
15767 synchronized(this) {
15768 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15769 "startServiceInPackage: " + service + " type=" + resolvedType);
15770 final long origId = Binder.clearCallingIdentity();
15771 ComponentName res = mServices.startServiceLocked(null, service,
15772 resolvedType, -1, uid, callingPackage, userId);
15773 Binder.restoreCallingIdentity(origId);
15779 public int stopService(IApplicationThread caller, Intent service,
15780 String resolvedType, int userId) {
15781 enforceNotIsolatedCaller("stopService");
15782 // Refuse possible leaked file descriptors
15783 if (service != null && service.hasFileDescriptors() == true) {
15784 throw new IllegalArgumentException("File descriptors passed in Intent");
15787 synchronized(this) {
15788 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15793 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15794 enforceNotIsolatedCaller("peekService");
15795 // Refuse possible leaked file descriptors
15796 if (service != null && service.hasFileDescriptors() == true) {
15797 throw new IllegalArgumentException("File descriptors passed in Intent");
15800 if (callingPackage == null) {
15801 throw new IllegalArgumentException("callingPackage cannot be null");
15804 synchronized(this) {
15805 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15810 public boolean stopServiceToken(ComponentName className, IBinder token,
15812 synchronized(this) {
15813 return mServices.stopServiceTokenLocked(className, token, startId);
15818 public void setServiceForeground(ComponentName className, IBinder token,
15819 int id, Notification notification, boolean removeNotification) {
15820 synchronized(this) {
15821 mServices.setServiceForegroundLocked(className, token, id, notification,
15822 removeNotification);
15827 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15828 boolean requireFull, String name, String callerPackage) {
15829 return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15830 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15833 int unsafeConvertIncomingUser(int userId) {
15834 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15835 ? mCurrentUserId : userId;
15838 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15839 int allowMode, String name, String callerPackage) {
15840 final int callingUserId = UserHandle.getUserId(callingUid);
15841 if (callingUserId == userId) {
15845 // Note that we may be accessing mCurrentUserId outside of a lock...
15846 // shouldn't be a big deal, if this is being called outside
15847 // of a locked context there is intrinsically a race with
15848 // the value the caller will receive and someone else changing it.
15849 // We assume that USER_CURRENT_OR_SELF will use the current user; later
15850 // we will switch to the calling user if access to the current user fails.
15851 int targetUserId = unsafeConvertIncomingUser(userId);
15853 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15854 final boolean allow;
15855 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15856 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15857 // If the caller has this permission, they always pass go. And collect $200.
15859 } else if (allowMode == ALLOW_FULL_ONLY) {
15860 // We require full access, sucks to be you.
15862 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15863 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15864 // If the caller does not have either permission, they are always doomed.
15866 } else if (allowMode == ALLOW_NON_FULL) {
15867 // We are blanket allowing non-full access, you lucky caller!
15869 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15870 // We may or may not allow this depending on whether the two users are
15871 // in the same profile.
15872 synchronized (mUserProfileGroupIdsSelfLocked) {
15873 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15874 UserInfo.NO_PROFILE_GROUP_ID);
15875 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15876 UserInfo.NO_PROFILE_GROUP_ID);
15877 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15878 && callingProfile == targetProfile;
15881 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15884 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15885 // In this case, they would like to just execute as their
15886 // owner user instead of failing.
15887 targetUserId = callingUserId;
15889 StringBuilder builder = new StringBuilder(128);
15890 builder.append("Permission Denial: ");
15891 builder.append(name);
15892 if (callerPackage != null) {
15893 builder.append(" from ");
15894 builder.append(callerPackage);
15896 builder.append(" asks to run as user ");
15897 builder.append(userId);
15898 builder.append(" but is calling from user ");
15899 builder.append(UserHandle.getUserId(callingUid));
15900 builder.append("; this requires ");
15901 builder.append(INTERACT_ACROSS_USERS_FULL);
15902 if (allowMode != ALLOW_FULL_ONLY) {
15903 builder.append(" or ");
15904 builder.append(INTERACT_ACROSS_USERS);
15906 String msg = builder.toString();
15908 throw new SecurityException(msg);
15912 if (!allowAll && targetUserId < 0) {
15913 throw new IllegalArgumentException(
15914 "Call does not support special user #" + targetUserId);
15916 // Check shell permission
15917 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15918 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15920 throw new SecurityException("Shell does not have permission to access user "
15921 + targetUserId + "\n " + Debug.getCallers(3));
15924 return targetUserId;
15927 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15928 String className, int flags) {
15929 boolean result = false;
15930 // For apps that don't have pre-defined UIDs, check for permission
15931 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15932 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15933 if (ActivityManager.checkUidPermission(
15934 INTERACT_ACROSS_USERS,
15935 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15936 ComponentName comp = new ComponentName(aInfo.packageName, className);
15937 String msg = "Permission Denial: Component " + comp.flattenToShortString()
15938 + " requests FLAG_SINGLE_USER, but app does not hold "
15939 + INTERACT_ACROSS_USERS;
15941 throw new SecurityException(msg);
15943 // Permission passed
15946 } else if ("system".equals(componentProcessName)) {
15948 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15949 // Phone app and persistent apps are allowed to export singleuser providers.
15950 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15951 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15953 if (DEBUG_MU) Slog.v(TAG_MU,
15954 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15955 + Integer.toHexString(flags) + ") = " + result);
15960 * Checks to see if the caller is in the same app as the singleton
15961 * component, or the component is in a special app. It allows special apps
15962 * to export singleton components but prevents exporting singleton
15963 * components for regular apps.
15965 boolean isValidSingletonCall(int callingUid, int componentUid) {
15966 int componentAppId = UserHandle.getAppId(componentUid);
15967 return UserHandle.isSameApp(callingUid, componentUid)
15968 || componentAppId == Process.SYSTEM_UID
15969 || componentAppId == Process.PHONE_UID
15970 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15971 == PackageManager.PERMISSION_GRANTED;
15974 public int bindService(IApplicationThread caller, IBinder token, Intent service,
15975 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15976 int userId) throws TransactionTooLargeException {
15977 enforceNotIsolatedCaller("bindService");
15979 // Refuse possible leaked file descriptors
15980 if (service != null && service.hasFileDescriptors() == true) {
15981 throw new IllegalArgumentException("File descriptors passed in Intent");
15984 if (callingPackage == null) {
15985 throw new IllegalArgumentException("callingPackage cannot be null");
15988 synchronized(this) {
15989 return mServices.bindServiceLocked(caller, token, service,
15990 resolvedType, connection, flags, callingPackage, userId);
15994 public boolean unbindService(IServiceConnection connection) {
15995 synchronized (this) {
15996 return mServices.unbindServiceLocked(connection);
16000 public void publishService(IBinder token, Intent intent, IBinder service) {
16001 // Refuse possible leaked file descriptors
16002 if (intent != null && intent.hasFileDescriptors() == true) {
16003 throw new IllegalArgumentException("File descriptors passed in Intent");
16006 synchronized(this) {
16007 if (!(token instanceof ServiceRecord)) {
16008 throw new IllegalArgumentException("Invalid service token");
16010 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16014 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16015 // Refuse possible leaked file descriptors
16016 if (intent != null && intent.hasFileDescriptors() == true) {
16017 throw new IllegalArgumentException("File descriptors passed in Intent");
16020 synchronized(this) {
16021 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16025 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16026 synchronized(this) {
16027 if (!(token instanceof ServiceRecord)) {
16028 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16029 throw new IllegalArgumentException("Invalid service token");
16031 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16035 // =========================================================
16036 // BACKUP AND RESTORE
16037 // =========================================================
16039 // Cause the target app to be launched if necessary and its backup agent
16040 // instantiated. The backup agent will invoke backupAgentCreated() on the
16041 // activity manager to announce its creation.
16042 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
16043 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
16044 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16046 IPackageManager pm = AppGlobals.getPackageManager();
16047 ApplicationInfo app = null;
16049 app = pm.getApplicationInfo(packageName, 0, userId);
16050 } catch (RemoteException e) {
16051 // can't happen; package manager is process-local
16054 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
16058 synchronized(this) {
16059 // !!! TODO: currently no check here that we're already bound
16060 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16061 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16062 synchronized (stats) {
16063 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16066 // Backup agent is now in use, its package can't be stopped.
16068 AppGlobals.getPackageManager().setPackageStoppedState(
16069 app.packageName, false, UserHandle.getUserId(app.uid));
16070 } catch (RemoteException e) {
16071 } catch (IllegalArgumentException e) {
16072 Slog.w(TAG, "Failed trying to unstop package "
16073 + app.packageName + ": " + e);
16076 BackupRecord r = new BackupRecord(ss, app, backupMode);
16077 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16078 ? new ComponentName(app.packageName, app.backupAgentName)
16079 : new ComponentName("android", "FullBackupAgent");
16080 // startProcessLocked() returns existing proc's record if it's already running
16081 ProcessRecord proc = startProcessLocked(app.processName, app,
16082 false, 0, "backup", hostingName, false, false, false);
16083 if (proc == null) {
16084 Slog.e(TAG, "Unable to start backup agent process " + r);
16090 mBackupAppName = app.packageName;
16092 // Try not to kill the process during backup
16093 updateOomAdjLocked(proc);
16095 // If the process is already attached, schedule the creation of the backup agent now.
16096 // If it is not yet live, this will be done when it attaches to the framework.
16097 if (proc.thread != null) {
16098 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16100 proc.thread.scheduleCreateBackupAgent(app,
16101 compatibilityInfoForPackageLocked(app), backupMode);
16102 } catch (RemoteException e) {
16103 // Will time out on the backup manager side
16106 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16108 // Invariants: at this point, the target app process exists and the application
16109 // is either already running or in the process of coming up. mBackupTarget and
16110 // mBackupAppName describe the app, so that when it binds back to the AM we
16111 // know that it's scheduled for a backup-agent operation.
16118 public void clearPendingBackup() {
16119 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16120 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16122 synchronized (this) {
16123 mBackupTarget = null;
16124 mBackupAppName = null;
16128 // A backup agent has just come up
16129 public void backupAgentCreated(String agentPackageName, IBinder agent) {
16130 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16133 synchronized(this) {
16134 if (!agentPackageName.equals(mBackupAppName)) {
16135 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16140 long oldIdent = Binder.clearCallingIdentity();
16142 IBackupManager bm = IBackupManager.Stub.asInterface(
16143 ServiceManager.getService(Context.BACKUP_SERVICE));
16144 bm.agentConnected(agentPackageName, agent);
16145 } catch (RemoteException e) {
16146 // can't happen; the backup manager service is local
16147 } catch (Exception e) {
16148 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16149 e.printStackTrace();
16151 Binder.restoreCallingIdentity(oldIdent);
16155 // done with this agent
16156 public void unbindBackupAgent(ApplicationInfo appInfo) {
16157 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16158 if (appInfo == null) {
16159 Slog.w(TAG, "unbind backup agent for null app");
16163 synchronized(this) {
16165 if (mBackupAppName == null) {
16166 Slog.w(TAG, "Unbinding backup agent with no active backup");
16170 if (!mBackupAppName.equals(appInfo.packageName)) {
16171 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16175 // Not backing this app up any more; reset its OOM adjustment
16176 final ProcessRecord proc = mBackupTarget.app;
16177 updateOomAdjLocked(proc);
16179 // If the app crashed during backup, 'thread' will be null here
16180 if (proc.thread != null) {
16182 proc.thread.scheduleDestroyBackupAgent(appInfo,
16183 compatibilityInfoForPackageLocked(appInfo));
16184 } catch (Exception e) {
16185 Slog.e(TAG, "Exception when unbinding backup agent:");
16186 e.printStackTrace();
16190 mBackupTarget = null;
16191 mBackupAppName = null;
16195 // =========================================================
16197 // =========================================================
16199 boolean isPendingBroadcastProcessLocked(int pid) {
16200 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16201 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16204 void skipPendingBroadcastLocked(int pid) {
16205 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16206 for (BroadcastQueue queue : mBroadcastQueues) {
16207 queue.skipPendingBroadcastLocked(pid);
16211 // The app just attached; send any pending broadcasts that it should receive
16212 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16213 boolean didSomething = false;
16214 for (BroadcastQueue queue : mBroadcastQueues) {
16215 didSomething |= queue.sendPendingBroadcastsLocked(app);
16217 return didSomething;
16220 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16221 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16222 enforceNotIsolatedCaller("registerReceiver");
16223 ArrayList<Intent> stickyIntents = null;
16224 ProcessRecord callerApp = null;
16227 synchronized(this) {
16228 if (caller != null) {
16229 callerApp = getRecordForAppLocked(caller);
16230 if (callerApp == null) {
16231 throw new SecurityException(
16232 "Unable to find app for caller " + caller
16233 + " (pid=" + Binder.getCallingPid()
16234 + ") when registering receiver " + receiver);
16236 if (callerApp.info.uid != Process.SYSTEM_UID &&
16237 !callerApp.pkgList.containsKey(callerPackage) &&
16238 !"android".equals(callerPackage)) {
16239 throw new SecurityException("Given caller package " + callerPackage
16240 + " is not running in process " + callerApp);
16242 callingUid = callerApp.info.uid;
16243 callingPid = callerApp.pid;
16245 callerPackage = null;
16246 callingUid = Binder.getCallingUid();
16247 callingPid = Binder.getCallingPid();
16250 userId = handleIncomingUser(callingPid, callingUid, userId,
16251 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16253 Iterator<String> actions = filter.actionsIterator();
16254 if (actions == null) {
16255 ArrayList<String> noAction = new ArrayList<String>(1);
16256 noAction.add(null);
16257 actions = noAction.iterator();
16260 // Collect stickies of users
16261 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16262 while (actions.hasNext()) {
16263 String action = actions.next();
16264 for (int id : userIds) {
16265 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16266 if (stickies != null) {
16267 ArrayList<Intent> intents = stickies.get(action);
16268 if (intents != null) {
16269 if (stickyIntents == null) {
16270 stickyIntents = new ArrayList<Intent>();
16272 stickyIntents.addAll(intents);
16279 ArrayList<Intent> allSticky = null;
16280 if (stickyIntents != null) {
16281 final ContentResolver resolver = mContext.getContentResolver();
16282 // Look for any matching sticky broadcasts...
16283 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16284 Intent intent = stickyIntents.get(i);
16285 // If intent has scheme "content", it will need to acccess
16286 // provider that needs to lock mProviderMap in ActivityThread
16287 // and also it may need to wait application response, so we
16288 // cannot lock ActivityManagerService here.
16289 if (filter.match(resolver, intent, true, TAG) >= 0) {
16290 if (allSticky == null) {
16291 allSticky = new ArrayList<Intent>();
16293 allSticky.add(intent);
16298 // The first sticky in the list is returned directly back to the client.
16299 Intent sticky = allSticky != null ? allSticky.get(0) : null;
16300 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16301 if (receiver == null) {
16305 synchronized (this) {
16306 if (callerApp != null && (callerApp.thread == null
16307 || callerApp.thread.asBinder() != caller.asBinder())) {
16308 // Original caller already died
16311 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16313 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16315 if (rl.app != null) {
16316 rl.app.receivers.add(rl);
16319 receiver.asBinder().linkToDeath(rl, 0);
16320 } catch (RemoteException e) {
16323 rl.linkedToDeath = true;
16325 mRegisteredReceivers.put(receiver.asBinder(), rl);
16326 } else if (rl.uid != callingUid) {
16327 throw new IllegalArgumentException(
16328 "Receiver requested to register for uid " + callingUid
16329 + " was previously registered for uid " + rl.uid);
16330 } else if (rl.pid != callingPid) {
16331 throw new IllegalArgumentException(
16332 "Receiver requested to register for pid " + callingPid
16333 + " was previously registered for pid " + rl.pid);
16334 } else if (rl.userId != userId) {
16335 throw new IllegalArgumentException(
16336 "Receiver requested to register for user " + userId
16337 + " was previously registered for user " + rl.userId);
16339 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16340 permission, callingUid, userId);
16342 if (!bf.debugCheck()) {
16343 Slog.w(TAG, "==> For Dynamic broadcast");
16345 mReceiverResolver.addFilter(bf);
16347 // Enqueue broadcasts for all existing stickies that match
16349 if (allSticky != null) {
16350 ArrayList receivers = new ArrayList();
16353 final int stickyCount = allSticky.size();
16354 for (int i = 0; i < stickyCount; i++) {
16355 Intent intent = allSticky.get(i);
16356 BroadcastQueue queue = broadcastQueueForIntent(intent);
16357 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16358 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16359 null, 0, null, null, false, true, true, -1);
16360 queue.enqueueParallelBroadcastLocked(r);
16361 queue.scheduleBroadcastsLocked();
16369 public void unregisterReceiver(IIntentReceiver receiver) {
16370 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16372 final long origId = Binder.clearCallingIdentity();
16374 boolean doTrim = false;
16376 synchronized(this) {
16377 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16379 final BroadcastRecord r = rl.curBroadcast;
16380 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16381 final boolean doNext = r.queue.finishReceiverLocked(
16382 r, r.resultCode, r.resultData, r.resultExtras,
16383 r.resultAbort, false);
16386 r.queue.processNextBroadcast(false);
16390 if (rl.app != null) {
16391 rl.app.receivers.remove(rl);
16393 removeReceiverLocked(rl);
16394 if (rl.linkedToDeath) {
16395 rl.linkedToDeath = false;
16396 rl.receiver.asBinder().unlinkToDeath(rl, 0);
16401 // If we actually concluded any broadcasts, we might now be able
16402 // to trim the recipients' apps from our working set
16404 trimApplications();
16409 Binder.restoreCallingIdentity(origId);
16413 void removeReceiverLocked(ReceiverList rl) {
16414 mRegisteredReceivers.remove(rl.receiver.asBinder());
16415 for (int i = rl.size() - 1; i >= 0; i--) {
16416 mReceiverResolver.removeFilter(rl.get(i));
16420 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16421 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16422 ProcessRecord r = mLruProcesses.get(i);
16423 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16425 r.thread.dispatchPackageBroadcast(cmd, packages);
16426 } catch (RemoteException ex) {
16432 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16433 int callingUid, int[] users) {
16434 List<ResolveInfo> receivers = null;
16436 HashSet<ComponentName> singleUserReceivers = null;
16437 boolean scannedFirstReceivers = false;
16438 for (int user : users) {
16439 // Skip users that have Shell restrictions
16440 if (callingUid == Process.SHELL_UID
16441 && getUserManagerLocked().hasUserRestriction(
16442 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16445 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16446 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16447 if (user != UserHandle.USER_OWNER && newReceivers != null) {
16448 // If this is not the primary user, we need to check for
16449 // any receivers that should be filtered out.
16450 for (int i=0; i<newReceivers.size(); i++) {
16451 ResolveInfo ri = newReceivers.get(i);
16452 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16453 newReceivers.remove(i);
16458 if (newReceivers != null && newReceivers.size() == 0) {
16459 newReceivers = null;
16461 if (receivers == null) {
16462 receivers = newReceivers;
16463 } else if (newReceivers != null) {
16464 // We need to concatenate the additional receivers
16465 // found with what we have do far. This would be easy,
16466 // but we also need to de-dup any receivers that are
16468 if (!scannedFirstReceivers) {
16469 // Collect any single user receivers we had already retrieved.
16470 scannedFirstReceivers = true;
16471 for (int i=0; i<receivers.size(); i++) {
16472 ResolveInfo ri = receivers.get(i);
16473 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16474 ComponentName cn = new ComponentName(
16475 ri.activityInfo.packageName, ri.activityInfo.name);
16476 if (singleUserReceivers == null) {
16477 singleUserReceivers = new HashSet<ComponentName>();
16479 singleUserReceivers.add(cn);
16483 // Add the new results to the existing results, tracking
16484 // and de-dupping single user receivers.
16485 for (int i=0; i<newReceivers.size(); i++) {
16486 ResolveInfo ri = newReceivers.get(i);
16487 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16488 ComponentName cn = new ComponentName(
16489 ri.activityInfo.packageName, ri.activityInfo.name);
16490 if (singleUserReceivers == null) {
16491 singleUserReceivers = new HashSet<ComponentName>();
16493 if (!singleUserReceivers.contains(cn)) {
16494 singleUserReceivers.add(cn);
16503 } catch (RemoteException ex) {
16504 // pm is in same process, this will never happen.
16509 private final int broadcastIntentLocked(ProcessRecord callerApp,
16510 String callerPackage, Intent intent, String resolvedType,
16511 IIntentReceiver resultTo, int resultCode, String resultData,
16512 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16513 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16514 intent = new Intent(intent);
16516 // By default broadcasts do not go to stopped apps.
16517 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16519 // If we have not finished booting, don't allow this to launch new processes.
16520 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16521 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16524 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16525 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16526 + " ordered=" + ordered + " userid=" + userId);
16527 if ((resultTo != null) && !ordered) {
16528 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16531 userId = handleIncomingUser(callingPid, callingUid, userId,
16532 true, ALLOW_NON_FULL, "broadcast", callerPackage);
16534 // Make sure that the user who is receiving this broadcast is running.
16535 // If not, we will just skip it. Make an exception for shutdown broadcasts
16536 // and upgrade steps.
16538 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16539 if ((callingUid != Process.SYSTEM_UID
16540 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16541 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16542 Slog.w(TAG, "Skipping broadcast of " + intent
16543 + ": user " + userId + " is stopped");
16544 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16548 BroadcastOptions brOptions = null;
16549 if (options != null) {
16550 brOptions = new BroadcastOptions(options);
16551 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16552 // See if the caller is allowed to do this. Note we are checking against
16553 // the actual real caller (not whoever provided the operation as say a
16554 // PendingIntent), because that who is actually supplied the arguments.
16555 if (checkComponentPermission(
16556 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16557 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16558 != PackageManager.PERMISSION_GRANTED) {
16559 String msg = "Permission Denial: " + intent.getAction()
16560 + " broadcast from " + callerPackage + " (pid=" + callingPid
16561 + ", uid=" + callingUid + ")"
16563 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16565 throw new SecurityException(msg);
16571 * Prevent non-system code (defined here to be non-persistent
16572 * processes) from sending protected broadcasts.
16574 int callingAppId = UserHandle.getAppId(callingUid);
16575 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16576 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16577 || callingAppId == Process.NFC_UID || callingUid == 0) {
16579 } else if (callerApp == null || !callerApp.persistent) {
16581 if (AppGlobals.getPackageManager().isProtectedBroadcast(
16582 intent.getAction())) {
16583 String msg = "Permission Denial: not allowed to send broadcast "
16584 + intent.getAction() + " from pid="
16585 + callingPid + ", uid=" + callingUid;
16587 throw new SecurityException(msg);
16588 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16589 // Special case for compatibility: we don't want apps to send this,
16590 // but historically it has not been protected and apps may be using it
16591 // to poke their own app widget. So, instead of making it protected,
16592 // just limit it to the caller.
16593 if (callerApp == null) {
16594 String msg = "Permission Denial: not allowed to send broadcast "
16595 + intent.getAction() + " from unknown caller.";
16597 throw new SecurityException(msg);
16598 } else if (intent.getComponent() != null) {
16599 // They are good enough to send to an explicit component... verify
16600 // it is being sent to the calling app.
16601 if (!intent.getComponent().getPackageName().equals(
16602 callerApp.info.packageName)) {
16603 String msg = "Permission Denial: not allowed to send broadcast "
16604 + intent.getAction() + " to "
16605 + intent.getComponent().getPackageName() + " from "
16606 + callerApp.info.packageName;
16608 throw new SecurityException(msg);
16611 // Limit broadcast to their own package.
16612 intent.setPackage(callerApp.info.packageName);
16615 } catch (RemoteException e) {
16616 Slog.w(TAG, "Remote exception", e);
16617 return ActivityManager.BROADCAST_SUCCESS;
16621 final String action = intent.getAction();
16622 if (action != null) {
16624 case Intent.ACTION_UID_REMOVED:
16625 case Intent.ACTION_PACKAGE_REMOVED:
16626 case Intent.ACTION_PACKAGE_CHANGED:
16627 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16628 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16629 // Handle special intents: if this broadcast is from the package
16630 // manager about a package being removed, we need to remove all of
16631 // its activities from the history stack.
16632 if (checkComponentPermission(
16633 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16634 callingPid, callingUid, -1, true)
16635 != PackageManager.PERMISSION_GRANTED) {
16636 String msg = "Permission Denial: " + intent.getAction()
16637 + " broadcast from " + callerPackage + " (pid=" + callingPid
16638 + ", uid=" + callingUid + ")"
16640 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16642 throw new SecurityException(msg);
16645 case Intent.ACTION_UID_REMOVED:
16646 final Bundle intentExtras = intent.getExtras();
16647 final int uid = intentExtras != null
16648 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16650 mBatteryStatsService.removeUid(uid);
16651 mAppOpsService.uidRemoved(uid);
16654 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16655 // If resources are unavailable just force stop all those packages
16656 // and flush the attribute cache as well.
16658 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16659 if (list != null && list.length > 0) {
16660 for (int i = 0; i < list.length; i++) {
16661 forceStopPackageLocked(list[i], -1, false, true, true,
16662 false, false, userId, "storage unmount");
16664 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16665 sendPackageBroadcastLocked(
16666 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16670 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16671 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16673 case Intent.ACTION_PACKAGE_REMOVED:
16674 case Intent.ACTION_PACKAGE_CHANGED:
16675 Uri data = intent.getData();
16677 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16678 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16679 boolean fullUninstall = removed &&
16680 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16681 final boolean killProcess =
16682 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16684 forceStopPackageLocked(ssp, UserHandle.getAppId(
16685 intent.getIntExtra(Intent.EXTRA_UID, -1)),
16686 false, true, true, false, fullUninstall, userId,
16687 removed ? "pkg removed" : "pkg changed");
16690 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16691 new String[] {ssp}, userId);
16692 if (fullUninstall) {
16693 mAppOpsService.packageRemoved(
16694 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16696 // Remove all permissions granted from/to this package
16697 removeUriPermissionsForPackageLocked(ssp, userId, true);
16699 removeTasksByPackageNameLocked(ssp, userId);
16700 mBatteryStatsService.notePackageUninstalled(ssp);
16703 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16704 intent.getStringArrayExtra(
16705 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16711 case Intent.ACTION_PACKAGE_ADDED:
16712 // Special case for adding a package: by default turn on compatibility mode.
16713 Uri data = intent.getData();
16715 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16716 final boolean replacing =
16717 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16718 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16721 ApplicationInfo ai = AppGlobals.getPackageManager().
16722 getApplicationInfo(ssp, 0, 0);
16723 mBatteryStatsService.notePackageInstalled(ssp,
16724 ai != null ? ai.versionCode : 0);
16725 } catch (RemoteException e) {
16729 case Intent.ACTION_TIMEZONE_CHANGED:
16730 // If this is the time zone changed action, queue up a message that will reset
16731 // the timezone of all currently running processes. This message will get
16732 // queued up before the broadcast happens.
16733 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16735 case Intent.ACTION_TIME_CHANGED:
16736 // If the user set the time, let all running processes know.
16737 final int is24Hour =
16738 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16740 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16741 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16742 synchronized (stats) {
16743 stats.noteCurrentTimeChangedLocked();
16746 case Intent.ACTION_CLEAR_DNS_CACHE:
16747 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16749 case Proxy.PROXY_CHANGE_ACTION:
16750 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16751 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16756 // Add to the sticky list if requested.
16758 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16759 callingPid, callingUid)
16760 != PackageManager.PERMISSION_GRANTED) {
16761 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16762 + callingPid + ", uid=" + callingUid
16763 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16765 throw new SecurityException(msg);
16767 if (requiredPermissions != null && requiredPermissions.length > 0) {
16768 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16769 + " and enforce permissions " + Arrays.toString(requiredPermissions));
16770 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16772 if (intent.getComponent() != null) {
16773 throw new SecurityException(
16774 "Sticky broadcasts can't target a specific component");
16776 // We use userId directly here, since the "all" target is maintained
16777 // as a separate set of sticky broadcasts.
16778 if (userId != UserHandle.USER_ALL) {
16779 // But first, if this is not a broadcast to all users, then
16780 // make sure it doesn't conflict with an existing broadcast to
16782 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16783 UserHandle.USER_ALL);
16784 if (stickies != null) {
16785 ArrayList<Intent> list = stickies.get(intent.getAction());
16786 if (list != null) {
16787 int N = list.size();
16789 for (i=0; i<N; i++) {
16790 if (intent.filterEquals(list.get(i))) {
16791 throw new IllegalArgumentException(
16792 "Sticky broadcast " + intent + " for user "
16793 + userId + " conflicts with existing global broadcast");
16799 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16800 if (stickies == null) {
16801 stickies = new ArrayMap<>();
16802 mStickyBroadcasts.put(userId, stickies);
16804 ArrayList<Intent> list = stickies.get(intent.getAction());
16805 if (list == null) {
16806 list = new ArrayList<>();
16807 stickies.put(intent.getAction(), list);
16809 final int stickiesCount = list.size();
16811 for (i = 0; i < stickiesCount; i++) {
16812 if (intent.filterEquals(list.get(i))) {
16813 // This sticky already exists, replace it.
16814 list.set(i, new Intent(intent));
16818 if (i >= stickiesCount) {
16819 list.add(new Intent(intent));
16824 if (userId == UserHandle.USER_ALL) {
16825 // Caller wants broadcast to go to all started users.
16826 users = mStartedUserArray;
16828 // Caller wants broadcast to go to one specific user.
16829 users = new int[] {userId};
16832 // Figure out who all will receive this broadcast.
16833 List receivers = null;
16834 List<BroadcastFilter> registeredReceivers = null;
16835 // Need to resolve the intent to interested receivers...
16836 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16838 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16840 if (intent.getComponent() == null) {
16841 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16842 // Query one target user at a time, excluding shell-restricted users
16843 UserManagerService ums = getUserManagerLocked();
16844 for (int i = 0; i < users.length; i++) {
16845 if (ums.hasUserRestriction(
16846 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16849 List<BroadcastFilter> registeredReceiversForUser =
16850 mReceiverResolver.queryIntent(intent,
16851 resolvedType, false, users[i]);
16852 if (registeredReceivers == null) {
16853 registeredReceivers = registeredReceiversForUser;
16854 } else if (registeredReceiversForUser != null) {
16855 registeredReceivers.addAll(registeredReceiversForUser);
16859 registeredReceivers = mReceiverResolver.queryIntent(intent,
16860 resolvedType, false, userId);
16864 final boolean replacePending =
16865 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16867 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16868 + " replacePending=" + replacePending);
16870 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16871 if (!ordered && NR > 0) {
16872 // If we are not serializing this broadcast, then send the
16873 // registered receivers separately so they don't wait for the
16874 // components to be launched.
16875 final BroadcastQueue queue = broadcastQueueForIntent(intent);
16876 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16877 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16878 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16879 resultExtras, ordered, sticky, false, userId);
16880 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16881 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16883 queue.enqueueParallelBroadcastLocked(r);
16884 queue.scheduleBroadcastsLocked();
16886 registeredReceivers = null;
16890 // Merge into one list.
16892 if (receivers != null) {
16893 // A special case for PACKAGE_ADDED: do not allow the package
16894 // being added to see this broadcast. This prevents them from
16895 // using this as a back door to get run as soon as they are
16896 // installed. Maybe in the future we want to have a special install
16897 // broadcast or such for apps, but we'd like to deliberately make
16899 String skipPackages[] = null;
16900 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16901 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16902 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16903 Uri data = intent.getData();
16904 if (data != null) {
16905 String pkgName = data.getSchemeSpecificPart();
16906 if (pkgName != null) {
16907 skipPackages = new String[] { pkgName };
16910 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16911 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16913 if (skipPackages != null && (skipPackages.length > 0)) {
16914 for (String skipPackage : skipPackages) {
16915 if (skipPackage != null) {
16916 int NT = receivers.size();
16917 for (int it=0; it<NT; it++) {
16918 ResolveInfo curt = (ResolveInfo)receivers.get(it);
16919 if (curt.activityInfo.packageName.equals(skipPackage)) {
16920 receivers.remove(it);
16929 int NT = receivers != null ? receivers.size() : 0;
16931 ResolveInfo curt = null;
16932 BroadcastFilter curr = null;
16933 while (it < NT && ir < NR) {
16934 if (curt == null) {
16935 curt = (ResolveInfo)receivers.get(it);
16937 if (curr == null) {
16938 curr = registeredReceivers.get(ir);
16940 if (curr.getPriority() >= curt.priority) {
16941 // Insert this broadcast record into the final list.
16942 receivers.add(it, curr);
16948 // Skip to the next ResolveInfo in the final list.
16955 if (receivers == null) {
16956 receivers = new ArrayList();
16958 receivers.add(registeredReceivers.get(ir));
16962 if ((receivers != null && receivers.size() > 0)
16963 || resultTo != null) {
16964 BroadcastQueue queue = broadcastQueueForIntent(intent);
16965 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16966 callerPackage, callingPid, callingUid, resolvedType,
16967 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16968 resultData, resultExtras, ordered, sticky, false, userId);
16970 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16971 + ": prev had " + queue.mOrderedBroadcasts.size());
16972 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16973 "Enqueueing broadcast " + r.intent.getAction());
16975 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16977 queue.enqueueOrderedBroadcastLocked(r);
16978 queue.scheduleBroadcastsLocked();
16982 return ActivityManager.BROADCAST_SUCCESS;
16985 final Intent verifyBroadcastLocked(Intent intent) {
16986 // Refuse possible leaked file descriptors
16987 if (intent != null && intent.hasFileDescriptors() == true) {
16988 throw new IllegalArgumentException("File descriptors passed in Intent");
16991 int flags = intent.getFlags();
16993 if (!mProcessesReady) {
16994 // if the caller really truly claims to know what they're doing, go
16995 // ahead and allow the broadcast without launching any receivers
16996 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16997 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16998 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16999 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17000 + " before boot completion");
17001 throw new IllegalStateException("Cannot broadcast before boot completed");
17005 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17006 throw new IllegalArgumentException(
17007 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17013 public final int broadcastIntent(IApplicationThread caller,
17014 Intent intent, String resolvedType, IIntentReceiver resultTo,
17015 int resultCode, String resultData, Bundle resultExtras,
17016 String[] requiredPermissions, int appOp, Bundle options,
17017 boolean serialized, boolean sticky, int userId) {
17018 enforceNotIsolatedCaller("broadcastIntent");
17019 synchronized(this) {
17020 intent = verifyBroadcastLocked(intent);
17022 final ProcessRecord callerApp = getRecordForAppLocked(caller);
17023 final int callingPid = Binder.getCallingPid();
17024 final int callingUid = Binder.getCallingUid();
17025 final long origId = Binder.clearCallingIdentity();
17026 int res = broadcastIntentLocked(callerApp,
17027 callerApp != null ? callerApp.info.packageName : null,
17028 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17029 requiredPermissions, appOp, null, serialized, sticky,
17030 callingPid, callingUid, userId);
17031 Binder.restoreCallingIdentity(origId);
17037 int broadcastIntentInPackage(String packageName, int uid,
17038 Intent intent, String resolvedType, IIntentReceiver resultTo,
17039 int resultCode, String resultData, Bundle resultExtras,
17040 String requiredPermission, Bundle options, boolean serialized, boolean sticky,
17042 synchronized(this) {
17043 intent = verifyBroadcastLocked(intent);
17045 final long origId = Binder.clearCallingIdentity();
17046 String[] requiredPermissions = requiredPermission == null ? null
17047 : new String[] {requiredPermission};
17048 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17049 resultTo, resultCode, resultData, resultExtras,
17050 requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
17051 sticky, -1, uid, userId);
17052 Binder.restoreCallingIdentity(origId);
17057 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17058 // Refuse possible leaked file descriptors
17059 if (intent != null && intent.hasFileDescriptors() == true) {
17060 throw new IllegalArgumentException("File descriptors passed in Intent");
17063 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17064 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17066 synchronized(this) {
17067 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17068 != PackageManager.PERMISSION_GRANTED) {
17069 String msg = "Permission Denial: unbroadcastIntent() from pid="
17070 + Binder.getCallingPid()
17071 + ", uid=" + Binder.getCallingUid()
17072 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17074 throw new SecurityException(msg);
17076 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17077 if (stickies != null) {
17078 ArrayList<Intent> list = stickies.get(intent.getAction());
17079 if (list != null) {
17080 int N = list.size();
17082 for (i=0; i<N; i++) {
17083 if (intent.filterEquals(list.get(i))) {
17088 if (list.size() <= 0) {
17089 stickies.remove(intent.getAction());
17092 if (stickies.size() <= 0) {
17093 mStickyBroadcasts.remove(userId);
17099 void backgroundServicesFinishedLocked(int userId) {
17100 for (BroadcastQueue queue : mBroadcastQueues) {
17101 queue.backgroundServicesFinishedLocked(userId);
17105 public void finishReceiver(IBinder who, int resultCode, String resultData,
17106 Bundle resultExtras, boolean resultAbort, int flags) {
17107 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17109 // Refuse possible leaked file descriptors
17110 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17111 throw new IllegalArgumentException("File descriptors passed in Bundle");
17114 final long origId = Binder.clearCallingIdentity();
17116 boolean doNext = false;
17119 synchronized(this) {
17120 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17121 ? mFgBroadcastQueue : mBgBroadcastQueue;
17122 r = queue.getMatchingOrderedReceiver(who);
17124 doNext = r.queue.finishReceiverLocked(r, resultCode,
17125 resultData, resultExtras, resultAbort, true);
17130 r.queue.processNextBroadcast(false);
17132 trimApplications();
17134 Binder.restoreCallingIdentity(origId);
17138 // =========================================================
17140 // =========================================================
17142 public boolean startInstrumentation(ComponentName className,
17143 String profileFile, int flags, Bundle arguments,
17144 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17145 int userId, String abiOverride) {
17146 enforceNotIsolatedCaller("startInstrumentation");
17147 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17148 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17149 // Refuse possible leaked file descriptors
17150 if (arguments != null && arguments.hasFileDescriptors()) {
17151 throw new IllegalArgumentException("File descriptors passed in Bundle");
17154 synchronized(this) {
17155 InstrumentationInfo ii = null;
17156 ApplicationInfo ai = null;
17158 ii = mContext.getPackageManager().getInstrumentationInfo(
17159 className, STOCK_PM_FLAGS);
17160 ai = AppGlobals.getPackageManager().getApplicationInfo(
17161 ii.targetPackage, STOCK_PM_FLAGS, userId);
17162 } catch (PackageManager.NameNotFoundException e) {
17163 } catch (RemoteException e) {
17166 reportStartInstrumentationFailure(watcher, className,
17167 "Unable to find instrumentation info for: " + className);
17171 reportStartInstrumentationFailure(watcher, className,
17172 "Unable to find instrumentation target package: " + ii.targetPackage);
17176 int match = mContext.getPackageManager().checkSignatures(
17177 ii.targetPackage, ii.packageName);
17178 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17179 String msg = "Permission Denial: starting instrumentation "
17180 + className + " from pid="
17181 + Binder.getCallingPid()
17182 + ", uid=" + Binder.getCallingPid()
17183 + " not allowed because package " + ii.packageName
17184 + " does not have a signature matching the target "
17185 + ii.targetPackage;
17186 reportStartInstrumentationFailure(watcher, className, msg);
17187 throw new SecurityException(msg);
17190 final long origId = Binder.clearCallingIdentity();
17191 // Instrumentation can kill and relaunch even persistent processes
17192 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17194 ProcessRecord app = addAppLocked(ai, false, abiOverride);
17195 app.instrumentationClass = className;
17196 app.instrumentationInfo = ai;
17197 app.instrumentationProfileFile = profileFile;
17198 app.instrumentationArguments = arguments;
17199 app.instrumentationWatcher = watcher;
17200 app.instrumentationUiAutomationConnection = uiAutomationConnection;
17201 app.instrumentationResultClass = className;
17202 Binder.restoreCallingIdentity(origId);
17209 * Report errors that occur while attempting to start Instrumentation. Always writes the
17210 * error to the logs, but if somebody is watching, send the report there too. This enables
17211 * the "am" command to report errors with more information.
17213 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
17214 * @param cn The component name of the instrumentation.
17215 * @param report The error report.
17217 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17218 ComponentName cn, String report) {
17219 Slog.w(TAG, report);
17221 if (watcher != null) {
17222 Bundle results = new Bundle();
17223 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17224 results.putString("Error", report);
17225 watcher.instrumentationStatus(cn, -1, results);
17227 } catch (RemoteException e) {
17232 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17233 if (app.instrumentationWatcher != null) {
17235 // NOTE: IInstrumentationWatcher *must* be oneway here
17236 app.instrumentationWatcher.instrumentationFinished(
17237 app.instrumentationClass,
17240 } catch (RemoteException e) {
17244 // Can't call out of the system process with a lock held, so post a message.
17245 if (app.instrumentationUiAutomationConnection != null) {
17246 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17247 app.instrumentationUiAutomationConnection).sendToTarget();
17250 app.instrumentationWatcher = null;
17251 app.instrumentationUiAutomationConnection = null;
17252 app.instrumentationClass = null;
17253 app.instrumentationInfo = null;
17254 app.instrumentationProfileFile = null;
17255 app.instrumentationArguments = null;
17257 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17261 public void finishInstrumentation(IApplicationThread target,
17262 int resultCode, Bundle results) {
17263 int userId = UserHandle.getCallingUserId();
17264 // Refuse possible leaked file descriptors
17265 if (results != null && results.hasFileDescriptors()) {
17266 throw new IllegalArgumentException("File descriptors passed in Intent");
17269 synchronized(this) {
17270 ProcessRecord app = getRecordForAppLocked(target);
17272 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17275 final long origId = Binder.clearCallingIdentity();
17276 finishInstrumentationLocked(app, resultCode, results);
17277 Binder.restoreCallingIdentity(origId);
17281 // =========================================================
17283 // =========================================================
17285 public ConfigurationInfo getDeviceConfigurationInfo() {
17286 ConfigurationInfo config = new ConfigurationInfo();
17287 synchronized (this) {
17288 config.reqTouchScreen = mConfiguration.touchscreen;
17289 config.reqKeyboardType = mConfiguration.keyboard;
17290 config.reqNavigation = mConfiguration.navigation;
17291 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17292 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17293 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17295 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17296 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17297 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17299 config.reqGlEsVersion = GL_ES_VERSION;
17304 ActivityStack getFocusedStack() {
17305 return mStackSupervisor.getFocusedStack();
17309 public int getFocusedStackId() throws RemoteException {
17310 ActivityStack focusedStack = getFocusedStack();
17311 if (focusedStack != null) {
17312 return focusedStack.getStackId();
17317 public Configuration getConfiguration() {
17319 synchronized(this) {
17320 ci = new Configuration(mConfiguration);
17321 ci.userSetLocale = false;
17326 public void updatePersistentConfiguration(Configuration values) {
17327 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17328 "updateConfiguration()");
17329 enforceWriteSettingsPermission("updateConfiguration()");
17330 if (values == null) {
17331 throw new NullPointerException("Configuration must not be null");
17334 synchronized(this) {
17335 final long origId = Binder.clearCallingIdentity();
17336 updateConfigurationLocked(values, null, true, false);
17337 Binder.restoreCallingIdentity(origId);
17341 private void enforceWriteSettingsPermission(String func) {
17342 int uid = Binder.getCallingUid();
17343 if (uid == Process.ROOT_UID) {
17347 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17348 Settings.getPackageNameForUid(mContext, uid), false)) {
17352 String msg = "Permission Denial: " + func + " from pid="
17353 + Binder.getCallingPid()
17355 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17357 throw new SecurityException(msg);
17360 public void updateConfiguration(Configuration values) {
17361 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17362 "updateConfiguration()");
17364 synchronized(this) {
17365 if (values == null && mWindowManager != null) {
17366 // sentinel: fetch the current configuration from the window manager
17367 values = mWindowManager.computeNewConfiguration();
17370 if (mWindowManager != null) {
17371 mProcessList.applyDisplaySize(mWindowManager);
17374 final long origId = Binder.clearCallingIdentity();
17375 if (values != null) {
17376 Settings.System.clearConfiguration(values);
17378 updateConfigurationLocked(values, null, false, false);
17379 Binder.restoreCallingIdentity(origId);
17384 * Do either or both things: (1) change the current configuration, and (2)
17385 * make sure the given activity is running with the (now) current
17386 * configuration. Returns true if the activity has been left running, or
17387 * false if <var>starting</var> is being destroyed to match the new
17389 * @param persistent TODO
17391 boolean updateConfigurationLocked(Configuration values,
17392 ActivityRecord starting, boolean persistent, boolean initLocale) {
17395 if (values != null) {
17396 Configuration newConfig = new Configuration(mConfiguration);
17397 changes = newConfig.updateFrom(values);
17398 if (changes != 0) {
17399 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17400 "Updating configuration to: " + values);
17402 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17404 if (!initLocale && values.locale != null && values.userSetLocale) {
17405 final String languageTag = values.locale.toLanguageTag();
17406 SystemProperties.set("persist.sys.locale", languageTag);
17407 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17411 mConfigurationSeq++;
17412 if (mConfigurationSeq <= 0) {
17413 mConfigurationSeq = 1;
17415 newConfig.seq = mConfigurationSeq;
17416 mConfiguration = newConfig;
17417 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17418 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17419 //mUsageStatsService.noteStartConfig(newConfig);
17421 final Configuration configCopy = new Configuration(mConfiguration);
17423 // TODO: If our config changes, should we auto dismiss any currently
17424 // showing dialogs?
17425 mShowDialogs = shouldShowDialogs(newConfig);
17427 AttributeCache ac = AttributeCache.instance();
17429 ac.updateConfiguration(configCopy);
17432 // Make sure all resources in our process are updated
17433 // right now, so that anyone who is going to retrieve
17434 // resource values after we return will be sure to get
17435 // the new ones. This is especially important during
17436 // boot, where the first config change needs to guarantee
17437 // all resources have that config before following boot
17438 // code is executed.
17439 mSystemThread.applyConfigurationToResources(configCopy);
17441 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17442 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17443 msg.obj = new Configuration(configCopy);
17444 mHandler.sendMessage(msg);
17447 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17448 ProcessRecord app = mLruProcesses.get(i);
17450 if (app.thread != null) {
17451 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17452 + app.processName + " new config " + mConfiguration);
17453 app.thread.scheduleConfigurationChanged(configCopy);
17455 } catch (Exception e) {
17458 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17459 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17460 | Intent.FLAG_RECEIVER_REPLACE_PENDING
17461 | Intent.FLAG_RECEIVER_FOREGROUND);
17462 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17463 null, AppOpsManager.OP_NONE, null, false, false,
17464 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17465 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17466 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17467 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17468 if (!mProcessesReady) {
17469 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17471 broadcastIntentLocked(null, null, intent,
17472 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17473 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17478 boolean kept = true;
17479 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17480 // mainStack is null during startup.
17481 if (mainStack != null) {
17482 if (changes != 0 && starting == null) {
17483 // If the configuration changed, and the caller is not already
17484 // in the process of starting an activity, then find the top
17485 // activity to check if its configuration needs to change.
17486 starting = mainStack.topRunningActivityLocked(null);
17489 if (starting != null) {
17490 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17491 // And we need to make sure at this point that all other activities
17492 // are made visible with the correct configuration.
17493 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17497 if (values != null && mWindowManager != null) {
17498 mWindowManager.setNewConfiguration(mConfiguration);
17505 * Decide based on the configuration whether we should shouw the ANR,
17506 * crash, etc dialogs. The idea is that if there is no affordnace to
17507 * press the on-screen buttons, we shouldn't show the dialog.
17509 * A thought: SystemUI might also want to get told about this, the Power
17510 * dialog / global actions also might want different behaviors.
17512 private static final boolean shouldShowDialogs(Configuration config) {
17513 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17514 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17515 && config.navigation == Configuration.NAVIGATION_NONAV);
17519 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17520 synchronized (this) {
17521 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17522 if (srec != null) {
17523 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17529 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17530 Intent resultData) {
17532 synchronized (this) {
17533 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17535 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17541 public int getLaunchedFromUid(IBinder activityToken) {
17542 ActivityRecord srec;
17543 synchronized (this) {
17544 srec = ActivityRecord.forTokenLocked(activityToken);
17546 if (srec == null) {
17549 return srec.launchedFromUid;
17552 public String getLaunchedFromPackage(IBinder activityToken) {
17553 ActivityRecord srec;
17554 synchronized (this) {
17555 srec = ActivityRecord.forTokenLocked(activityToken);
17557 if (srec == null) {
17560 return srec.launchedFromPackage;
17563 // =========================================================
17564 // LIFETIME MANAGEMENT
17565 // =========================================================
17567 // Returns which broadcast queue the app is the current [or imminent] receiver
17568 // on, or 'null' if the app is not an active broadcast recipient.
17569 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17570 BroadcastRecord r = app.curReceiver;
17575 // It's not the current receiver, but it might be starting up to become one
17576 synchronized (this) {
17577 for (BroadcastQueue queue : mBroadcastQueues) {
17578 r = queue.mPendingBroadcast;
17579 if (r != null && r.curApp == app) {
17580 // found it; report which queue it's in
17589 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17590 ComponentName targetComponent, String targetProcess) {
17591 if (!mTrackingAssociations) {
17594 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17595 = mAssociations.get(targetUid);
17596 if (components == null) {
17597 components = new ArrayMap<>();
17598 mAssociations.put(targetUid, components);
17600 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17601 if (sourceUids == null) {
17602 sourceUids = new SparseArray<>();
17603 components.put(targetComponent, sourceUids);
17605 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17606 if (sourceProcesses == null) {
17607 sourceProcesses = new ArrayMap<>();
17608 sourceUids.put(sourceUid, sourceProcesses);
17610 Association ass = sourceProcesses.get(sourceProcess);
17612 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17614 sourceProcesses.put(sourceProcess, ass);
17618 if (ass.mNesting == 1) {
17619 ass.mStartTime = SystemClock.uptimeMillis();
17624 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17625 ComponentName targetComponent) {
17626 if (!mTrackingAssociations) {
17629 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17630 = mAssociations.get(targetUid);
17631 if (components == null) {
17634 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17635 if (sourceUids == null) {
17638 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17639 if (sourceProcesses == null) {
17642 Association ass = sourceProcesses.get(sourceProcess);
17643 if (ass == null || ass.mNesting <= 0) {
17647 if (ass.mNesting == 0) {
17648 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17652 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17653 boolean doingAll, long now) {
17654 if (mAdjSeq == app.adjSeq) {
17655 // This adjustment has already been computed.
17656 return app.curRawAdj;
17659 if (app.thread == null) {
17660 app.adjSeq = mAdjSeq;
17661 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17662 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17663 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17666 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17667 app.adjSource = null;
17668 app.adjTarget = null;
17670 app.cached = false;
17672 final int activitiesSize = app.activities.size();
17674 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17675 // The max adjustment doesn't allow this app to be anything
17676 // below foreground, so it is not worth doing work for it.
17677 app.adjType = "fixed";
17678 app.adjSeq = mAdjSeq;
17679 app.curRawAdj = app.maxAdj;
17680 app.foregroundActivities = false;
17681 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17682 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17683 // System processes can do UI, and when they do we want to have
17684 // them trim their memory after the user leaves the UI. To
17685 // facilitate this, here we need to determine whether or not it
17686 // is currently showing UI.
17687 app.systemNoUi = true;
17688 if (app == TOP_APP) {
17689 app.systemNoUi = false;
17690 } else if (activitiesSize > 0) {
17691 for (int j = 0; j < activitiesSize; j++) {
17692 final ActivityRecord r = app.activities.get(j);
17694 app.systemNoUi = false;
17698 if (!app.systemNoUi) {
17699 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17701 return (app.curAdj=app.maxAdj);
17704 app.systemNoUi = false;
17706 final int PROCESS_STATE_TOP = mTopProcessState;
17708 // Determine the importance of the process, starting with most
17709 // important to least, and assign an appropriate OOM adjustment.
17713 boolean foregroundActivities = false;
17714 BroadcastQueue queue;
17715 if (app == TOP_APP) {
17716 // The last app on the list is the foreground app.
17717 adj = ProcessList.FOREGROUND_APP_ADJ;
17718 schedGroup = Process.THREAD_GROUP_DEFAULT;
17719 app.adjType = "top-activity";
17720 foregroundActivities = true;
17721 procState = PROCESS_STATE_TOP;
17722 } else if (app.instrumentationClass != null) {
17723 // Don't want to kill running instrumentation.
17724 adj = ProcessList.FOREGROUND_APP_ADJ;
17725 schedGroup = Process.THREAD_GROUP_DEFAULT;
17726 app.adjType = "instrumentation";
17727 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17728 } else if ((queue = isReceivingBroadcast(app)) != null) {
17729 // An app that is currently receiving a broadcast also
17730 // counts as being in the foreground for OOM killer purposes.
17731 // It's placed in a sched group based on the nature of the
17732 // broadcast as reflected by which queue it's active in.
17733 adj = ProcessList.FOREGROUND_APP_ADJ;
17734 schedGroup = (queue == mFgBroadcastQueue)
17735 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17736 app.adjType = "broadcast";
17737 procState = ActivityManager.PROCESS_STATE_RECEIVER;
17738 } else if (app.executingServices.size() > 0) {
17739 // An app that is currently executing a service callback also
17740 // counts as being in the foreground.
17741 adj = ProcessList.FOREGROUND_APP_ADJ;
17742 schedGroup = app.execServicesFg ?
17743 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17744 app.adjType = "exec-service";
17745 procState = ActivityManager.PROCESS_STATE_SERVICE;
17746 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17748 // As far as we know the process is empty. We may change our mind later.
17749 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17750 // At this point we don't actually know the adjustment. Use the cached adj
17751 // value that the caller wants us to.
17753 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17756 app.adjType = "cch-empty";
17759 // Examine all activities if not already foreground.
17760 if (!foregroundActivities && activitiesSize > 0) {
17761 for (int j = 0; j < activitiesSize; j++) {
17762 final ActivityRecord r = app.activities.get(j);
17763 if (r.app != app) {
17764 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17765 + app + "?!? Using " + r.app + " instead.");
17769 // App has a visible activity; only upgrade adjustment.
17770 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17771 adj = ProcessList.VISIBLE_APP_ADJ;
17772 app.adjType = "visible";
17774 if (procState > PROCESS_STATE_TOP) {
17775 procState = PROCESS_STATE_TOP;
17777 schedGroup = Process.THREAD_GROUP_DEFAULT;
17778 app.cached = false;
17780 foregroundActivities = true;
17782 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17783 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17784 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17785 app.adjType = "pausing";
17787 if (procState > PROCESS_STATE_TOP) {
17788 procState = PROCESS_STATE_TOP;
17790 schedGroup = Process.THREAD_GROUP_DEFAULT;
17791 app.cached = false;
17793 foregroundActivities = true;
17794 } else if (r.state == ActivityState.STOPPING) {
17795 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17796 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17797 app.adjType = "stopping";
17799 // For the process state, we will at this point consider the
17800 // process to be cached. It will be cached either as an activity
17801 // or empty depending on whether the activity is finishing. We do
17802 // this so that we can treat the process as cached for purposes of
17803 // memory trimming (determing current memory level, trim command to
17804 // send to process) since there can be an arbitrary number of stopping
17805 // processes and they should soon all go into the cached state.
17806 if (!r.finishing) {
17807 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17808 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17811 app.cached = false;
17813 foregroundActivities = true;
17815 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17816 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17817 app.adjType = "cch-act";
17823 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17824 if (app.foregroundServices) {
17825 // The user is aware of this app, so make it visible.
17826 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17827 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17828 app.cached = false;
17829 app.adjType = "fg-service";
17830 schedGroup = Process.THREAD_GROUP_DEFAULT;
17831 } else if (app.forcingToForeground != null) {
17832 // The user is aware of this app, so make it visible.
17833 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17834 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17835 app.cached = false;
17836 app.adjType = "force-fg";
17837 app.adjSource = app.forcingToForeground;
17838 schedGroup = Process.THREAD_GROUP_DEFAULT;
17842 if (app == mHeavyWeightProcess) {
17843 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17844 // We don't want to kill the current heavy-weight process.
17845 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17846 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17847 app.cached = false;
17848 app.adjType = "heavy";
17850 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17851 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17855 if (app == mHomeProcess) {
17856 if (adj > ProcessList.HOME_APP_ADJ) {
17857 // This process is hosting what we currently consider to be the
17858 // home app, so we don't want to let it go into the background.
17859 adj = ProcessList.HOME_APP_ADJ;
17860 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17861 app.cached = false;
17862 app.adjType = "home";
17864 if (procState > ActivityManager.PROCESS_STATE_HOME) {
17865 procState = ActivityManager.PROCESS_STATE_HOME;
17869 if (app == mPreviousProcess && app.activities.size() > 0) {
17870 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17871 // This was the previous process that showed UI to the user.
17872 // We want to try to keep it around more aggressively, to give
17873 // a good experience around switching between two apps.
17874 adj = ProcessList.PREVIOUS_APP_ADJ;
17875 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17876 app.cached = false;
17877 app.adjType = "previous";
17879 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17880 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17884 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17885 + " reason=" + app.adjType);
17887 // By default, we use the computed adjustment. It may be changed if
17888 // there are applications dependent on our services or providers, but
17889 // this gives us a baseline and makes sure we don't get into an
17890 // infinite recursion.
17891 app.adjSeq = mAdjSeq;
17892 app.curRawAdj = adj;
17893 app.hasStartedServices = false;
17895 if (mBackupTarget != null && app == mBackupTarget.app) {
17896 // If possible we want to avoid killing apps while they're being backed up
17897 if (adj > ProcessList.BACKUP_APP_ADJ) {
17898 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17899 adj = ProcessList.BACKUP_APP_ADJ;
17900 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17901 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17903 app.adjType = "backup";
17904 app.cached = false;
17906 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17907 procState = ActivityManager.PROCESS_STATE_BACKUP;
17911 boolean mayBeTop = false;
17913 for (int is = app.services.size()-1;
17914 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17915 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17916 || procState > ActivityManager.PROCESS_STATE_TOP);
17918 ServiceRecord s = app.services.valueAt(is);
17919 if (s.startRequested) {
17920 app.hasStartedServices = true;
17921 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17922 procState = ActivityManager.PROCESS_STATE_SERVICE;
17924 if (app.hasShownUi && app != mHomeProcess) {
17925 // If this process has shown some UI, let it immediately
17926 // go to the LRU list because it may be pretty heavy with
17927 // UI stuff. We'll tag it with a label just to help
17928 // debug and understand what is going on.
17929 if (adj > ProcessList.SERVICE_ADJ) {
17930 app.adjType = "cch-started-ui-services";
17933 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17934 // This service has seen some activity within
17935 // recent memory, so we will keep its process ahead
17936 // of the background processes.
17937 if (adj > ProcessList.SERVICE_ADJ) {
17938 adj = ProcessList.SERVICE_ADJ;
17939 app.adjType = "started-services";
17940 app.cached = false;
17943 // If we have let the service slide into the background
17944 // state, still have some text describing what it is doing
17945 // even though the service no longer has an impact.
17946 if (adj > ProcessList.SERVICE_ADJ) {
17947 app.adjType = "cch-started-services";
17951 for (int conni = s.connections.size()-1;
17952 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17953 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17954 || procState > ActivityManager.PROCESS_STATE_TOP);
17956 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17958 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17959 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17960 || procState > ActivityManager.PROCESS_STATE_TOP);
17962 // XXX should compute this based on the max of
17963 // all connected clients.
17964 ConnectionRecord cr = clist.get(i);
17965 if (cr.binding.client == app) {
17966 // Binding to ourself is not interesting.
17969 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17970 ProcessRecord client = cr.binding.client;
17971 int clientAdj = computeOomAdjLocked(client, cachedAdj,
17972 TOP_APP, doingAll, now);
17973 int clientProcState = client.curProcState;
17974 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17975 // If the other app is cached for any reason, for purposes here
17976 // we are going to consider it empty. The specific cached state
17977 // doesn't propagate except under certain conditions.
17978 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17980 String adjType = null;
17981 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17982 // Not doing bind OOM management, so treat
17983 // this guy more like a started service.
17984 if (app.hasShownUi && app != mHomeProcess) {
17985 // If this process has shown some UI, let it immediately
17986 // go to the LRU list because it may be pretty heavy with
17987 // UI stuff. We'll tag it with a label just to help
17988 // debug and understand what is going on.
17989 if (adj > clientAdj) {
17990 adjType = "cch-bound-ui-services";
17992 app.cached = false;
17994 clientProcState = procState;
17996 if (now >= (s.lastActivity
17997 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17998 // This service has not seen activity within
17999 // recent memory, so allow it to drop to the
18000 // LRU list if there is no other reason to keep
18001 // it around. We'll also tag it with a label just
18002 // to help debug and undertand what is going on.
18003 if (adj > clientAdj) {
18004 adjType = "cch-bound-services";
18010 if (adj > clientAdj) {
18011 // If this process has recently shown UI, and
18012 // the process that is binding to it is less
18013 // important than being visible, then we don't
18014 // care about the binding as much as we care
18015 // about letting this process get into the LRU
18016 // list to be killed and restarted if needed for
18018 if (app.hasShownUi && app != mHomeProcess
18019 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18020 adjType = "cch-bound-ui-services";
18022 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18023 |Context.BIND_IMPORTANT)) != 0) {
18024 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18025 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18026 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18027 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18028 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18029 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18030 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
18033 if (adj > ProcessList.VISIBLE_APP_ADJ) {
18034 adj = ProcessList.VISIBLE_APP_ADJ;
18037 if (!client.cached) {
18038 app.cached = false;
18040 adjType = "service";
18043 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18044 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18045 schedGroup = Process.THREAD_GROUP_DEFAULT;
18047 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18048 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18049 // Special handling of clients who are in the top state.
18050 // We *may* want to consider this process to be in the
18051 // top state as well, but only if there is not another
18052 // reason for it to be running. Being on the top is a
18053 // special state, meaning you are specifically running
18054 // for the current top app. If the process is already
18055 // running in the background for some other reason, it
18056 // is more important to continue considering it to be
18057 // in the background state.
18059 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18061 // Special handling for above-top states (persistent
18062 // processes). These should not bring the current process
18063 // into the top state, since they are not on top. Instead
18064 // give them the best state after that.
18065 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18067 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18068 } else if (mWakefulness
18069 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18070 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18073 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18076 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18081 if (clientProcState <
18082 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18084 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18087 if (procState > clientProcState) {
18088 procState = clientProcState;
18090 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18091 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18092 app.pendingUiClean = true;
18094 if (adjType != null) {
18095 app.adjType = adjType;
18096 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18097 .REASON_SERVICE_IN_USE;
18098 app.adjSource = cr.binding.client;
18099 app.adjSourceProcState = clientProcState;
18100 app.adjTarget = s.name;
18103 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18104 app.treatLikeActivity = true;
18106 final ActivityRecord a = cr.activity;
18107 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18108 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18109 (a.visible || a.state == ActivityState.RESUMED
18110 || a.state == ActivityState.PAUSING)) {
18111 adj = ProcessList.FOREGROUND_APP_ADJ;
18112 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18113 schedGroup = Process.THREAD_GROUP_DEFAULT;
18115 app.cached = false;
18116 app.adjType = "service";
18117 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18118 .REASON_SERVICE_IN_USE;
18120 app.adjSourceProcState = procState;
18121 app.adjTarget = s.name;
18128 for (int provi = app.pubProviders.size()-1;
18129 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18130 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18131 || procState > ActivityManager.PROCESS_STATE_TOP);
18133 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18134 for (int i = cpr.connections.size()-1;
18135 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18136 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18137 || procState > ActivityManager.PROCESS_STATE_TOP);
18139 ContentProviderConnection conn = cpr.connections.get(i);
18140 ProcessRecord client = conn.client;
18141 if (client == app) {
18142 // Being our own client is not interesting.
18145 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18146 int clientProcState = client.curProcState;
18147 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18148 // If the other app is cached for any reason, for purposes here
18149 // we are going to consider it empty.
18150 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18152 if (adj > clientAdj) {
18153 if (app.hasShownUi && app != mHomeProcess
18154 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18155 app.adjType = "cch-ui-provider";
18157 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18158 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18159 app.adjType = "provider";
18161 app.cached &= client.cached;
18162 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18163 .REASON_PROVIDER_IN_USE;
18164 app.adjSource = client;
18165 app.adjSourceProcState = clientProcState;
18166 app.adjTarget = cpr.name;
18168 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18169 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18170 // Special handling of clients who are in the top state.
18171 // We *may* want to consider this process to be in the
18172 // top state as well, but only if there is not another
18173 // reason for it to be running. Being on the top is a
18174 // special state, meaning you are specifically running
18175 // for the current top app. If the process is already
18176 // running in the background for some other reason, it
18177 // is more important to continue considering it to be
18178 // in the background state.
18180 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18182 // Special handling for above-top states (persistent
18183 // processes). These should not bring the current process
18184 // into the top state, since they are not on top. Instead
18185 // give them the best state after that.
18187 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18190 if (procState > clientProcState) {
18191 procState = clientProcState;
18193 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18194 schedGroup = Process.THREAD_GROUP_DEFAULT;
18197 // If the provider has external (non-framework) process
18198 // dependencies, ensure that its adjustment is at least
18199 // FOREGROUND_APP_ADJ.
18200 if (cpr.hasExternalProcessHandles()) {
18201 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18202 adj = ProcessList.FOREGROUND_APP_ADJ;
18203 schedGroup = Process.THREAD_GROUP_DEFAULT;
18204 app.cached = false;
18205 app.adjType = "provider";
18206 app.adjTarget = cpr.name;
18208 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18209 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18214 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18215 // A client of one of our services or providers is in the top state. We
18216 // *may* want to be in the top state, but not if we are already running in
18217 // the background for some other reason. For the decision here, we are going
18218 // to pick out a few specific states that we want to remain in when a client
18219 // is top (states that tend to be longer-term) and otherwise allow it to go
18220 // to the top state.
18221 switch (procState) {
18222 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18223 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18224 case ActivityManager.PROCESS_STATE_SERVICE:
18225 // These all are longer-term states, so pull them up to the top
18226 // of the background states, but not all the way to the top state.
18227 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18230 // Otherwise, top is a better choice, so take it.
18231 procState = ActivityManager.PROCESS_STATE_TOP;
18236 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18237 if (app.hasClientActivities) {
18238 // This is a cached process, but with client activities. Mark it so.
18239 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18240 app.adjType = "cch-client-act";
18241 } else if (app.treatLikeActivity) {
18242 // This is a cached process, but somebody wants us to treat it like it has
18243 // an activity, okay!
18244 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18245 app.adjType = "cch-as-act";
18249 if (adj == ProcessList.SERVICE_ADJ) {
18251 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18252 mNewNumServiceProcs++;
18253 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18254 if (!app.serviceb) {
18255 // This service isn't far enough down on the LRU list to
18256 // normally be a B service, but if we are low on RAM and it
18257 // is large we want to force it down since we would prefer to
18258 // keep launcher over it.
18259 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18260 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18261 app.serviceHighRam = true;
18262 app.serviceb = true;
18263 //Slog.i(TAG, "ADJ " + app + " high ram!");
18265 mNewNumAServiceProcs++;
18266 //Slog.i(TAG, "ADJ " + app + " not high ram!");
18269 app.serviceHighRam = false;
18272 if (app.serviceb) {
18273 adj = ProcessList.SERVICE_B_ADJ;
18277 app.curRawAdj = adj;
18279 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18280 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18281 if (adj > app.maxAdj) {
18283 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18284 schedGroup = Process.THREAD_GROUP_DEFAULT;
18288 // Do final modification to adj. Everything we do between here and applying
18289 // the final setAdj must be done in this function, because we will also use
18290 // it when computing the final cached adj later. Note that we don't need to
18291 // worry about this for max adj above, since max adj will always be used to
18292 // keep it out of the cached vaues.
18293 app.curAdj = app.modifyRawOomAdj(adj);
18294 app.curSchedGroup = schedGroup;
18295 app.curProcState = procState;
18296 app.foregroundActivities = foregroundActivities;
18298 return app.curRawAdj;
18302 * Record new PSS sample for a process.
18304 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18305 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18306 proc.lastPssTime = now;
18307 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18308 if (DEBUG_PSS) Slog.d(TAG_PSS,
18309 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18310 + " state=" + ProcessList.makeProcStateString(procState));
18311 if (proc.initialIdlePss == 0) {
18312 proc.initialIdlePss = pss;
18314 proc.lastPss = pss;
18315 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18316 proc.lastCachedPss = pss;
18319 final SparseArray<Pair<Long, String>> watchUids
18320 = mMemWatchProcesses.getMap().get(proc.processName);
18322 if (watchUids != null) {
18323 Pair<Long, String> val = watchUids.get(proc.uid);
18325 val = watchUids.get(0);
18331 if (check != null) {
18332 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18333 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18334 if (!isDebuggable) {
18335 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18336 isDebuggable = true;
18339 if (isDebuggable) {
18340 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18341 final ProcessRecord myProc = proc;
18342 final File heapdumpFile = DumpHeapProvider.getJavaFile();
18343 mMemWatchDumpProcName = proc.processName;
18344 mMemWatchDumpFile = heapdumpFile.toString();
18345 mMemWatchDumpPid = proc.pid;
18346 mMemWatchDumpUid = proc.uid;
18347 BackgroundThread.getHandler().post(new Runnable() {
18349 public void run() {
18350 revokeUriPermission(ActivityThread.currentActivityThread()
18351 .getApplicationThread(),
18352 DumpHeapActivity.JAVA_URI,
18353 Intent.FLAG_GRANT_READ_URI_PERMISSION
18354 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18355 UserHandle.myUserId());
18356 ParcelFileDescriptor fd = null;
18358 heapdumpFile.delete();
18359 fd = ParcelFileDescriptor.open(heapdumpFile,
18360 ParcelFileDescriptor.MODE_CREATE |
18361 ParcelFileDescriptor.MODE_TRUNCATE |
18362 ParcelFileDescriptor.MODE_WRITE_ONLY |
18363 ParcelFileDescriptor.MODE_APPEND);
18364 IApplicationThread thread = myProc.thread;
18365 if (thread != null) {
18367 if (DEBUG_PSS) Slog.d(TAG_PSS,
18368 "Requesting dump heap from "
18369 + myProc + " to " + heapdumpFile);
18370 thread.dumpHeap(true, heapdumpFile.toString(), fd);
18371 } catch (RemoteException e) {
18374 } catch (FileNotFoundException e) {
18375 e.printStackTrace();
18380 } catch (IOException e) {
18387 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18388 + ", but debugging not enabled");
18395 * Schedule PSS collection of a process.
18397 void requestPssLocked(ProcessRecord proc, int procState) {
18398 if (mPendingPssProcesses.contains(proc)) {
18401 if (mPendingPssProcesses.size() == 0) {
18402 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18404 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18405 proc.pssProcState = procState;
18406 mPendingPssProcesses.add(proc);
18410 * Schedule PSS collection of all processes.
18412 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18414 if (now < (mLastFullPssTime +
18415 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18419 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
18420 mLastFullPssTime = now;
18421 mFullPssPending = true;
18422 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18423 mPendingPssProcesses.clear();
18424 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18425 ProcessRecord app = mLruProcesses.get(i);
18426 if (app.thread == null
18427 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18430 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18431 app.pssProcState = app.setProcState;
18432 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18433 mTestPssMode, isSleeping(), now);
18434 mPendingPssProcesses.add(app);
18437 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18440 public void setTestPssMode(boolean enabled) {
18441 synchronized (this) {
18442 mTestPssMode = enabled;
18444 // Whenever we enable the mode, we want to take a snapshot all of current
18445 // process mem use.
18446 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18452 * Ask a given process to GC right now.
18454 final void performAppGcLocked(ProcessRecord app) {
18456 app.lastRequestedGc = SystemClock.uptimeMillis();
18457 if (app.thread != null) {
18458 if (app.reportLowMemory) {
18459 app.reportLowMemory = false;
18460 app.thread.scheduleLowMemory();
18462 app.thread.processInBackground();
18465 } catch (Exception e) {
18471 * Returns true if things are idle enough to perform GCs.
18473 private final boolean canGcNowLocked() {
18474 boolean processingBroadcasts = false;
18475 for (BroadcastQueue q : mBroadcastQueues) {
18476 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18477 processingBroadcasts = true;
18480 return !processingBroadcasts
18481 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18485 * Perform GCs on all processes that are waiting for it, but only
18486 * if things are idle.
18488 final void performAppGcsLocked() {
18489 final int N = mProcessesToGc.size();
18493 if (canGcNowLocked()) {
18494 while (mProcessesToGc.size() > 0) {
18495 ProcessRecord proc = mProcessesToGc.remove(0);
18496 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18497 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18498 <= SystemClock.uptimeMillis()) {
18499 // To avoid spamming the system, we will GC processes one
18500 // at a time, waiting a few seconds between each.
18501 performAppGcLocked(proc);
18502 scheduleAppGcsLocked();
18505 // It hasn't been long enough since we last GCed this
18506 // process... put it in the list to wait for its time.
18507 addProcessToGcListLocked(proc);
18513 scheduleAppGcsLocked();
18518 * If all looks good, perform GCs on all processes waiting for them.
18520 final void performAppGcsIfAppropriateLocked() {
18521 if (canGcNowLocked()) {
18522 performAppGcsLocked();
18525 // Still not idle, wait some more.
18526 scheduleAppGcsLocked();
18530 * Schedule the execution of all pending app GCs.
18532 final void scheduleAppGcsLocked() {
18533 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18535 if (mProcessesToGc.size() > 0) {
18536 // Schedule a GC for the time to the next process.
18537 ProcessRecord proc = mProcessesToGc.get(0);
18538 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18540 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18541 long now = SystemClock.uptimeMillis();
18542 if (when < (now+GC_TIMEOUT)) {
18543 when = now + GC_TIMEOUT;
18545 mHandler.sendMessageAtTime(msg, when);
18550 * Add a process to the array of processes waiting to be GCed. Keeps the
18551 * list in sorted order by the last GC time. The process can't already be
18554 final void addProcessToGcListLocked(ProcessRecord proc) {
18555 boolean added = false;
18556 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18557 if (mProcessesToGc.get(i).lastRequestedGc <
18558 proc.lastRequestedGc) {
18560 mProcessesToGc.add(i+1, proc);
18565 mProcessesToGc.add(0, proc);
18570 * Set up to ask a process to GC itself. This will either do it
18571 * immediately, or put it on the list of processes to gc the next
18572 * time things are idle.
18574 final void scheduleAppGcLocked(ProcessRecord app) {
18575 long now = SystemClock.uptimeMillis();
18576 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18579 if (!mProcessesToGc.contains(app)) {
18580 addProcessToGcListLocked(app);
18581 scheduleAppGcsLocked();
18585 final void checkExcessivePowerUsageLocked(boolean doKills) {
18586 updateCpuStatsNow();
18588 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18589 boolean doWakeKills = doKills;
18590 boolean doCpuKills = doKills;
18591 if (mLastPowerCheckRealtime == 0) {
18592 doWakeKills = false;
18594 if (mLastPowerCheckUptime == 0) {
18595 doCpuKills = false;
18597 if (stats.isScreenOn()) {
18598 doWakeKills = false;
18600 final long curRealtime = SystemClock.elapsedRealtime();
18601 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18602 final long curUptime = SystemClock.uptimeMillis();
18603 final long uptimeSince = curUptime - mLastPowerCheckUptime;
18604 mLastPowerCheckRealtime = curRealtime;
18605 mLastPowerCheckUptime = curUptime;
18606 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18607 doWakeKills = false;
18609 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18610 doCpuKills = false;
18612 int i = mLruProcesses.size();
18615 ProcessRecord app = mLruProcesses.get(i);
18616 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18618 synchronized (stats) {
18619 wtime = stats.getProcessWakeTime(app.info.uid,
18620 app.pid, curRealtime);
18622 long wtimeUsed = wtime - app.lastWakeTime;
18623 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18625 StringBuilder sb = new StringBuilder(128);
18626 sb.append("Wake for ");
18627 app.toShortString(sb);
18628 sb.append(": over ");
18629 TimeUtils.formatDuration(realtimeSince, sb);
18630 sb.append(" used ");
18631 TimeUtils.formatDuration(wtimeUsed, sb);
18633 sb.append((wtimeUsed*100)/realtimeSince);
18635 Slog.i(TAG_POWER, sb.toString());
18637 sb.append("CPU for ");
18638 app.toShortString(sb);
18639 sb.append(": over ");
18640 TimeUtils.formatDuration(uptimeSince, sb);
18641 sb.append(" used ");
18642 TimeUtils.formatDuration(cputimeUsed, sb);
18644 sb.append((cputimeUsed*100)/uptimeSince);
18646 Slog.i(TAG_POWER, sb.toString());
18648 // If a process has held a wake lock for more
18649 // than 50% of the time during this period,
18650 // that sounds bad. Kill!
18651 if (doWakeKills && realtimeSince > 0
18652 && ((wtimeUsed*100)/realtimeSince) >= 50) {
18653 synchronized (stats) {
18654 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18655 realtimeSince, wtimeUsed);
18657 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18658 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18659 } else if (doCpuKills && uptimeSince > 0
18660 && ((cputimeUsed*100)/uptimeSince) >= 25) {
18661 synchronized (stats) {
18662 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18663 uptimeSince, cputimeUsed);
18665 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18666 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18668 app.lastWakeTime = wtime;
18669 app.lastCpuTime = app.curCpuTime;
18675 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18676 boolean success = true;
18678 if (app.curRawAdj != app.setRawAdj) {
18679 app.setRawAdj = app.curRawAdj;
18684 if (app.curAdj != app.setAdj) {
18685 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18686 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18687 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18689 app.setAdj = app.curAdj;
18692 if (app.setSchedGroup != app.curSchedGroup) {
18693 app.setSchedGroup = app.curSchedGroup;
18694 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18695 "Setting process group of " + app.processName
18696 + " to " + app.curSchedGroup);
18697 if (app.waitingToKill != null && app.curReceiver == null
18698 && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18699 app.kill(app.waitingToKill, true);
18703 long oldId = Binder.clearCallingIdentity();
18705 Process.setProcessGroup(app.pid, app.curSchedGroup);
18706 } catch (Exception e) {
18707 Slog.w(TAG, "Failed setting process group of " + app.pid
18708 + " to " + app.curSchedGroup);
18709 e.printStackTrace();
18711 Binder.restoreCallingIdentity(oldId);
18714 if (app.thread != null) {
18716 app.thread.setSchedulingGroup(app.curSchedGroup);
18717 } catch (RemoteException e) {
18721 Process.setSwappiness(app.pid,
18722 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18725 if (app.repForegroundActivities != app.foregroundActivities) {
18726 app.repForegroundActivities = app.foregroundActivities;
18727 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18729 if (app.repProcState != app.curProcState) {
18730 app.repProcState = app.curProcState;
18731 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18732 if (app.thread != null) {
18735 //RuntimeException h = new RuntimeException("here");
18736 Slog.i(TAG, "Sending new process state " + app.repProcState
18737 + " to " + app /*, h*/);
18739 app.thread.setProcessState(app.repProcState);
18740 } catch (RemoteException e) {
18744 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18745 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18746 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18747 // Experimental code to more aggressively collect pss while
18748 // running test... the problem is that this tends to collect
18749 // the data right when a process is transitioning between process
18750 // states, which well tend to give noisy data.
18751 long start = SystemClock.uptimeMillis();
18752 long pss = Debug.getPss(app.pid, mTmpLong, null);
18753 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18754 mPendingPssProcesses.remove(app);
18755 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18756 + " to " + app.curProcState + ": "
18757 + (SystemClock.uptimeMillis()-start) + "ms");
18759 app.lastStateTime = now;
18760 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18761 mTestPssMode, isSleeping(), now);
18762 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18763 + ProcessList.makeProcStateString(app.setProcState) + " to "
18764 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18765 + (app.nextPssTime-now) + ": " + app);
18767 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18768 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18770 requestPssLocked(app, app.setProcState);
18771 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18772 mTestPssMode, isSleeping(), now);
18773 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18774 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18776 if (app.setProcState != app.curProcState) {
18777 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18778 "Proc state change of " + app.processName
18779 + " to " + app.curProcState);
18780 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18781 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18782 if (setImportant && !curImportant) {
18783 // This app is no longer something we consider important enough to allow to
18784 // use arbitrary amounts of battery power. Note
18785 // its current wake lock time to later know to kill it if
18786 // it is not behaving well.
18787 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18788 synchronized (stats) {
18789 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18790 app.pid, SystemClock.elapsedRealtime());
18792 app.lastCpuTime = app.curCpuTime;
18795 // Inform UsageStats of important process state change
18796 // Must be called before updating setProcState
18797 maybeUpdateUsageStatsLocked(app);
18799 app.setProcState = app.curProcState;
18800 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18801 app.notCachedSinceIdle = false;
18804 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18806 app.procStateChanged = true;
18810 if (changes != 0) {
18811 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18812 "Changes in " + app + ": " + changes);
18813 int i = mPendingProcessChanges.size()-1;
18814 ProcessChangeItem item = null;
18816 item = mPendingProcessChanges.get(i);
18817 if (item.pid == app.pid) {
18818 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18819 "Re-using existing item: " + item);
18825 // No existing item in pending changes; need a new one.
18826 final int NA = mAvailProcessChanges.size();
18828 item = mAvailProcessChanges.remove(NA-1);
18829 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18830 "Retrieving available item: " + item);
18832 item = new ProcessChangeItem();
18833 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18834 "Allocating new item: " + item);
18837 item.pid = app.pid;
18838 item.uid = app.info.uid;
18839 if (mPendingProcessChanges.size() == 0) {
18840 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18841 "*** Enqueueing dispatch processes changed!");
18842 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18844 mPendingProcessChanges.add(item);
18846 item.changes |= changes;
18847 item.processState = app.repProcState;
18848 item.foregroundActivities = app.repForegroundActivities;
18849 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18850 "Item " + Integer.toHexString(System.identityHashCode(item))
18851 + " " + app.toShortString() + ": changes=" + item.changes
18852 + " procState=" + item.processState
18853 + " foreground=" + item.foregroundActivities
18854 + " type=" + app.adjType + " source=" + app.adjSource
18855 + " target=" + app.adjTarget);
18861 private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18862 if (uidRec.pendingChange == null) {
18863 if (mPendingUidChanges.size() == 0) {
18864 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18865 "*** Enqueueing dispatch uid changed!");
18866 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18868 final int NA = mAvailUidChanges.size();
18870 uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18871 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18872 "Retrieving available item: " + uidRec.pendingChange);
18874 uidRec.pendingChange = new UidRecord.ChangeItem();
18875 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18876 "Allocating new item: " + uidRec.pendingChange);
18878 uidRec.pendingChange.uidRecord = uidRec;
18879 uidRec.pendingChange.uid = uidRec.uid;
18880 mPendingUidChanges.add(uidRec.pendingChange);
18882 uidRec.pendingChange.gone = gone;
18883 uidRec.pendingChange.processState = uidRec.setProcState;
18886 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18887 String authority) {
18888 if (app == null) return;
18889 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18890 UserState userState = mStartedUsers.get(app.userId);
18891 if (userState == null) return;
18892 final long now = SystemClock.elapsedRealtime();
18893 Long lastReported = userState.mProviderLastReportedFg.get(authority);
18894 if (lastReported == null || lastReported < now - 60 * 1000L) {
18895 mUsageStatsService.reportContentProviderUsage(
18896 authority, providerPkgName, app.userId);
18897 userState.mProviderLastReportedFg.put(authority, now);
18902 private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18903 if (DEBUG_USAGE_STATS) {
18904 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18905 + "] state changes: old = " + app.setProcState + ", new = "
18906 + app.curProcState);
18908 if (mUsageStatsService == null) {
18911 boolean isInteraction;
18912 // To avoid some abuse patterns, we are going to be careful about what we consider
18913 // to be an app interaction. Being the top activity doesn't count while the display
18914 // is sleeping, nor do short foreground services.
18915 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18916 isInteraction = true;
18917 app.fgInteractionTime = 0;
18918 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18919 final long now = SystemClock.elapsedRealtime();
18920 if (app.fgInteractionTime == 0) {
18921 app.fgInteractionTime = now;
18922 isInteraction = false;
18924 isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18927 isInteraction = app.curProcState
18928 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18929 app.fgInteractionTime = 0;
18931 if (isInteraction && !app.reportedInteraction) {
18932 String[] packages = app.getPackageList();
18933 if (packages != null) {
18934 for (int i = 0; i < packages.length; i++) {
18935 mUsageStatsService.reportEvent(packages[i], app.userId,
18936 UsageEvents.Event.SYSTEM_INTERACTION);
18940 app.reportedInteraction = isInteraction;
18943 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18944 if (proc.thread != null) {
18945 if (proc.baseProcessTracker != null) {
18946 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18948 if (proc.repProcState >= 0) {
18949 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18950 proc.repProcState);
18955 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18956 ProcessRecord TOP_APP, boolean doingAll, long now) {
18957 if (app.thread == null) {
18961 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18963 return applyOomAdjLocked(app, doingAll, now);
18966 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18968 if (isForeground != proc.foregroundServices) {
18969 proc.foregroundServices = isForeground;
18970 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18972 if (isForeground) {
18973 if (curProcs == null) {
18974 curProcs = new ArrayList<ProcessRecord>();
18975 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18977 if (!curProcs.contains(proc)) {
18978 curProcs.add(proc);
18979 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18980 proc.info.packageName, proc.info.uid);
18983 if (curProcs != null) {
18984 if (curProcs.remove(proc)) {
18985 mBatteryStatsService.noteEvent(
18986 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18987 proc.info.packageName, proc.info.uid);
18988 if (curProcs.size() <= 0) {
18989 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18995 updateOomAdjLocked();
19000 private final ActivityRecord resumedAppLocked() {
19001 ActivityRecord act = mStackSupervisor.resumedAppLocked();
19005 pkg = act.packageName;
19006 uid = act.info.applicationInfo.uid;
19011 // Has the UID or resumed package name changed?
19012 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19013 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19014 if (mCurResumedPackage != null) {
19015 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19016 mCurResumedPackage, mCurResumedUid);
19018 mCurResumedPackage = pkg;
19019 mCurResumedUid = uid;
19020 if (mCurResumedPackage != null) {
19021 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19022 mCurResumedPackage, mCurResumedUid);
19028 final boolean updateOomAdjLocked(ProcessRecord app) {
19029 final ActivityRecord TOP_ACT = resumedAppLocked();
19030 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19031 final boolean wasCached = app.cached;
19035 // This is the desired cached adjusment we want to tell it to use.
19036 // If our app is currently cached, we know it, and that is it. Otherwise,
19037 // we don't know it yet, and it needs to now be cached we will then
19038 // need to do a complete oom adj.
19039 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19040 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19041 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19042 SystemClock.uptimeMillis());
19043 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19044 // Changed to/from cached state, so apps after it in the LRU
19045 // list may also be changed.
19046 updateOomAdjLocked();
19051 final void updateOomAdjLocked() {
19052 final ActivityRecord TOP_ACT = resumedAppLocked();
19053 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19054 final long now = SystemClock.uptimeMillis();
19055 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19056 final int N = mLruProcesses.size();
19059 RuntimeException e = new RuntimeException();
19060 e.fillInStackTrace();
19061 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19064 // Reset state in all uid records.
19065 for (int i=mActiveUids.size()-1; i>=0; i--) {
19066 final UidRecord uidRec = mActiveUids.valueAt(i);
19067 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19068 "Starting update of " + uidRec);
19073 mNewNumServiceProcs = 0;
19074 mNewNumAServiceProcs = 0;
19076 final int emptyProcessLimit;
19077 final int cachedProcessLimit;
19078 if (mProcessLimit <= 0) {
19079 emptyProcessLimit = cachedProcessLimit = 0;
19080 } else if (mProcessLimit == 1) {
19081 emptyProcessLimit = 1;
19082 cachedProcessLimit = 0;
19084 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19085 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19088 // Let's determine how many processes we have running vs.
19089 // how many slots we have for background processes; we may want
19090 // to put multiple processes in a slot of there are enough of
19092 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19093 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19094 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19095 if (numEmptyProcs > cachedProcessLimit) {
19096 // If there are more empty processes than our limit on cached
19097 // processes, then use the cached process limit for the factor.
19098 // This ensures that the really old empty processes get pushed
19099 // down to the bottom, so if we are running low on memory we will
19100 // have a better chance at keeping around more cached processes
19101 // instead of a gazillion empty processes.
19102 numEmptyProcs = cachedProcessLimit;
19104 int emptyFactor = numEmptyProcs/numSlots;
19105 if (emptyFactor < 1) emptyFactor = 1;
19106 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19107 if (cachedFactor < 1) cachedFactor = 1;
19108 int stepCached = 0;
19112 int numTrimming = 0;
19114 mNumNonCachedProcs = 0;
19115 mNumCachedHiddenProcs = 0;
19117 // First update the OOM adjustment for each of the
19118 // application processes based on their current state.
19119 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19120 int nextCachedAdj = curCachedAdj+1;
19121 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19122 int nextEmptyAdj = curEmptyAdj+2;
19123 for (int i=N-1; i>=0; i--) {
19124 ProcessRecord app = mLruProcesses.get(i);
19125 if (!app.killedByAm && app.thread != null) {
19126 app.procStateChanged = false;
19127 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19129 // If we haven't yet assigned the final cached adj
19130 // to the process, do that now.
19131 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19132 switch (app.curProcState) {
19133 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19134 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19135 // This process is a cached process holding activities...
19136 // assign it the next cached value for that type, and then
19137 // step that cached level.
19138 app.curRawAdj = curCachedAdj;
19139 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19140 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19141 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19143 if (curCachedAdj != nextCachedAdj) {
19145 if (stepCached >= cachedFactor) {
19147 curCachedAdj = nextCachedAdj;
19148 nextCachedAdj += 2;
19149 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19150 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19156 // For everything else, assign next empty cached process
19157 // level and bump that up. Note that this means that
19158 // long-running services that have dropped down to the
19159 // cached level will be treated as empty (since their process
19160 // state is still as a service), which is what we want.
19161 app.curRawAdj = curEmptyAdj;
19162 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19163 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19164 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19166 if (curEmptyAdj != nextEmptyAdj) {
19168 if (stepEmpty >= emptyFactor) {
19170 curEmptyAdj = nextEmptyAdj;
19172 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19173 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19181 applyOomAdjLocked(app, true, now);
19183 // Count the number of process types.
19184 switch (app.curProcState) {
19185 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19186 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19187 mNumCachedHiddenProcs++;
19189 if (numCached > cachedProcessLimit) {
19190 app.kill("cached #" + numCached, true);
19193 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19194 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19195 && app.lastActivityTime < oldTime) {
19196 app.kill("empty for "
19197 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19198 / 1000) + "s", true);
19201 if (numEmpty > emptyProcessLimit) {
19202 app.kill("empty #" + numEmpty, true);
19207 mNumNonCachedProcs++;
19211 if (app.isolated && app.services.size() <= 0) {
19212 // If this is an isolated process, and there are no
19213 // services running in it, then the process is no longer
19214 // needed. We agressively kill these because we can by
19215 // definition not re-use the same process again, and it is
19216 // good to avoid having whatever code was running in them
19217 // left sitting around after no longer needed.
19218 app.kill("isolated not needed", true);
19220 // Keeping this process, update its uid.
19221 final UidRecord uidRec = app.uidRecord;
19222 if (uidRec != null && uidRec.curProcState > app.curProcState) {
19223 uidRec.curProcState = app.curProcState;
19227 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19228 && !app.killedByAm) {
19234 mNumServiceProcs = mNewNumServiceProcs;
19236 // Now determine the memory trimming level of background processes.
19237 // Unfortunately we need to start at the back of the list to do this
19238 // properly. We only do this if the number of background apps we
19239 // are managing to keep around is less than half the maximum we desire;
19240 // if we are keeping a good number around, we'll let them use whatever
19241 // memory they want.
19242 final int numCachedAndEmpty = numCached + numEmpty;
19244 if (numCached <= ProcessList.TRIM_CACHED_APPS
19245 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19246 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19247 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19248 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19249 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19251 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19254 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19256 // We always allow the memory level to go up (better). We only allow it to go
19257 // down if we are in a state where that is allowed, *and* the total number of processes
19258 // has gone down since last time.
19259 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19260 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19261 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19262 if (memFactor > mLastMemoryLevel) {
19263 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19264 memFactor = mLastMemoryLevel;
19265 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19268 mLastMemoryLevel = memFactor;
19269 mLastNumProcesses = mLruProcesses.size();
19270 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19271 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19272 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19273 if (mLowRamStartTime == 0) {
19274 mLowRamStartTime = now;
19278 switch (memFactor) {
19279 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19280 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19282 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19283 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19286 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19289 int factor = numTrimming/3;
19291 if (mHomeProcess != null) minFactor++;
19292 if (mPreviousProcess != null) minFactor++;
19293 if (factor < minFactor) factor = minFactor;
19294 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19295 for (int i=N-1; i>=0; i--) {
19296 ProcessRecord app = mLruProcesses.get(i);
19297 if (allChanged || app.procStateChanged) {
19298 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19299 app.procStateChanged = false;
19301 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19302 && !app.killedByAm) {
19303 if (app.trimMemoryLevel < curLevel && app.thread != null) {
19305 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19306 "Trimming memory of " + app.processName + " to " + curLevel);
19307 app.thread.scheduleTrimMemory(curLevel);
19308 } catch (RemoteException e) {
19311 // For now we won't do this; our memory trimming seems
19312 // to be good enough at this point that destroying
19313 // activities causes more harm than good.
19314 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19315 && app != mHomeProcess && app != mPreviousProcess) {
19316 // Need to do this on its own message because the stack may not
19317 // be in a consistent state at this point.
19318 // For these apps we will also finish their activities
19319 // to help them free memory.
19320 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19324 app.trimMemoryLevel = curLevel;
19326 if (step >= factor) {
19328 switch (curLevel) {
19329 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19330 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19332 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19333 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19337 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19338 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19339 && app.thread != null) {
19341 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19342 "Trimming memory of heavy-weight " + app.processName
19343 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19344 app.thread.scheduleTrimMemory(
19345 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19346 } catch (RemoteException e) {
19349 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19351 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19352 || app.systemNoUi) && app.pendingUiClean) {
19353 // If this application is now in the background and it
19354 // had done UI, then give it the special trim level to
19355 // have it free UI resources.
19356 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19357 if (app.trimMemoryLevel < level && app.thread != null) {
19359 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19360 "Trimming memory of bg-ui " + app.processName
19362 app.thread.scheduleTrimMemory(level);
19363 } catch (RemoteException e) {
19366 app.pendingUiClean = false;
19368 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19370 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19371 "Trimming memory of fg " + app.processName
19372 + " to " + fgTrimLevel);
19373 app.thread.scheduleTrimMemory(fgTrimLevel);
19374 } catch (RemoteException e) {
19377 app.trimMemoryLevel = fgTrimLevel;
19381 if (mLowRamStartTime != 0) {
19382 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19383 mLowRamStartTime = 0;
19385 for (int i=N-1; i>=0; i--) {
19386 ProcessRecord app = mLruProcesses.get(i);
19387 if (allChanged || app.procStateChanged) {
19388 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19389 app.procStateChanged = false;
19391 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19392 || app.systemNoUi) && app.pendingUiClean) {
19393 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19394 && app.thread != null) {
19396 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19397 "Trimming memory of ui hidden " + app.processName
19398 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19399 app.thread.scheduleTrimMemory(
19400 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19401 } catch (RemoteException e) {
19404 app.pendingUiClean = false;
19406 app.trimMemoryLevel = 0;
19410 if (mAlwaysFinishActivities) {
19411 // Need to do this on its own message because the stack may not
19412 // be in a consistent state at this point.
19413 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19417 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19420 // Update from any uid changes.
19421 for (int i=mActiveUids.size()-1; i>=0; i--) {
19422 final UidRecord uidRec = mActiveUids.valueAt(i);
19423 if (uidRec.setProcState != uidRec.curProcState) {
19424 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19425 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19426 + " to " + uidRec.curProcState);
19427 uidRec.setProcState = uidRec.curProcState;
19428 enqueueUidChangeLocked(uidRec, false);
19432 if (mProcessStats.shouldWriteNowLocked(now)) {
19433 mHandler.post(new Runnable() {
19434 @Override public void run() {
19435 synchronized (ActivityManagerService.this) {
19436 mProcessStats.writeStateAsyncLocked();
19442 if (DEBUG_OOM_ADJ) {
19443 final long duration = SystemClock.uptimeMillis() - now;
19445 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19446 new RuntimeException("here").fillInStackTrace());
19448 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19453 final void trimApplications() {
19454 synchronized (this) {
19457 // First remove any unused application processes whose package
19458 // has been removed.
19459 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19460 final ProcessRecord app = mRemovedProcesses.get(i);
19461 if (app.activities.size() == 0
19462 && app.curReceiver == null && app.services.size() == 0) {
19464 TAG, "Exiting empty application process "
19465 + app.processName + " ("
19466 + (app.thread != null ? app.thread.asBinder() : null)
19468 if (app.pid > 0 && app.pid != MY_PID) {
19469 app.kill("empty", false);
19472 app.thread.scheduleExit();
19473 } catch (Exception e) {
19474 // Ignore exceptions.
19477 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
19478 mRemovedProcesses.remove(i);
19480 if (app.persistent) {
19481 addAppLocked(app.info, false, null /* ABI override */);
19486 // Now update the oom adj for all processes.
19487 updateOomAdjLocked();
19491 /** This method sends the specified signal to each of the persistent apps */
19492 public void signalPersistentProcesses(int sig) throws RemoteException {
19493 if (sig != Process.SIGNAL_USR1) {
19494 throw new SecurityException("Only SIGNAL_USR1 is allowed");
19497 synchronized (this) {
19498 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19499 != PackageManager.PERMISSION_GRANTED) {
19500 throw new SecurityException("Requires permission "
19501 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19504 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19505 ProcessRecord r = mLruProcesses.get(i);
19506 if (r.thread != null && r.persistent) {
19507 Process.sendSignal(r.pid, sig);
19513 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19514 if (proc == null || proc == mProfileProc) {
19515 proc = mProfileProc;
19516 profileType = mProfileType;
19517 clearProfilerLocked();
19519 if (proc == null) {
19523 proc.thread.profilerControl(false, null, profileType);
19524 } catch (RemoteException e) {
19525 throw new IllegalStateException("Process disappeared");
19529 private void clearProfilerLocked() {
19530 if (mProfileFd != null) {
19532 mProfileFd.close();
19533 } catch (IOException e) {
19536 mProfileApp = null;
19537 mProfileProc = null;
19538 mProfileFile = null;
19540 mAutoStopProfiler = false;
19541 mSamplingInterval = 0;
19544 public boolean profileControl(String process, int userId, boolean start,
19545 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19548 synchronized (this) {
19549 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19550 // its own permission.
19551 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19552 != PackageManager.PERMISSION_GRANTED) {
19553 throw new SecurityException("Requires permission "
19554 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19557 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19558 throw new IllegalArgumentException("null profile info or fd");
19561 ProcessRecord proc = null;
19562 if (process != null) {
19563 proc = findProcessLocked(process, userId, "profileControl");
19566 if (start && (proc == null || proc.thread == null)) {
19567 throw new IllegalArgumentException("Unknown process: " + process);
19571 stopProfilerLocked(null, 0);
19572 setProfileApp(proc.info, proc.processName, profilerInfo);
19573 mProfileProc = proc;
19574 mProfileType = profileType;
19575 ParcelFileDescriptor fd = profilerInfo.profileFd;
19578 } catch (IOException e) {
19581 profilerInfo.profileFd = fd;
19582 proc.thread.profilerControl(start, profilerInfo, profileType);
19586 stopProfilerLocked(proc, profileType);
19587 if (profilerInfo != null && profilerInfo.profileFd != null) {
19589 profilerInfo.profileFd.close();
19590 } catch (IOException e) {
19597 } catch (RemoteException e) {
19598 throw new IllegalStateException("Process disappeared");
19600 if (profilerInfo != null && profilerInfo.profileFd != null) {
19602 profilerInfo.profileFd.close();
19603 } catch (IOException e) {
19609 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19610 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19611 userId, true, ALLOW_FULL_ONLY, callName, null);
19612 ProcessRecord proc = null;
19614 int pid = Integer.parseInt(process);
19615 synchronized (mPidsSelfLocked) {
19616 proc = mPidsSelfLocked.get(pid);
19618 } catch (NumberFormatException e) {
19621 if (proc == null) {
19622 ArrayMap<String, SparseArray<ProcessRecord>> all
19623 = mProcessNames.getMap();
19624 SparseArray<ProcessRecord> procs = all.get(process);
19625 if (procs != null && procs.size() > 0) {
19626 proc = procs.valueAt(0);
19627 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19628 for (int i=1; i<procs.size(); i++) {
19629 ProcessRecord thisProc = procs.valueAt(i);
19630 if (thisProc.userId == userId) {
19642 public boolean dumpHeap(String process, int userId, boolean managed,
19643 String path, ParcelFileDescriptor fd) throws RemoteException {
19646 synchronized (this) {
19647 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19648 // its own permission (same as profileControl).
19649 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19650 != PackageManager.PERMISSION_GRANTED) {
19651 throw new SecurityException("Requires permission "
19652 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19656 throw new IllegalArgumentException("null fd");
19659 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19660 if (proc == null || proc.thread == null) {
19661 throw new IllegalArgumentException("Unknown process: " + process);
19664 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19665 if (!isDebuggable) {
19666 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19667 throw new SecurityException("Process not debuggable: " + proc);
19671 proc.thread.dumpHeap(managed, path, fd);
19675 } catch (RemoteException e) {
19676 throw new IllegalStateException("Process disappeared");
19681 } catch (IOException e) {
19688 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19689 String reportPackage) {
19690 if (processName != null) {
19691 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19692 "setDumpHeapDebugLimit()");
19694 synchronized (mPidsSelfLocked) {
19695 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19696 if (proc == null) {
19697 throw new SecurityException("No process found for calling pid "
19698 + Binder.getCallingPid());
19700 if (!Build.IS_DEBUGGABLE
19701 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19702 throw new SecurityException("Not running a debuggable build");
19704 processName = proc.processName;
19706 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19707 throw new SecurityException("Package " + reportPackage + " is not running in "
19712 synchronized (this) {
19713 if (maxMemSize > 0) {
19714 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19717 mMemWatchProcesses.remove(processName, uid);
19719 mMemWatchProcesses.getMap().remove(processName);
19726 public void dumpHeapFinished(String path) {
19727 synchronized (this) {
19728 if (Binder.getCallingPid() != mMemWatchDumpPid) {
19729 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19730 + " does not match last pid " + mMemWatchDumpPid);
19733 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19734 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19735 + " does not match last path " + mMemWatchDumpFile);
19738 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19739 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19743 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19744 public void monitor() {
19745 synchronized (this) { }
19748 void onCoreSettingsChange(Bundle settings) {
19749 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19750 ProcessRecord processRecord = mLruProcesses.get(i);
19752 if (processRecord.thread != null) {
19753 processRecord.thread.setCoreSettings(settings);
19755 } catch (RemoteException re) {
19761 // Multi-user methods
19764 * Start user, if its not already running, but don't bring it to foreground.
19767 public boolean startUserInBackground(final int userId) {
19768 return startUser(userId, /* foreground */ false);
19772 * Start user, if its not already running, and bring it to foreground.
19774 boolean startUserInForeground(final int userId, Dialog dlg) {
19775 boolean result = startUser(userId, /* foreground */ true);
19781 * Refreshes the list of users related to the current user when either a
19782 * user switch happens or when a new related user is started in the
19785 private void updateCurrentProfileIdsLocked() {
19786 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19787 mCurrentUserId, false /* enabledOnly */);
19788 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19789 for (int i = 0; i < currentProfileIds.length; i++) {
19790 currentProfileIds[i] = profiles.get(i).id;
19792 mCurrentProfileIds = currentProfileIds;
19794 synchronized (mUserProfileGroupIdsSelfLocked) {
19795 mUserProfileGroupIdsSelfLocked.clear();
19796 final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19797 for (int i = 0; i < users.size(); i++) {
19798 UserInfo user = users.get(i);
19799 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19800 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19806 private Set<Integer> getProfileIdsLocked(int userId) {
19807 Set<Integer> userIds = new HashSet<Integer>();
19808 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19809 userId, false /* enabledOnly */);
19810 for (UserInfo user : profiles) {
19811 userIds.add(Integer.valueOf(user.id));
19817 public boolean switchUser(final int userId) {
19818 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19820 synchronized (this) {
19821 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19822 if (userInfo == null) {
19823 Slog.w(TAG, "No user info for user #" + userId);
19826 if (userInfo.isManagedProfile()) {
19827 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19830 userName = userInfo.name;
19831 mTargetUserId = userId;
19833 mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19834 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19838 private void showUserSwitchDialog(int userId, String userName) {
19839 // The dialog will show and then initiate the user switch by calling startUserInForeground
19840 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19841 true /* above system */);
19845 private boolean startUser(final int userId, final boolean foreground) {
19846 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19847 != PackageManager.PERMISSION_GRANTED) {
19848 String msg = "Permission Denial: switchUser() from pid="
19849 + Binder.getCallingPid()
19850 + ", uid=" + Binder.getCallingUid()
19851 + " requires " + INTERACT_ACROSS_USERS_FULL;
19853 throw new SecurityException(msg);
19856 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19858 final long ident = Binder.clearCallingIdentity();
19860 synchronized (this) {
19861 final int oldUserId = mCurrentUserId;
19862 if (oldUserId == userId) {
19866 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19867 "startUser", false);
19869 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19870 if (userInfo == null) {
19871 Slog.w(TAG, "No user info for user #" + userId);
19874 if (foreground && userInfo.isManagedProfile()) {
19875 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19880 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19881 R.anim.screen_user_enter);
19884 boolean needStart = false;
19886 // If the user we are switching to is not currently started, then
19887 // we need to start it now.
19888 if (mStartedUsers.get(userId) == null) {
19889 mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19890 updateStartedUserArrayLocked();
19894 final Integer userIdInt = Integer.valueOf(userId);
19895 mUserLru.remove(userIdInt);
19896 mUserLru.add(userIdInt);
19899 mCurrentUserId = userId;
19900 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19901 updateCurrentProfileIdsLocked();
19902 mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19903 // Once the internal notion of the active user has switched, we lock the device
19904 // with the option to show the user switcher on the keyguard.
19905 mWindowManager.lockNow(null);
19907 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19908 updateCurrentProfileIdsLocked();
19909 mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19910 mUserLru.remove(currentUserIdInt);
19911 mUserLru.add(currentUserIdInt);
19914 final UserState uss = mStartedUsers.get(userId);
19916 // Make sure user is in the started state. If it is currently
19917 // stopping, we need to knock that off.
19918 if (uss.mState == UserState.STATE_STOPPING) {
19919 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19920 // so we can just fairly silently bring the user back from
19921 // the almost-dead.
19922 uss.mState = UserState.STATE_RUNNING;
19923 updateStartedUserArrayLocked();
19925 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19926 // This means ACTION_SHUTDOWN has been sent, so we will
19927 // need to treat this as a new boot of the user.
19928 uss.mState = UserState.STATE_BOOTING;
19929 updateStartedUserArrayLocked();
19933 if (uss.mState == UserState.STATE_BOOTING) {
19934 // Booting up a new user, need to tell system services about it.
19935 // Note that this is on the same handler as scheduling of broadcasts,
19936 // which is important because it needs to go first.
19937 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19941 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19943 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19944 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19945 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19946 oldUserId, userId, uss));
19947 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19948 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19952 // Send USER_STARTED broadcast
19953 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19954 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19955 | Intent.FLAG_RECEIVER_FOREGROUND);
19956 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19957 broadcastIntentLocked(null, null, intent,
19958 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19959 null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19962 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19963 if (userId != UserHandle.USER_OWNER) {
19964 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19965 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19966 broadcastIntentLocked(null, null, intent, null,
19967 new IIntentReceiver.Stub() {
19968 public void performReceive(Intent intent, int resultCode,
19969 String data, Bundle extras, boolean ordered,
19970 boolean sticky, int sendingUser) {
19971 onUserInitialized(uss, foreground, oldUserId, userId);
19973 }, 0, null, null, null, AppOpsManager.OP_NONE,
19974 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19975 uss.initializing = true;
19977 getUserManagerLocked().makeInitialized(userInfo.id);
19982 if (!uss.initializing) {
19983 moveUserToForeground(uss, oldUserId, userId);
19986 mStackSupervisor.startBackgroundUserLocked(userId, uss);
19990 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19991 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19992 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19993 broadcastIntentLocked(null, null, intent,
19994 null, new IIntentReceiver.Stub() {
19996 public void performReceive(Intent intent, int resultCode,
19997 String data, Bundle extras, boolean ordered, boolean sticky,
19998 int sendingUser) throws RemoteException {
20001 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20002 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20006 Binder.restoreCallingIdentity(ident);
20012 void dispatchForegroundProfileChanged(int userId) {
20013 final int N = mUserSwitchObservers.beginBroadcast();
20014 for (int i = 0; i < N; i++) {
20016 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
20017 } catch (RemoteException e) {
20021 mUserSwitchObservers.finishBroadcast();
20024 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
20025 long ident = Binder.clearCallingIdentity();
20028 if (oldUserId >= 0) {
20029 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
20030 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
20031 int count = profiles.size();
20032 for (int i = 0; i < count; i++) {
20033 int profileUserId = profiles.get(i).id;
20034 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
20035 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20036 | Intent.FLAG_RECEIVER_FOREGROUND);
20037 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20038 broadcastIntentLocked(null, null, intent,
20039 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20040 null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20043 if (newUserId >= 0) {
20044 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
20045 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
20046 int count = profiles.size();
20047 for (int i = 0; i < count; i++) {
20048 int profileUserId = profiles.get(i).id;
20049 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
20050 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20051 | Intent.FLAG_RECEIVER_FOREGROUND);
20052 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20053 broadcastIntentLocked(null, null, intent,
20054 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20055 null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20057 intent = new Intent(Intent.ACTION_USER_SWITCHED);
20058 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20059 | Intent.FLAG_RECEIVER_FOREGROUND);
20060 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
20061 broadcastIntentLocked(null, null, intent,
20062 null, null, 0, null, null,
20063 new String[] {android.Manifest.permission.MANAGE_USERS},
20064 AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20065 UserHandle.USER_ALL);
20068 Binder.restoreCallingIdentity(ident);
20072 void dispatchUserSwitch(final UserState uss, final int oldUserId,
20073 final int newUserId) {
20074 final int N = mUserSwitchObservers.beginBroadcast();
20076 final IRemoteCallback callback = new IRemoteCallback.Stub() {
20079 public void sendResult(Bundle data) throws RemoteException {
20080 synchronized (ActivityManagerService.this) {
20081 if (mCurUserSwitchCallback == this) {
20084 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20090 synchronized (this) {
20091 uss.switching = true;
20092 mCurUserSwitchCallback = callback;
20094 for (int i=0; i<N; i++) {
20096 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20097 newUserId, callback);
20098 } catch (RemoteException e) {
20102 synchronized (this) {
20103 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20106 mUserSwitchObservers.finishBroadcast();
20109 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20110 synchronized (this) {
20111 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20112 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20116 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20117 mCurUserSwitchCallback = null;
20118 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20119 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20120 oldUserId, newUserId, uss));
20123 void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20124 synchronized (this) {
20126 moveUserToForeground(uss, oldUserId, newUserId);
20130 completeSwitchAndInitialize(uss, newUserId, true, false);
20133 void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20134 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20136 startHomeActivityLocked(newUserId, "moveUserToFroreground");
20138 mStackSupervisor.resumeTopActivitiesLocked();
20140 EventLogTags.writeAmSwitchUser(newUserId);
20141 getUserManagerLocked().onUserForeground(newUserId);
20142 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20145 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20146 completeSwitchAndInitialize(uss, newUserId, false, true);
20149 void completeSwitchAndInitialize(UserState uss, int newUserId,
20150 boolean clearInitializing, boolean clearSwitching) {
20151 boolean unfrozen = false;
20152 synchronized (this) {
20153 if (clearInitializing) {
20154 uss.initializing = false;
20155 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20157 if (clearSwitching) {
20158 uss.switching = false;
20160 if (!uss.switching && !uss.initializing) {
20161 mWindowManager.stopFreezingScreen();
20166 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20167 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20170 stopGuestUserIfBackground();
20173 /** Called on handler thread */
20174 void dispatchUserSwitchComplete(int userId) {
20175 final int observerCount = mUserSwitchObservers.beginBroadcast();
20176 for (int i = 0; i < observerCount; i++) {
20178 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20179 } catch (RemoteException e) {
20182 mUserSwitchObservers.finishBroadcast();
20186 * Stops the guest user if it has gone to the background.
20188 private void stopGuestUserIfBackground() {
20189 synchronized (this) {
20190 final int num = mUserLru.size();
20191 for (int i = 0; i < num; i++) {
20192 Integer oldUserId = mUserLru.get(i);
20193 UserState oldUss = mStartedUsers.get(oldUserId);
20194 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20195 || oldUss.mState == UserState.STATE_STOPPING
20196 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20199 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20200 if (userInfo.isGuest()) {
20201 // This is a user to be stopped.
20202 stopUserLocked(oldUserId, null);
20209 void scheduleStartProfilesLocked() {
20210 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20211 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20212 DateUtils.SECOND_IN_MILLIS);
20216 void startProfilesLocked() {
20217 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20218 List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20219 mCurrentUserId, false /* enabledOnly */);
20220 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20221 for (UserInfo user : profiles) {
20222 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20223 && user.id != mCurrentUserId) {
20227 final int n = toStart.size();
20229 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20230 startUserInBackground(toStart.get(i).id);
20233 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20237 void finishUserBoot(UserState uss) {
20238 synchronized (this) {
20239 if (uss.mState == UserState.STATE_BOOTING
20240 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20241 uss.mState = UserState.STATE_RUNNING;
20242 final int userId = uss.mHandle.getIdentifier();
20243 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20244 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20245 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20246 broadcastIntentLocked(null, null, intent,
20247 null, null, 0, null, null,
20248 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20249 AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20255 void finishUserSwitch(UserState uss) {
20256 synchronized (this) {
20257 finishUserBoot(uss);
20259 startProfilesLocked();
20261 int num = mUserLru.size();
20263 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20264 Integer oldUserId = mUserLru.get(i);
20265 UserState oldUss = mStartedUsers.get(oldUserId);
20266 if (oldUss == null) {
20267 // Shouldn't happen, but be sane if it does.
20268 mUserLru.remove(i);
20272 if (oldUss.mState == UserState.STATE_STOPPING
20273 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20274 // This user is already stopping, doesn't count.
20279 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20280 // Owner and current can't be stopped, but count as running.
20284 // This is a user to be stopped.
20285 stopUserLocked(oldUserId, null);
20293 public int stopUser(final int userId, final IStopUserCallback callback) {
20294 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20295 != PackageManager.PERMISSION_GRANTED) {
20296 String msg = "Permission Denial: switchUser() from pid="
20297 + Binder.getCallingPid()
20298 + ", uid=" + Binder.getCallingUid()
20299 + " requires " + INTERACT_ACROSS_USERS_FULL;
20301 throw new SecurityException(msg);
20303 if (userId < 0 || userId == UserHandle.USER_OWNER) {
20304 throw new IllegalArgumentException("Can't stop primary user " + userId);
20306 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20307 synchronized (this) {
20308 return stopUserLocked(userId, callback);
20312 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20313 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20314 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20315 return ActivityManager.USER_OP_IS_CURRENT;
20318 final UserState uss = mStartedUsers.get(userId);
20320 // User is not started, nothing to do... but we do need to
20321 // callback if requested.
20322 if (callback != null) {
20323 mHandler.post(new Runnable() {
20325 public void run() {
20327 callback.userStopped(userId);
20328 } catch (RemoteException e) {
20333 return ActivityManager.USER_OP_SUCCESS;
20336 if (callback != null) {
20337 uss.mStopCallbacks.add(callback);
20340 if (uss.mState != UserState.STATE_STOPPING
20341 && uss.mState != UserState.STATE_SHUTDOWN) {
20342 uss.mState = UserState.STATE_STOPPING;
20343 updateStartedUserArrayLocked();
20345 long ident = Binder.clearCallingIdentity();
20347 // We are going to broadcast ACTION_USER_STOPPING and then
20348 // once that is done send a final ACTION_SHUTDOWN and then
20350 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20351 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20352 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20353 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20354 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20355 // This is the result receiver for the final shutdown broadcast.
20356 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20358 public void performReceive(Intent intent, int resultCode, String data,
20359 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20360 finishUserStop(uss);
20363 // This is the result receiver for the initial stopping broadcast.
20364 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20366 public void performReceive(Intent intent, int resultCode, String data,
20367 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20369 synchronized (ActivityManagerService.this) {
20370 if (uss.mState != UserState.STATE_STOPPING) {
20371 // Whoops, we are being started back up. Abort, abort!
20374 uss.mState = UserState.STATE_SHUTDOWN;
20376 mBatteryStatsService.noteEvent(
20377 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20378 Integer.toString(userId), userId);
20379 mSystemServiceManager.stopUser(userId);
20380 broadcastIntentLocked(null, null, shutdownIntent,
20381 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20382 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20385 // Kick things off.
20386 broadcastIntentLocked(null, null, stoppingIntent,
20387 null, stoppingReceiver, 0, null, null,
20388 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20389 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20391 Binder.restoreCallingIdentity(ident);
20395 return ActivityManager.USER_OP_SUCCESS;
20398 void finishUserStop(UserState uss) {
20399 final int userId = uss.mHandle.getIdentifier();
20401 ArrayList<IStopUserCallback> callbacks;
20402 synchronized (this) {
20403 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20404 if (mStartedUsers.get(userId) != uss) {
20406 } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20410 // User can no longer run.
20411 mStartedUsers.remove(userId);
20412 mUserLru.remove(Integer.valueOf(userId));
20413 updateStartedUserArrayLocked();
20415 // Clean up all state and processes associated with the user.
20416 // Kill all the processes for the user.
20417 forceStopUserLocked(userId, "finish user");
20420 // Explicitly remove the old information in mRecentTasks.
20421 mRecentTasks.removeTasksForUserLocked(userId);
20424 for (int i=0; i<callbacks.size(); i++) {
20426 if (stopped) callbacks.get(i).userStopped(userId);
20427 else callbacks.get(i).userStopAborted(userId);
20428 } catch (RemoteException e) {
20433 mSystemServiceManager.cleanupUser(userId);
20434 synchronized (this) {
20435 mStackSupervisor.removeUserLocked(userId);
20441 public UserInfo getCurrentUser() {
20442 if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20443 != PackageManager.PERMISSION_GRANTED) && (
20444 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20445 != PackageManager.PERMISSION_GRANTED)) {
20446 String msg = "Permission Denial: getCurrentUser() from pid="
20447 + Binder.getCallingPid()
20448 + ", uid=" + Binder.getCallingUid()
20449 + " requires " + INTERACT_ACROSS_USERS;
20451 throw new SecurityException(msg);
20453 synchronized (this) {
20454 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20455 return getUserManagerLocked().getUserInfo(userId);
20459 int getCurrentUserIdLocked() {
20460 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20464 public boolean isUserRunning(int userId, boolean orStopped) {
20465 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20466 != PackageManager.PERMISSION_GRANTED) {
20467 String msg = "Permission Denial: isUserRunning() from pid="
20468 + Binder.getCallingPid()
20469 + ", uid=" + Binder.getCallingUid()
20470 + " requires " + INTERACT_ACROSS_USERS;
20472 throw new SecurityException(msg);
20474 synchronized (this) {
20475 return isUserRunningLocked(userId, orStopped);
20479 boolean isUserRunningLocked(int userId, boolean orStopped) {
20480 UserState state = mStartedUsers.get(userId);
20481 if (state == null) {
20487 return state.mState != UserState.STATE_STOPPING
20488 && state.mState != UserState.STATE_SHUTDOWN;
20492 public int[] getRunningUserIds() {
20493 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20494 != PackageManager.PERMISSION_GRANTED) {
20495 String msg = "Permission Denial: isUserRunning() from pid="
20496 + Binder.getCallingPid()
20497 + ", uid=" + Binder.getCallingUid()
20498 + " requires " + INTERACT_ACROSS_USERS;
20500 throw new SecurityException(msg);
20502 synchronized (this) {
20503 return mStartedUserArray;
20507 private void updateStartedUserArrayLocked() {
20509 for (int i=0; i<mStartedUsers.size(); i++) {
20510 UserState uss = mStartedUsers.valueAt(i);
20511 // This list does not include stopping users.
20512 if (uss.mState != UserState.STATE_STOPPING
20513 && uss.mState != UserState.STATE_SHUTDOWN) {
20517 mStartedUserArray = new int[num];
20519 for (int i=0; i<mStartedUsers.size(); i++) {
20520 UserState uss = mStartedUsers.valueAt(i);
20521 if (uss.mState != UserState.STATE_STOPPING
20522 && uss.mState != UserState.STATE_SHUTDOWN) {
20523 mStartedUserArray[num] = mStartedUsers.keyAt(i);
20530 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20531 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20532 != PackageManager.PERMISSION_GRANTED) {
20533 String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20534 + Binder.getCallingPid()
20535 + ", uid=" + Binder.getCallingUid()
20536 + " requires " + INTERACT_ACROSS_USERS_FULL;
20538 throw new SecurityException(msg);
20541 mUserSwitchObservers.register(observer);
20545 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20546 mUserSwitchObservers.unregister(observer);
20549 int[] getUsersLocked() {
20550 UserManagerService ums = getUserManagerLocked();
20551 return ums != null ? ums.getUserIds() : new int[] { 0 };
20554 UserManagerService getUserManagerLocked() {
20555 if (mUserManager == null) {
20556 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20557 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20559 return mUserManager;
20562 private int applyUserId(int uid, int userId) {
20563 return UserHandle.getUid(userId, uid);
20566 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20567 if (info == null) return null;
20568 ApplicationInfo newInfo = new ApplicationInfo(info);
20569 newInfo.uid = applyUserId(info.uid, userId);
20570 newInfo.dataDir = Environment
20571 .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20572 .getAbsolutePath();
20576 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20578 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20582 ActivityInfo info = new ActivityInfo(aInfo);
20583 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20587 private final class LocalService extends ActivityManagerInternal {
20589 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
20590 int targetUserId) {
20591 synchronized (ActivityManagerService.this) {
20592 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
20593 targetPkg, intent, null, targetUserId);
20598 public String checkContentProviderAccess(String authority, int userId) {
20599 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
20603 public void onWakefulnessChanged(int wakefulness) {
20604 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20608 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20609 String processName, String abiOverride, int uid, Runnable crashHandler) {
20610 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20611 processName, abiOverride, uid, crashHandler);
20615 public SleepToken acquireSleepToken(String tag) {
20616 Preconditions.checkNotNull(tag);
20618 synchronized (ActivityManagerService.this) {
20619 SleepTokenImpl token = new SleepTokenImpl(tag);
20620 mSleepTokens.add(token);
20621 updateSleepIfNeededLocked();
20627 public ComponentName getHomeActivityForUser(int userId) {
20628 synchronized (ActivityManagerService.this) {
20629 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20630 return homeActivity == null ? null : homeActivity.realActivity;
20635 private final class SleepTokenImpl extends SleepToken {
20636 private final String mTag;
20637 private final long mAcquireTime;
20639 public SleepTokenImpl(String tag) {
20641 mAcquireTime = SystemClock.uptimeMillis();
20645 public void release() {
20646 synchronized (ActivityManagerService.this) {
20647 if (mSleepTokens.remove(this)) {
20648 updateSleepIfNeededLocked();
20654 public String toString() {
20655 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20660 * An implementation of IAppTask, that allows an app to manage its own tasks via
20661 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
20662 * only the process that calls getAppTasks() can call the AppTask methods.
20664 class AppTaskImpl extends IAppTask.Stub {
20665 private int mTaskId;
20666 private int mCallingUid;
20668 public AppTaskImpl(int taskId, int callingUid) {
20670 mCallingUid = callingUid;
20673 private void checkCaller() {
20674 if (mCallingUid != Binder.getCallingUid()) {
20675 throw new SecurityException("Caller " + mCallingUid
20676 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20681 public void finishAndRemoveTask() {
20684 synchronized (ActivityManagerService.this) {
20685 long origId = Binder.clearCallingIdentity();
20687 if (!removeTaskByIdLocked(mTaskId, false)) {
20688 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20691 Binder.restoreCallingIdentity(origId);
20697 public ActivityManager.RecentTaskInfo getTaskInfo() {
20700 synchronized (ActivityManagerService.this) {
20701 long origId = Binder.clearCallingIdentity();
20703 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20705 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20707 return createRecentTaskInfoFromTaskRecord(tr);
20709 Binder.restoreCallingIdentity(origId);
20715 public void moveToFront() {
20717 // Will bring task to front if it already has a root activity.
20718 startActivityFromRecentsInner(mTaskId, null);
20722 public int startActivity(IBinder whoThread, String callingPackage,
20723 Intent intent, String resolvedType, Bundle options) {
20726 int callingUser = UserHandle.getCallingUserId();
20728 IApplicationThread appThread;
20729 synchronized (ActivityManagerService.this) {
20730 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20732 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20734 appThread = ApplicationThreadNative.asInterface(whoThread);
20735 if (appThread == null) {
20736 throw new IllegalArgumentException("Bad app thread " + appThread);
20739 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20740 resolvedType, null, null, null, null, 0, 0, null, null,
20741 null, options, false, callingUser, null, tr);
20745 public void setExcludeFromRecents(boolean exclude) {
20748 synchronized (ActivityManagerService.this) {
20749 long origId = Binder.clearCallingIdentity();
20751 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20753 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20755 Intent intent = tr.getBaseIntent();
20757 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20759 intent.setFlags(intent.getFlags()
20760 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20763 Binder.restoreCallingIdentity(origId);