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.Settings;
216 import android.text.format.DateUtils;
217 import android.text.format.Time;
218 import android.util.AtomicFile;
219 import android.util.EventLog;
220 import android.util.Log;
221 import android.util.Pair;
222 import android.util.PrintWriterPrinter;
223 import android.util.Slog;
224 import android.util.SparseArray;
225 import android.util.TimeUtils;
226 import android.util.Xml;
227 import android.view.Gravity;
228 import android.view.LayoutInflater;
229 import android.view.View;
230 import android.view.WindowManager;
232 import dalvik.system.VMRuntime;
234 import java.io.BufferedInputStream;
235 import java.io.BufferedOutputStream;
236 import java.io.DataInputStream;
237 import java.io.DataOutputStream;
239 import java.io.FileDescriptor;
240 import java.io.FileInputStream;
241 import java.io.FileNotFoundException;
242 import java.io.FileOutputStream;
243 import java.io.IOException;
244 import java.io.InputStreamReader;
245 import java.io.PrintWriter;
246 import java.io.StringWriter;
247 import java.lang.ref.WeakReference;
248 import java.nio.charset.StandardCharsets;
249 import java.util.ArrayList;
250 import java.util.Arrays;
251 import java.util.Collections;
252 import java.util.Comparator;
253 import java.util.HashMap;
254 import java.util.HashSet;
255 import java.util.Iterator;
256 import java.util.List;
257 import java.util.Locale;
258 import java.util.Map;
259 import java.util.Set;
260 import java.util.concurrent.atomic.AtomicBoolean;
261 import java.util.concurrent.atomic.AtomicLong;
263 public final class ActivityManagerService extends ActivityManagerNative
264 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
266 // File that stores last updated system version and called preboot receivers
267 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
269 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
270 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
271 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
272 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
273 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
274 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
275 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
276 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
277 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
278 private static final String TAG_LRU = TAG + POSTFIX_LRU;
279 private static final String TAG_MU = TAG + POSTFIX_MU;
280 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
281 private static final String TAG_POWER = TAG + POSTFIX_POWER;
282 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
283 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
284 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
285 private static final String TAG_PSS = TAG + POSTFIX_PSS;
286 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
287 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
288 private static final String TAG_STACK = TAG + POSTFIX_STACK;
289 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
290 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
291 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
292 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
293 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
295 /** Control over CPU and battery monitoring */
296 // write battery stats every 30 minutes.
297 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
298 static final boolean MONITOR_CPU_USAGE = true;
299 // don't sample cpu less than every 5 seconds.
300 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
301 // wait possibly forever for next cpu sample.
302 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
303 static final boolean MONITOR_THREAD_CPU_USAGE = false;
305 // The flags that are set for all calls we make to the package manager.
306 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
308 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
310 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
312 // Amount of time after a call to stopAppSwitches() during which we will
313 // prevent further untrusted switches from happening.
314 static final long APP_SWITCH_DELAY_TIME = 5*1000;
316 // How long we wait for a launched process to attach to the activity manager
317 // before we decide it's never going to come up for real.
318 static final int PROC_START_TIMEOUT = 10*1000;
320 // How long we wait for a launched process to attach to the activity manager
321 // before we decide it's never going to come up for real, when the process was
322 // started with a wrapper for instrumentation (such as Valgrind) because it
323 // could take much longer than usual.
324 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
326 // How long to wait after going idle before forcing apps to GC.
327 static final int GC_TIMEOUT = 5*1000;
329 // The minimum amount of time between successive GC requests for a process.
330 static final int GC_MIN_INTERVAL = 60*1000;
332 // The minimum amount of time between successive PSS requests for a process.
333 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
335 // The minimum amount of time between successive PSS requests for a process
336 // when the request is due to the memory state being lowered.
337 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
339 // The rate at which we check for apps using excessive power -- 15 mins.
340 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
342 // The minimum sample duration we will allow before deciding we have
343 // enough data on wake locks to start killing things.
344 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
346 // The minimum sample duration we will allow before deciding we have
347 // enough data on CPU usage to start killing things.
348 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
350 // How long we allow a receiver to run before giving up on it.
351 static final int BROADCAST_FG_TIMEOUT = 10*1000;
352 static final int BROADCAST_BG_TIMEOUT = 60*1000;
354 // How long we wait until we timeout on key dispatching.
355 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
357 // How long we wait until we timeout on key dispatching during instrumentation.
358 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
360 // Amount of time we wait for observers to handle a user switch before
361 // giving up on them and unfreezing the screen.
362 static final int USER_SWITCH_TIMEOUT = 2*1000;
364 // This is the amount of time an app needs to be running a foreground service before
365 // we will consider it to be doing interaction for usage stats.
366 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
368 // Maximum number of users we allow to be running at a time.
369 static final int MAX_RUNNING_USERS = 3;
371 // How long to wait in getAssistContextExtras for the activity and foreground services
372 // to respond with the result.
373 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
375 // How long top wait when going through the modern assist (which doesn't need to block
376 // on getting this result before starting to launch its UI).
377 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
379 // Maximum number of persisted Uri grants a package is allowed
380 static final int MAX_PERSISTED_URI_GRANTS = 128;
382 static final int MY_PID = Process.myPid();
384 static final String[] EMPTY_STRING_ARRAY = new String[0];
386 // How many bytes to write into the dropbox log before truncating
387 static final int DROPBOX_MAX_SIZE = 256 * 1024;
389 // Access modes for handleIncomingUser.
390 static final int ALLOW_NON_FULL = 0;
391 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
392 static final int ALLOW_FULL_ONLY = 2;
394 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
396 // Delay in notifying task stack change listeners (in millis)
397 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
399 // Necessary ApplicationInfo flags to mark an app as persistent
400 private static final int PERSISTENT_MASK =
401 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
403 /** All system services */
404 SystemServiceManager mSystemServiceManager;
406 private Installer mInstaller;
408 /** Run all ActivityStacks through this */
409 ActivityStackSupervisor mStackSupervisor;
411 /** Task stack change listeners. */
412 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
413 new RemoteCallbackList<ITaskStackListener>();
415 public IntentFirewall mIntentFirewall;
417 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
418 // default actuion automatically. Important for devices without direct input
420 private boolean mShowDialogs = true;
422 BroadcastQueue mFgBroadcastQueue;
423 BroadcastQueue mBgBroadcastQueue;
424 // Convenient for easy iteration over the queues. Foreground is first
425 // so that dispatch of foreground broadcasts gets precedence.
426 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
428 BroadcastQueue broadcastQueueForIntent(Intent intent) {
429 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
430 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
431 "Broadcast intent " + intent + " on "
432 + (isFg ? "foreground" : "background") + " queue");
433 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
437 * Activity we have told the window manager to have key focus.
439 ActivityRecord mFocusedActivity = null;
442 * User id of the last activity mFocusedActivity was set to.
444 private int mLastFocusedUserId;
447 * If non-null, we are tracking the time the user spends in the currently focused app.
449 private AppTimeTracker mCurAppTimeTracker;
452 * List of intents that were used to start the most recent tasks.
454 private final RecentTasks mRecentTasks;
457 * For addAppTask: cached of the last activity component that was added.
459 ComponentName mLastAddedTaskComponent;
462 * For addAppTask: cached of the last activity uid that was added.
464 int mLastAddedTaskUid;
467 * For addAppTask: cached of the last ActivityInfo that was added.
469 ActivityInfo mLastAddedTaskActivity;
472 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
474 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
477 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
479 String mDeviceOwnerName;
481 public class PendingAssistExtras extends Binder implements Runnable {
482 public final ActivityRecord activity;
483 public final Bundle extras;
484 public final Intent intent;
485 public final String hint;
486 public final IResultReceiver receiver;
487 public final int userHandle;
488 public boolean haveResult = false;
489 public Bundle result = null;
490 public AssistStructure structure = null;
491 public AssistContent content = null;
492 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
493 String _hint, IResultReceiver _receiver, int _userHandle) {
494 activity = _activity;
498 receiver = _receiver;
499 userHandle = _userHandle;
503 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
504 synchronized (this) {
508 pendingAssistExtrasTimedOut(this);
512 final ArrayList<PendingAssistExtras> mPendingAssistExtras
513 = new ArrayList<PendingAssistExtras>();
516 * Process management.
518 final ProcessList mProcessList = new ProcessList();
521 * All of the applications we currently have running organized by name.
522 * The keys are strings of the application package name (as
523 * returned by the package manager), and the keys are ApplicationRecord
526 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
529 * Tracking long-term execution of processes to look for abuse and other
532 final ProcessStatsService mProcessStats;
535 * The currently running isolated processes.
537 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
540 * Counter for assigning isolated process uids, to avoid frequently reusing the
543 int mNextIsolatedProcessUid = 0;
546 * The currently running heavy-weight process, if any.
548 ProcessRecord mHeavyWeightProcess = null;
551 * The last time that various processes have crashed.
553 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
556 * Information about a process that is currently marked as bad.
558 static final class BadProcessInfo {
559 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
561 this.shortMsg = shortMsg;
562 this.longMsg = longMsg;
567 final String shortMsg;
568 final String longMsg;
573 * Set of applications that we consider to be bad, and will reject
574 * incoming broadcasts from (which the user has no control over).
575 * Processes are added to this set when they have crashed twice within
576 * a minimum amount of time; they are removed from it when they are
577 * later restarted (hopefully due to some user action). The value is the
578 * time it was added to the list.
580 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
583 * All of the processes we currently have running organized by pid.
584 * The keys are the pid running the application.
586 * <p>NOTE: This object is protected by its own lock, NOT the global
587 * activity manager lock!
589 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
592 * All of the processes that have been forced to be foreground. The key
593 * is the pid of the caller who requested it (we hold a death
596 abstract class ForegroundToken implements IBinder.DeathRecipient {
600 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
603 * List of records for processes that someone had tried to start before the
604 * system was ready. We don't start them at that point, but ensure they
605 * are started by the time booting is complete.
607 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
610 * List of persistent applications that are in the process
613 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
616 * Processes that are being forcibly torn down.
618 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
621 * List of running applications, sorted by recent usage.
622 * The first entry in the list is the least recently used.
624 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
627 * Where in mLruProcesses that the processes hosting activities start.
629 int mLruProcessActivityStart = 0;
632 * Where in mLruProcesses that the processes hosting services start.
633 * This is after (lower index) than mLruProcessesActivityStart.
635 int mLruProcessServiceStart = 0;
638 * List of processes that should gc as soon as things are idle.
640 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
643 * Processes we want to collect PSS data from.
645 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
648 * Last time we requested PSS data of all processes.
650 long mLastFullPssTime = SystemClock.uptimeMillis();
653 * If set, the next time we collect PSS data we should do a full collection
654 * with data from native processes and the kernel.
656 boolean mFullPssPending = false;
659 * This is the process holding what we currently consider to be
660 * the "home" activity.
662 ProcessRecord mHomeProcess;
665 * This is the process holding the activity the user last visited that
666 * is in a different process from the one they are currently in.
668 ProcessRecord mPreviousProcess;
671 * The time at which the previous process was last visible.
673 long mPreviousProcessVisibleTime;
676 * Track all uids that have actively running processes.
678 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
681 * Which users have been started, so are allowed to run code.
683 final SparseArray<UserState> mStartedUsers = new SparseArray<>();
686 * LRU list of history of current users. Most recently current is at the end.
688 final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
691 * Constant array of the users that are currently started.
693 int[] mStartedUserArray = new int[] { 0 };
696 * Registered observers of the user switching mechanics.
698 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
699 = new RemoteCallbackList<IUserSwitchObserver>();
702 * Currently active user switch.
704 Object mCurUserSwitchCallback;
707 * Packages that the user has asked to have run in screen size
708 * compatibility mode instead of filling the screen.
710 final CompatModePackages mCompatModePackages;
713 * Set of IntentSenderRecord objects that are currently active.
715 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
716 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
719 * Fingerprints (hashCode()) of stack traces that we've
720 * already logged DropBox entries for. Guarded by itself. If
721 * something (rogue user app) forces this over
722 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
724 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
725 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
728 * Strict Mode background batched logging state.
730 * The string buffer is guarded by itself, and its lock is also
731 * used to determine if another batched write is already
734 private final StringBuilder mStrictModeBuffer = new StringBuilder();
737 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
738 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
740 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
743 * Resolver for broadcast intents to registered receivers.
744 * Holds BroadcastFilter (subclass of IntentFilter).
746 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
747 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
749 protected boolean allowFilterResult(
750 BroadcastFilter filter, List<BroadcastFilter> dest) {
751 IBinder target = filter.receiverList.receiver.asBinder();
752 for (int i = dest.size() - 1; i >= 0; i--) {
753 if (dest.get(i).receiverList.receiver.asBinder() == target) {
761 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
762 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
763 || userId == filter.owningUserId) {
764 return super.newResult(filter, match, userId);
770 protected BroadcastFilter[] newArray(int size) {
771 return new BroadcastFilter[size];
775 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
776 return packageName.equals(filter.packageName);
781 * State of all active sticky broadcasts per user. Keys are the action of the
782 * sticky Intent, values are an ArrayList of all broadcasted intents with
783 * that action (which should usually be one). The SparseArray is keyed
784 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
785 * for stickies that are sent to all users.
787 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
788 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
790 final ActiveServices mServices;
792 final static class Association {
793 final int mSourceUid;
794 final String mSourceProcess;
795 final int mTargetUid;
796 final ComponentName mTargetComponent;
797 final String mTargetProcess;
805 Association(int sourceUid, String sourceProcess, int targetUid,
806 ComponentName targetComponent, String targetProcess) {
807 mSourceUid = sourceUid;
808 mSourceProcess = sourceProcess;
809 mTargetUid = targetUid;
810 mTargetComponent = targetComponent;
811 mTargetProcess = targetProcess;
816 * When service association tracking is enabled, this is all of the associations we
817 * have seen. Mapping is target uid -> target component -> source uid -> source process name
818 * -> association data.
820 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
821 mAssociations = new SparseArray<>();
822 boolean mTrackingAssociations;
825 * Backup/restore process management
827 String mBackupAppName = null;
828 BackupRecord mBackupTarget = null;
830 final ProviderMap mProviderMap;
833 * List of content providers who have clients waiting for them. The
834 * application is currently being launched and the provider will be
835 * removed from this list once it is published.
837 final ArrayList<ContentProviderRecord> mLaunchingProviders
838 = new ArrayList<ContentProviderRecord>();
841 * File storing persisted {@link #mGrantedUriPermissions}.
843 private final AtomicFile mGrantFile;
845 /** XML constants used in {@link #mGrantFile} */
846 private static final String TAG_URI_GRANTS = "uri-grants";
847 private static final String TAG_URI_GRANT = "uri-grant";
848 private static final String ATTR_USER_HANDLE = "userHandle";
849 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
850 private static final String ATTR_TARGET_USER_ID = "targetUserId";
851 private static final String ATTR_SOURCE_PKG = "sourcePkg";
852 private static final String ATTR_TARGET_PKG = "targetPkg";
853 private static final String ATTR_URI = "uri";
854 private static final String ATTR_MODE_FLAGS = "modeFlags";
855 private static final String ATTR_CREATED_TIME = "createdTime";
856 private static final String ATTR_PREFIX = "prefix";
859 * Global set of specific {@link Uri} permissions that have been granted.
860 * This optimized lookup structure maps from {@link UriPermission#targetUid}
861 * to {@link UriPermission#uri} to {@link UriPermission}.
864 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
865 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
867 public static class GrantUri {
868 public final int sourceUserId;
869 public final Uri uri;
870 public boolean prefix;
872 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
873 this.sourceUserId = sourceUserId;
875 this.prefix = prefix;
879 public int hashCode() {
881 hashCode = 31 * hashCode + sourceUserId;
882 hashCode = 31 * hashCode + uri.hashCode();
883 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
888 public boolean equals(Object o) {
889 if (o instanceof GrantUri) {
890 GrantUri other = (GrantUri) o;
891 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
892 && prefix == other.prefix;
898 public String toString() {
899 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
900 if (prefix) result += " [prefix]";
904 public String toSafeString() {
905 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
906 if (prefix) result += " [prefix]";
910 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
911 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
912 ContentProvider.getUriWithoutUserId(uri), false);
916 CoreSettingsObserver mCoreSettingsObserver;
919 * Thread-local storage used to carry caller permissions over through
920 * indirect content-provider access.
922 private class Identity {
923 public final IBinder token;
924 public final int pid;
925 public final int uid;
927 Identity(IBinder _token, int _pid, int _uid) {
934 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
937 * All information we have collected about the runtime performance of
938 * any user id that can impact battery performance.
940 final BatteryStatsService mBatteryStatsService;
943 * Information about component usage
945 UsageStatsManagerInternal mUsageStatsService;
948 * Access to DeviceIdleController service.
950 DeviceIdleController.LocalService mLocalDeviceIdleController;
953 * Information about and control over application operations
955 final AppOpsService mAppOpsService;
958 * Save recent tasks information across reboots.
960 final TaskPersister mTaskPersister;
963 * Current configuration information. HistoryRecord objects are given
964 * a reference to this object to indicate which configuration they are
965 * currently running in, so this object must be kept immutable.
967 Configuration mConfiguration = new Configuration();
970 * Current sequencing integer of the configuration, for skipping old
973 int mConfigurationSeq = 0;
976 * Hardware-reported OpenGLES version.
978 final int GL_ES_VERSION;
981 * List of initialization arguments to pass to all processes when binding applications to them.
982 * For example, references to the commonly used services.
984 HashMap<String, IBinder> mAppBindArgs;
987 * Temporary to avoid allocations. Protected by main lock.
989 final StringBuilder mStringBuilder = new StringBuilder(256);
992 * Used to control how we initialize the service.
994 ComponentName mTopComponent;
995 String mTopAction = Intent.ACTION_MAIN;
997 boolean mProcessesReady = false;
998 boolean mSystemReady = false;
999 boolean mBooting = false;
1000 boolean mCallFinishBooting = false;
1001 boolean mBootAnimationComplete = false;
1002 boolean mWaitingUpdate = false;
1003 boolean mDidUpdate = false;
1004 boolean mOnBattery = false;
1005 boolean mLaunchWarningShown = false;
1011 boolean mCheckedForSetup;
1014 * The time at which we will allow normal application switches again,
1015 * after a call to {@link #stopAppSwitches()}.
1017 long mAppSwitchesAllowedTime;
1020 * This is set to true after the first switch after mAppSwitchesAllowedTime
1021 * is set; any switches after that will clear the time.
1023 boolean mDidAppSwitch;
1026 * Last time (in realtime) at which we checked for power usage.
1028 long mLastPowerCheckRealtime;
1031 * Last time (in uptime) at which we checked for power usage.
1033 long mLastPowerCheckUptime;
1036 * Set while we are wanting to sleep, to prevent any
1037 * activities from being started/resumed.
1039 private boolean mSleeping = false;
1042 * The process state used for processes that are running the top activities.
1043 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1045 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1048 * Set while we are running a voice interaction. This overrides
1049 * sleeping while it is active.
1051 private IVoiceInteractionSession mRunningVoice;
1054 * For some direct access we need to power manager.
1056 PowerManagerInternal mLocalPowerManager;
1059 * We want to hold a wake lock while running a voice interaction session, since
1060 * this may happen with the screen off and we need to keep the CPU running to
1061 * be able to continue to interact with the user.
1063 PowerManager.WakeLock mVoiceWakeLock;
1066 * State of external calls telling us if the device is awake or asleep.
1068 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1071 * A list of tokens that cause the top activity to be put to sleep.
1072 * They are used by components that may hide and block interaction with underlying
1075 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1077 static final int LOCK_SCREEN_HIDDEN = 0;
1078 static final int LOCK_SCREEN_LEAVING = 1;
1079 static final int LOCK_SCREEN_SHOWN = 2;
1081 * State of external call telling us if the lock screen is shown.
1083 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1086 * Set if we are shutting down the system, similar to sleeping.
1088 boolean mShuttingDown = false;
1091 * Current sequence id for oom_adj computation traversal.
1096 * Current sequence id for process LRU updating.
1101 * Keep track of the non-cached/empty process we last found, to help
1102 * determine how to distribute cached/empty processes next time.
1104 int mNumNonCachedProcs = 0;
1107 * Keep track of the number of cached hidden procs, to balance oom adj
1108 * distribution between those and empty procs.
1110 int mNumCachedHiddenProcs = 0;
1113 * Keep track of the number of service processes we last found, to
1114 * determine on the next iteration which should be B services.
1116 int mNumServiceProcs = 0;
1117 int mNewNumAServiceProcs = 0;
1118 int mNewNumServiceProcs = 0;
1121 * Allow the current computed overall memory level of the system to go down?
1122 * This is set to false when we are killing processes for reasons other than
1123 * memory management, so that the now smaller process list will not be taken as
1124 * an indication that memory is tighter.
1126 boolean mAllowLowerMemLevel = false;
1129 * The last computed memory level, for holding when we are in a state that
1130 * processes are going away for other reasons.
1132 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1135 * The last total number of process we have, to determine if changes actually look
1136 * like a shrinking number of process due to lower RAM.
1138 int mLastNumProcesses;
1141 * The uptime of the last time we performed idle maintenance.
1143 long mLastIdleTime = SystemClock.uptimeMillis();
1146 * Total time spent with RAM that has been added in the past since the last idle time.
1148 long mLowRamTimeSinceLastIdle = 0;
1151 * If RAM is currently low, when that horrible situation started.
1153 long mLowRamStartTime = 0;
1156 * For reporting to battery stats the current top application.
1158 private String mCurResumedPackage = null;
1159 private int mCurResumedUid = -1;
1162 * For reporting to battery stats the apps currently running foreground
1163 * service. The ProcessMap is package/uid tuples; each of these contain
1164 * an array of the currently foreground processes.
1166 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1167 = new ProcessMap<ArrayList<ProcessRecord>>();
1170 * This is set if we had to do a delayed dexopt of an app before launching
1171 * it, to increase the ANR timeouts in that case.
1176 * Set if the systemServer made a call to enterSafeMode.
1181 * If true, we are running under a test environment so will sample PSS from processes
1182 * much more rapidly to try to collect better data when the tests are rapidly
1183 * running through apps.
1185 boolean mTestPssMode = false;
1187 String mDebugApp = null;
1188 boolean mWaitForDebugger = false;
1189 boolean mDebugTransient = false;
1190 String mOrigDebugApp = null;
1191 boolean mOrigWaitForDebugger = false;
1192 boolean mAlwaysFinishActivities = false;
1193 IActivityController mController = null;
1194 String mProfileApp = null;
1195 ProcessRecord mProfileProc = null;
1196 String mProfileFile;
1197 ParcelFileDescriptor mProfileFd;
1198 int mSamplingInterval = 0;
1199 boolean mAutoStopProfiler = false;
1200 int mProfileType = 0;
1201 String mOpenGlTraceApp = null;
1202 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1203 String mMemWatchDumpProcName;
1204 String mMemWatchDumpFile;
1205 int mMemWatchDumpPid;
1206 int mMemWatchDumpUid;
1208 final long[] mTmpLong = new long[1];
1210 static final class ProcessChangeItem {
1211 static final int CHANGE_ACTIVITIES = 1<<0;
1212 static final int CHANGE_PROCESS_STATE = 1<<1;
1217 boolean foregroundActivities;
1220 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1221 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1223 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1224 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1226 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1227 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1229 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1230 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1233 * Runtime CPU use collection thread. This object's lock is used to
1234 * perform synchronization with the thread (notifying it to run).
1236 final Thread mProcessCpuThread;
1239 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1240 * Must acquire this object's lock when accessing it.
1241 * NOTE: this lock will be held while doing long operations (trawling
1242 * through all processes in /proc), so it should never be acquired by
1243 * any critical paths such as when holding the main activity manager lock.
1245 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1246 MONITOR_THREAD_CPU_USAGE);
1247 final AtomicLong mLastCpuTime = new AtomicLong(0);
1248 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1250 long mLastWriteTime = 0;
1253 * Used to retain an update lock when the foreground activity is in
1256 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1259 * Set to true after the system has finished booting.
1261 boolean mBooted = false;
1263 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1264 int mProcessLimitOverride = -1;
1266 WindowManagerService mWindowManager;
1268 final ActivityThread mSystemThread;
1270 // Holds the current foreground user's id
1271 int mCurrentUserId = 0;
1272 // Holds the target user's id during a user switch
1273 int mTargetUserId = UserHandle.USER_NULL;
1274 // If there are multiple profiles for the current user, their ids are here
1275 // Currently only the primary user can have managed profiles
1276 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1279 * Mapping from each known user ID to the profile group ID it is associated with.
1281 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1283 private UserManagerService mUserManager;
1285 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1286 final ProcessRecord mApp;
1288 final IApplicationThread mAppThread;
1290 AppDeathRecipient(ProcessRecord app, int pid,
1291 IApplicationThread thread) {
1292 if (DEBUG_ALL) Slog.v(
1293 TAG, "New death recipient " + this
1294 + " for thread " + thread.asBinder());
1297 mAppThread = thread;
1301 public void binderDied() {
1302 if (DEBUG_ALL) Slog.v(
1303 TAG, "Death received in " + this
1304 + " for thread " + mAppThread.asBinder());
1305 synchronized(ActivityManagerService.this) {
1306 appDiedLocked(mApp, mPid, mAppThread, true);
1311 static final int SHOW_ERROR_MSG = 1;
1312 static final int SHOW_NOT_RESPONDING_MSG = 2;
1313 static final int SHOW_FACTORY_ERROR_MSG = 3;
1314 static final int UPDATE_CONFIGURATION_MSG = 4;
1315 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1316 static final int WAIT_FOR_DEBUGGER_MSG = 6;
1317 static final int SERVICE_TIMEOUT_MSG = 12;
1318 static final int UPDATE_TIME_ZONE = 13;
1319 static final int SHOW_UID_ERROR_MSG = 14;
1320 static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1321 static final int PROC_START_TIMEOUT_MSG = 20;
1322 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1323 static final int KILL_APPLICATION_MSG = 22;
1324 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1325 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1326 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1327 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1328 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1329 static final int CLEAR_DNS_CACHE_MSG = 28;
1330 static final int UPDATE_HTTP_PROXY_MSG = 29;
1331 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1332 static final int DISPATCH_PROCESSES_CHANGED = 31;
1333 static final int DISPATCH_PROCESS_DIED = 32;
1334 static final int REPORT_MEM_USAGE_MSG = 33;
1335 static final int REPORT_USER_SWITCH_MSG = 34;
1336 static final int CONTINUE_USER_SWITCH_MSG = 35;
1337 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1338 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1339 static final int PERSIST_URI_GRANTS_MSG = 38;
1340 static final int REQUEST_ALL_PSS_MSG = 39;
1341 static final int START_PROFILES_MSG = 40;
1342 static final int UPDATE_TIME = 41;
1343 static final int SYSTEM_USER_START_MSG = 42;
1344 static final int SYSTEM_USER_CURRENT_MSG = 43;
1345 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1346 static final int FINISH_BOOTING_MSG = 45;
1347 static final int START_USER_SWITCH_MSG = 46;
1348 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1349 static final int DISMISS_DIALOG_MSG = 48;
1350 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1351 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1352 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1353 static final int DELETE_DUMPHEAP_MSG = 52;
1354 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1355 static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1356 static final int REPORT_TIME_TRACKER_MSG = 55;
1357 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1358 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1360 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1361 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1362 static final int FIRST_COMPAT_MODE_MSG = 300;
1363 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1365 CompatModeDialog mCompatModeDialog;
1366 long mLastMemUsageReportTime = 0;
1369 * Flag whether the current user is a "monkey", i.e. whether
1370 * the UI is driven by a UI automation tool.
1372 private boolean mUserIsMonkey;
1374 /** Flag whether the device has a Recents UI */
1375 boolean mHasRecents;
1377 /** The dimensions of the thumbnails in the Recents UI. */
1378 int mThumbnailWidth;
1379 int mThumbnailHeight;
1381 final ServiceThread mHandlerThread;
1382 final MainHandler mHandler;
1383 final UiHandler mUiHandler;
1385 final class UiHandler extends Handler {
1386 public UiHandler() {
1387 super(com.android.server.UiThread.get().getLooper(), null, true);
1391 public void handleMessage(Message msg) {
1393 case SHOW_ERROR_MSG: {
1394 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1395 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1396 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1397 synchronized (ActivityManagerService.this) {
1398 ProcessRecord proc = (ProcessRecord)data.get("app");
1399 AppErrorResult res = (AppErrorResult) data.get("result");
1400 if (proc != null && proc.crashDialog != null) {
1401 Slog.e(TAG, "App already has crash dialog: " + proc);
1407 boolean isBackground = (UserHandle.getAppId(proc.uid)
1408 >= Process.FIRST_APPLICATION_UID
1409 && proc.pid != MY_PID);
1410 for (int userId : mCurrentProfileIds) {
1411 isBackground &= (proc.userId != userId);
1413 if (isBackground && !showBackground) {
1414 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1420 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1421 Dialog d = new AppErrorDialog(mContext,
1422 ActivityManagerService.this, res, proc);
1424 proc.crashDialog = d;
1426 // The device is asleep, so just pretend that the user
1427 // saw a crash dialog and hit "force quit".
1434 ensureBootCompleted();
1436 case SHOW_NOT_RESPONDING_MSG: {
1437 synchronized (ActivityManagerService.this) {
1438 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1439 ProcessRecord proc = (ProcessRecord)data.get("app");
1440 if (proc != null && proc.anrDialog != null) {
1441 Slog.e(TAG, "App already has anr dialog: " + proc);
1445 Intent intent = new Intent("android.intent.action.ANR");
1446 if (!mProcessesReady) {
1447 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1448 | Intent.FLAG_RECEIVER_FOREGROUND);
1450 broadcastIntentLocked(null, null, intent,
1451 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1452 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1455 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1456 mContext, proc, (ActivityRecord)data.get("activity"),
1461 // Just kill the app if there is no dialog to be shown.
1462 killAppAtUsersRequest(proc, null);
1466 ensureBootCompleted();
1468 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1469 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1470 synchronized (ActivityManagerService.this) {
1471 ProcessRecord proc = (ProcessRecord) data.get("app");
1473 Slog.e(TAG, "App not found when showing strict mode dialog.");
1476 if (proc.crashDialog != null) {
1477 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1480 AppErrorResult res = (AppErrorResult) data.get("result");
1481 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1482 Dialog d = new StrictModeViolationDialog(mContext,
1483 ActivityManagerService.this, res, proc);
1485 proc.crashDialog = d;
1487 // The device is asleep, so just pretend that the user
1488 // saw a crash dialog and hit "force quit".
1492 ensureBootCompleted();
1494 case SHOW_FACTORY_ERROR_MSG: {
1495 Dialog d = new FactoryErrorDialog(
1496 mContext, msg.getData().getCharSequence("msg"));
1498 ensureBootCompleted();
1500 case WAIT_FOR_DEBUGGER_MSG: {
1501 synchronized (ActivityManagerService.this) {
1502 ProcessRecord app = (ProcessRecord)msg.obj;
1503 if (msg.arg1 != 0) {
1504 if (!app.waitedForDebugger) {
1505 Dialog d = new AppWaitingForDebuggerDialog(
1506 ActivityManagerService.this,
1509 app.waitedForDebugger = true;
1513 if (app.waitDialog != null) {
1514 app.waitDialog.dismiss();
1515 app.waitDialog = null;
1520 case SHOW_UID_ERROR_MSG: {
1522 AlertDialog d = new BaseErrorDialog(mContext);
1523 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1524 d.setCancelable(false);
1525 d.setTitle(mContext.getText(R.string.android_system_label));
1526 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1527 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1528 obtainMessage(DISMISS_DIALOG_MSG, d));
1532 case SHOW_FINGERPRINT_ERROR_MSG: {
1534 AlertDialog d = new BaseErrorDialog(mContext);
1535 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1536 d.setCancelable(false);
1537 d.setTitle(mContext.getText(R.string.android_system_label));
1538 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1539 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1540 obtainMessage(DISMISS_DIALOG_MSG, d));
1544 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1545 synchronized (ActivityManagerService.this) {
1546 ActivityRecord ar = (ActivityRecord) msg.obj;
1547 if (mCompatModeDialog != null) {
1548 if (mCompatModeDialog.mAppInfo.packageName.equals(
1549 ar.info.applicationInfo.packageName)) {
1552 mCompatModeDialog.dismiss();
1553 mCompatModeDialog = null;
1555 if (ar != null && false) {
1556 if (mCompatModePackages.getPackageAskCompatModeLocked(
1558 int mode = mCompatModePackages.computeCompatModeLocked(
1559 ar.info.applicationInfo);
1560 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1561 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1562 mCompatModeDialog = new CompatModeDialog(
1563 ActivityManagerService.this, mContext,
1564 ar.info.applicationInfo);
1565 mCompatModeDialog.show();
1572 case START_USER_SWITCH_MSG: {
1573 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1576 case DISMISS_DIALOG_MSG: {
1577 final Dialog d = (Dialog) msg.obj;
1581 case DISPATCH_PROCESSES_CHANGED: {
1582 dispatchProcessesChanged();
1585 case DISPATCH_PROCESS_DIED: {
1586 final int pid = msg.arg1;
1587 final int uid = msg.arg2;
1588 dispatchProcessDied(pid, uid);
1591 case DISPATCH_UIDS_CHANGED_MSG: {
1592 dispatchUidsChanged();
1598 final class MainHandler extends Handler {
1599 public MainHandler(Looper looper) {
1600 super(looper, null, true);
1604 public void handleMessage(Message msg) {
1606 case UPDATE_CONFIGURATION_MSG: {
1607 final ContentResolver resolver = mContext.getContentResolver();
1608 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1610 case GC_BACKGROUND_PROCESSES_MSG: {
1611 synchronized (ActivityManagerService.this) {
1612 performAppGcsIfAppropriateLocked();
1615 case SERVICE_TIMEOUT_MSG: {
1618 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1620 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1623 mServices.serviceTimeout((ProcessRecord)msg.obj);
1625 case UPDATE_TIME_ZONE: {
1626 synchronized (ActivityManagerService.this) {
1627 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1628 ProcessRecord r = mLruProcesses.get(i);
1629 if (r.thread != null) {
1631 r.thread.updateTimeZone();
1632 } catch (RemoteException ex) {
1633 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1639 case CLEAR_DNS_CACHE_MSG: {
1640 synchronized (ActivityManagerService.this) {
1641 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1642 ProcessRecord r = mLruProcesses.get(i);
1643 if (r.thread != null) {
1645 r.thread.clearDnsCache();
1646 } catch (RemoteException ex) {
1647 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1653 case UPDATE_HTTP_PROXY_MSG: {
1654 ProxyInfo proxy = (ProxyInfo)msg.obj;
1657 String exclList = "";
1658 Uri pacFileUrl = Uri.EMPTY;
1659 if (proxy != null) {
1660 host = proxy.getHost();
1661 port = Integer.toString(proxy.getPort());
1662 exclList = proxy.getExclusionListAsString();
1663 pacFileUrl = proxy.getPacFileUrl();
1665 synchronized (ActivityManagerService.this) {
1666 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1667 ProcessRecord r = mLruProcesses.get(i);
1668 if (r.thread != null) {
1670 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1671 } catch (RemoteException ex) {
1672 Slog.w(TAG, "Failed to update http proxy for: " +
1673 r.info.processName);
1679 case PROC_START_TIMEOUT_MSG: {
1682 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1684 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1687 ProcessRecord app = (ProcessRecord)msg.obj;
1688 synchronized (ActivityManagerService.this) {
1689 processStartTimedOutLocked(app);
1692 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1693 synchronized (ActivityManagerService.this) {
1694 mStackSupervisor.doPendingActivityLaunchesLocked(true);
1697 case KILL_APPLICATION_MSG: {
1698 synchronized (ActivityManagerService.this) {
1699 int appid = msg.arg1;
1700 boolean restart = (msg.arg2 == 1);
1701 Bundle bundle = (Bundle)msg.obj;
1702 String pkg = bundle.getString("pkg");
1703 String reason = bundle.getString("reason");
1704 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1705 false, UserHandle.USER_ALL, reason);
1708 case FINALIZE_PENDING_INTENT_MSG: {
1709 ((PendingIntentRecord)msg.obj).completeFinalize();
1711 case POST_HEAVY_NOTIFICATION_MSG: {
1712 INotificationManager inm = NotificationManager.getService();
1717 ActivityRecord root = (ActivityRecord)msg.obj;
1718 ProcessRecord process = root.app;
1719 if (process == null) {
1724 Context context = mContext.createPackageContext(process.info.packageName, 0);
1725 String text = mContext.getString(R.string.heavy_weight_notification,
1726 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1727 Notification notification = new Notification.Builder(context)
1728 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1732 .setColor(mContext.getColor(
1733 com.android.internal.R.color.system_notification_accent_color))
1734 .setContentTitle(text)
1736 mContext.getText(R.string.heavy_weight_notification_detail))
1737 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1738 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1739 new UserHandle(root.userId)))
1742 int[] outId = new int[1];
1743 inm.enqueueNotificationWithTag("android", "android", null,
1744 R.string.heavy_weight_notification,
1745 notification, outId, root.userId);
1746 } catch (RuntimeException e) {
1747 Slog.w(ActivityManagerService.TAG,
1748 "Error showing notification for heavy-weight app", e);
1749 } catch (RemoteException e) {
1751 } catch (NameNotFoundException e) {
1752 Slog.w(TAG, "Unable to create context for heavy notification", e);
1755 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1756 INotificationManager inm = NotificationManager.getService();
1761 inm.cancelNotificationWithTag("android", null,
1762 R.string.heavy_weight_notification, msg.arg1);
1763 } catch (RuntimeException e) {
1764 Slog.w(ActivityManagerService.TAG,
1765 "Error canceling notification for service", e);
1766 } catch (RemoteException e) {
1769 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1770 synchronized (ActivityManagerService.this) {
1771 checkExcessivePowerUsageLocked(true);
1772 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1773 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1774 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1777 case REPORT_MEM_USAGE_MSG: {
1778 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1779 Thread thread = new Thread() {
1780 @Override public void run() {
1781 reportMemUsage(memInfos);
1787 case REPORT_USER_SWITCH_MSG: {
1788 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1791 case CONTINUE_USER_SWITCH_MSG: {
1792 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1795 case USER_SWITCH_TIMEOUT_MSG: {
1796 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1799 case IMMERSIVE_MODE_LOCK_MSG: {
1800 final boolean nextState = (msg.arg1 != 0);
1801 if (mUpdateLock.isHeld() != nextState) {
1802 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1803 "Applying new update lock state '" + nextState
1804 + "' for " + (ActivityRecord)msg.obj);
1806 mUpdateLock.acquire();
1808 mUpdateLock.release();
1813 case PERSIST_URI_GRANTS_MSG: {
1814 writeGrantedUriPermissions();
1817 case REQUEST_ALL_PSS_MSG: {
1818 synchronized (ActivityManagerService.this) {
1819 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1823 case START_PROFILES_MSG: {
1824 synchronized (ActivityManagerService.this) {
1825 startProfilesLocked();
1830 synchronized (ActivityManagerService.this) {
1831 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1832 ProcessRecord r = mLruProcesses.get(i);
1833 if (r.thread != null) {
1835 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1836 } catch (RemoteException ex) {
1837 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1844 case SYSTEM_USER_START_MSG: {
1845 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1846 Integer.toString(msg.arg1), msg.arg1);
1847 mSystemServiceManager.startUser(msg.arg1);
1850 case SYSTEM_USER_CURRENT_MSG: {
1851 mBatteryStatsService.noteEvent(
1852 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1853 Integer.toString(msg.arg2), msg.arg2);
1854 mBatteryStatsService.noteEvent(
1855 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1856 Integer.toString(msg.arg1), msg.arg1);
1857 mSystemServiceManager.switchUser(msg.arg1);
1860 case ENTER_ANIMATION_COMPLETE_MSG: {
1861 synchronized (ActivityManagerService.this) {
1862 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1863 if (r != null && r.app != null && r.app.thread != null) {
1865 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1866 } catch (RemoteException e) {
1872 case FINISH_BOOTING_MSG: {
1873 if (msg.arg1 != 0) {
1876 if (msg.arg2 != 0) {
1877 enableScreenAfterBoot();
1881 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1883 Locale l = (Locale) msg.obj;
1884 IBinder service = ServiceManager.getService("mount");
1885 IMountService mountService = IMountService.Stub.asInterface(service);
1886 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1887 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1888 } catch (RemoteException e) {
1889 Log.e(TAG, "Error storing locale for decryption UI", e);
1893 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1894 synchronized (ActivityManagerService.this) {
1895 int i = mTaskStackListeners.beginBroadcast();
1899 // Make a one-way callback to the listener
1900 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1901 } catch (RemoteException e){
1902 // Handled by the RemoteCallbackList
1905 mTaskStackListeners.finishBroadcast();
1909 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1910 final int uid = msg.arg1;
1911 final byte[] firstPacket = (byte[]) msg.obj;
1913 synchronized (mPidsSelfLocked) {
1914 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1915 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1918 p.thread.notifyCleartextNetwork(firstPacket);
1919 } catch (RemoteException ignored) {
1926 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1927 final String procName;
1929 final long memLimit;
1930 final String reportPackage;
1931 synchronized (ActivityManagerService.this) {
1932 procName = mMemWatchDumpProcName;
1933 uid = mMemWatchDumpUid;
1934 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1936 val = mMemWatchProcesses.get(procName, 0);
1939 memLimit = val.first;
1940 reportPackage = val.second;
1943 reportPackage = null;
1946 if (procName == null) {
1950 if (DEBUG_PSS) Slog.d(TAG_PSS,
1951 "Showing dump heap notification from " + procName + "/" + uid);
1953 INotificationManager inm = NotificationManager.getService();
1958 String text = mContext.getString(R.string.dump_heap_notification, procName);
1961 Intent deleteIntent = new Intent();
1962 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1963 Intent intent = new Intent();
1964 intent.setClassName("android", DumpHeapActivity.class.getName());
1965 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1966 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1967 if (reportPackage != null) {
1968 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1970 int userId = UserHandle.getUserId(uid);
1971 Notification notification = new Notification.Builder(mContext)
1972 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1975 .setAutoCancel(true)
1977 .setColor(mContext.getColor(
1978 com.android.internal.R.color.system_notification_accent_color))
1979 .setContentTitle(text)
1981 mContext.getText(R.string.dump_heap_notification_detail))
1982 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1983 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1984 new UserHandle(userId)))
1985 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1986 deleteIntent, 0, UserHandle.OWNER))
1990 int[] outId = new int[1];
1991 inm.enqueueNotificationWithTag("android", "android", null,
1992 R.string.dump_heap_notification,
1993 notification, outId, userId);
1994 } catch (RuntimeException e) {
1995 Slog.w(ActivityManagerService.TAG,
1996 "Error showing notification for dump heap", e);
1997 } catch (RemoteException e) {
2000 case DELETE_DUMPHEAP_MSG: {
2001 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2002 DumpHeapActivity.JAVA_URI,
2003 Intent.FLAG_GRANT_READ_URI_PERMISSION
2004 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2005 UserHandle.myUserId());
2006 synchronized (ActivityManagerService.this) {
2007 mMemWatchDumpFile = null;
2008 mMemWatchDumpProcName = null;
2009 mMemWatchDumpPid = -1;
2010 mMemWatchDumpUid = -1;
2013 case FOREGROUND_PROFILE_CHANGED_MSG: {
2014 dispatchForegroundProfileChanged(msg.arg1);
2016 case REPORT_TIME_TRACKER_MSG: {
2017 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2018 tracker.deliverResult(mContext);
2020 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2021 dispatchUserSwitchComplete(msg.arg1);
2023 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2024 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2026 connection.shutdown();
2027 } catch (RemoteException e) {
2028 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2030 // Only a UiAutomation can set this flag and now that
2031 // it is finished we make sure it is reset to its default.
2032 mUserIsMonkey = false;
2038 static final int COLLECT_PSS_BG_MSG = 1;
2040 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2042 public void handleMessage(Message msg) {
2044 case COLLECT_PSS_BG_MSG: {
2045 long start = SystemClock.uptimeMillis();
2046 MemInfoReader memInfo = null;
2047 synchronized (ActivityManagerService.this) {
2048 if (mFullPssPending) {
2049 mFullPssPending = false;
2050 memInfo = new MemInfoReader();
2053 if (memInfo != null) {
2054 updateCpuStatsNow();
2055 long nativeTotalPss = 0;
2056 synchronized (mProcessCpuTracker) {
2057 final int N = mProcessCpuTracker.countStats();
2058 for (int j=0; j<N; j++) {
2059 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2060 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2061 // This is definitely an application process; skip it.
2064 synchronized (mPidsSelfLocked) {
2065 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2066 // This is one of our own processes; skip it.
2070 nativeTotalPss += Debug.getPss(st.pid, null, null);
2073 memInfo.readMemInfo();
2074 synchronized (ActivityManagerService.this) {
2075 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2076 + (SystemClock.uptimeMillis()-start) + "ms");
2077 final long cachedKb = memInfo.getCachedSizeKb();
2078 final long freeKb = memInfo.getFreeSizeKb();
2079 final long zramKb = memInfo.getZramTotalSizeKb();
2080 final long kernelKb = memInfo.getKernelUsedSizeKb();
2081 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2082 kernelKb*1024, nativeTotalPss*1024);
2083 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2089 long[] tmp = new long[1];
2095 synchronized (ActivityManagerService.this) {
2096 if (mPendingPssProcesses.size() <= 0) {
2097 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2098 "Collected PSS of " + num + " processes in "
2099 + (SystemClock.uptimeMillis() - start) + "ms");
2100 mPendingPssProcesses.clear();
2103 proc = mPendingPssProcesses.remove(0);
2104 procState = proc.pssProcState;
2105 lastPssTime = proc.lastPssTime;
2106 if (proc.thread != null && procState == proc.setProcState
2107 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2108 < SystemClock.uptimeMillis()) {
2116 long pss = Debug.getPss(pid, tmp, null);
2117 synchronized (ActivityManagerService.this) {
2118 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2119 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2121 recordPssSampleLocked(proc, procState, pss, tmp[0],
2122 SystemClock.uptimeMillis());
2132 public void setSystemProcess() {
2134 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2135 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2136 ServiceManager.addService("meminfo", new MemBinder(this));
2137 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2138 ServiceManager.addService("dbinfo", new DbBinder(this));
2139 if (MONITOR_CPU_USAGE) {
2140 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2142 ServiceManager.addService("permission", new PermissionController(this));
2143 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2145 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2146 "android", STOCK_PM_FLAGS);
2147 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2149 synchronized (this) {
2150 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2151 app.persistent = true;
2153 app.maxAdj = ProcessList.SYSTEM_ADJ;
2154 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2155 synchronized (mPidsSelfLocked) {
2156 mPidsSelfLocked.put(app.pid, app);
2158 updateLruProcessLocked(app, false, null);
2159 updateOomAdjLocked();
2161 } catch (PackageManager.NameNotFoundException e) {
2162 throw new RuntimeException(
2163 "Unable to find android system package", e);
2167 public void setWindowManager(WindowManagerService wm) {
2168 mWindowManager = wm;
2169 mStackSupervisor.setWindowManager(wm);
2172 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2173 mUsageStatsService = usageStatsManager;
2176 public void startObservingNativeCrashes() {
2177 final NativeCrashListener ncl = new NativeCrashListener(this);
2181 public IAppOpsService getAppOpsService() {
2182 return mAppOpsService;
2185 static class MemBinder extends Binder {
2186 ActivityManagerService mActivityManagerService;
2187 MemBinder(ActivityManagerService activityManagerService) {
2188 mActivityManagerService = activityManagerService;
2192 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2193 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2194 != PackageManager.PERMISSION_GRANTED) {
2195 pw.println("Permission Denial: can't dump meminfo from from pid="
2196 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2197 + " without permission " + android.Manifest.permission.DUMP);
2201 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2205 static class GraphicsBinder extends Binder {
2206 ActivityManagerService mActivityManagerService;
2207 GraphicsBinder(ActivityManagerService activityManagerService) {
2208 mActivityManagerService = activityManagerService;
2212 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2213 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2214 != PackageManager.PERMISSION_GRANTED) {
2215 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2216 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2217 + " without permission " + android.Manifest.permission.DUMP);
2221 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2225 static class DbBinder extends Binder {
2226 ActivityManagerService mActivityManagerService;
2227 DbBinder(ActivityManagerService activityManagerService) {
2228 mActivityManagerService = activityManagerService;
2232 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2233 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2234 != PackageManager.PERMISSION_GRANTED) {
2235 pw.println("Permission Denial: can't dump dbinfo from from pid="
2236 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2237 + " without permission " + android.Manifest.permission.DUMP);
2241 mActivityManagerService.dumpDbInfo(fd, pw, args);
2245 static class CpuBinder extends Binder {
2246 ActivityManagerService mActivityManagerService;
2247 CpuBinder(ActivityManagerService activityManagerService) {
2248 mActivityManagerService = activityManagerService;
2252 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2253 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2254 != PackageManager.PERMISSION_GRANTED) {
2255 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2256 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2257 + " without permission " + android.Manifest.permission.DUMP);
2261 synchronized (mActivityManagerService.mProcessCpuTracker) {
2262 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2263 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2264 SystemClock.uptimeMillis()));
2269 public static final class Lifecycle extends SystemService {
2270 private final ActivityManagerService mService;
2272 public Lifecycle(Context context) {
2274 mService = new ActivityManagerService(context);
2278 public void onStart() {
2282 public ActivityManagerService getService() {
2287 // Note: This method is invoked on the main thread but may need to attach various
2288 // handlers to other threads. So take care to be explicit about the looper.
2289 public ActivityManagerService(Context systemContext) {
2290 mContext = systemContext;
2291 mFactoryTest = FactoryTest.getMode();
2292 mSystemThread = ActivityThread.currentActivityThread();
2294 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2296 mHandlerThread = new ServiceThread(TAG,
2297 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2298 mHandlerThread.start();
2299 mHandler = new MainHandler(mHandlerThread.getLooper());
2300 mUiHandler = new UiHandler();
2302 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2303 "foreground", BROADCAST_FG_TIMEOUT, false);
2304 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2305 "background", BROADCAST_BG_TIMEOUT, true);
2306 mBroadcastQueues[0] = mFgBroadcastQueue;
2307 mBroadcastQueues[1] = mBgBroadcastQueue;
2309 mServices = new ActiveServices(this);
2310 mProviderMap = new ProviderMap(this);
2312 // TODO: Move creation of battery stats service outside of activity manager service.
2313 File dataDir = Environment.getDataDirectory();
2314 File systemDir = new File(dataDir, "system");
2316 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2317 mBatteryStatsService.getActiveStatistics().readLocked();
2318 mBatteryStatsService.scheduleWriteToDisk();
2319 mOnBattery = DEBUG_POWER ? true
2320 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2321 mBatteryStatsService.getActiveStatistics().setCallback(this);
2323 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2325 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2327 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2329 // User 0 is the first and only user that runs at boot.
2330 mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2331 mUserLru.add(UserHandle.USER_OWNER);
2332 updateStartedUserArrayLocked();
2334 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2335 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2337 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2339 mConfiguration.setToDefaults();
2340 mConfiguration.setLocale(Locale.getDefault());
2342 mConfigurationSeq = mConfiguration.seq = 1;
2343 mProcessCpuTracker.init();
2345 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2346 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2347 mRecentTasks = new RecentTasks(this);
2348 mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2349 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2351 mProcessCpuThread = new Thread("CpuTracker") {
2357 synchronized(this) {
2358 final long now = SystemClock.uptimeMillis();
2359 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2360 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2361 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2362 // + ", write delay=" + nextWriteDelay);
2363 if (nextWriteDelay < nextCpuDelay) {
2364 nextCpuDelay = nextWriteDelay;
2366 if (nextCpuDelay > 0) {
2367 mProcessCpuMutexFree.set(true);
2368 this.wait(nextCpuDelay);
2371 } catch (InterruptedException e) {
2373 updateCpuStatsNow();
2374 } catch (Exception e) {
2375 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2381 Watchdog.getInstance().addMonitor(this);
2382 Watchdog.getInstance().addThread(mHandler);
2385 public void setSystemServiceManager(SystemServiceManager mgr) {
2386 mSystemServiceManager = mgr;
2389 public void setInstaller(Installer installer) {
2390 mInstaller = installer;
2393 private void start() {
2394 Process.removeAllProcessGroups();
2395 mProcessCpuThread.start();
2397 mBatteryStatsService.publish(mContext);
2398 mAppOpsService.publish(mContext);
2399 Slog.d("AppOps", "AppOpsService published");
2400 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2403 public void initPowerManagement() {
2404 mStackSupervisor.initPowerManagement();
2405 mBatteryStatsService.initPowerManagement();
2406 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2407 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2408 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2409 mVoiceWakeLock.setReferenceCounted(false);
2413 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2414 throws RemoteException {
2415 if (code == SYSPROPS_TRANSACTION) {
2416 // We need to tell all apps about the system property change.
2417 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2418 synchronized(this) {
2419 final int NP = mProcessNames.getMap().size();
2420 for (int ip=0; ip<NP; ip++) {
2421 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2422 final int NA = apps.size();
2423 for (int ia=0; ia<NA; ia++) {
2424 ProcessRecord app = apps.valueAt(ia);
2425 if (app.thread != null) {
2426 procs.add(app.thread.asBinder());
2432 int N = procs.size();
2433 for (int i=0; i<N; i++) {
2434 Parcel data2 = Parcel.obtain();
2436 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2437 } catch (RemoteException e) {
2443 return super.onTransact(code, data, reply, flags);
2444 } catch (RuntimeException e) {
2445 // The activity manager only throws security exceptions, so let's
2447 if (!(e instanceof SecurityException)) {
2448 Slog.wtf(TAG, "Activity Manager Crash", e);
2454 void updateCpuStats() {
2455 final long now = SystemClock.uptimeMillis();
2456 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2459 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2460 synchronized (mProcessCpuThread) {
2461 mProcessCpuThread.notify();
2466 void updateCpuStatsNow() {
2467 synchronized (mProcessCpuTracker) {
2468 mProcessCpuMutexFree.set(false);
2469 final long now = SystemClock.uptimeMillis();
2470 boolean haveNewCpuStats = false;
2472 if (MONITOR_CPU_USAGE &&
2473 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2474 mLastCpuTime.set(now);
2475 mProcessCpuTracker.update();
2476 if (mProcessCpuTracker.hasGoodLastStats()) {
2477 haveNewCpuStats = true;
2478 //Slog.i(TAG, mProcessCpu.printCurrentState());
2479 //Slog.i(TAG, "Total CPU usage: "
2480 // + mProcessCpu.getTotalCpuPercent() + "%");
2482 // Slog the cpu usage if the property is set.
2483 if ("true".equals(SystemProperties.get("events.cpu"))) {
2484 int user = mProcessCpuTracker.getLastUserTime();
2485 int system = mProcessCpuTracker.getLastSystemTime();
2486 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2487 int irq = mProcessCpuTracker.getLastIrqTime();
2488 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2489 int idle = mProcessCpuTracker.getLastIdleTime();
2491 int total = user + system + iowait + irq + softIrq + idle;
2492 if (total == 0) total = 1;
2494 EventLog.writeEvent(EventLogTags.CPU,
2495 ((user+system+iowait+irq+softIrq) * 100) / total,
2496 (user * 100) / total,
2497 (system * 100) / total,
2498 (iowait * 100) / total,
2499 (irq * 100) / total,
2500 (softIrq * 100) / total);
2505 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2506 synchronized(bstats) {
2507 synchronized(mPidsSelfLocked) {
2508 if (haveNewCpuStats) {
2509 if (bstats.startAddingCpuLocked()) {
2512 final int N = mProcessCpuTracker.countStats();
2513 for (int i=0; i<N; i++) {
2514 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2518 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2519 totalUTime += st.rel_utime;
2520 totalSTime += st.rel_stime;
2522 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2523 if (ps == null || !ps.isActive()) {
2524 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2525 pr.info.uid, pr.processName);
2527 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2528 pr.curCpuTime += st.rel_utime + st.rel_stime;
2530 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2531 if (ps == null || !ps.isActive()) {
2532 st.batteryStats = ps = bstats.getProcessStatsLocked(
2533 bstats.mapUid(st.uid), st.name);
2535 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2538 final int userTime = mProcessCpuTracker.getLastUserTime();
2539 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2540 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2541 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2542 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2543 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2544 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2545 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2550 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2551 mLastWriteTime = now;
2552 mBatteryStatsService.scheduleWriteToDisk();
2559 public void batteryNeedsCpuUpdate() {
2560 updateCpuStatsNow();
2564 public void batteryPowerChanged(boolean onBattery) {
2565 // When plugging in, update the CPU stats first before changing
2567 updateCpuStatsNow();
2568 synchronized (this) {
2569 synchronized(mPidsSelfLocked) {
2570 mOnBattery = DEBUG_POWER ? true : onBattery;
2576 public void batterySendBroadcast(Intent intent) {
2577 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2578 AppOpsManager.OP_NONE, null, false, false,
2579 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2583 * Initialize the application bind args. These are passed to each
2584 * process when the bindApplication() IPC is sent to the process. They're
2585 * lazily setup to make sure the services are running when they're asked for.
2587 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2588 if (mAppBindArgs == null) {
2589 mAppBindArgs = new HashMap<>();
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 // Setup the application init args
2595 mAppBindArgs.put("package", ServiceManager.getService("package"));
2596 mAppBindArgs.put("window", ServiceManager.getService("window"));
2597 mAppBindArgs.put(Context.ALARM_SERVICE,
2598 ServiceManager.getService(Context.ALARM_SERVICE));
2601 return mAppBindArgs;
2604 final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2605 if (r != null && mFocusedActivity != r) {
2606 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2607 ActivityRecord last = mFocusedActivity;
2608 mFocusedActivity = r;
2609 if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2610 && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2611 if (mCurAppTimeTracker != r.appTimeTracker) {
2612 // We are switching app tracking. Complete the current one.
2613 if (mCurAppTimeTracker != null) {
2614 mCurAppTimeTracker.stop();
2615 mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2616 mCurAppTimeTracker).sendToTarget();
2617 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2618 mCurAppTimeTracker = null;
2620 if (r.appTimeTracker != null) {
2621 mCurAppTimeTracker = r.appTimeTracker;
2622 startTimeTrackingFocusedActivityLocked();
2625 startTimeTrackingFocusedActivityLocked();
2628 r.appTimeTracker = null;
2630 if (r.task != null && r.task.voiceInteractor != null) {
2631 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2633 finishRunningVoiceLocked();
2634 if (last != null && last.task.voiceSession != null) {
2635 // We had been in a voice interaction session, but now focused has
2636 // move to something different. Just finish the session, we can't
2637 // return to it and retain the proper state and synchronization with
2638 // the voice interaction service.
2639 finishVoiceTask(last.task.voiceSession);
2642 if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2643 mWindowManager.setFocusedApp(r.appToken, true);
2645 applyUpdateLockStateLocked(r);
2646 if (mFocusedActivity.userId != mLastFocusedUserId) {
2647 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2648 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2649 mFocusedActivity.userId, 0));
2650 mLastFocusedUserId = mFocusedActivity.userId;
2653 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2654 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2655 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2658 final void clearFocusedActivity(ActivityRecord r) {
2659 if (mFocusedActivity == r) {
2660 ActivityStack stack = mStackSupervisor.getFocusedStack();
2661 if (stack != null) {
2662 ActivityRecord top = stack.topActivity();
2663 if (top != null && top.userId != mLastFocusedUserId) {
2664 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2665 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2667 mLastFocusedUserId = top.userId;
2670 mFocusedActivity = null;
2671 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2676 public void setFocusedStack(int stackId) {
2677 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2678 synchronized (ActivityManagerService.this) {
2679 ActivityStack stack = mStackSupervisor.getStack(stackId);
2680 if (stack != null) {
2681 ActivityRecord r = stack.topRunningActivityLocked(null);
2683 setFocusedActivityLocked(r, "setFocusedStack");
2684 mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2690 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2692 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2693 synchronized (ActivityManagerService.this) {
2694 if (listener != null) {
2695 mTaskStackListeners.register(listener);
2701 public void notifyActivityDrawn(IBinder token) {
2702 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2703 synchronized (this) {
2704 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2706 r.task.stack.notifyActivityDrawnLocked(r);
2711 final void applyUpdateLockStateLocked(ActivityRecord r) {
2712 // Modifications to the UpdateLock state are done on our handler, outside
2713 // the activity manager's locks. The new state is determined based on the
2714 // state *now* of the relevant activity record. The object is passed to
2715 // the handler solely for logging detail, not to be consulted/modified.
2716 final boolean nextState = r != null && r.immersive;
2717 mHandler.sendMessage(
2718 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2721 final void showAskCompatModeDialogLocked(ActivityRecord r) {
2722 Message msg = Message.obtain();
2723 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2724 msg.obj = r.task.askedCompatMode ? null : r;
2725 mUiHandler.sendMessage(msg);
2728 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2729 String what, Object obj, ProcessRecord srcApp) {
2730 app.lastActivityTime = now;
2732 if (app.activities.size() > 0) {
2733 // Don't want to touch dependent processes that are hosting activities.
2737 int lrui = mLruProcesses.lastIndexOf(app);
2739 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2740 + what + " " + obj + " from " + srcApp);
2744 if (lrui >= index) {
2745 // Don't want to cause this to move dependent processes *back* in the
2746 // list as if they were less frequently used.
2750 if (lrui >= mLruProcessActivityStart) {
2751 // Don't want to touch dependent processes that are hosting activities.
2755 mLruProcesses.remove(lrui);
2759 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2760 + " in LRU list: " + app);
2761 mLruProcesses.add(index, app);
2765 private static void killProcessGroup(int uid, int pid) {
2766 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2767 Process.killProcessGroup(uid, pid);
2768 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2771 final void removeLruProcessLocked(ProcessRecord app) {
2772 int lrui = mLruProcesses.lastIndexOf(app);
2775 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2776 Process.killProcessQuiet(app.pid);
2777 killProcessGroup(app.info.uid, app.pid);
2779 if (lrui <= mLruProcessActivityStart) {
2780 mLruProcessActivityStart--;
2782 if (lrui <= mLruProcessServiceStart) {
2783 mLruProcessServiceStart--;
2785 mLruProcesses.remove(lrui);
2789 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2790 ProcessRecord client) {
2791 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2792 || app.treatLikeActivity;
2793 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2794 if (!activityChange && hasActivity) {
2795 // The process has activities, so we are only allowing activity-based adjustments
2796 // to move it. It should be kept in the front of the list with other
2797 // processes that have activities, and we don't want those to change their
2798 // order except due to activity operations.
2803 final long now = SystemClock.uptimeMillis();
2804 app.lastActivityTime = now;
2806 // First a quick reject: if the app is already at the position we will
2807 // put it, then there is nothing to do.
2809 final int N = mLruProcesses.size();
2810 if (N > 0 && mLruProcesses.get(N-1) == app) {
2811 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2815 if (mLruProcessServiceStart > 0
2816 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2817 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2822 int lrui = mLruProcesses.lastIndexOf(app);
2824 if (app.persistent && lrui >= 0) {
2825 // We don't care about the position of persistent processes, as long as
2826 // they are in the list.
2827 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2831 /* In progress: compute new position first, so we can avoid doing work
2832 if the process is not actually going to move. Not yet working.
2835 boolean inActivity = false, inService = false;
2837 // Process has activities, put it at the very tipsy-top.
2838 addIndex = mLruProcesses.size();
2839 nextIndex = mLruProcessServiceStart;
2841 } else if (hasService) {
2842 // Process has services, put it at the top of the service list.
2843 addIndex = mLruProcessActivityStart;
2844 nextIndex = mLruProcessServiceStart;
2848 // Process not otherwise of interest, it goes to the top of the non-service area.
2849 addIndex = mLruProcessServiceStart;
2850 if (client != null) {
2851 int clientIndex = mLruProcesses.lastIndexOf(client);
2852 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2854 if (clientIndex >= 0 && addIndex > clientIndex) {
2855 addIndex = clientIndex;
2858 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2861 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2862 + mLruProcessActivityStart + "): " + app);
2866 if (lrui < mLruProcessActivityStart) {
2867 mLruProcessActivityStart--;
2869 if (lrui < mLruProcessServiceStart) {
2870 mLruProcessServiceStart--;
2873 if (addIndex > lrui) {
2876 if (nextIndex > lrui) {
2880 mLruProcesses.remove(lrui);
2884 mLruProcesses.add(addIndex, app);
2886 mLruProcessActivityStart++;
2889 mLruProcessActivityStart++;
2895 final int N = mLruProcesses.size();
2896 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2897 // Process doesn't have activities, but has clients with
2898 // activities... move it up, but one below the top (the top
2899 // should always have a real activity).
2900 if (DEBUG_LRU) Slog.d(TAG_LRU,
2901 "Adding to second-top of LRU activity list: " + app);
2902 mLruProcesses.add(N - 1, app);
2903 // To keep it from spamming the LRU list (by making a bunch of clients),
2904 // we will push down any other entries owned by the app.
2905 final int uid = app.info.uid;
2906 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2907 ProcessRecord subProc = mLruProcesses.get(i);
2908 if (subProc.info.uid == uid) {
2909 // We want to push this one down the list. If the process after
2910 // it is for the same uid, however, don't do so, because we don't
2911 // want them internally to be re-ordered.
2912 if (mLruProcesses.get(i - 1).info.uid != uid) {
2913 if (DEBUG_LRU) Slog.d(TAG_LRU,
2914 "Pushing uid " + uid + " swapping at " + i + ": "
2915 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2916 ProcessRecord tmp = mLruProcesses.get(i);
2917 mLruProcesses.set(i, mLruProcesses.get(i - 1));
2918 mLruProcesses.set(i - 1, tmp);
2922 // A gap, we can stop here.
2927 // Process has activities, put it at the very tipsy-top.
2928 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2929 mLruProcesses.add(app);
2931 nextIndex = mLruProcessServiceStart;
2932 } else if (hasService) {
2933 // Process has services, put it at the top of the service list.
2934 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2935 mLruProcesses.add(mLruProcessActivityStart, app);
2936 nextIndex = mLruProcessServiceStart;
2937 mLruProcessActivityStart++;
2939 // Process not otherwise of interest, it goes to the top of the non-service area.
2940 int index = mLruProcessServiceStart;
2941 if (client != null) {
2942 // If there is a client, don't allow the process to be moved up higher
2943 // in the list than that client.
2944 int clientIndex = mLruProcesses.lastIndexOf(client);
2945 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2946 + " when updating " + app);
2947 if (clientIndex <= lrui) {
2948 // Don't allow the client index restriction to push it down farther in the
2949 // list than it already is.
2952 if (clientIndex >= 0 && index > clientIndex) {
2953 index = clientIndex;
2956 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2957 mLruProcesses.add(index, app);
2958 nextIndex = index-1;
2959 mLruProcessActivityStart++;
2960 mLruProcessServiceStart++;
2963 // If the app is currently using a content provider or service,
2964 // bump those processes as well.
2965 for (int j=app.connections.size()-1; j>=0; j--) {
2966 ConnectionRecord cr = app.connections.valueAt(j);
2967 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2968 && cr.binding.service.app != null
2969 && cr.binding.service.app.lruSeq != mLruSeq
2970 && !cr.binding.service.app.persistent) {
2971 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2972 "service connection", cr, app);
2975 for (int j=app.conProviders.size()-1; j>=0; j--) {
2976 ContentProviderRecord cpr = app.conProviders.get(j).provider;
2977 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2978 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2979 "provider reference", cpr, app);
2984 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2985 if (uid == Process.SYSTEM_UID) {
2986 // The system gets to run in any process. If there are multiple
2987 // processes with the same uid, just pick the first (this
2988 // should never happen).
2989 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2990 if (procs == null) return null;
2991 final int procCount = procs.size();
2992 for (int i = 0; i < procCount; i++) {
2993 final int procUid = procs.keyAt(i);
2994 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2995 // Don't use an app process or different user process for system component.
2998 return procs.valueAt(i);
3001 ProcessRecord proc = mProcessNames.get(processName, uid);
3002 if (false && proc != null && !keepIfLarge
3003 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3004 && proc.lastCachedPss >= 4000) {
3005 // Turn this condition on to cause killing to happen regularly, for testing.
3006 if (proc.baseProcessTracker != null) {
3007 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3009 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3010 } else if (proc != null && !keepIfLarge
3011 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3012 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3013 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3014 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3015 if (proc.baseProcessTracker != null) {
3016 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3018 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3024 void ensurePackageDexOpt(String packageName) {
3025 IPackageManager pm = AppGlobals.getPackageManager();
3027 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3030 } catch (RemoteException e) {
3034 boolean isNextTransitionForward() {
3035 int transit = mWindowManager.getPendingAppTransition();
3036 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3037 || transit == AppTransition.TRANSIT_TASK_OPEN
3038 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3041 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3042 String processName, String abiOverride, int uid, Runnable crashHandler) {
3043 synchronized(this) {
3044 ApplicationInfo info = new ApplicationInfo();
3045 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3046 // For isolated processes, the former contains the parent's uid and the latter the
3047 // actual uid of the isolated process.
3048 // In the special case introduced by this method (which is, starting an isolated
3049 // process directly from the SystemServer without an actual parent app process) the
3050 // closest thing to a parent's uid is SYSTEM_UID.
3051 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3052 // the |isolated| logic in the ProcessRecord constructor.
3053 info.uid = Process.SYSTEM_UID;
3054 info.processName = processName;
3055 info.className = entryPoint;
3056 info.packageName = "android";
3057 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3058 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3059 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3060 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3062 return proc != null ? proc.pid : 0;
3066 final ProcessRecord startProcessLocked(String processName,
3067 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3068 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3069 boolean isolated, boolean keepIfLarge) {
3070 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3071 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3072 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3073 null /* crashHandler */);
3076 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3077 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3078 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3079 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3080 long startTime = SystemClock.elapsedRealtime();
3083 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3084 checkTime(startTime, "startProcess: after getProcessRecord");
3086 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3087 // If we are in the background, then check to see if this process
3088 // is bad. If so, we will just silently fail.
3089 if (mBadProcesses.get(info.processName, info.uid) != null) {
3090 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3091 + "/" + info.processName);
3095 // When the user is explicitly starting a process, then clear its
3096 // crash count so that we won't make it bad until they see at
3097 // least one crash dialog again, and make the process good again
3098 // if it had been bad.
3099 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3100 + "/" + info.processName);
3101 mProcessCrashTimes.remove(info.processName, info.uid);
3102 if (mBadProcesses.get(info.processName, info.uid) != null) {
3103 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3104 UserHandle.getUserId(info.uid), info.uid,
3106 mBadProcesses.remove(info.processName, info.uid);
3113 // If this is an isolated process, it can't re-use an existing process.
3117 // We don't have to do anything more if:
3118 // (1) There is an existing application record; and
3119 // (2) The caller doesn't think it is dead, OR there is no thread
3120 // object attached to it so we know it couldn't have crashed; and
3121 // (3) There is a pid assigned to it, so it is either starting or
3123 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3124 + " app=" + app + " knownToBeDead=" + knownToBeDead
3125 + " thread=" + (app != null ? app.thread : null)
3126 + " pid=" + (app != null ? app.pid : -1));
3127 if (app != null && app.pid > 0) {
3128 if (!knownToBeDead || app.thread == null) {
3129 // We already have the app running, or are waiting for it to
3130 // come up (we have a pid but not yet its thread), so keep it.
3131 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3132 // If this is a new package in the process, add the package to the list
3133 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3134 checkTime(startTime, "startProcess: done, added package to proc");
3138 // An application record is attached to a previous process,
3140 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3141 checkTime(startTime, "startProcess: bad proc running, killing");
3142 killProcessGroup(app.info.uid, app.pid);
3143 handleAppDiedLocked(app, true, true);
3144 checkTime(startTime, "startProcess: done killing old proc");
3147 String hostingNameStr = hostingName != null
3148 ? hostingName.flattenToShortString() : null;
3151 checkTime(startTime, "startProcess: creating new process record");
3152 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3154 Slog.w(TAG, "Failed making new process record for "
3155 + processName + "/" + info.uid + " isolated=" + isolated);
3158 app.crashHandler = crashHandler;
3159 checkTime(startTime, "startProcess: done creating new process record");
3161 // If this is a new package in the process, add the package to the list
3162 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3163 checkTime(startTime, "startProcess: added package to existing proc");
3166 // If the system is not ready yet, then hold off on starting this
3167 // process until it is.
3168 if (!mProcessesReady
3169 && !isAllowedWhileBooting(info)
3170 && !allowWhileBooting) {
3171 if (!mProcessesOnHold.contains(app)) {
3172 mProcessesOnHold.add(app);
3174 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3175 "System not ready, putting on hold: " + app);
3176 checkTime(startTime, "startProcess: returning with proc on hold");
3180 checkTime(startTime, "startProcess: stepping in to startProcess");
3182 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3183 checkTime(startTime, "startProcess: done starting proc!");
3184 return (app.pid != 0) ? app : null;
3187 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3188 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3191 private final void startProcessLocked(ProcessRecord app,
3192 String hostingType, String hostingNameStr) {
3193 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3194 null /* entryPoint */, null /* entryPointArgs */);
3197 private final void startProcessLocked(ProcessRecord app, String hostingType,
3198 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3199 long startTime = SystemClock.elapsedRealtime();
3200 if (app.pid > 0 && app.pid != MY_PID) {
3201 checkTime(startTime, "startProcess: removing from pids map");
3202 synchronized (mPidsSelfLocked) {
3203 mPidsSelfLocked.remove(app.pid);
3204 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3206 checkTime(startTime, "startProcess: done removing from pids map");
3210 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3211 "startProcessLocked removing on hold: " + app);
3212 mProcessesOnHold.remove(app);
3214 checkTime(startTime, "startProcess: starting to update cpu stats");
3216 checkTime(startTime, "startProcess: done updating cpu stats");
3220 if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3221 // This is caught below as if we had failed to fork zygote
3222 throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3224 } catch (RemoteException e) {
3225 throw e.rethrowAsRuntimeException();
3230 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3231 if (!app.isolated) {
3232 int[] permGids = null;
3234 checkTime(startTime, "startProcess: getting gids from package manager");
3235 final IPackageManager pm = AppGlobals.getPackageManager();
3236 permGids = pm.getPackageGids(app.info.packageName, app.userId);
3237 MountServiceInternal mountServiceInternal = LocalServices.getService(
3238 MountServiceInternal.class);
3239 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3240 app.info.packageName);
3241 } catch (RemoteException e) {
3242 throw e.rethrowAsRuntimeException();
3246 * Add shared application and profile GIDs so applications can share some
3247 * resources like shared libraries and access user-wide resources
3249 if (ArrayUtils.isEmpty(permGids)) {
3252 gids = new int[permGids.length + 2];
3253 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3255 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3256 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3258 checkTime(startTime, "startProcess: building args");
3259 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3260 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3261 && mTopComponent != null
3262 && app.processName.equals(mTopComponent.getPackageName())) {
3265 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3266 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3271 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3272 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3273 // Also turn on CheckJNI for debuggable apps. It's quite
3274 // awkward to turn on otherwise.
3275 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3277 // Run the app in safe mode if its manifest requests so or the
3278 // system is booted in safe mode.
3279 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3280 mSafeMode == true) {
3281 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3283 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3284 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3286 String jitDebugProperty = SystemProperties.get("debug.usejit");
3287 if ("true".equals(jitDebugProperty)) {
3288 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3289 } else if (!"false".equals(jitDebugProperty)) {
3290 // If we didn't force disable by setting false, defer to the dalvik vm options.
3291 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3292 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3295 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3296 if ("true".equals(genDebugInfoProperty)) {
3297 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3299 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3300 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3302 if ("1".equals(SystemProperties.get("debug.assert"))) {
3303 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3306 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3307 if (requiredAbi == null) {
3308 requiredAbi = Build.SUPPORTED_ABIS[0];
3311 String instructionSet = null;
3312 if (app.info.primaryCpuAbi != null) {
3313 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3317 app.requiredAbi = requiredAbi;
3318 app.instructionSet = instructionSet;
3320 // Start the process. It will either succeed and return a result containing
3321 // the PID of the new process, or else throw a RuntimeException.
3322 boolean isActivityProcess = (entryPoint == null);
3323 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3324 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3326 checkTime(startTime, "startProcess: asking zygote to start proc");
3327 Process.ProcessStartResult startResult = Process.start(entryPoint,
3328 app.processName, uid, uid, gids, debugFlags, mountExternal,
3329 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3330 app.info.dataDir, entryPointArgs);
3331 checkTime(startTime, "startProcess: returned from zygote!");
3332 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3335 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3337 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3338 checkTime(startTime, "startProcess: done updating battery stats");
3340 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3341 UserHandle.getUserId(uid), startResult.pid, uid,
3342 app.processName, hostingType,
3343 hostingNameStr != null ? hostingNameStr : "");
3345 if (app.persistent) {
3346 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3349 checkTime(startTime, "startProcess: building log message");
3350 StringBuilder buf = mStringBuilder;
3352 buf.append("Start proc ");
3353 buf.append(startResult.pid);
3355 buf.append(app.processName);
3357 UserHandle.formatUid(buf, uid);
3358 if (!isActivityProcess) {
3360 buf.append(entryPoint);
3363 buf.append(" for ");
3364 buf.append(hostingType);
3365 if (hostingNameStr != null) {
3367 buf.append(hostingNameStr);
3369 Slog.i(TAG, buf.toString());
3370 app.setPid(startResult.pid);
3371 app.usingWrapper = startResult.usingWrapper;
3372 app.removed = false;
3374 app.killedByAm = false;
3375 checkTime(startTime, "startProcess: starting to update pids map");
3376 synchronized (mPidsSelfLocked) {
3377 this.mPidsSelfLocked.put(startResult.pid, app);
3378 if (isActivityProcess) {
3379 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3381 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3382 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3385 checkTime(startTime, "startProcess: done updating pids map");
3386 } catch (RuntimeException e) {
3387 // XXX do better error recovery.
3389 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3391 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3393 Slog.e(TAG, "Failure starting process " + app.processName, e);
3397 void updateUsageStats(ActivityRecord component, boolean resumed) {
3398 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3399 "updateUsageStats: comp=" + component + "res=" + resumed);
3400 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3402 if (mUsageStatsService != null) {
3403 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3404 UsageEvents.Event.MOVE_TO_FOREGROUND);
3406 synchronized (stats) {
3407 stats.noteActivityResumedLocked(component.app.uid);
3410 if (mUsageStatsService != null) {
3411 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3412 UsageEvents.Event.MOVE_TO_BACKGROUND);
3414 synchronized (stats) {
3415 stats.noteActivityPausedLocked(component.app.uid);
3420 Intent getHomeIntent() {
3421 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3422 intent.setComponent(mTopComponent);
3423 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3424 intent.addCategory(Intent.CATEGORY_HOME);
3429 boolean startHomeActivityLocked(int userId, String reason) {
3430 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3431 && mTopAction == null) {
3432 // We are running in factory test mode, but unable to find
3433 // the factory test app, so just sit around displaying the
3434 // error message and don't try to start anything.
3437 Intent intent = getHomeIntent();
3438 ActivityInfo aInfo =
3439 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3440 if (aInfo != null) {
3441 intent.setComponent(new ComponentName(
3442 aInfo.applicationInfo.packageName, aInfo.name));
3443 // Don't do this if the home app is currently being
3445 aInfo = new ActivityInfo(aInfo);
3446 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3447 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3448 aInfo.applicationInfo.uid, true);
3449 if (app == null || app.instrumentationClass == null) {
3450 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3451 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3458 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3459 ActivityInfo ai = null;
3460 ComponentName comp = intent.getComponent();
3464 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3466 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3468 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3472 ai = info.activityInfo;
3475 } catch (RemoteException e) {
3483 * Starts the "new version setup screen" if appropriate.
3485 void startSetupActivityLocked() {
3486 // Only do this once per boot.
3487 if (mCheckedForSetup) {
3491 // We will show this screen if the current one is a different
3492 // version than the last one shown, and we are not running in
3493 // low-level factory test mode.
3494 final ContentResolver resolver = mContext.getContentResolver();
3495 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3496 Settings.Global.getInt(resolver,
3497 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3498 mCheckedForSetup = true;
3500 // See if we should be showing the platform update setup UI.
3501 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3502 List<ResolveInfo> ris = mContext.getPackageManager()
3503 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3505 // We don't allow third party apps to replace this.
3506 ResolveInfo ri = null;
3507 for (int i=0; ris != null && i<ris.size(); i++) {
3508 if ((ris.get(i).activityInfo.applicationInfo.flags
3509 & ApplicationInfo.FLAG_SYSTEM) != 0) {
3516 String vers = ri.activityInfo.metaData != null
3517 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3519 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3520 vers = ri.activityInfo.applicationInfo.metaData.getString(
3521 Intent.METADATA_SETUP_VERSION);
3523 String lastVers = Settings.Secure.getString(
3524 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3525 if (vers != null && !vers.equals(lastVers)) {
3526 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3527 intent.setComponent(new ComponentName(
3528 ri.activityInfo.packageName, ri.activityInfo.name));
3529 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3530 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3537 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3538 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3541 void enforceNotIsolatedCaller(String caller) {
3542 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3543 throw new SecurityException("Isolated process not allowed to call " + caller);
3547 void enforceShellRestriction(String restriction, int userHandle) {
3548 if (Binder.getCallingUid() == Process.SHELL_UID) {
3550 || mUserManager.hasUserRestriction(restriction, userHandle)) {
3551 throw new SecurityException("Shell does not have permission to access user "
3558 public int getFrontActivityScreenCompatMode() {
3559 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3560 synchronized (this) {
3561 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3566 public void setFrontActivityScreenCompatMode(int mode) {
3567 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3568 "setFrontActivityScreenCompatMode");
3569 synchronized (this) {
3570 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3575 public int getPackageScreenCompatMode(String packageName) {
3576 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3577 synchronized (this) {
3578 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3583 public void setPackageScreenCompatMode(String packageName, int mode) {
3584 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3585 "setPackageScreenCompatMode");
3586 synchronized (this) {
3587 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3592 public boolean getPackageAskScreenCompat(String packageName) {
3593 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3594 synchronized (this) {
3595 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3600 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3601 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3602 "setPackageAskScreenCompat");
3603 synchronized (this) {
3604 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3608 private boolean hasUsageStatsPermission(String callingPackage) {
3609 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3610 Binder.getCallingUid(), callingPackage);
3611 if (mode == AppOpsManager.MODE_DEFAULT) {
3612 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3613 == PackageManager.PERMISSION_GRANTED;
3615 return mode == AppOpsManager.MODE_ALLOWED;
3619 public int getPackageProcessState(String packageName, String callingPackage) {
3620 if (!hasUsageStatsPermission(callingPackage)) {
3621 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3622 "getPackageProcessState");
3625 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3626 synchronized (this) {
3627 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3628 final ProcessRecord proc = mLruProcesses.get(i);
3629 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3630 || procState > proc.setProcState) {
3631 boolean found = false;
3632 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3633 if (proc.pkgList.keyAt(j).equals(packageName)) {
3634 procState = proc.setProcState;
3638 if (proc.pkgDeps != null && !found) {
3639 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3640 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3641 procState = proc.setProcState;
3653 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3654 synchronized (this) {
3655 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3659 if (app.trimMemoryLevel < level && app.thread != null &&
3660 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3661 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3663 app.thread.scheduleTrimMemory(level);
3664 app.trimMemoryLevel = level;
3666 } catch (RemoteException e) {
3667 // Fallthrough to failure case.
3674 private void dispatchProcessesChanged() {
3676 synchronized (this) {
3677 N = mPendingProcessChanges.size();
3678 if (mActiveProcessChanges.length < N) {
3679 mActiveProcessChanges = new ProcessChangeItem[N];
3681 mPendingProcessChanges.toArray(mActiveProcessChanges);
3682 mPendingProcessChanges.clear();
3683 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3684 "*** Delivering " + N + " process changes");
3687 int i = mProcessObservers.beginBroadcast();
3690 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3691 if (observer != null) {
3693 for (int j=0; j<N; j++) {
3694 ProcessChangeItem item = mActiveProcessChanges[j];
3695 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3696 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3697 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3698 + item.uid + ": " + item.foregroundActivities);
3699 observer.onForegroundActivitiesChanged(item.pid, item.uid,
3700 item.foregroundActivities);
3702 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3703 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3704 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3705 + ": " + item.processState);
3706 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3709 } catch (RemoteException e) {
3713 mProcessObservers.finishBroadcast();
3715 synchronized (this) {
3716 for (int j=0; j<N; j++) {
3717 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3722 private void dispatchProcessDied(int pid, int uid) {
3723 int i = mProcessObservers.beginBroadcast();
3726 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3727 if (observer != null) {
3729 observer.onProcessDied(pid, uid);
3730 } catch (RemoteException e) {
3734 mProcessObservers.finishBroadcast();
3737 private void dispatchUidsChanged() {
3739 synchronized (this) {
3740 N = mPendingUidChanges.size();
3741 if (mActiveUidChanges.length < N) {
3742 mActiveUidChanges = new UidRecord.ChangeItem[N];
3744 for (int i=0; i<N; i++) {
3745 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3746 mActiveUidChanges[i] = change;
3747 change.uidRecord.pendingChange = null;
3748 change.uidRecord = null;
3750 mPendingUidChanges.clear();
3751 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3752 "*** Delivering " + N + " uid changes");
3755 if (mLocalPowerManager != null) {
3756 for (int j=0; j<N; j++) {
3757 UidRecord.ChangeItem item = mActiveUidChanges[j];
3759 mLocalPowerManager.uidGone(item.uid);
3761 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3766 int i = mUidObservers.beginBroadcast();
3769 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3770 if (observer != null) {
3772 for (int j=0; j<N; j++) {
3773 UidRecord.ChangeItem item = mActiveUidChanges[j];
3775 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3776 "UID gone uid=" + item.uid);
3777 observer.onUidGone(item.uid);
3779 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3780 "UID CHANGED uid=" + item.uid
3781 + ": " + item.processState);
3782 observer.onUidStateChanged(item.uid, item.processState);
3785 } catch (RemoteException e) {
3789 mUidObservers.finishBroadcast();
3791 synchronized (this) {
3792 for (int j=0; j<N; j++) {
3793 mAvailUidChanges.add(mActiveUidChanges[j]);
3799 public final int startActivity(IApplicationThread caller, String callingPackage,
3800 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3801 int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3802 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3803 resultWho, requestCode, startFlags, profilerInfo, options,
3804 UserHandle.getCallingUserId());
3808 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3809 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3810 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3811 enforceNotIsolatedCaller("startActivity");
3812 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3813 false, ALLOW_FULL_ONLY, "startActivity", null);
3814 // TODO: Switch to user app stacks here.
3815 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3816 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3817 profilerInfo, null, null, options, false, userId, null, null);
3821 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3822 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3823 int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3826 // This is very dangerous -- it allows you to perform a start activity (including
3827 // permission grants) as any app that may launch one of your own activities. So
3828 // we will only allow this to be done from activities that are part of the core framework,
3829 // and then only when they are running as the system.
3830 final ActivityRecord sourceRecord;
3831 final int targetUid;
3832 final String targetPackage;
3833 synchronized (this) {
3834 if (resultTo == null) {
3835 throw new SecurityException("Must be called from an activity");
3837 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3838 if (sourceRecord == null) {
3839 throw new SecurityException("Called with bad activity token: " + resultTo);
3841 if (!sourceRecord.info.packageName.equals("android")) {
3842 throw new SecurityException(
3843 "Must be called from an activity that is declared in the android package");
3845 if (sourceRecord.app == null) {
3846 throw new SecurityException("Called without a process attached to activity");
3848 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3849 // This is still okay, as long as this activity is running under the
3850 // uid of the original calling activity.
3851 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3852 throw new SecurityException(
3853 "Calling activity in uid " + sourceRecord.app.uid
3854 + " must be system uid or original calling uid "
3855 + sourceRecord.launchedFromUid);
3858 if (ignoreTargetSecurity) {
3859 if (intent.getComponent() == null) {
3860 throw new SecurityException(
3861 "Component must be specified with ignoreTargetSecurity");
3863 if (intent.getSelector() != null) {
3864 throw new SecurityException(
3865 "Selector not allowed with ignoreTargetSecurity");
3868 targetUid = sourceRecord.launchedFromUid;
3869 targetPackage = sourceRecord.launchedFromPackage;
3872 if (userId == UserHandle.USER_NULL) {
3873 userId = UserHandle.getUserId(sourceRecord.app.uid);
3876 // TODO: Switch to user app stacks here.
3878 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3879 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3880 null, null, options, ignoreTargetSecurity, userId, null, null);
3882 } catch (SecurityException e) {
3883 // XXX need to figure out how to propagate to original app.
3884 // A SecurityException here is generally actually a fault of the original
3885 // calling activity (such as a fairly granting permissions), so propagate it
3888 StringBuilder msg = new StringBuilder();
3889 msg.append("While launching");
3890 msg.append(intent.toString());
3892 msg.append(e.getMessage());
3899 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3900 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3901 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3902 enforceNotIsolatedCaller("startActivityAndWait");
3903 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3904 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3905 WaitResult res = new WaitResult();
3906 // TODO: Switch to user app stacks here.
3907 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3908 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3909 options, false, userId, null, null);
3914 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3915 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3916 int startFlags, Configuration config, Bundle options, int userId) {
3917 enforceNotIsolatedCaller("startActivityWithConfig");
3918 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3919 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3920 // TODO: Switch to user app stacks here.
3921 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3922 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3923 null, null, config, options, false, userId, null, null);
3928 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3929 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3930 int requestCode, int flagsMask, int flagsValues, Bundle options)
3931 throws TransactionTooLargeException {
3932 enforceNotIsolatedCaller("startActivityIntentSender");
3933 // Refuse possible leaked file descriptors
3934 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3935 throw new IllegalArgumentException("File descriptors passed in Intent");
3938 IIntentSender sender = intent.getTarget();
3939 if (!(sender instanceof PendingIntentRecord)) {
3940 throw new IllegalArgumentException("Bad PendingIntent object");
3943 PendingIntentRecord pir = (PendingIntentRecord)sender;
3945 synchronized (this) {
3946 // If this is coming from the currently resumed activity, it is
3947 // effectively saying that app switches are allowed at this point.
3948 final ActivityStack stack = getFocusedStack();
3949 if (stack.mResumedActivity != null &&
3950 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3951 mAppSwitchesAllowedTime = 0;
3954 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3955 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3960 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3961 Intent intent, String resolvedType, IVoiceInteractionSession session,
3962 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3963 Bundle options, int userId) {
3964 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3965 != PackageManager.PERMISSION_GRANTED) {
3966 String msg = "Permission Denial: startVoiceActivity() from pid="
3967 + Binder.getCallingPid()
3968 + ", uid=" + Binder.getCallingUid()
3969 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3971 throw new SecurityException(msg);
3973 if (session == null || interactor == null) {
3974 throw new NullPointerException("null session or interactor");
3976 userId = handleIncomingUser(callingPid, callingUid, userId,
3977 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3978 // TODO: Switch to user app stacks here.
3979 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3980 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3981 null, options, false, userId, null, null);
3985 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
3986 synchronized (this) {
3987 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
3989 mVoiceWakeLock.acquire();
3991 mVoiceWakeLock.release();
3998 public boolean startNextMatchingActivity(IBinder callingActivity,
3999 Intent intent, Bundle options) {
4000 // Refuse possible leaked file descriptors
4001 if (intent != null && intent.hasFileDescriptors() == true) {
4002 throw new IllegalArgumentException("File descriptors passed in Intent");
4005 synchronized (this) {
4006 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4008 ActivityOptions.abort(options);
4011 if (r.app == null || r.app.thread == null) {
4012 // The caller is not running... d'oh!
4013 ActivityOptions.abort(options);
4016 intent = new Intent(intent);
4017 // The caller is not allowed to change the data.
4018 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4019 // And we are resetting to find the next component...
4020 intent.setComponent(null);
4022 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4024 ActivityInfo aInfo = null;
4026 List<ResolveInfo> resolves =
4027 AppGlobals.getPackageManager().queryIntentActivities(
4028 intent, r.resolvedType,
4029 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4030 UserHandle.getCallingUserId());
4032 // Look for the original activity in the list...
4033 final int N = resolves != null ? resolves.size() : 0;
4034 for (int i=0; i<N; i++) {
4035 ResolveInfo rInfo = resolves.get(i);
4036 if (rInfo.activityInfo.packageName.equals(r.packageName)
4037 && rInfo.activityInfo.name.equals(r.info.name)) {
4038 // We found the current one... the next matching is
4042 aInfo = resolves.get(i).activityInfo;
4045 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4046 + "/" + r.info.name);
4047 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4048 + "/" + aInfo.name);
4053 } catch (RemoteException e) {
4056 if (aInfo == null) {
4057 // Nobody who is next!
4058 ActivityOptions.abort(options);
4059 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4063 intent.setComponent(new ComponentName(
4064 aInfo.applicationInfo.packageName, aInfo.name));
4065 intent.setFlags(intent.getFlags()&~(
4066 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4067 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4068 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4069 Intent.FLAG_ACTIVITY_NEW_TASK));
4071 // Okay now we need to start the new activity, replacing the
4072 // currently running activity. This is a little tricky because
4073 // we want to start the new one as if the current one is finished,
4074 // but not finish the current one first so that there is no flicker.
4076 final boolean wasFinishing = r.finishing;
4079 // Propagate reply information over to the new activity.
4080 final ActivityRecord resultTo = r.resultTo;
4081 final String resultWho = r.resultWho;
4082 final int requestCode = r.requestCode;
4084 if (resultTo != null) {
4085 resultTo.removeResultsLocked(r, resultWho, requestCode);
4088 final long origId = Binder.clearCallingIdentity();
4089 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4090 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4091 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4092 -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4093 Binder.restoreCallingIdentity(origId);
4095 r.finishing = wasFinishing;
4096 if (res != ActivityManager.START_SUCCESS) {
4104 public final int startActivityFromRecents(int taskId, Bundle options) {
4105 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4106 String msg = "Permission Denial: startActivityFromRecents called without " +
4107 START_TASKS_FROM_RECENTS;
4109 throw new SecurityException(msg);
4111 return startActivityFromRecentsInner(taskId, options);
4114 final int startActivityFromRecentsInner(int taskId, Bundle options) {
4115 final TaskRecord task;
4116 final int callingUid;
4117 final String callingPackage;
4118 final Intent intent;
4120 synchronized (this) {
4121 task = mStackSupervisor.anyTaskForIdLocked(taskId);
4123 throw new IllegalArgumentException("Task " + taskId + " not found.");
4125 if (task.getRootActivity() != null) {
4126 moveTaskToFrontLocked(task.taskId, 0, null);
4127 return ActivityManager.START_TASK_TO_FRONT;
4129 callingUid = task.mCallingUid;
4130 callingPackage = task.mCallingPackage;
4131 intent = task.intent;
4132 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4133 userId = task.userId;
4135 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4136 options, userId, null, task);
4139 final int startActivityInPackage(int uid, String callingPackage,
4140 Intent intent, String resolvedType, IBinder resultTo,
4141 String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4142 IActivityContainer container, TaskRecord inTask) {
4144 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4145 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4147 // TODO: Switch to user app stacks here.
4148 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4149 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4150 null, null, null, options, false, userId, container, inTask);
4155 public final int startActivities(IApplicationThread caller, String callingPackage,
4156 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4158 enforceNotIsolatedCaller("startActivities");
4159 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4160 false, ALLOW_FULL_ONLY, "startActivity", null);
4161 // TODO: Switch to user app stacks here.
4162 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4163 resolvedTypes, resultTo, options, userId);
4167 final int startActivitiesInPackage(int uid, String callingPackage,
4168 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4169 Bundle options, int userId) {
4171 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4172 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4173 // TODO: Switch to user app stacks here.
4174 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4175 resultTo, options, userId);
4180 public void reportActivityFullyDrawn(IBinder token) {
4181 synchronized (this) {
4182 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4186 r.reportFullyDrawnLocked();
4191 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4192 synchronized (this) {
4193 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4197 if (r.task != null && r.task.mResizeable) {
4198 // Fixed screen orientation isn't supported with resizeable activities.
4201 final long origId = Binder.clearCallingIdentity();
4202 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4203 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4204 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4205 if (config != null) {
4206 r.frozenBeforeDestroy = true;
4207 if (!updateConfigurationLocked(config, r, false, false)) {
4208 mStackSupervisor.resumeTopActivitiesLocked();
4211 Binder.restoreCallingIdentity(origId);
4216 public int getRequestedOrientation(IBinder token) {
4217 synchronized (this) {
4218 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4220 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4222 return mWindowManager.getAppOrientation(r.appToken);
4227 * This is the internal entry point for handling Activity.finish().
4229 * @param token The Binder token referencing the Activity we want to finish.
4230 * @param resultCode Result code, if any, from this Activity.
4231 * @param resultData Result data (Intent), if any, from this Activity.
4232 * @param finishTask Whether to finish the task associated with this Activity. Only applies to
4233 * the root Activity in the task.
4235 * @return Returns true if the activity successfully finished, or false if it is still running.
4238 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4239 boolean finishTask) {
4240 // Refuse possible leaked file descriptors
4241 if (resultData != null && resultData.hasFileDescriptors() == true) {
4242 throw new IllegalArgumentException("File descriptors passed in Intent");
4245 synchronized(this) {
4246 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4250 // Keep track of the root activity of the task before we finish it
4251 TaskRecord tr = r.task;
4252 ActivityRecord rootR = tr.getRootActivity();
4253 if (rootR == null) {
4254 Slog.w(TAG, "Finishing task with all activities already finished");
4256 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4258 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4259 mStackSupervisor.isLastLockedTask(tr)) {
4260 Slog.i(TAG, "Not finishing task in lock task mode");
4261 mStackSupervisor.showLockTaskToast();
4264 if (mController != null) {
4265 // Find the first activity that is not finishing.
4266 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4268 // ask watcher if this is allowed
4269 boolean resumeOK = true;
4271 resumeOK = mController.activityResuming(next.packageName);
4272 } catch (RemoteException e) {
4274 Watchdog.getInstance().setActivityController(null);
4278 Slog.i(TAG, "Not finishing activity because controller resumed");
4283 final long origId = Binder.clearCallingIdentity();
4286 if (finishTask && r == rootR) {
4287 // If requested, remove the task that is associated to this activity only if it
4288 // was the root activity in the task. The result code and data is ignored
4289 // because we don't support returning them across task boundaries.
4290 res = removeTaskByIdLocked(tr.taskId, false);
4292 Slog.i(TAG, "Removing task failed to finish activity");
4295 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4296 resultData, "app-request", true);
4298 Slog.i(TAG, "Failed to finish by app-request");
4303 Binder.restoreCallingIdentity(origId);
4309 public final void finishHeavyWeightApp() {
4310 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4311 != PackageManager.PERMISSION_GRANTED) {
4312 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4313 + Binder.getCallingPid()
4314 + ", uid=" + Binder.getCallingUid()
4315 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4317 throw new SecurityException(msg);
4320 synchronized(this) {
4321 if (mHeavyWeightProcess == null) {
4325 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4326 for (int i = 0; i < activities.size(); i++) {
4327 ActivityRecord r = activities.get(i);
4328 if (!r.finishing && r.isInStackLocked()) {
4329 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4330 null, "finish-heavy", true);
4334 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4335 mHeavyWeightProcess.userId, 0));
4336 mHeavyWeightProcess = null;
4341 public void crashApplication(int uid, int initialPid, String packageName,
4343 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4344 != PackageManager.PERMISSION_GRANTED) {
4345 String msg = "Permission Denial: crashApplication() from pid="
4346 + Binder.getCallingPid()
4347 + ", uid=" + Binder.getCallingUid()
4348 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4350 throw new SecurityException(msg);
4353 synchronized(this) {
4354 ProcessRecord proc = null;
4356 // Figure out which process to kill. We don't trust that initialPid
4357 // still has any relation to current pids, so must scan through the
4359 synchronized (mPidsSelfLocked) {
4360 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4361 ProcessRecord p = mPidsSelfLocked.valueAt(i);
4365 if (p.pid == initialPid) {
4369 if (p.pkgList.containsKey(packageName)) {
4376 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4377 + " initialPid=" + initialPid
4378 + " packageName=" + packageName);
4382 if (proc.thread != null) {
4383 if (proc.pid == Process.myPid()) {
4384 Log.w(TAG, "crashApplication: trying to crash self!");
4387 long ident = Binder.clearCallingIdentity();
4389 proc.thread.scheduleCrash(message);
4390 } catch (RemoteException e) {
4392 Binder.restoreCallingIdentity(ident);
4398 public final void finishSubActivity(IBinder token, String resultWho,
4400 synchronized(this) {
4401 final long origId = Binder.clearCallingIdentity();
4402 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4404 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4406 Binder.restoreCallingIdentity(origId);
4411 public boolean finishActivityAffinity(IBinder token) {
4412 synchronized(this) {
4413 final long origId = Binder.clearCallingIdentity();
4415 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4420 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4422 final TaskRecord task = r.task;
4423 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4424 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4425 mStackSupervisor.showLockTaskToast();
4428 return task.stack.finishActivityAffinityLocked(r);
4430 Binder.restoreCallingIdentity(origId);
4436 public void finishVoiceTask(IVoiceInteractionSession session) {
4437 synchronized(this) {
4438 final long origId = Binder.clearCallingIdentity();
4440 mStackSupervisor.finishVoiceTask(session);
4442 Binder.restoreCallingIdentity(origId);
4449 public boolean releaseActivityInstance(IBinder token) {
4450 synchronized(this) {
4451 final long origId = Binder.clearCallingIdentity();
4453 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4457 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4459 Binder.restoreCallingIdentity(origId);
4465 public void releaseSomeActivities(IApplicationThread appInt) {
4466 synchronized(this) {
4467 final long origId = Binder.clearCallingIdentity();
4469 ProcessRecord app = getRecordForAppLocked(appInt);
4470 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4472 Binder.restoreCallingIdentity(origId);
4478 public boolean willActivityBeVisible(IBinder token) {
4479 synchronized(this) {
4480 ActivityStack stack = ActivityRecord.getStackLocked(token);
4481 if (stack != null) {
4482 return stack.willActivityBeVisibleLocked(token);
4489 public void overridePendingTransition(IBinder token, String packageName,
4490 int enterAnim, int exitAnim) {
4491 synchronized(this) {
4492 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4497 final long origId = Binder.clearCallingIdentity();
4499 if (self.state == ActivityState.RESUMED
4500 || self.state == ActivityState.PAUSING) {
4501 mWindowManager.overridePendingAppTransition(packageName,
4502 enterAnim, exitAnim, null);
4505 Binder.restoreCallingIdentity(origId);
4510 * Main function for removing an existing process from the activity manager
4511 * as a result of that process going away. Clears out all connections
4514 private final void handleAppDiedLocked(ProcessRecord app,
4515 boolean restarting, boolean allowRestart) {
4517 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4518 if (!kept && !restarting) {
4519 removeLruProcessLocked(app);
4521 ProcessList.remove(pid);
4525 if (mProfileProc == app) {
4526 clearProfilerLocked();
4529 // Remove this application's activities from active lists.
4530 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4532 app.activities.clear();
4534 if (app.instrumentationClass != null) {
4535 Slog.w(TAG, "Crash of app " + app.processName
4536 + " running instrumentation " + app.instrumentationClass);
4537 Bundle info = new Bundle();
4538 info.putString("shortMsg", "Process crashed.");
4539 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4542 if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4543 // If there was nothing to resume, and we are not already
4544 // restarting this process, but there is a visible activity that
4545 // is hosted by the process... then make sure all visible
4546 // activities are running, taking care of restarting this
4548 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4552 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4553 IBinder threadBinder = thread.asBinder();
4554 // Find the application record.
4555 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4556 ProcessRecord rec = mLruProcesses.get(i);
4557 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4564 final ProcessRecord getRecordForAppLocked(
4565 IApplicationThread thread) {
4566 if (thread == null) {
4570 int appIndex = getLRURecordIndexForAppLocked(thread);
4571 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4574 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4575 // If there are no longer any background processes running,
4576 // and the app that died was not running instrumentation,
4577 // then tell everyone we are now low on memory.
4578 boolean haveBg = false;
4579 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4580 ProcessRecord rec = mLruProcesses.get(i);
4581 if (rec.thread != null
4582 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4589 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4591 long now = SystemClock.uptimeMillis();
4592 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4595 mLastMemUsageReportTime = now;
4598 final ArrayList<ProcessMemInfo> memInfos
4599 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4600 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4601 long now = SystemClock.uptimeMillis();
4602 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4603 ProcessRecord rec = mLruProcesses.get(i);
4604 if (rec == dyingProc || rec.thread == null) {
4608 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4609 rec.setProcState, rec.adjType, rec.makeAdjReason()));
4611 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4612 // The low memory report is overriding any current
4613 // state for a GC request. Make sure to do
4614 // heavy/important/visible/foreground processes first.
4615 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4616 rec.lastRequestedGc = 0;
4618 rec.lastRequestedGc = rec.lastLowMemory;
4620 rec.reportLowMemory = true;
4621 rec.lastLowMemory = now;
4622 mProcessesToGc.remove(rec);
4623 addProcessToGcListLocked(rec);
4627 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4628 mHandler.sendMessage(msg);
4630 scheduleAppGcsLocked();
4634 final void appDiedLocked(ProcessRecord app) {
4635 appDiedLocked(app, app.pid, app.thread, false);
4638 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4639 boolean fromBinderDied) {
4640 // First check if this ProcessRecord is actually active for the pid.
4641 synchronized (mPidsSelfLocked) {
4642 ProcessRecord curProc = mPidsSelfLocked.get(pid);
4643 if (curProc != app) {
4644 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4649 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4650 synchronized (stats) {
4651 stats.noteProcessDiedLocked(app.info.uid, pid);
4655 if (!fromBinderDied) {
4656 Process.killProcessQuiet(pid);
4658 killProcessGroup(app.info.uid, pid);
4662 // Clean up already done if the process has been re-started.
4663 if (app.pid == pid && app.thread != null &&
4664 app.thread.asBinder() == thread.asBinder()) {
4665 boolean doLowMem = app.instrumentationClass == null;
4666 boolean doOomAdj = doLowMem;
4667 if (!app.killedByAm) {
4668 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4670 mAllowLowerMemLevel = true;
4672 // Note that we always want to do oom adj to update our state with the
4673 // new number of procs.
4674 mAllowLowerMemLevel = false;
4677 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4678 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4679 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4680 handleAppDiedLocked(app, false, true);
4683 updateOomAdjLocked();
4686 doLowMemReportIfNeededLocked(app);
4688 } else if (app.pid != pid) {
4689 // A new process has already been started.
4690 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4691 + ") has died and restarted (pid " + app.pid + ").");
4692 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4693 } else if (DEBUG_PROCESSES) {
4694 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4695 + thread.asBinder());
4700 * If a stack trace dump file is configured, dump process stack traces.
4701 * @param clearTraces causes the dump file to be erased prior to the new
4702 * traces being written, if true; when false, the new traces will be
4703 * appended to any existing file content.
4704 * @param firstPids of dalvik VM processes to dump stack traces for first
4705 * @param lastPids of dalvik VM processes to dump stack traces for last
4706 * @param nativeProcs optional list of native process names to dump stack crawls
4707 * @return file containing stack traces, or null if no dump file is configured
4709 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4710 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4711 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4712 if (tracesPath == null || tracesPath.length() == 0) {
4716 File tracesFile = new File(tracesPath);
4718 File tracesDir = tracesFile.getParentFile();
4719 if (!tracesDir.exists()) {
4721 if (!SELinux.restorecon(tracesDir)) {
4725 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4727 if (clearTraces && tracesFile.exists()) tracesFile.delete();
4728 tracesFile.createNewFile();
4729 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4730 } catch (IOException e) {
4731 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4735 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4739 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4740 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4741 // Use a FileObserver to detect when traces finish writing.
4742 // The order of traces is considered important to maintain for legibility.
4743 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4745 public synchronized void onEvent(int event, String path) { notify(); }
4749 observer.startWatching();
4751 // First collect all of the stacks of the most important pids.
4752 if (firstPids != null) {
4754 int num = firstPids.size();
4755 for (int i = 0; i < num; i++) {
4756 synchronized (observer) {
4757 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4758 observer.wait(200); // Wait for write-close, give up after 200msec
4761 } catch (InterruptedException e) {
4766 // Next collect the stacks of the native pids
4767 if (nativeProcs != null) {
4768 int[] pids = Process.getPidsForCommands(nativeProcs);
4770 for (int pid : pids) {
4771 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4776 // Lastly, measure CPU usage.
4777 if (processCpuTracker != null) {
4778 processCpuTracker.init();
4780 processCpuTracker.update();
4782 synchronized (processCpuTracker) {
4783 processCpuTracker.wait(500); // measure over 1/2 second.
4785 } catch (InterruptedException e) {
4787 processCpuTracker.update();
4789 // We'll take the stack crawls of just the top apps using CPU.
4790 final int N = processCpuTracker.countWorkingStats();
4792 for (int i=0; i<N && numProcs<5; i++) {
4793 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4794 if (lastPids.indexOfKey(stats.pid) >= 0) {
4797 synchronized (observer) {
4798 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4799 observer.wait(200); // Wait for write-close, give up after 200msec
4801 } catch (InterruptedException e) {
4809 observer.stopWatching();
4813 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4814 if (true || IS_USER_BUILD) {
4817 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4818 if (tracesPath == null || tracesPath.length() == 0) {
4822 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4823 StrictMode.allowThreadDiskWrites();
4825 final File tracesFile = new File(tracesPath);
4826 final File tracesDir = tracesFile.getParentFile();
4827 final File tracesTmp = new File(tracesDir, "__tmp__");
4829 if (!tracesDir.exists()) {
4831 if (!SELinux.restorecon(tracesDir.getPath())) {
4835 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4837 if (tracesFile.exists()) {
4839 tracesFile.renameTo(tracesTmp);
4841 StringBuilder sb = new StringBuilder();
4842 Time tobj = new Time();
4843 tobj.set(System.currentTimeMillis());
4844 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4846 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4847 sb.append(" since ");
4849 FileOutputStream fos = new FileOutputStream(tracesFile);
4850 fos.write(sb.toString().getBytes());
4852 fos.write("\n*** No application process!".getBytes());
4855 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4856 } catch (IOException e) {
4857 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4862 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4863 firstPids.add(app.pid);
4864 dumpStackTraces(tracesPath, firstPids, null, null, null);
4867 File lastTracesFile = null;
4868 File curTracesFile = null;
4869 for (int i=9; i>=0; i--) {
4870 String name = String.format(Locale.US, "slow%02d.txt", i);
4871 curTracesFile = new File(tracesDir, name);
4872 if (curTracesFile.exists()) {
4873 if (lastTracesFile != null) {
4874 curTracesFile.renameTo(lastTracesFile);
4876 curTracesFile.delete();
4879 lastTracesFile = curTracesFile;
4881 tracesFile.renameTo(curTracesFile);
4882 if (tracesTmp.exists()) {
4883 tracesTmp.renameTo(tracesFile);
4886 StrictMode.setThreadPolicy(oldPolicy);
4890 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4891 ActivityRecord parent, boolean aboveSystem, final String annotation) {
4892 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4893 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4895 if (mController != null) {
4897 // 0 == continue, -1 = kill process immediately
4898 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4899 if (res < 0 && app.pid != MY_PID) {
4900 app.kill("anr", true);
4902 } catch (RemoteException e) {
4904 Watchdog.getInstance().setActivityController(null);
4908 long anrTime = SystemClock.uptimeMillis();
4909 if (MONITOR_CPU_USAGE) {
4910 updateCpuStatsNow();
4913 synchronized (this) {
4914 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4915 if (mShuttingDown) {
4916 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4918 } else if (app.notResponding) {
4919 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4921 } else if (app.crashing) {
4922 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4926 // In case we come through here for the same app before completing
4927 // this one, mark as anring now so we will bail out.
4928 app.notResponding = true;
4930 // Log the ANR to the event log.
4931 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4932 app.processName, app.info.flags, annotation);
4934 // Dump thread traces as quickly as we can, starting with "interesting" processes.
4935 firstPids.add(app.pid);
4937 int parentPid = app.pid;
4938 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4939 if (parentPid != app.pid) firstPids.add(parentPid);
4941 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4943 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4944 ProcessRecord r = mLruProcesses.get(i);
4945 if (r != null && r.thread != null) {
4947 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4951 lastPids.put(pid, Boolean.TRUE);
4958 // Log the ANR to the main log.
4959 StringBuilder info = new StringBuilder();
4961 info.append("ANR in ").append(app.processName);
4962 if (activity != null && activity.shortComponentName != null) {
4963 info.append(" (").append(activity.shortComponentName).append(")");
4966 info.append("PID: ").append(app.pid).append("\n");
4967 if (annotation != null) {
4968 info.append("Reason: ").append(annotation).append("\n");
4970 if (parent != null && parent != activity) {
4971 info.append("Parent: ").append(parent.shortComponentName).append("\n");
4974 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4976 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4977 NATIVE_STACKS_OF_INTEREST);
4979 String cpuInfo = null;
4980 if (MONITOR_CPU_USAGE) {
4981 updateCpuStatsNow();
4982 synchronized (mProcessCpuTracker) {
4983 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4985 info.append(processCpuTracker.printCurrentLoad());
4986 info.append(cpuInfo);
4989 info.append(processCpuTracker.printCurrentState(anrTime));
4991 Slog.e(TAG, info.toString());
4992 if (tracesFile == null) {
4993 // There is no trace file, so dump (only) the alleged culprit's threads to the log
4994 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4997 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4998 cpuInfo, tracesFile, null);
5000 if (mController != null) {
5002 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5003 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5005 if (res < 0 && app.pid != MY_PID) {
5006 app.kill("anr", true);
5008 synchronized (this) {
5009 mServices.scheduleServiceTimeoutLocked(app);
5014 } catch (RemoteException e) {
5016 Watchdog.getInstance().setActivityController(null);
5020 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5021 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5022 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5024 synchronized (this) {
5025 mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5027 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5028 app.kill("bg anr", true);
5032 // Set the app's notResponding state, and look up the errorReportReceiver
5033 makeAppNotRespondingLocked(app,
5034 activity != null ? activity.shortComponentName : null,
5035 annotation != null ? "ANR " + annotation : "ANR",
5038 // Bring up the infamous App Not Responding dialog
5039 Message msg = Message.obtain();
5040 HashMap<String, Object> map = new HashMap<String, Object>();
5041 msg.what = SHOW_NOT_RESPONDING_MSG;
5043 msg.arg1 = aboveSystem ? 1 : 0;
5044 map.put("app", app);
5045 if (activity != null) {
5046 map.put("activity", activity);
5049 mUiHandler.sendMessage(msg);
5053 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5054 if (!mLaunchWarningShown) {
5055 mLaunchWarningShown = true;
5056 mUiHandler.post(new Runnable() {
5059 synchronized (ActivityManagerService.this) {
5060 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5062 mUiHandler.postDelayed(new Runnable() {
5065 synchronized (ActivityManagerService.this) {
5067 mLaunchWarningShown = false;
5078 public boolean clearApplicationUserData(final String packageName,
5079 final IPackageDataObserver observer, int userId) {
5080 enforceNotIsolatedCaller("clearApplicationUserData");
5081 if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5082 throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5084 int uid = Binder.getCallingUid();
5085 int pid = Binder.getCallingPid();
5086 userId = handleIncomingUser(pid, uid,
5087 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5088 long callingId = Binder.clearCallingIdentity();
5090 IPackageManager pm = AppGlobals.getPackageManager();
5092 synchronized(this) {
5094 pkgUid = pm.getPackageUid(packageName, userId);
5095 } catch (RemoteException e) {
5098 Slog.w(TAG, "Invalid packageName: " + packageName);
5099 if (observer != null) {
5101 observer.onRemoveCompleted(packageName, false);
5102 } catch (RemoteException e) {
5103 Slog.i(TAG, "Observer no longer exists.");
5108 if (uid == pkgUid || checkComponentPermission(
5109 android.Manifest.permission.CLEAR_APP_USER_DATA,
5111 == PackageManager.PERMISSION_GRANTED) {
5112 forceStopPackageLocked(packageName, pkgUid, "clear data");
5114 throw new SecurityException("PID " + pid + " does not have permission "
5115 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5116 + " of package " + packageName);
5119 // Remove all tasks match the cleared application package and user
5120 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5121 final TaskRecord tr = mRecentTasks.get(i);
5122 final String taskPackageName =
5123 tr.getBaseIntent().getComponent().getPackageName();
5124 if (tr.userId != userId) continue;
5125 if (!taskPackageName.equals(packageName)) continue;
5126 removeTaskByIdLocked(tr.taskId, false);
5131 // Clear application user data
5132 pm.clearApplicationUserData(packageName, observer, userId);
5134 synchronized(this) {
5135 // Remove all permissions granted from/to this package
5136 removeUriPermissionsForPackageLocked(packageName, userId, true);
5139 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5140 Uri.fromParts("package", packageName, null));
5141 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5142 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5143 null, null, 0, null, null, null, null, false, false, userId);
5144 } catch (RemoteException e) {
5147 Binder.restoreCallingIdentity(callingId);
5153 public void killBackgroundProcesses(final String packageName, int userId) {
5154 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5155 != PackageManager.PERMISSION_GRANTED &&
5156 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5157 != PackageManager.PERMISSION_GRANTED) {
5158 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5159 + Binder.getCallingPid()
5160 + ", uid=" + Binder.getCallingUid()
5161 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5163 throw new SecurityException(msg);
5166 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5167 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5168 long callingId = Binder.clearCallingIdentity();
5170 IPackageManager pm = AppGlobals.getPackageManager();
5171 synchronized(this) {
5174 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5175 } catch (RemoteException e) {
5178 Slog.w(TAG, "Invalid packageName: " + packageName);
5181 killPackageProcessesLocked(packageName, appId, userId,
5182 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5185 Binder.restoreCallingIdentity(callingId);
5190 public void killAllBackgroundProcesses() {
5191 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5192 != PackageManager.PERMISSION_GRANTED) {
5193 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5194 + Binder.getCallingPid()
5195 + ", uid=" + Binder.getCallingUid()
5196 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5198 throw new SecurityException(msg);
5201 long callingId = Binder.clearCallingIdentity();
5203 synchronized(this) {
5204 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5205 final int NP = mProcessNames.getMap().size();
5206 for (int ip=0; ip<NP; ip++) {
5207 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5208 final int NA = apps.size();
5209 for (int ia=0; ia<NA; ia++) {
5210 ProcessRecord app = apps.valueAt(ia);
5211 if (app.persistent) {
5212 // we don't kill persistent processes
5217 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5224 int N = procs.size();
5225 for (int i=0; i<N; i++) {
5226 removeProcessLocked(procs.get(i), false, true, "kill all background");
5228 mAllowLowerMemLevel = true;
5229 updateOomAdjLocked();
5230 doLowMemReportIfNeededLocked(null);
5233 Binder.restoreCallingIdentity(callingId);
5238 public void forceStopPackage(final String packageName, int userId) {
5239 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5240 != PackageManager.PERMISSION_GRANTED) {
5241 String msg = "Permission Denial: forceStopPackage() from pid="
5242 + Binder.getCallingPid()
5243 + ", uid=" + Binder.getCallingUid()
5244 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5246 throw new SecurityException(msg);
5248 final int callingPid = Binder.getCallingPid();
5249 userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5250 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5251 long callingId = Binder.clearCallingIdentity();
5253 IPackageManager pm = AppGlobals.getPackageManager();
5254 synchronized(this) {
5255 int[] users = userId == UserHandle.USER_ALL
5256 ? getUsersLocked() : new int[] { userId };
5257 for (int user : users) {
5260 pkgUid = pm.getPackageUid(packageName, user);
5261 } catch (RemoteException e) {
5264 Slog.w(TAG, "Invalid packageName: " + packageName);
5268 pm.setPackageStoppedState(packageName, true, user);
5269 } catch (RemoteException e) {
5270 } catch (IllegalArgumentException e) {
5271 Slog.w(TAG, "Failed trying to unstop package "
5272 + packageName + ": " + e);
5274 if (isUserRunningLocked(user, false)) {
5275 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5280 Binder.restoreCallingIdentity(callingId);
5285 public void addPackageDependency(String packageName) {
5286 synchronized (this) {
5287 int callingPid = Binder.getCallingPid();
5288 if (callingPid == Process.myPid()) {
5293 synchronized (mPidsSelfLocked) {
5294 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5297 if (proc.pkgDeps == null) {
5298 proc.pkgDeps = new ArraySet<String>(1);
5300 proc.pkgDeps.add(packageName);
5306 * The pkg name and app id have to be specified.
5309 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5313 // Make sure the uid is valid.
5315 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5318 int callerUid = Binder.getCallingUid();
5319 // Only the system server can kill an application
5320 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5321 // Post an aysnc message to kill the application
5322 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5325 Bundle bundle = new Bundle();
5326 bundle.putString("pkg", pkg);
5327 bundle.putString("reason", reason);
5329 mHandler.sendMessage(msg);
5331 throw new SecurityException(callerUid + " cannot kill pkg: " +
5337 public void closeSystemDialogs(String reason) {
5338 enforceNotIsolatedCaller("closeSystemDialogs");
5340 final int pid = Binder.getCallingPid();
5341 final int uid = Binder.getCallingUid();
5342 final long origId = Binder.clearCallingIdentity();
5344 synchronized (this) {
5345 // Only allow this from foreground processes, so that background
5346 // applications can't abuse it to prevent system UI from being shown.
5347 if (uid >= Process.FIRST_APPLICATION_UID) {
5349 synchronized (mPidsSelfLocked) {
5350 proc = mPidsSelfLocked.get(pid);
5352 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5353 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5354 + " from background process " + proc);
5358 closeSystemDialogsLocked(reason);
5361 Binder.restoreCallingIdentity(origId);
5365 void closeSystemDialogsLocked(String reason) {
5366 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5367 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5368 | Intent.FLAG_RECEIVER_FOREGROUND);
5369 if (reason != null) {
5370 intent.putExtra("reason", reason);
5372 mWindowManager.closeSystemDialogs(reason);
5374 mStackSupervisor.closeSystemDialogsLocked();
5376 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5377 AppOpsManager.OP_NONE, null, false, false,
5378 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5382 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5383 enforceNotIsolatedCaller("getProcessMemoryInfo");
5384 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5385 for (int i=pids.length-1; i>=0; i--) {
5388 synchronized (this) {
5389 synchronized (mPidsSelfLocked) {
5390 proc = mPidsSelfLocked.get(pids[i]);
5391 oomAdj = proc != null ? proc.setAdj : 0;
5394 infos[i] = new Debug.MemoryInfo();
5395 Debug.getMemoryInfo(pids[i], infos[i]);
5397 synchronized (this) {
5398 if (proc.thread != null && proc.setAdj == oomAdj) {
5399 // Record this for posterity if the process has been stable.
5400 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5401 infos[i].getTotalUss(), false, proc.pkgList);
5410 public long[] getProcessPss(int[] pids) {
5411 enforceNotIsolatedCaller("getProcessPss");
5412 long[] pss = new long[pids.length];
5413 for (int i=pids.length-1; i>=0; i--) {
5416 synchronized (this) {
5417 synchronized (mPidsSelfLocked) {
5418 proc = mPidsSelfLocked.get(pids[i]);
5419 oomAdj = proc != null ? proc.setAdj : 0;
5422 long[] tmpUss = new long[1];
5423 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5425 synchronized (this) {
5426 if (proc.thread != null && proc.setAdj == oomAdj) {
5427 // Record this for posterity if the process has been stable.
5428 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5437 public void killApplicationProcess(String processName, int uid) {
5438 if (processName == null) {
5442 int callerUid = Binder.getCallingUid();
5443 // Only the system server can kill an application
5444 if (callerUid == Process.SYSTEM_UID) {
5445 synchronized (this) {
5446 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5447 if (app != null && app.thread != null) {
5449 app.thread.scheduleSuicide();
5450 } catch (RemoteException e) {
5451 // If the other end already died, then our work here is done.
5454 Slog.w(TAG, "Process/uid not found attempting kill of "
5455 + processName + " / " + uid);
5459 throw new SecurityException(callerUid + " cannot kill app process: " +
5464 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5465 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5466 false, true, false, false, UserHandle.getUserId(uid), reason);
5467 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5468 Uri.fromParts("package", packageName, null));
5469 if (!mProcessesReady) {
5470 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5471 | Intent.FLAG_RECEIVER_FOREGROUND);
5473 intent.putExtra(Intent.EXTRA_UID, uid);
5474 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5475 broadcastIntentLocked(null, null, intent,
5476 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5477 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5480 private void forceStopUserLocked(int userId, String reason) {
5481 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5482 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5483 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5484 | Intent.FLAG_RECEIVER_FOREGROUND);
5485 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5486 broadcastIntentLocked(null, null, intent,
5487 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5488 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5491 private final boolean killPackageProcessesLocked(String packageName, int appId,
5492 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5493 boolean doit, boolean evenPersistent, String reason) {
5494 ArrayList<ProcessRecord> procs = new ArrayList<>();
5496 // Remove all processes this package may have touched: all with the
5497 // same UID (except for the system or root user), and all whose name
5498 // matches the package name.
5499 final int NP = mProcessNames.getMap().size();
5500 for (int ip=0; ip<NP; ip++) {
5501 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5502 final int NA = apps.size();
5503 for (int ia=0; ia<NA; ia++) {
5504 ProcessRecord app = apps.valueAt(ia);
5505 if (app.persistent && !evenPersistent) {
5506 // we don't kill persistent processes
5516 // Skip process if it doesn't meet our oom adj requirement.
5517 if (app.setAdj < minOomAdj) {
5521 // If no package is specified, we call all processes under the
5523 if (packageName == null) {
5524 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5527 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5530 // Package has been specified, we want to hit all processes
5531 // that match it. We need to qualify this by the processes
5532 // that are running under the specified app and user ID.
5534 final boolean isDep = app.pkgDeps != null
5535 && app.pkgDeps.contains(packageName);
5536 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5539 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5542 if (!app.pkgList.containsKey(packageName) && !isDep) {
5547 // Process has passed all conditions, kill it!
5556 int N = procs.size();
5557 for (int i=0; i<N; i++) {
5558 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5560 updateOomAdjLocked();
5564 private void cleanupDisabledPackageComponentsLocked(
5565 String packageName, int userId, boolean killProcess, String[] changedClasses) {
5567 Set<String> disabledClasses = null;
5568 boolean packageDisabled = false;
5569 IPackageManager pm = AppGlobals.getPackageManager();
5571 if (changedClasses == null) {
5572 // Nothing changed...
5576 // Determine enable/disable state of the package and its components.
5577 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5578 for (int i = changedClasses.length - 1; i >= 0; i--) {
5579 final String changedClass = changedClasses[i];
5581 if (changedClass.equals(packageName)) {
5583 // Entire package setting changed
5584 enabled = pm.getApplicationEnabledSetting(packageName,
5585 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5586 } catch (Exception e) {
5587 // No such package/component; probably racing with uninstall. In any
5588 // event it means we have nothing further to do here.
5591 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5592 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5593 if (packageDisabled) {
5594 // Entire package is disabled.
5595 // No need to continue to check component states.
5596 disabledClasses = null;
5601 enabled = pm.getComponentEnabledSetting(
5602 new ComponentName(packageName, changedClass),
5603 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5604 } catch (Exception e) {
5605 // As above, probably racing with uninstall.
5608 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5609 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5610 if (disabledClasses == null) {
5611 disabledClasses = new ArraySet<>(changedClasses.length);
5613 disabledClasses.add(changedClass);
5618 if (!packageDisabled && disabledClasses == null) {
5619 // Nothing to do here...
5623 // Clean-up disabled activities.
5624 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5625 packageName, disabledClasses, true, false, userId) && mBooted) {
5626 mStackSupervisor.resumeTopActivitiesLocked();
5627 mStackSupervisor.scheduleIdleLocked();
5630 // Clean-up disabled tasks
5631 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5633 // Clean-up disabled services.
5634 mServices.bringDownDisabledPackageServicesLocked(
5635 packageName, disabledClasses, userId, false, killProcess, true);
5637 // Clean-up disabled providers.
5638 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5639 mProviderMap.collectPackageProvidersLocked(
5640 packageName, disabledClasses, true, false, userId, providers);
5641 for (int i = providers.size() - 1; i >= 0; i--) {
5642 removeDyingProviderLocked(null, providers.get(i), true);
5645 // Clean-up disabled broadcast receivers.
5646 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5647 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5648 packageName, disabledClasses, userId, true);
5653 private final boolean forceStopPackageLocked(String packageName, int appId,
5654 boolean callerWillRestart, boolean purgeCache, boolean doit,
5655 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5658 if (userId == UserHandle.USER_ALL && packageName == null) {
5659 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5662 if (appId < 0 && packageName != null) {
5664 appId = UserHandle.getAppId(
5665 AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5666 } catch (RemoteException e) {
5671 if (packageName != null) {
5672 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5673 + " user=" + userId + ": " + reason);
5675 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5678 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5679 for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5680 SparseArray<Long> ba = pmap.valueAt(ip);
5681 for (i = ba.size() - 1; i >= 0; i--) {
5682 boolean remove = false;
5683 final int entUid = ba.keyAt(i);
5684 if (packageName != null) {
5685 if (userId == UserHandle.USER_ALL) {
5686 if (UserHandle.getAppId(entUid) == appId) {
5690 if (entUid == UserHandle.getUid(userId, appId)) {
5694 } else if (UserHandle.getUserId(entUid) == userId) {
5701 if (ba.size() == 0) {
5707 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5708 -100, callerWillRestart, true, doit, evenPersistent,
5709 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5711 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5712 packageName, null, doit, evenPersistent, userId)) {
5716 didSomething = true;
5719 if (mServices.bringDownDisabledPackageServicesLocked(
5720 packageName, null, userId, evenPersistent, true, doit)) {
5724 didSomething = true;
5727 if (packageName == null) {
5728 // Remove all sticky broadcasts from this user.
5729 mStickyBroadcasts.remove(userId);
5732 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5733 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5734 userId, providers)) {
5738 didSomething = true;
5740 for (i = providers.size() - 1; i >= 0; i--) {
5741 removeDyingProviderLocked(null, providers.get(i), true);
5744 // Remove transient permissions granted from/to this package/user
5745 removeUriPermissionsForPackageLocked(packageName, userId, false);
5748 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5749 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5750 packageName, null, userId, doit);
5754 if (packageName == null || uninstalling) {
5755 // Remove pending intents. For now we only do this when force
5756 // stopping users, because we have some problems when doing this
5757 // for packages -- app widgets are not currently cleaned up for
5758 // such packages, so they can be left with bad pending intents.
5759 if (mIntentSenderRecords.size() > 0) {
5760 Iterator<WeakReference<PendingIntentRecord>> it
5761 = mIntentSenderRecords.values().iterator();
5762 while (it.hasNext()) {
5763 WeakReference<PendingIntentRecord> wpir = it.next();
5768 PendingIntentRecord pir = wpir.get();
5773 if (packageName == null) {
5774 // Stopping user, remove all objects for the user.
5775 if (pir.key.userId != userId) {
5776 // Not the same user, skip it.
5780 if (UserHandle.getAppId(pir.uid) != appId) {
5781 // Different app id, skip it.
5784 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5785 // Different user, skip it.
5788 if (!pir.key.packageName.equals(packageName)) {
5789 // Different package, skip it.
5796 didSomething = true;
5798 pir.canceled = true;
5799 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5800 pir.key.activity.pendingResults.remove(pir.ref);
5807 if (purgeCache && packageName != null) {
5808 AttributeCache ac = AttributeCache.instance();
5810 ac.removePackage(packageName);
5814 mStackSupervisor.resumeTopActivitiesLocked();
5815 mStackSupervisor.scheduleIdleLocked();
5819 return didSomething;
5822 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5823 ProcessRecord old = mProcessNames.remove(name, uid);
5825 old.uidRecord.numProcs--;
5826 if (old.uidRecord.numProcs == 0) {
5827 // No more processes using this uid, tell clients it is gone.
5828 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5829 "No more processes in " + old.uidRecord);
5830 enqueueUidChangeLocked(old.uidRecord, true);
5831 mActiveUids.remove(uid);
5833 old.uidRecord = null;
5835 mIsolatedProcesses.remove(uid);
5839 private final void addProcessNameLocked(ProcessRecord proc) {
5840 // We shouldn't already have a process under this name, but just in case we
5841 // need to clean up whatever may be there now.
5842 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5843 if (old == proc && proc.persistent) {
5844 // We are re-adding a persistent process. Whatevs! Just leave it there.
5845 Slog.w(TAG, "Re-adding persistent process " + proc);
5846 } else if (old != null) {
5847 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5849 UidRecord uidRec = mActiveUids.get(proc.uid);
5850 if (uidRec == null) {
5851 uidRec = new UidRecord(proc.uid);
5852 // This is the first appearance of the uid, report it now!
5853 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5854 "Creating new process uid: " + uidRec);
5855 mActiveUids.put(proc.uid, uidRec);
5856 enqueueUidChangeLocked(uidRec, false);
5858 proc.uidRecord = uidRec;
5860 mProcessNames.put(proc.processName, proc.uid, proc);
5861 if (proc.isolated) {
5862 mIsolatedProcesses.put(proc.uid, proc);
5866 private final boolean removeProcessLocked(ProcessRecord app,
5867 boolean callerWillRestart, boolean allowRestart, String reason) {
5868 final String name = app.processName;
5869 final int uid = app.uid;
5870 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5871 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5873 removeProcessNameLocked(name, uid);
5874 if (mHeavyWeightProcess == app) {
5875 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5876 mHeavyWeightProcess.userId, 0));
5877 mHeavyWeightProcess = null;
5879 boolean needRestart = false;
5880 if (app.pid > 0 && app.pid != MY_PID) {
5882 synchronized (mPidsSelfLocked) {
5883 mPidsSelfLocked.remove(pid);
5884 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5886 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5888 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5890 boolean willRestart = false;
5891 if (app.persistent && !app.isolated) {
5892 if (!callerWillRestart) {
5898 app.kill(reason, true);
5899 handleAppDiedLocked(app, willRestart, allowRestart);
5901 removeLruProcessLocked(app);
5902 addAppLocked(app.info, false, null /* ABI override */);
5905 mRemovedProcesses.add(app);
5911 private final void processStartTimedOutLocked(ProcessRecord app) {
5912 final int pid = app.pid;
5913 boolean gone = false;
5914 synchronized (mPidsSelfLocked) {
5915 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5916 if (knownApp != null && knownApp.thread == null) {
5917 mPidsSelfLocked.remove(pid);
5923 Slog.w(TAG, "Process " + app + " failed to attach");
5924 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5925 pid, app.uid, app.processName);
5926 removeProcessNameLocked(app.processName, app.uid);
5927 if (mHeavyWeightProcess == app) {
5928 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5929 mHeavyWeightProcess.userId, 0));
5930 mHeavyWeightProcess = null;
5932 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5934 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5936 // Take care of any launching providers waiting for this process.
5937 checkAppInLaunchingProvidersLocked(app, true);
5938 // Take care of any services that are waiting for the process.
5939 mServices.processStartTimedOutLocked(app);
5940 app.kill("start timeout", true);
5941 removeLruProcessLocked(app);
5942 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5943 Slog.w(TAG, "Unattached app died before backup, skipping");
5945 IBackupManager bm = IBackupManager.Stub.asInterface(
5946 ServiceManager.getService(Context.BACKUP_SERVICE));
5947 bm.agentDisconnected(app.info.packageName);
5948 } catch (RemoteException e) {
5949 // Can't happen; the backup manager is local
5952 if (isPendingBroadcastProcessLocked(pid)) {
5953 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5954 skipPendingBroadcastLocked(pid);
5957 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5961 private final boolean attachApplicationLocked(IApplicationThread thread,
5964 // Find the application record that is being attached... either via
5965 // the pid if we are running in multiple processes, or just pull the
5966 // next app record if we are emulating process with anonymous threads.
5968 if (pid != MY_PID && pid >= 0) {
5969 synchronized (mPidsSelfLocked) {
5970 app = mPidsSelfLocked.get(pid);
5977 Slog.w(TAG, "No pending application record for pid " + pid
5978 + " (IApplicationThread " + thread + "); dropping process");
5979 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5980 if (pid > 0 && pid != MY_PID) {
5981 Process.killProcessQuiet(pid);
5982 //TODO: killProcessGroup(app.info.uid, pid);
5985 thread.scheduleExit();
5986 } catch (Exception e) {
5987 // Ignore exceptions.
5993 // If this application record is still attached to a previous
5994 // process, clean it up now.
5995 if (app.thread != null) {
5996 handleAppDiedLocked(app, true, true);
5999 // Tell the process all about itself.
6001 if (DEBUG_ALL) Slog.v(
6002 TAG, "Binding process pid " + pid + " to record " + app);
6004 final String processName = app.processName;
6006 AppDeathRecipient adr = new AppDeathRecipient(
6008 thread.asBinder().linkToDeath(adr, 0);
6009 app.deathRecipient = adr;
6010 } catch (RemoteException e) {
6011 app.resetPackageList(mProcessStats);
6012 startProcessLocked(app, "link fail", processName);
6016 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6018 app.makeActive(thread, mProcessStats);
6019 app.curAdj = app.setAdj = -100;
6020 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6021 app.forcingToForeground = null;
6022 updateProcessForegroundLocked(app, false, false);
6023 app.hasShownUi = false;
6024 app.debugging = false;
6026 app.killedByAm = false;
6028 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6030 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6031 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6034 Slog.i(TAG, "Launching preboot mode app: " + app);
6037 if (DEBUG_ALL) Slog.v(
6038 TAG, "New app record " + app
6039 + " thread=" + thread.asBinder() + " pid=" + pid);
6041 int testMode = IApplicationThread.DEBUG_OFF;
6042 if (mDebugApp != null && mDebugApp.equals(processName)) {
6043 testMode = mWaitForDebugger
6044 ? IApplicationThread.DEBUG_WAIT
6045 : IApplicationThread.DEBUG_ON;
6046 app.debugging = true;
6047 if (mDebugTransient) {
6048 mDebugApp = mOrigDebugApp;
6049 mWaitForDebugger = mOrigWaitForDebugger;
6052 String profileFile = app.instrumentationProfileFile;
6053 ParcelFileDescriptor profileFd = null;
6054 int samplingInterval = 0;
6055 boolean profileAutoStop = false;
6056 if (mProfileApp != null && mProfileApp.equals(processName)) {
6058 profileFile = mProfileFile;
6059 profileFd = mProfileFd;
6060 samplingInterval = mSamplingInterval;
6061 profileAutoStop = mAutoStopProfiler;
6063 boolean enableOpenGlTrace = false;
6064 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6065 enableOpenGlTrace = true;
6066 mOpenGlTraceApp = null;
6069 // If the app is being launched for restore or full backup, set it up specially
6070 boolean isRestrictedBackupMode = false;
6071 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6072 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6073 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6074 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6077 ensurePackageDexOpt(app.instrumentationInfo != null
6078 ? app.instrumentationInfo.packageName
6079 : app.info.packageName);
6080 if (app.instrumentationClass != null) {
6081 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6083 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6084 + processName + " with config " + mConfiguration);
6085 ApplicationInfo appInfo = app.instrumentationInfo != null
6086 ? app.instrumentationInfo : app.info;
6087 app.compat = compatibilityInfoForPackageLocked(appInfo);
6088 if (profileFd != null) {
6089 profileFd = profileFd.dup();
6091 ProfilerInfo profilerInfo = profileFile == null ? null
6092 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6093 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6094 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6095 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6096 isRestrictedBackupMode || !normalMode, app.persistent,
6097 new Configuration(mConfiguration), app.compat,
6098 getCommonServicesLocked(app.isolated),
6099 mCoreSettingsObserver.getCoreSettingsLocked());
6100 updateLruProcessLocked(app, false, null);
6101 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6102 } catch (Exception e) {
6103 // todo: Yikes! What should we do? For now we will try to
6104 // start another process, but that could easily get us in
6105 // an infinite loop of restarting processes...
6106 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6108 app.resetPackageList(mProcessStats);
6109 app.unlinkDeathRecipient();
6110 startProcessLocked(app, "bind fail", processName);
6114 // Remove this record from the list of starting applications.
6115 mPersistentStartingProcesses.remove(app);
6116 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6117 "Attach application locked removing on hold: " + app);
6118 mProcessesOnHold.remove(app);
6120 boolean badApp = false;
6121 boolean didSomething = false;
6123 // See if the top visible activity is waiting to run in this process...
6126 if (mStackSupervisor.attachApplicationLocked(app)) {
6127 didSomething = true;
6129 } catch (Exception e) {
6130 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6135 // Find any services that should be running in this process...
6138 didSomething |= mServices.attachApplicationLocked(app, processName);
6139 } catch (Exception e) {
6140 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6145 // Check if a next-broadcast receiver is in this process...
6146 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6148 didSomething |= sendPendingBroadcastsLocked(app);
6149 } catch (Exception e) {
6150 // If the app died trying to launch the receiver we declare it 'bad'
6151 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6156 // Check whether the next backup agent is in this process...
6157 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6158 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6159 "New app is backup target, launching agent for " + app);
6160 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6162 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6163 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6164 mBackupTarget.backupMode);
6165 } catch (Exception e) {
6166 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6172 app.kill("error during init", true);
6173 handleAppDiedLocked(app, false, true);
6177 if (!didSomething) {
6178 updateOomAdjLocked();
6185 public final void attachApplication(IApplicationThread thread) {
6186 synchronized (this) {
6187 int callingPid = Binder.getCallingPid();
6188 final long origId = Binder.clearCallingIdentity();
6189 attachApplicationLocked(thread, callingPid);
6190 Binder.restoreCallingIdentity(origId);
6195 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6196 final long origId = Binder.clearCallingIdentity();
6197 synchronized (this) {
6198 ActivityStack stack = ActivityRecord.getStackLocked(token);
6199 if (stack != null) {
6201 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6202 if (stopProfiling) {
6203 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6206 } catch (IOException e) {
6208 clearProfilerLocked();
6213 Binder.restoreCallingIdentity(origId);
6216 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6217 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6218 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6221 void enableScreenAfterBoot() {
6222 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6223 SystemClock.uptimeMillis());
6224 mWindowManager.enableScreenAfterBoot();
6226 synchronized (this) {
6227 updateEventDispatchingLocked();
6232 public void showBootMessage(final CharSequence msg, final boolean always) {
6233 if (Binder.getCallingUid() != Process.myUid()) {
6234 // These days only the core system can call this, so apps can't get in
6235 // the way of what we show about running them.
6237 mWindowManager.showBootMessage(msg, always);
6241 public void keyguardWaitingForActivityDrawn() {
6242 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6243 final long token = Binder.clearCallingIdentity();
6245 synchronized (this) {
6246 if (DEBUG_LOCKSCREEN) logLockScreen("");
6247 mWindowManager.keyguardWaitingForActivityDrawn();
6248 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6249 mLockScreenShown = LOCK_SCREEN_LEAVING;
6250 updateSleepIfNeededLocked();
6254 Binder.restoreCallingIdentity(token);
6259 public void keyguardGoingAway(boolean disableWindowAnimations,
6260 boolean keyguardGoingToNotificationShade) {
6261 enforceNotIsolatedCaller("keyguardGoingAway");
6262 final long token = Binder.clearCallingIdentity();
6264 synchronized (this) {
6265 if (DEBUG_LOCKSCREEN) logLockScreen("");
6266 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6267 keyguardGoingToNotificationShade);
6268 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6269 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6270 updateSleepIfNeededLocked();
6274 Binder.restoreCallingIdentity(token);
6278 final void finishBooting() {
6279 synchronized (this) {
6280 if (!mBootAnimationComplete) {
6281 mCallFinishBooting = true;
6284 mCallFinishBooting = false;
6287 ArraySet<String> completedIsas = new ArraySet<String>();
6288 for (String abi : Build.SUPPORTED_ABIS) {
6289 Process.establishZygoteConnectionForAbi(abi);
6290 final String instructionSet = VMRuntime.getInstructionSet(abi);
6291 if (!completedIsas.contains(instructionSet)) {
6292 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6293 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6295 completedIsas.add(instructionSet);
6299 IntentFilter pkgFilter = new IntentFilter();
6300 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6301 pkgFilter.addDataScheme("package");
6302 mContext.registerReceiver(new BroadcastReceiver() {
6304 public void onReceive(Context context, Intent intent) {
6305 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6307 for (String pkg : pkgs) {
6308 synchronized (ActivityManagerService.this) {
6309 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6310 0, "query restart")) {
6311 setResultCode(Activity.RESULT_OK);
6320 IntentFilter dumpheapFilter = new IntentFilter();
6321 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6322 mContext.registerReceiver(new BroadcastReceiver() {
6324 public void onReceive(Context context, Intent intent) {
6325 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6326 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6328 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6333 // Let system services know.
6334 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6336 synchronized (this) {
6337 // Ensure that any processes we had put on hold are now started
6339 final int NP = mProcessesOnHold.size();
6341 ArrayList<ProcessRecord> procs =
6342 new ArrayList<ProcessRecord>(mProcessesOnHold);
6343 for (int ip=0; ip<NP; ip++) {
6344 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6346 startProcessLocked(procs.get(ip), "on-hold", null);
6350 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6351 // Start looking for apps that are abusing wake locks.
6352 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6353 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6354 // Tell anyone interested that we are done booting!
6355 SystemProperties.set("sys.boot_completed", "1");
6357 // And trigger dev.bootcomplete if we are not showing encryption progress
6358 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6359 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6360 SystemProperties.set("dev.bootcomplete", "1");
6362 for (int i=0; i<mStartedUsers.size(); i++) {
6363 UserState uss = mStartedUsers.valueAt(i);
6364 if (uss.mState == UserState.STATE_BOOTING) {
6365 uss.mState = UserState.STATE_RUNNING;
6366 final int userId = mStartedUsers.keyAt(i);
6367 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6368 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6369 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6370 broadcastIntentLocked(null, null, intent, null,
6371 new IIntentReceiver.Stub() {
6373 public void performReceive(Intent intent, int resultCode,
6374 String data, Bundle extras, boolean ordered,
6375 boolean sticky, int sendingUser) {
6376 synchronized (ActivityManagerService.this) {
6377 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6383 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6384 AppOpsManager.OP_NONE, null, true, false,
6385 MY_PID, Process.SYSTEM_UID, userId);
6388 scheduleStartProfilesLocked();
6394 public void bootAnimationComplete() {
6395 final boolean callFinishBooting;
6396 synchronized (this) {
6397 callFinishBooting = mCallFinishBooting;
6398 mBootAnimationComplete = true;
6400 if (callFinishBooting) {
6405 final void ensureBootCompleted() {
6407 boolean enableScreen;
6408 synchronized (this) {
6411 enableScreen = !mBooted;
6420 enableScreenAfterBoot();
6425 public final void activityResumed(IBinder token) {
6426 final long origId = Binder.clearCallingIdentity();
6427 synchronized(this) {
6428 ActivityStack stack = ActivityRecord.getStackLocked(token);
6429 if (stack != null) {
6430 ActivityRecord.activityResumedLocked(token);
6433 Binder.restoreCallingIdentity(origId);
6437 public final void activityPaused(IBinder token) {
6438 final long origId = Binder.clearCallingIdentity();
6439 synchronized(this) {
6440 ActivityStack stack = ActivityRecord.getStackLocked(token);
6441 if (stack != null) {
6442 stack.activityPausedLocked(token, false);
6445 Binder.restoreCallingIdentity(origId);
6449 public final void activityStopped(IBinder token, Bundle icicle,
6450 PersistableBundle persistentState, CharSequence description) {
6451 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6453 // Refuse possible leaked file descriptors
6454 if (icicle != null && icicle.hasFileDescriptors()) {
6455 throw new IllegalArgumentException("File descriptors passed in Bundle");
6458 final long origId = Binder.clearCallingIdentity();
6460 synchronized (this) {
6461 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6463 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6469 Binder.restoreCallingIdentity(origId);
6473 public final void activityDestroyed(IBinder token) {
6474 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6475 synchronized (this) {
6476 ActivityStack stack = ActivityRecord.getStackLocked(token);
6477 if (stack != null) {
6478 stack.activityDestroyedLocked(token, "activityDestroyed");
6484 public final void backgroundResourcesReleased(IBinder token) {
6485 final long origId = Binder.clearCallingIdentity();
6487 synchronized (this) {
6488 ActivityStack stack = ActivityRecord.getStackLocked(token);
6489 if (stack != null) {
6490 stack.backgroundResourcesReleased();
6494 Binder.restoreCallingIdentity(origId);
6499 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6500 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6504 public final void notifyEnterAnimationComplete(IBinder token) {
6505 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6509 public String getCallingPackage(IBinder token) {
6510 synchronized (this) {
6511 ActivityRecord r = getCallingRecordLocked(token);
6512 return r != null ? r.info.packageName : null;
6517 public ComponentName getCallingActivity(IBinder token) {
6518 synchronized (this) {
6519 ActivityRecord r = getCallingRecordLocked(token);
6520 return r != null ? r.intent.getComponent() : null;
6524 private ActivityRecord getCallingRecordLocked(IBinder token) {
6525 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6533 public ComponentName getActivityClassForToken(IBinder token) {
6534 synchronized(this) {
6535 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6539 return r.intent.getComponent();
6544 public String getPackageForToken(IBinder token) {
6545 synchronized(this) {
6546 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6550 return r.packageName;
6555 public boolean isRootVoiceInteraction(IBinder token) {
6556 synchronized(this) {
6557 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6561 return r.rootVoiceInteraction;
6566 public IIntentSender getIntentSender(int type,
6567 String packageName, IBinder token, String resultWho,
6568 int requestCode, Intent[] intents, String[] resolvedTypes,
6569 int flags, Bundle options, int userId) {
6570 enforceNotIsolatedCaller("getIntentSender");
6571 // Refuse possible leaked file descriptors
6572 if (intents != null) {
6573 if (intents.length < 1) {
6574 throw new IllegalArgumentException("Intents array length must be >= 1");
6576 for (int i=0; i<intents.length; i++) {
6577 Intent intent = intents[i];
6578 if (intent != null) {
6579 if (intent.hasFileDescriptors()) {
6580 throw new IllegalArgumentException("File descriptors passed in Intent");
6582 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6583 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6584 throw new IllegalArgumentException(
6585 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6587 intents[i] = new Intent(intent);
6590 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6591 throw new IllegalArgumentException(
6592 "Intent array length does not match resolvedTypes length");
6595 if (options != null) {
6596 if (options.hasFileDescriptors()) {
6597 throw new IllegalArgumentException("File descriptors passed in options");
6601 synchronized(this) {
6602 int callingUid = Binder.getCallingUid();
6603 int origUserId = userId;
6604 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6605 type == ActivityManager.INTENT_SENDER_BROADCAST,
6606 ALLOW_NON_FULL, "getIntentSender", null);
6607 if (origUserId == UserHandle.USER_CURRENT) {
6608 // We don't want to evaluate this until the pending intent is
6609 // actually executed. However, we do want to always do the
6610 // security checking for it above.
6611 userId = UserHandle.USER_CURRENT;
6614 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6615 int uid = AppGlobals.getPackageManager()
6616 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6617 if (!UserHandle.isSameApp(callingUid, uid)) {
6618 String msg = "Permission Denial: getIntentSender() from pid="
6619 + Binder.getCallingPid()
6620 + ", uid=" + Binder.getCallingUid()
6621 + ", (need uid=" + uid + ")"
6622 + " is not allowed to send as package " + packageName;
6624 throw new SecurityException(msg);
6628 return getIntentSenderLocked(type, packageName, callingUid, userId,
6629 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6631 } catch (RemoteException e) {
6632 throw new SecurityException(e);
6637 IIntentSender getIntentSenderLocked(int type, String packageName,
6638 int callingUid, int userId, IBinder token, String resultWho,
6639 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6641 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6642 ActivityRecord activity = null;
6643 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6644 activity = ActivityRecord.isInStackLocked(token);
6645 if (activity == null) {
6648 if (activity.finishing) {
6653 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6654 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6655 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6656 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6657 |PendingIntent.FLAG_UPDATE_CURRENT);
6659 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6660 type, packageName, activity, resultWho,
6661 requestCode, intents, resolvedTypes, flags, options, userId);
6662 WeakReference<PendingIntentRecord> ref;
6663 ref = mIntentSenderRecords.get(key);
6664 PendingIntentRecord rec = ref != null ? ref.get() : null;
6666 if (!cancelCurrent) {
6667 if (updateCurrent) {
6668 if (rec.key.requestIntent != null) {
6669 rec.key.requestIntent.replaceExtras(intents != null ?
6670 intents[intents.length - 1] : null);
6672 if (intents != null) {
6673 intents[intents.length-1] = rec.key.requestIntent;
6674 rec.key.allIntents = intents;
6675 rec.key.allResolvedTypes = resolvedTypes;
6677 rec.key.allIntents = null;
6678 rec.key.allResolvedTypes = null;
6683 rec.canceled = true;
6684 mIntentSenderRecords.remove(key);
6689 rec = new PendingIntentRecord(this, key, callingUid);
6690 mIntentSenderRecords.put(key, rec.ref);
6691 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6692 if (activity.pendingResults == null) {
6693 activity.pendingResults
6694 = new HashSet<WeakReference<PendingIntentRecord>>();
6696 activity.pendingResults.add(rec.ref);
6702 public void cancelIntentSender(IIntentSender sender) {
6703 if (!(sender instanceof PendingIntentRecord)) {
6706 synchronized(this) {
6707 PendingIntentRecord rec = (PendingIntentRecord)sender;
6709 int uid = AppGlobals.getPackageManager()
6710 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6711 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6712 String msg = "Permission Denial: cancelIntentSender() from pid="
6713 + Binder.getCallingPid()
6714 + ", uid=" + Binder.getCallingUid()
6715 + " is not allowed to cancel packges "
6716 + rec.key.packageName;
6718 throw new SecurityException(msg);
6720 } catch (RemoteException e) {
6721 throw new SecurityException(e);
6723 cancelIntentSenderLocked(rec, true);
6727 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6728 rec.canceled = true;
6729 mIntentSenderRecords.remove(rec.key);
6730 if (cleanActivity && rec.key.activity != null) {
6731 rec.key.activity.pendingResults.remove(rec.ref);
6736 public String getPackageForIntentSender(IIntentSender pendingResult) {
6737 if (!(pendingResult instanceof PendingIntentRecord)) {
6741 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6742 return res.key.packageName;
6743 } catch (ClassCastException e) {
6749 public int getUidForIntentSender(IIntentSender sender) {
6750 if (sender instanceof PendingIntentRecord) {
6752 PendingIntentRecord res = (PendingIntentRecord)sender;
6754 } catch (ClassCastException e) {
6761 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6762 if (!(pendingResult instanceof PendingIntentRecord)) {
6766 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6767 if (res.key.allIntents == null) {
6770 for (int i=0; i<res.key.allIntents.length; i++) {
6771 Intent intent = res.key.allIntents[i];
6772 if (intent.getPackage() != null && intent.getComponent() != null) {
6777 } catch (ClassCastException e) {
6783 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6784 if (!(pendingResult instanceof PendingIntentRecord)) {
6788 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6789 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6793 } catch (ClassCastException e) {
6799 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6800 if (!(pendingResult instanceof PendingIntentRecord)) {
6804 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6805 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6806 } catch (ClassCastException e) {
6812 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6813 if (!(pendingResult instanceof PendingIntentRecord)) {
6817 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6818 synchronized (this) {
6819 return getTagForIntentSenderLocked(res, prefix);
6821 } catch (ClassCastException e) {
6826 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6827 final Intent intent = res.key.requestIntent;
6828 if (intent != null) {
6829 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6830 || res.lastTagPrefix.equals(prefix))) {
6833 res.lastTagPrefix = prefix;
6834 final StringBuilder sb = new StringBuilder(128);
6835 if (prefix != null) {
6838 if (intent.getAction() != null) {
6839 sb.append(intent.getAction());
6840 } else if (intent.getComponent() != null) {
6841 intent.getComponent().appendShortString(sb);
6845 return res.lastTag = sb.toString();
6851 public void setProcessLimit(int max) {
6852 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6853 "setProcessLimit()");
6854 synchronized (this) {
6855 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6856 mProcessLimitOverride = max;
6862 public int getProcessLimit() {
6863 synchronized (this) {
6864 return mProcessLimitOverride;
6868 void foregroundTokenDied(ForegroundToken token) {
6869 synchronized (ActivityManagerService.this) {
6870 synchronized (mPidsSelfLocked) {
6872 = mForegroundProcesses.get(token.pid);
6876 mForegroundProcesses.remove(token.pid);
6877 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6881 pr.forcingToForeground = null;
6882 updateProcessForegroundLocked(pr, false, false);
6884 updateOomAdjLocked();
6889 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6890 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6891 "setProcessForeground()");
6892 synchronized(this) {
6893 boolean changed = false;
6895 synchronized (mPidsSelfLocked) {
6896 ProcessRecord pr = mPidsSelfLocked.get(pid);
6897 if (pr == null && isForeground) {
6898 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6901 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6902 if (oldToken != null) {
6903 oldToken.token.unlinkToDeath(oldToken, 0);
6904 mForegroundProcesses.remove(pid);
6906 pr.forcingToForeground = null;
6910 if (isForeground && token != null) {
6911 ForegroundToken newToken = new ForegroundToken() {
6913 public void binderDied() {
6914 foregroundTokenDied(this);
6918 newToken.token = token;
6920 token.linkToDeath(newToken, 0);
6921 mForegroundProcesses.put(pid, newToken);
6922 pr.forcingToForeground = token;
6924 } catch (RemoteException e) {
6925 // If the process died while doing this, we will later
6926 // do the cleanup with the process death link.
6932 updateOomAdjLocked();
6937 // =========================================================
6939 // =========================================================
6941 static class ProcessInfoService extends IProcessInfoService.Stub {
6942 final ActivityManagerService mActivityManagerService;
6943 ProcessInfoService(ActivityManagerService activityManagerService) {
6944 mActivityManagerService = activityManagerService;
6948 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6949 mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6954 * For each PID in the given input array, write the current process state
6955 * for that process into the output array, or -1 to indicate that no
6956 * process with the given PID exists.
6958 public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6960 throw new NullPointerException("pids");
6961 } else if (states == null) {
6962 throw new NullPointerException("states");
6963 } else if (pids.length != states.length) {
6964 throw new IllegalArgumentException("input and output arrays have different lengths!");
6967 synchronized (mPidsSelfLocked) {
6968 for (int i = 0; i < pids.length; i++) {
6969 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6970 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6976 // =========================================================
6978 // =========================================================
6980 static class PermissionController extends IPermissionController.Stub {
6981 ActivityManagerService mActivityManagerService;
6982 PermissionController(ActivityManagerService activityManagerService) {
6983 mActivityManagerService = activityManagerService;
6987 public boolean checkPermission(String permission, int pid, int uid) {
6988 return mActivityManagerService.checkPermission(permission, pid,
6989 uid) == PackageManager.PERMISSION_GRANTED;
6993 public String[] getPackagesForUid(int uid) {
6994 return mActivityManagerService.mContext.getPackageManager()
6995 .getPackagesForUid(uid);
6999 public boolean isRuntimePermission(String permission) {
7001 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7002 .getPermissionInfo(permission, 0);
7003 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7004 } catch (NameNotFoundException nnfe) {
7005 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7011 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7013 public int checkComponentPermission(String permission, int pid, int uid,
7014 int owningUid, boolean exported) {
7015 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7016 owningUid, exported);
7020 public Object getAMSLock() {
7021 return ActivityManagerService.this;
7026 * This can be called with or without the global lock held.
7028 int checkComponentPermission(String permission, int pid, int uid,
7029 int owningUid, boolean exported) {
7030 if (pid == MY_PID) {
7031 return PackageManager.PERMISSION_GRANTED;
7033 return ActivityManager.checkComponentPermission(permission, uid,
7034 owningUid, exported);
7038 * As the only public entry point for permissions checking, this method
7039 * can enforce the semantic that requesting a check on a null global
7040 * permission is automatically denied. (Internally a null permission
7041 * string is used when calling {@link #checkComponentPermission} in cases
7042 * when only uid-based security is needed.)
7044 * This can be called with or without the global lock held.
7047 public int checkPermission(String permission, int pid, int uid) {
7048 if (permission == null) {
7049 return PackageManager.PERMISSION_DENIED;
7051 return checkComponentPermission(permission, pid, uid, -1, true);
7055 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7056 if (permission == null) {
7057 return PackageManager.PERMISSION_DENIED;
7060 // We might be performing an operation on behalf of an indirect binder
7061 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7062 // client identity accordingly before proceeding.
7063 Identity tlsIdentity = sCallerIdentity.get();
7064 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7065 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7066 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7067 uid = tlsIdentity.uid;
7068 pid = tlsIdentity.pid;
7071 return checkComponentPermission(permission, pid, uid, -1, true);
7075 * Binder IPC calls go through the public entry point.
7076 * This can be called with or without the global lock held.
7078 int checkCallingPermission(String permission) {
7079 return checkPermission(permission,
7080 Binder.getCallingPid(),
7081 UserHandle.getAppId(Binder.getCallingUid()));
7085 * This can be called with or without the global lock held.
7087 void enforceCallingPermission(String permission, String func) {
7088 if (checkCallingPermission(permission)
7089 == PackageManager.PERMISSION_GRANTED) {
7093 String msg = "Permission Denial: " + func + " from pid="
7094 + Binder.getCallingPid()
7095 + ", uid=" + Binder.getCallingUid()
7096 + " requires " + permission;
7098 throw new SecurityException(msg);
7102 * Determine if UID is holding permissions required to access {@link Uri} in
7103 * the given {@link ProviderInfo}. Final permission checking is always done
7104 * in {@link ContentProvider}.
7106 private final boolean checkHoldingPermissionsLocked(
7107 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7108 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7109 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7110 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7111 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7112 != PERMISSION_GRANTED) {
7116 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7119 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7120 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7121 if (pi.applicationInfo.uid == uid) {
7123 } else if (!pi.exported) {
7127 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7128 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7130 // check if target holds top-level <provider> permissions
7131 if (!readMet && pi.readPermission != null && considerUidPermissions
7132 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7135 if (!writeMet && pi.writePermission != null && considerUidPermissions
7136 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7140 // track if unprotected read/write is allowed; any denied
7141 // <path-permission> below removes this ability
7142 boolean allowDefaultRead = pi.readPermission == null;
7143 boolean allowDefaultWrite = pi.writePermission == null;
7145 // check if target holds any <path-permission> that match uri
7146 final PathPermission[] pps = pi.pathPermissions;
7148 final String path = grantUri.uri.getPath();
7150 while (i > 0 && (!readMet || !writeMet)) {
7152 PathPermission pp = pps[i];
7153 if (pp.match(path)) {
7155 final String pprperm = pp.getReadPermission();
7156 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7157 "Checking read perm for " + pprperm + " for " + pp.getPath()
7158 + ": match=" + pp.match(path)
7159 + " check=" + pm.checkUidPermission(pprperm, uid));
7160 if (pprperm != null) {
7161 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7162 == PERMISSION_GRANTED) {
7165 allowDefaultRead = false;
7170 final String ppwperm = pp.getWritePermission();
7171 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7172 "Checking write perm " + ppwperm + " for " + pp.getPath()
7173 + ": match=" + pp.match(path)
7174 + " check=" + pm.checkUidPermission(ppwperm, uid));
7175 if (ppwperm != null) {
7176 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7177 == PERMISSION_GRANTED) {
7180 allowDefaultWrite = false;
7188 // grant unprotected <provider> read/write, if not blocked by
7189 // <path-permission> above
7190 if (allowDefaultRead) readMet = true;
7191 if (allowDefaultWrite) writeMet = true;
7193 } catch (RemoteException e) {
7197 return readMet && writeMet;
7200 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7201 ProviderInfo pi = null;
7202 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7207 pi = AppGlobals.getPackageManager().resolveContentProvider(
7208 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7209 } catch (RemoteException ex) {
7215 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7216 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7217 if (targetUris != null) {
7218 return targetUris.get(grantUri);
7223 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7224 String targetPkg, int targetUid, GrantUri grantUri) {
7225 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7226 if (targetUris == null) {
7227 targetUris = Maps.newArrayMap();
7228 mGrantedUriPermissions.put(targetUid, targetUris);
7231 UriPermission perm = targetUris.get(grantUri);
7233 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7234 targetUris.put(grantUri, perm);
7240 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7241 final int modeFlags) {
7242 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7243 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7244 : UriPermission.STRENGTH_OWNED;
7246 // Root gets to do everything.
7251 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7252 if (perms == null) return false;
7254 // First look for exact match
7255 final UriPermission exactPerm = perms.get(grantUri);
7256 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7260 // No exact match, look for prefixes
7261 final int N = perms.size();
7262 for (int i = 0; i < N; i++) {
7263 final UriPermission perm = perms.valueAt(i);
7264 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7265 && perm.getStrength(modeFlags) >= minStrength) {
7274 * @param uri This uri must NOT contain an embedded userId.
7275 * @param userId The userId in which the uri is to be resolved.
7278 public int checkUriPermission(Uri uri, int pid, int uid,
7279 final int modeFlags, int userId, IBinder callerToken) {
7280 enforceNotIsolatedCaller("checkUriPermission");
7282 // Another redirected-binder-call permissions check as in
7283 // {@link checkPermissionWithToken}.
7284 Identity tlsIdentity = sCallerIdentity.get();
7285 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7286 uid = tlsIdentity.uid;
7287 pid = tlsIdentity.pid;
7290 // Our own process gets to do everything.
7291 if (pid == MY_PID) {
7292 return PackageManager.PERMISSION_GRANTED;
7294 synchronized (this) {
7295 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7296 ? PackageManager.PERMISSION_GRANTED
7297 : PackageManager.PERMISSION_DENIED;
7302 * Check if the targetPkg can be granted permission to access uri by
7303 * the callingUid using the given modeFlags. Throws a security exception
7304 * if callingUid is not allowed to do this. Returns the uid of the target
7305 * if the URI permission grant should be performed; returns -1 if it is not
7306 * needed (for example targetPkg already has permission to access the URI).
7307 * If you already know the uid of the target, you can supply it in
7308 * lastTargetUid else set that to -1.
7310 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7311 final int modeFlags, int lastTargetUid) {
7312 if (!Intent.isAccessUriMode(modeFlags)) {
7316 if (targetPkg != null) {
7317 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7318 "Checking grant " + targetPkg + " permission to " + grantUri);
7321 final IPackageManager pm = AppGlobals.getPackageManager();
7323 // If this is not a content: uri, we can't do anything with it.
7324 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7325 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7326 "Can't grant URI permission for non-content URI: " + grantUri);
7330 final String authority = grantUri.uri.getAuthority();
7331 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7333 Slog.w(TAG, "No content provider found for permission check: " +
7334 grantUri.uri.toSafeString());
7338 int targetUid = lastTargetUid;
7339 if (targetUid < 0 && targetPkg != null) {
7341 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7342 if (targetUid < 0) {
7343 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7344 "Can't grant URI permission no uid for: " + targetPkg);
7347 } catch (RemoteException ex) {
7352 if (targetUid >= 0) {
7353 // First... does the target actually need this permission?
7354 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7355 // No need to grant the target this permission.
7356 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7357 "Target " + targetPkg + " already has full permission to " + grantUri);
7361 // First... there is no target package, so can anyone access it?
7362 boolean allowed = pi.exported;
7363 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7364 if (pi.readPermission != null) {
7368 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7369 if (pi.writePermission != null) {
7378 /* There is a special cross user grant if:
7379 * - The target is on another user.
7380 * - Apps on the current user can access the uri without any uid permissions.
7381 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7382 * grant uri permissions.
7384 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7385 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7386 modeFlags, false /*without considering the uid permissions*/);
7388 // Second... is the provider allowing granting of URI permissions?
7389 if (!specialCrossUserGrant) {
7390 if (!pi.grantUriPermissions) {
7391 throw new SecurityException("Provider " + pi.packageName
7393 + " does not allow granting of Uri permissions (uri "
7396 if (pi.uriPermissionPatterns != null) {
7397 final int N = pi.uriPermissionPatterns.length;
7398 boolean allowed = false;
7399 for (int i=0; i<N; i++) {
7400 if (pi.uriPermissionPatterns[i] != null
7401 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7407 throw new SecurityException("Provider " + pi.packageName
7409 + " does not allow granting of permission to path of Uri "
7415 // Third... does the caller itself have permission to access
7417 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7418 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7419 // Require they hold a strong enough Uri permission
7420 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7421 throw new SecurityException("Uid " + callingUid
7422 + " does not have permission to uri " + grantUri);
7430 * @param uri This uri must NOT contain an embedded userId.
7431 * @param userId The userId in which the uri is to be resolved.
7434 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7435 final int modeFlags, int userId) {
7436 enforceNotIsolatedCaller("checkGrantUriPermission");
7437 synchronized(this) {
7438 return checkGrantUriPermissionLocked(callingUid, targetPkg,
7439 new GrantUri(userId, uri, false), modeFlags, -1);
7443 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7444 final int modeFlags, UriPermissionOwner owner) {
7445 if (!Intent.isAccessUriMode(modeFlags)) {
7449 // So here we are: the caller has the assumed permission
7450 // to the uri, and the target doesn't. Let's now give this to
7453 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7454 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7456 final String authority = grantUri.uri.getAuthority();
7457 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7459 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7463 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7464 grantUri.prefix = true;
7466 final UriPermission perm = findOrCreateUriPermissionLocked(
7467 pi.packageName, targetPkg, targetUid, grantUri);
7468 perm.grantModes(modeFlags, owner);
7471 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7472 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7473 if (targetPkg == null) {
7474 throw new NullPointerException("targetPkg");
7477 final IPackageManager pm = AppGlobals.getPackageManager();
7479 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7480 } catch (RemoteException ex) {
7484 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7486 if (targetUid < 0) {
7490 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7494 static class NeededUriGrants extends ArrayList<GrantUri> {
7495 final String targetPkg;
7496 final int targetUid;
7499 NeededUriGrants(String targetPkg, int targetUid, int flags) {
7500 this.targetPkg = targetPkg;
7501 this.targetUid = targetUid;
7507 * Like checkGrantUriPermissionLocked, but takes an Intent.
7509 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7510 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7511 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7512 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7513 + " clip=" + (intent != null ? intent.getClipData() : null)
7514 + " from " + intent + "; flags=0x"
7515 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7517 if (targetPkg == null) {
7518 throw new NullPointerException("targetPkg");
7521 if (intent == null) {
7524 Uri data = intent.getData();
7525 ClipData clip = intent.getClipData();
7526 if (data == null && clip == null) {
7529 // Default userId for uris in the intent (if they don't specify it themselves)
7530 int contentUserHint = intent.getContentUserHint();
7531 if (contentUserHint == UserHandle.USER_CURRENT) {
7532 contentUserHint = UserHandle.getUserId(callingUid);
7534 final IPackageManager pm = AppGlobals.getPackageManager();
7536 if (needed != null) {
7537 targetUid = needed.targetUid;
7540 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7541 } catch (RemoteException ex) {
7544 if (targetUid < 0) {
7545 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7546 "Can't grant URI permission no uid for: " + targetPkg
7547 + " on user " + targetUserId);
7552 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7553 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7555 if (targetUid > 0) {
7556 if (needed == null) {
7557 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7559 needed.add(grantUri);
7563 for (int i=0; i<clip.getItemCount(); i++) {
7564 Uri uri = clip.getItemAt(i).getUri();
7566 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7567 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7569 if (targetUid > 0) {
7570 if (needed == null) {
7571 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7573 needed.add(grantUri);
7576 Intent clipIntent = clip.getItemAt(i).getIntent();
7577 if (clipIntent != null) {
7578 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7579 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7580 if (newNeeded != null) {
7592 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7594 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7595 UriPermissionOwner owner) {
7596 if (needed != null) {
7597 for (int i=0; i<needed.size(); i++) {
7598 GrantUri grantUri = needed.get(i);
7599 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7600 grantUri, needed.flags, owner);
7605 void grantUriPermissionFromIntentLocked(int callingUid,
7606 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7607 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7608 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7609 if (needed == null) {
7613 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7617 * @param uri This uri must NOT contain an embedded userId.
7618 * @param userId The userId in which the uri is to be resolved.
7621 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7622 final int modeFlags, int userId) {
7623 enforceNotIsolatedCaller("grantUriPermission");
7624 GrantUri grantUri = new GrantUri(userId, uri, false);
7625 synchronized(this) {
7626 final ProcessRecord r = getRecordForAppLocked(caller);
7628 throw new SecurityException("Unable to find app for caller "
7630 + " when granting permission to uri " + grantUri);
7632 if (targetPkg == null) {
7633 throw new IllegalArgumentException("null target");
7635 if (grantUri == null) {
7636 throw new IllegalArgumentException("null uri");
7639 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7640 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7641 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7642 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7644 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7645 UserHandle.getUserId(r.uid));
7649 void removeUriPermissionIfNeededLocked(UriPermission perm) {
7650 if (perm.modeFlags == 0) {
7651 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7653 if (perms != null) {
7654 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7655 "Removing " + perm.targetUid + " permission to " + perm.uri);
7657 perms.remove(perm.uri);
7658 if (perms.isEmpty()) {
7659 mGrantedUriPermissions.remove(perm.targetUid);
7665 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7666 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7667 "Revoking all granted permissions to " + grantUri);
7669 final IPackageManager pm = AppGlobals.getPackageManager();
7670 final String authority = grantUri.uri.getAuthority();
7671 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7673 Slog.w(TAG, "No content provider found for permission revoke: "
7674 + grantUri.toSafeString());
7678 // Does the caller have this permission on the URI?
7679 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7680 // If they don't have direct access to the URI, then revoke any
7681 // ownerless URI permissions that have been granted to them.
7682 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7683 if (perms != null) {
7684 boolean persistChanged = false;
7685 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7686 final UriPermission perm = it.next();
7687 if (perm.uri.sourceUserId == grantUri.sourceUserId
7688 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7689 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7690 "Revoking non-owned " + perm.targetUid
7691 + " permission to " + perm.uri);
7692 persistChanged |= perm.revokeModes(
7693 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7694 if (perm.modeFlags == 0) {
7699 if (perms.isEmpty()) {
7700 mGrantedUriPermissions.remove(callingUid);
7702 if (persistChanged) {
7703 schedulePersistUriGrants();
7709 boolean persistChanged = false;
7711 // Go through all of the permissions and remove any that match.
7712 int N = mGrantedUriPermissions.size();
7713 for (int i = 0; i < N; i++) {
7714 final int targetUid = mGrantedUriPermissions.keyAt(i);
7715 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7717 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7718 final UriPermission perm = it.next();
7719 if (perm.uri.sourceUserId == grantUri.sourceUserId
7720 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7721 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7722 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7723 persistChanged |= perm.revokeModes(
7724 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7725 if (perm.modeFlags == 0) {
7731 if (perms.isEmpty()) {
7732 mGrantedUriPermissions.remove(targetUid);
7738 if (persistChanged) {
7739 schedulePersistUriGrants();
7744 * @param uri This uri must NOT contain an embedded userId.
7745 * @param userId The userId in which the uri is to be resolved.
7748 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7750 enforceNotIsolatedCaller("revokeUriPermission");
7751 synchronized(this) {
7752 final ProcessRecord r = getRecordForAppLocked(caller);
7754 throw new SecurityException("Unable to find app for caller "
7756 + " when revoking permission to uri " + uri);
7759 Slog.w(TAG, "revokeUriPermission: null uri");
7763 if (!Intent.isAccessUriMode(modeFlags)) {
7767 final String authority = uri.getAuthority();
7768 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7770 Slog.w(TAG, "No content provider found for permission revoke: "
7771 + uri.toSafeString());
7775 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7780 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7783 * @param packageName Package name to match, or {@code null} to apply to all
7785 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7787 * @param persistable If persistable grants should be removed.
7789 private void removeUriPermissionsForPackageLocked(
7790 String packageName, int userHandle, boolean persistable) {
7791 if (userHandle == UserHandle.USER_ALL && packageName == null) {
7792 throw new IllegalArgumentException("Must narrow by either package or user");
7795 boolean persistChanged = false;
7797 int N = mGrantedUriPermissions.size();
7798 for (int i = 0; i < N; i++) {
7799 final int targetUid = mGrantedUriPermissions.keyAt(i);
7800 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7802 // Only inspect grants matching user
7803 if (userHandle == UserHandle.USER_ALL
7804 || userHandle == UserHandle.getUserId(targetUid)) {
7805 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7806 final UriPermission perm = it.next();
7808 // Only inspect grants matching package
7809 if (packageName == null || perm.sourcePkg.equals(packageName)
7810 || perm.targetPkg.equals(packageName)) {
7811 persistChanged |= perm.revokeModes(persistable
7812 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7814 // Only remove when no modes remain; any persisted grants
7815 // will keep this alive.
7816 if (perm.modeFlags == 0) {
7822 if (perms.isEmpty()) {
7823 mGrantedUriPermissions.remove(targetUid);
7830 if (persistChanged) {
7831 schedulePersistUriGrants();
7836 public IBinder newUriPermissionOwner(String name) {
7837 enforceNotIsolatedCaller("newUriPermissionOwner");
7838 synchronized(this) {
7839 UriPermissionOwner owner = new UriPermissionOwner(this, name);
7840 return owner.getExternalTokenLocked();
7845 * @param uri This uri must NOT contain an embedded userId.
7846 * @param sourceUserId The userId in which the uri is to be resolved.
7847 * @param targetUserId The userId of the app that receives the grant.
7850 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7851 final int modeFlags, int sourceUserId, int targetUserId) {
7852 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7853 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7854 synchronized(this) {
7855 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7856 if (owner == null) {
7857 throw new IllegalArgumentException("Unknown owner: " + token);
7859 if (fromUid != Binder.getCallingUid()) {
7860 if (Binder.getCallingUid() != Process.myUid()) {
7861 // Only system code can grant URI permissions on behalf
7863 throw new SecurityException("nice try");
7866 if (targetPkg == null) {
7867 throw new IllegalArgumentException("null target");
7870 throw new IllegalArgumentException("null uri");
7873 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7874 modeFlags, owner, targetUserId);
7879 * @param uri This uri must NOT contain an embedded userId.
7880 * @param userId The userId in which the uri is to be resolved.
7883 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7884 synchronized(this) {
7885 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7886 if (owner == null) {
7887 throw new IllegalArgumentException("Unknown owner: " + token);
7891 owner.removeUriPermissionsLocked(mode);
7893 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7898 private void schedulePersistUriGrants() {
7899 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7900 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7901 10 * DateUtils.SECOND_IN_MILLIS);
7905 private void writeGrantedUriPermissions() {
7906 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7908 // Snapshot permissions so we can persist without lock
7909 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7910 synchronized (this) {
7911 final int size = mGrantedUriPermissions.size();
7912 for (int i = 0; i < size; i++) {
7913 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7914 for (UriPermission perm : perms.values()) {
7915 if (perm.persistedModeFlags != 0) {
7916 persist.add(perm.snapshot());
7922 FileOutputStream fos = null;
7924 fos = mGrantFile.startWrite();
7926 XmlSerializer out = new FastXmlSerializer();
7927 out.setOutput(fos, StandardCharsets.UTF_8.name());
7928 out.startDocument(null, true);
7929 out.startTag(null, TAG_URI_GRANTS);
7930 for (UriPermission.Snapshot perm : persist) {
7931 out.startTag(null, TAG_URI_GRANT);
7932 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7933 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7934 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7935 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7936 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7937 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7938 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7939 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7940 out.endTag(null, TAG_URI_GRANT);
7942 out.endTag(null, TAG_URI_GRANTS);
7945 mGrantFile.finishWrite(fos);
7946 } catch (IOException e) {
7948 mGrantFile.failWrite(fos);
7953 private void readGrantedUriPermissionsLocked() {
7954 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7956 final long now = System.currentTimeMillis();
7958 FileInputStream fis = null;
7960 fis = mGrantFile.openRead();
7961 final XmlPullParser in = Xml.newPullParser();
7962 in.setInput(fis, StandardCharsets.UTF_8.name());
7965 while ((type = in.next()) != END_DOCUMENT) {
7966 final String tag = in.getName();
7967 if (type == START_TAG) {
7968 if (TAG_URI_GRANT.equals(tag)) {
7969 final int sourceUserId;
7970 final int targetUserId;
7971 final int userHandle = readIntAttribute(in,
7972 ATTR_USER_HANDLE, UserHandle.USER_NULL);
7973 if (userHandle != UserHandle.USER_NULL) {
7974 // For backwards compatibility.
7975 sourceUserId = userHandle;
7976 targetUserId = userHandle;
7978 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7979 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7981 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7982 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7983 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7984 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7985 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7986 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7988 // Sanity check that provider still belongs to source package
7989 final ProviderInfo pi = getProviderInfoLocked(
7990 uri.getAuthority(), sourceUserId);
7991 if (pi != null && sourcePkg.equals(pi.packageName)) {
7994 targetUid = AppGlobals.getPackageManager()
7995 .getPackageUid(targetPkg, targetUserId);
7996 } catch (RemoteException e) {
7998 if (targetUid != -1) {
7999 final UriPermission perm = findOrCreateUriPermissionLocked(
8000 sourcePkg, targetPkg, targetUid,
8001 new GrantUri(sourceUserId, uri, prefix));
8002 perm.initPersistedModes(modeFlags, createdTime);
8005 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8006 + " but instead found " + pi);
8011 } catch (FileNotFoundException e) {
8012 // Missing grants is okay
8013 } catch (IOException e) {
8014 Slog.wtf(TAG, "Failed reading Uri grants", e);
8015 } catch (XmlPullParserException e) {
8016 Slog.wtf(TAG, "Failed reading Uri grants", e);
8018 IoUtils.closeQuietly(fis);
8023 * @param uri This uri must NOT contain an embedded userId.
8024 * @param userId The userId in which the uri is to be resolved.
8027 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8028 enforceNotIsolatedCaller("takePersistableUriPermission");
8030 Preconditions.checkFlagsArgument(modeFlags,
8031 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8033 synchronized (this) {
8034 final int callingUid = Binder.getCallingUid();
8035 boolean persistChanged = false;
8036 GrantUri grantUri = new GrantUri(userId, uri, false);
8038 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8039 new GrantUri(userId, uri, false));
8040 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8041 new GrantUri(userId, uri, true));
8043 final boolean exactValid = (exactPerm != null)
8044 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8045 final boolean prefixValid = (prefixPerm != null)
8046 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8048 if (!(exactValid || prefixValid)) {
8049 throw new SecurityException("No persistable permission grants found for UID "
8050 + callingUid + " and Uri " + grantUri.toSafeString());
8054 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8057 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8060 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8062 if (persistChanged) {
8063 schedulePersistUriGrants();
8069 * @param uri This uri must NOT contain an embedded userId.
8070 * @param userId The userId in which the uri is to be resolved.
8073 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8074 enforceNotIsolatedCaller("releasePersistableUriPermission");
8076 Preconditions.checkFlagsArgument(modeFlags,
8077 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8079 synchronized (this) {
8080 final int callingUid = Binder.getCallingUid();
8081 boolean persistChanged = false;
8083 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8084 new GrantUri(userId, uri, false));
8085 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8086 new GrantUri(userId, uri, true));
8087 if (exactPerm == null && prefixPerm == null) {
8088 throw new SecurityException("No permission grants found for UID " + callingUid
8089 + " and Uri " + uri.toSafeString());
8092 if (exactPerm != null) {
8093 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8094 removeUriPermissionIfNeededLocked(exactPerm);
8096 if (prefixPerm != null) {
8097 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8098 removeUriPermissionIfNeededLocked(prefixPerm);
8101 if (persistChanged) {
8102 schedulePersistUriGrants();
8108 * Prune any older {@link UriPermission} for the given UID until outstanding
8109 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8111 * @return if any mutations occured that require persisting.
8113 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8114 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8115 if (perms == null) return false;
8116 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8118 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8119 for (UriPermission perm : perms.values()) {
8120 if (perm.persistedModeFlags != 0) {
8121 persisted.add(perm);
8125 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8126 if (trimCount <= 0) return false;
8128 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8129 for (int i = 0; i < trimCount; i++) {
8130 final UriPermission perm = persisted.get(i);
8132 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8133 "Trimming grant created at " + perm.persistedCreateTime);
8135 perm.releasePersistableModes(~0);
8136 removeUriPermissionIfNeededLocked(perm);
8143 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8144 String packageName, boolean incoming) {
8145 enforceNotIsolatedCaller("getPersistedUriPermissions");
8146 Preconditions.checkNotNull(packageName, "packageName");
8148 final int callingUid = Binder.getCallingUid();
8149 final IPackageManager pm = AppGlobals.getPackageManager();
8151 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8152 if (packageUid != callingUid) {
8153 throw new SecurityException(
8154 "Package " + packageName + " does not belong to calling UID " + callingUid);
8156 } catch (RemoteException e) {
8157 throw new SecurityException("Failed to verify package name ownership");
8160 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8161 synchronized (this) {
8163 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8165 if (perms == null) {
8166 Slog.w(TAG, "No permission grants found for " + packageName);
8168 for (UriPermission perm : perms.values()) {
8169 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8170 result.add(perm.buildPersistedPublicApiObject());
8175 final int size = mGrantedUriPermissions.size();
8176 for (int i = 0; i < size; i++) {
8177 final ArrayMap<GrantUri, UriPermission> perms =
8178 mGrantedUriPermissions.valueAt(i);
8179 for (UriPermission perm : perms.values()) {
8180 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8181 result.add(perm.buildPersistedPublicApiObject());
8187 return new ParceledListSlice<android.content.UriPermission>(result);
8191 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8192 synchronized (this) {
8194 who != null ? getRecordForAppLocked(who) : null;
8195 if (app == null) return;
8197 Message msg = Message.obtain();
8198 msg.what = WAIT_FOR_DEBUGGER_MSG;
8200 msg.arg1 = waiting ? 1 : 0;
8201 mUiHandler.sendMessage(msg);
8206 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8207 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8208 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8209 outInfo.availMem = Process.getFreeMemory();
8210 outInfo.totalMem = Process.getTotalMemory();
8211 outInfo.threshold = homeAppMem;
8212 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8213 outInfo.hiddenAppThreshold = cachedAppMem;
8214 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8215 ProcessList.SERVICE_ADJ);
8216 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8217 ProcessList.VISIBLE_APP_ADJ);
8218 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8219 ProcessList.FOREGROUND_APP_ADJ);
8222 // =========================================================
8224 // =========================================================
8227 public List<IAppTask> getAppTasks(String callingPackage) {
8228 int callingUid = Binder.getCallingUid();
8229 long ident = Binder.clearCallingIdentity();
8231 synchronized(this) {
8232 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8234 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8236 final int N = mRecentTasks.size();
8237 for (int i = 0; i < N; i++) {
8238 TaskRecord tr = mRecentTasks.get(i);
8239 // Skip tasks that do not match the caller. We don't need to verify
8240 // callingPackage, because we are also limiting to callingUid and know
8241 // that will limit to the correct security sandbox.
8242 if (tr.effectiveUid != callingUid) {
8245 Intent intent = tr.getBaseIntent();
8246 if (intent == null ||
8247 !callingPackage.equals(intent.getComponent().getPackageName())) {
8250 ActivityManager.RecentTaskInfo taskInfo =
8251 createRecentTaskInfoFromTaskRecord(tr);
8252 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8256 Binder.restoreCallingIdentity(ident);
8263 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8264 final int callingUid = Binder.getCallingUid();
8265 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8267 synchronized(this) {
8268 if (DEBUG_ALL) Slog.v(
8269 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8271 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8274 // TODO: Improve with MRU list from all ActivityStacks.
8275 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8282 * Creates a new RecentTaskInfo from a TaskRecord.
8284 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8285 // Update the task description to reflect any changes in the task stack
8286 tr.updateTaskDescription();
8288 // Compose the recent task info
8289 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8290 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8291 rti.persistentId = tr.taskId;
8292 rti.baseIntent = new Intent(tr.getBaseIntent());
8293 rti.origActivity = tr.origActivity;
8294 rti.description = tr.lastDescription;
8295 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8296 rti.userId = tr.userId;
8297 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8298 rti.firstActiveTime = tr.firstActiveTime;
8299 rti.lastActiveTime = tr.lastActiveTime;
8300 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8301 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8302 rti.numActivities = 0;
8304 ActivityRecord base = null;
8305 ActivityRecord top = null;
8308 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8309 tmp = tr.mActivities.get(i);
8310 if (tmp.finishing) {
8314 if (top == null || (top.state == ActivityState.INITIALIZING)) {
8317 rti.numActivities++;
8320 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8321 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8326 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8327 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8328 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8330 if (checkPermission(android.Manifest.permission.GET_TASKS,
8331 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8332 // Temporary compatibility: some existing apps on the system image may
8333 // still be requesting the old permission and not switched to the new
8334 // one; if so, we'll still allow them full access. This means we need
8335 // to see if they are holding the old permission and are a system app.
8337 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8339 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8340 + " is using old GET_TASKS but privileged; allowing");
8342 } catch (RemoteException e) {
8347 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8348 + " does not hold REAL_GET_TASKS; limiting output");
8354 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8355 final int callingUid = Binder.getCallingUid();
8356 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8357 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8359 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8360 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8361 synchronized (this) {
8362 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8364 final boolean detailed = checkCallingPermission(
8365 android.Manifest.permission.GET_DETAILED_TASKS)
8366 == PackageManager.PERMISSION_GRANTED;
8368 final int recentsCount = mRecentTasks.size();
8369 ArrayList<ActivityManager.RecentTaskInfo> res =
8370 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8372 final Set<Integer> includedUsers;
8373 if (includeProfiles) {
8374 includedUsers = getProfileIdsLocked(userId);
8376 includedUsers = new HashSet<>();
8378 includedUsers.add(Integer.valueOf(userId));
8380 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8381 TaskRecord tr = mRecentTasks.get(i);
8382 // Only add calling user or related users recent tasks
8383 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8384 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8388 // Return the entry if desired by the caller. We always return
8389 // the first entry, because callers always expect this to be the
8390 // foreground app. We may filter others if the caller has
8391 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8392 // we should exclude the entry.
8396 || (tr.intent == null)
8397 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8400 // If the caller doesn't have the GET_TASKS permission, then only
8401 // allow them to see a small subset of tasks -- their own and home.
8402 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8403 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8407 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8408 if (tr.stack != null && tr.stack.isHomeStack()) {
8409 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8410 "Skipping, home stack task: " + tr);
8414 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8415 // Don't include auto remove tasks that are finished or finishing.
8416 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8417 "Skipping, auto-remove without activity: " + tr);
8420 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8421 && !tr.isAvailable) {
8422 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8423 "Skipping, unavail real act: " + tr);
8427 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8429 rti.baseIntent.replaceExtras((Bundle)null);
8441 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8442 synchronized (this) {
8443 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8444 "getTaskThumbnail()");
8445 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8447 return tr.getTaskThumbnailLocked();
8454 public int addAppTask(IBinder activityToken, Intent intent,
8455 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8456 final int callingUid = Binder.getCallingUid();
8457 final long callingIdent = Binder.clearCallingIdentity();
8460 synchronized (this) {
8461 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8463 throw new IllegalArgumentException("Activity does not exist; token="
8466 ComponentName comp = intent.getComponent();
8468 throw new IllegalArgumentException("Intent " + intent
8469 + " must specify explicit component");
8471 if (thumbnail.getWidth() != mThumbnailWidth
8472 || thumbnail.getHeight() != mThumbnailHeight) {
8473 throw new IllegalArgumentException("Bad thumbnail size: got "
8474 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8475 + mThumbnailWidth + "x" + mThumbnailHeight);
8477 if (intent.getSelector() != null) {
8478 intent.setSelector(null);
8480 if (intent.getSourceBounds() != null) {
8481 intent.setSourceBounds(null);
8483 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8484 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8485 // The caller has added this as an auto-remove task... that makes no
8486 // sense, so turn off auto-remove.
8487 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8489 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8490 // Must be a new task.
8491 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8493 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8494 mLastAddedTaskActivity = null;
8496 ActivityInfo ainfo = mLastAddedTaskActivity;
8497 if (ainfo == null) {
8498 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8499 comp, 0, UserHandle.getUserId(callingUid));
8500 if (ainfo.applicationInfo.uid != callingUid) {
8501 throw new SecurityException(
8502 "Can't add task for another application: target uid="
8503 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8507 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8508 intent, description);
8510 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8512 // If this would have caused a trim, then we'll abort because that
8513 // means it would be added at the end of the list but then just removed.
8514 return INVALID_TASK_ID;
8517 final int N = mRecentTasks.size();
8518 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8519 final TaskRecord tr = mRecentTasks.remove(N - 1);
8520 tr.removedFromRecents();
8523 task.inRecents = true;
8524 mRecentTasks.add(task);
8525 r.task.stack.addTask(task, false, false);
8527 task.setLastThumbnail(thumbnail);
8528 task.freeLastThumbnail();
8533 Binder.restoreCallingIdentity(callingIdent);
8538 public Point getAppTaskThumbnailSize() {
8539 synchronized (this) {
8540 return new Point(mThumbnailWidth, mThumbnailHeight);
8545 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8546 synchronized (this) {
8547 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8549 r.setTaskDescription(td);
8550 r.task.updateTaskDescription();
8556 public void setTaskResizeable(int taskId, boolean resizeable) {
8557 synchronized (this) {
8558 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8560 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8563 if (task.mResizeable != resizeable) {
8564 task.mResizeable = resizeable;
8565 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8566 mStackSupervisor.resumeTopActivitiesLocked();
8572 public void resizeTask(int taskId, Rect bounds) {
8573 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8575 long ident = Binder.clearCallingIdentity();
8577 synchronized (this) {
8578 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8580 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8583 mStackSupervisor.resizeTaskLocked(task, bounds);
8586 Binder.restoreCallingIdentity(ident);
8591 public Bitmap getTaskDescriptionIcon(String filename) {
8592 if (!FileUtils.isValidExtFilename(filename)
8593 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8594 throw new IllegalArgumentException("Bad filename: " + filename);
8596 return mTaskPersister.getTaskDescriptionIcon(filename);
8600 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8601 throws RemoteException {
8602 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8603 opts.getCustomInPlaceResId() == 0) {
8604 throw new IllegalArgumentException("Expected in-place ActivityOption " +
8605 "with valid animation");
8607 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8608 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8609 opts.getCustomInPlaceResId());
8610 mWindowManager.executeAppTransition();
8613 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8614 mRecentTasks.remove(tr);
8615 tr.removedFromRecents();
8616 ComponentName component = tr.getBaseIntent().getComponent();
8617 if (component == null) {
8618 Slog.w(TAG, "No component for base intent of task: " + tr);
8622 // Find any running services associated with this app and stop if needed.
8623 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8629 // Determine if the process(es) for this task should be killed.
8630 final String pkg = component.getPackageName();
8631 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8632 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8633 for (int i = 0; i < pmap.size(); i++) {
8635 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8636 for (int j = 0; j < uids.size(); j++) {
8637 ProcessRecord proc = uids.valueAt(j);
8638 if (proc.userId != tr.userId) {
8639 // Don't kill process for a different user.
8642 if (proc == mHomeProcess) {
8643 // Don't kill the home process along with tasks from the same package.
8646 if (!proc.pkgList.containsKey(pkg)) {
8647 // Don't kill process that is not associated with this task.
8651 for (int k = 0; k < proc.activities.size(); k++) {
8652 TaskRecord otherTask = proc.activities.get(k).task;
8653 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8654 // Don't kill process(es) that has an activity in a different task that is
8660 if (proc.foregroundServices) {
8661 // Don't kill process(es) with foreground service.
8665 // Add process to kill list.
8666 procsToKill.add(proc);
8670 // Kill the running processes.
8671 for (int i = 0; i < procsToKill.size(); i++) {
8672 ProcessRecord pr = procsToKill.get(i);
8673 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8674 && pr.curReceiver == null) {
8675 pr.kill("remove task", true);
8677 // We delay killing processes that are not in the background or running a receiver.
8678 pr.waitingToKill = "remove task";
8683 private void removeTasksByPackageNameLocked(String packageName, int userId) {
8684 // Remove all tasks with activities in the specified package from the list of recent tasks
8685 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8686 TaskRecord tr = mRecentTasks.get(i);
8687 if (tr.userId != userId) continue;
8689 ComponentName cn = tr.intent.getComponent();
8690 if (cn != null && cn.getPackageName().equals(packageName)) {
8691 // If the package name matches, remove the task.
8692 removeTaskByIdLocked(tr.taskId, true);
8697 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8700 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8701 TaskRecord tr = mRecentTasks.get(i);
8702 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8706 ComponentName cn = tr.intent.getComponent();
8707 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8708 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8709 if (sameComponent) {
8710 removeTaskByIdLocked(tr.taskId, false);
8716 * Removes the task with the specified task id.
8718 * @param taskId Identifier of the task to be removed.
8719 * @param killProcess Kill any process associated with the task if possible.
8720 * @return Returns true if the given task was found and removed.
8722 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8723 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8725 tr.removeTaskActivitiesLocked();
8726 cleanUpRemovedTaskLocked(tr, killProcess);
8727 if (tr.isPersistable) {
8728 notifyTaskPersisterLocked(null, true);
8732 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8737 public boolean removeTask(int taskId) {
8738 synchronized (this) {
8739 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8741 long ident = Binder.clearCallingIdentity();
8743 return removeTaskByIdLocked(taskId, true);
8745 Binder.restoreCallingIdentity(ident);
8751 * TODO: Add mController hook
8754 public void moveTaskToFront(int taskId, int flags, Bundle options) {
8755 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8757 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8758 synchronized(this) {
8759 moveTaskToFrontLocked(taskId, flags, options);
8763 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8764 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8765 Binder.getCallingUid(), -1, -1, "Task to front")) {
8766 ActivityOptions.abort(options);
8769 final long origId = Binder.clearCallingIdentity();
8771 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8773 Slog.d(TAG, "Could not find task for id: "+ taskId);
8776 if (mStackSupervisor.isLockTaskModeViolation(task)) {
8777 mStackSupervisor.showLockTaskToast();
8778 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8781 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8782 if (prev != null && prev.isRecentsActivity()) {
8783 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8785 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8787 Binder.restoreCallingIdentity(origId);
8789 ActivityOptions.abort(options);
8793 * Moves an activity, and all of the other activities within the same task, to the bottom
8794 * of the history stack. The activity's order within the task is unchanged.
8796 * @param token A reference to the activity we wish to move
8797 * @param nonRoot If false then this only works if the activity is the root
8798 * of a task; if true it will work for any activity in a task.
8799 * @return Returns true if the move completed, false if not.
8802 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8803 enforceNotIsolatedCaller("moveActivityTaskToBack");
8804 synchronized(this) {
8805 final long origId = Binder.clearCallingIdentity();
8807 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8808 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8810 if (mStackSupervisor.isLockedTask(task)) {
8811 mStackSupervisor.showLockTaskToast();
8814 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8817 Binder.restoreCallingIdentity(origId);
8824 public void moveTaskBackwards(int task) {
8825 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8826 "moveTaskBackwards()");
8828 synchronized(this) {
8829 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8830 Binder.getCallingUid(), -1, -1, "Task backwards")) {
8833 final long origId = Binder.clearCallingIdentity();
8834 moveTaskBackwardsLocked(task);
8835 Binder.restoreCallingIdentity(origId);
8839 private final void moveTaskBackwardsLocked(int task) {
8840 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8844 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8845 IActivityContainerCallback callback) throws RemoteException {
8846 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8847 "createActivityContainer()");
8848 synchronized (this) {
8849 if (parentActivityToken == null) {
8850 throw new IllegalArgumentException("parent token must not be null");
8852 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8856 if (callback == null) {
8857 throw new IllegalArgumentException("callback must not be null");
8859 return mStackSupervisor.createVirtualActivityContainer(r, callback);
8864 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8865 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8866 "deleteActivityContainer()");
8867 synchronized (this) {
8868 mStackSupervisor.deleteActivityContainer(container);
8873 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8874 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8875 "createStackOnDisplay()");
8876 synchronized (this) {
8877 final int stackId = mStackSupervisor.getNextStackId();
8878 final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8879 if (stack == null) {
8882 return stack.mActivityContainer;
8887 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8888 synchronized (this) {
8889 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8890 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8891 return stack.mActivityContainer.getDisplayId();
8893 return Display.DEFAULT_DISPLAY;
8898 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8899 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8900 "moveTaskToStack()");
8901 if (stackId == HOME_STACK_ID) {
8902 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8903 new RuntimeException("here").fillInStackTrace());
8905 synchronized (this) {
8906 long ident = Binder.clearCallingIdentity();
8908 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8909 + " to stackId=" + stackId + " toTop=" + toTop);
8910 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8912 Binder.restoreCallingIdentity(ident);
8918 public void resizeStack(int stackId, Rect bounds) {
8919 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8921 long ident = Binder.clearCallingIdentity();
8923 synchronized (this) {
8924 mStackSupervisor.resizeStackLocked(stackId, bounds);
8927 Binder.restoreCallingIdentity(ident);
8932 public List<StackInfo> getAllStackInfos() {
8933 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8934 "getAllStackInfos()");
8935 long ident = Binder.clearCallingIdentity();
8937 synchronized (this) {
8938 return mStackSupervisor.getAllStackInfosLocked();
8941 Binder.restoreCallingIdentity(ident);
8946 public StackInfo getStackInfo(int stackId) {
8947 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8949 long ident = Binder.clearCallingIdentity();
8951 synchronized (this) {
8952 return mStackSupervisor.getStackInfoLocked(stackId);
8955 Binder.restoreCallingIdentity(ident);
8960 public boolean isInHomeStack(int taskId) {
8961 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8963 long ident = Binder.clearCallingIdentity();
8965 synchronized (this) {
8966 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8967 return tr != null && tr.stack != null && tr.stack.isHomeStack();
8970 Binder.restoreCallingIdentity(ident);
8975 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8976 synchronized(this) {
8977 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8982 public void updateDeviceOwner(String packageName) {
8983 final int callingUid = Binder.getCallingUid();
8984 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8985 throw new SecurityException("updateDeviceOwner called from non-system process");
8987 synchronized (this) {
8988 mDeviceOwnerName = packageName;
8993 public void updateLockTaskPackages(int userId, String[] packages) {
8994 final int callingUid = Binder.getCallingUid();
8995 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
8996 throw new SecurityException("updateLockTaskPackage called from non-system process");
8998 synchronized (this) {
8999 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9000 Arrays.toString(packages));
9001 mLockTaskPackages.put(userId, packages);
9002 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9007 void startLockTaskModeLocked(TaskRecord task) {
9008 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9009 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9013 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9014 // is initiated by system after the pinning request was shown and locked mode is initiated
9015 // by an authorized app directly
9016 final int callingUid = Binder.getCallingUid();
9017 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9018 long ident = Binder.clearCallingIdentity();
9020 final ActivityStack stack = mStackSupervisor.getFocusedStack();
9021 if (!isSystemInitiated) {
9022 task.mLockTaskUid = callingUid;
9023 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9024 // startLockTask() called by app and task mode is lockTaskModeDefault.
9025 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9026 StatusBarManagerInternal statusBarManager =
9027 LocalServices.getService(StatusBarManagerInternal.class);
9028 if (statusBarManager != null) {
9029 statusBarManager.showScreenPinningRequest();
9034 if (stack == null || task != stack.topTask()) {
9035 throw new IllegalArgumentException("Invalid task, not in foreground");
9038 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9040 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9041 ActivityManager.LOCK_TASK_MODE_PINNED :
9042 ActivityManager.LOCK_TASK_MODE_LOCKED,
9043 "startLockTask", true);
9045 Binder.restoreCallingIdentity(ident);
9050 public void startLockTaskMode(int taskId) {
9051 synchronized (this) {
9052 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9054 startLockTaskModeLocked(task);
9060 public void startLockTaskMode(IBinder token) {
9061 synchronized (this) {
9062 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9066 final TaskRecord task = r.task;
9068 startLockTaskModeLocked(task);
9074 public void startLockTaskModeOnCurrent() throws RemoteException {
9075 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9076 "startLockTaskModeOnCurrent");
9077 long ident = Binder.clearCallingIdentity();
9079 synchronized (this) {
9080 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9082 startLockTaskModeLocked(r.task);
9086 Binder.restoreCallingIdentity(ident);
9091 public void stopLockTaskMode() {
9092 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9093 if (lockTask == null) {
9094 // Our work here is done.
9098 final int callingUid = Binder.getCallingUid();
9099 final int lockTaskUid = lockTask.mLockTaskUid;
9100 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9101 // It is possible lockTaskMode was started by the system process because
9102 // android:lockTaskMode is set to a locking value in the application manifest instead of
9103 // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9104 // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9105 if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9106 callingUid != lockTaskUid
9107 && (lockTaskUid != 0
9108 || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9109 throw new SecurityException("Invalid uid, expected " + lockTaskUid
9110 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9113 long ident = Binder.clearCallingIdentity();
9115 Log.d(TAG, "stopLockTaskMode");
9117 synchronized (this) {
9118 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9119 "stopLockTask", true);
9122 Binder.restoreCallingIdentity(ident);
9127 public void stopLockTaskModeOnCurrent() throws RemoteException {
9128 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9129 "stopLockTaskModeOnCurrent");
9130 long ident = Binder.clearCallingIdentity();
9134 Binder.restoreCallingIdentity(ident);
9139 public boolean isInLockTaskMode() {
9140 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9144 public int getLockTaskModeState() {
9145 synchronized (this) {
9146 return mStackSupervisor.getLockTaskModeState();
9151 public void showLockTaskEscapeMessage(IBinder token) {
9152 synchronized (this) {
9153 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9157 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9161 // =========================================================
9162 // CONTENT PROVIDERS
9163 // =========================================================
9165 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9166 List<ProviderInfo> providers = null;
9168 ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9169 queryContentProviders(app.processName, app.uid,
9170 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9171 providers = slice != null ? slice.getList() : null;
9172 } catch (RemoteException ex) {
9174 if (DEBUG_MU) Slog.v(TAG_MU,
9175 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9176 int userId = app.userId;
9177 if (providers != null) {
9178 int N = providers.size();
9179 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9180 for (int i=0; i<N; i++) {
9182 (ProviderInfo)providers.get(i);
9183 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9184 cpi.name, cpi.flags);
9185 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9186 // This is a singleton provider, but a user besides the
9187 // default user is asking to initialize a process it runs
9188 // in... well, no, it doesn't actually run in this process,
9189 // it runs in the process of the default user. Get rid of it.
9190 providers.remove(i);
9196 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9197 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9199 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9200 mProviderMap.putProviderByClass(comp, cpr);
9202 if (DEBUG_MU) Slog.v(TAG_MU,
9203 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9204 app.pubProviders.put(cpi.name, cpr);
9205 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9206 // Don't add this if it is a platform component that is marked
9207 // to run in multiple processes, because this is actually
9208 // part of the framework so doesn't make sense to track as a
9209 // separate apk in the process.
9210 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9213 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9220 * Check if {@link ProcessRecord} has a possible chance at accessing the
9221 * given {@link ProviderInfo}. Final permission checking is always done
9222 * in {@link ContentProvider}.
9224 private final String checkContentProviderPermissionLocked(
9225 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9226 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9227 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9228 boolean checkedGrants = false;
9230 // Looking for cross-user grants before enforcing the typical cross-users permissions
9231 int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9232 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9233 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9236 checkedGrants = true;
9238 userId = handleIncomingUser(callingPid, callingUid, userId,
9239 false, ALLOW_NON_FULL,
9240 "checkContentProviderPermissionLocked " + cpi.authority, null);
9241 if (userId != tmpTargetUserId) {
9242 // When we actually went to determine the final targer user ID, this ended
9243 // up different than our initial check for the authority. This is because
9244 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9245 // SELF. So we need to re-check the grants again.
9246 checkedGrants = false;
9249 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9250 cpi.applicationInfo.uid, cpi.exported)
9251 == PackageManager.PERMISSION_GRANTED) {
9254 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9255 cpi.applicationInfo.uid, cpi.exported)
9256 == PackageManager.PERMISSION_GRANTED) {
9260 PathPermission[] pps = cpi.pathPermissions;
9265 PathPermission pp = pps[i];
9266 String pprperm = pp.getReadPermission();
9267 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9268 cpi.applicationInfo.uid, cpi.exported)
9269 == PackageManager.PERMISSION_GRANTED) {
9272 String ppwperm = pp.getWritePermission();
9273 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9274 cpi.applicationInfo.uid, cpi.exported)
9275 == PackageManager.PERMISSION_GRANTED) {
9280 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9285 if (!cpi.exported) {
9286 msg = "Permission Denial: opening provider " + cpi.name
9287 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9288 + ", uid=" + callingUid + ") that is not exported from uid "
9289 + cpi.applicationInfo.uid;
9291 msg = "Permission Denial: opening provider " + cpi.name
9292 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9293 + ", uid=" + callingUid + ") requires "
9294 + cpi.readPermission + " or " + cpi.writePermission;
9301 * Returns if the ContentProvider has granted a uri to callingUid
9303 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9304 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9305 if (perms != null) {
9306 for (int i=perms.size()-1; i>=0; i--) {
9307 GrantUri grantUri = perms.keyAt(i);
9308 if (grantUri.sourceUserId == userId || !checkUser) {
9309 if (matchesProvider(grantUri.uri, cpi)) {
9319 * Returns true if the uri authority is one of the authorities specified in the provider.
9321 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9322 String uriAuth = uri.getAuthority();
9323 String cpiAuth = cpi.authority;
9324 if (cpiAuth.indexOf(';') == -1) {
9325 return cpiAuth.equals(uriAuth);
9327 String[] cpiAuths = cpiAuth.split(";");
9328 int length = cpiAuths.length;
9329 for (int i = 0; i < length; i++) {
9330 if (cpiAuths[i].equals(uriAuth)) return true;
9335 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9336 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9338 for (int i=0; i<r.conProviders.size(); i++) {
9339 ContentProviderConnection conn = r.conProviders.get(i);
9340 if (conn.provider == cpr) {
9341 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9342 "Adding provider requested by "
9343 + r.processName + " from process "
9344 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9345 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9348 conn.numStableIncs++;
9350 conn.unstableCount++;
9351 conn.numUnstableIncs++;
9356 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9358 conn.stableCount = 1;
9359 conn.numStableIncs = 1;
9361 conn.unstableCount = 1;
9362 conn.numUnstableIncs = 1;
9364 cpr.connections.add(conn);
9365 r.conProviders.add(conn);
9366 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9369 cpr.addExternalProcessHandleLocked(externalProcessToken);
9373 boolean decProviderCountLocked(ContentProviderConnection conn,
9374 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9376 cpr = conn.provider;
9377 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9378 "Removing provider requested by "
9379 + conn.client.processName + " from process "
9380 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9381 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9385 conn.unstableCount--;
9387 if (conn.stableCount == 0 && conn.unstableCount == 0) {
9388 cpr.connections.remove(conn);
9389 conn.client.conProviders.remove(conn);
9390 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9395 cpr.removeExternalProcessHandleLocked(externalProcessToken);
9399 private void checkTime(long startTime, String where) {
9400 long now = SystemClock.elapsedRealtime();
9401 if ((now-startTime) > 1000) {
9402 // If we are taking more than a second, log about it.
9403 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9407 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9408 String name, IBinder token, boolean stable, int userId) {
9409 ContentProviderRecord cpr;
9410 ContentProviderConnection conn = null;
9411 ProviderInfo cpi = null;
9413 synchronized(this) {
9414 long startTime = SystemClock.elapsedRealtime();
9416 ProcessRecord r = null;
9417 if (caller != null) {
9418 r = getRecordForAppLocked(caller);
9420 throw new SecurityException(
9421 "Unable to find app for caller " + caller
9422 + " (pid=" + Binder.getCallingPid()
9423 + ") when getting content provider " + name);
9427 boolean checkCrossUser = true;
9429 checkTime(startTime, "getContentProviderImpl: getProviderByName");
9431 // First check if this content provider has been published...
9432 cpr = mProviderMap.getProviderByName(name, userId);
9433 // If that didn't work, check if it exists for user 0 and then
9434 // verify that it's a singleton provider before using it.
9435 if (cpr == null && userId != UserHandle.USER_OWNER) {
9436 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9439 if (isSingleton(cpi.processName, cpi.applicationInfo,
9440 cpi.name, cpi.flags)
9441 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9442 userId = UserHandle.USER_OWNER;
9443 checkCrossUser = false;
9451 boolean providerRunning = cpr != null;
9452 if (providerRunning) {
9455 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9456 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9458 throw new SecurityException(msg);
9460 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9462 if (r != null && cpr.canRunHere(r)) {
9463 // This provider has been published or is in the process
9464 // of being published... but it is also allowed to run
9465 // in the caller's process, so don't make a connection
9466 // and just let the caller instantiate its own instance.
9467 ContentProviderHolder holder = cpr.newHolder(null);
9468 // don't give caller the provider object, it needs
9470 holder.provider = null;
9474 final long origId = Binder.clearCallingIdentity();
9476 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9478 // In this case the provider instance already exists, so we can
9479 // return it right away.
9480 conn = incProviderCountLocked(r, cpr, token, stable);
9481 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9482 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9483 // If this is a perceptible app accessing the provider,
9484 // make sure to count it as being accessed and thus
9485 // back up on the LRU list. This is good because
9486 // content providers are often expensive to start.
9487 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9488 updateLruProcessLocked(cpr.proc, false, null);
9489 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9493 if (cpr.proc != null) {
9495 if (cpr.name.flattenToShortString().equals(
9496 "com.android.providers.calendar/.CalendarProvider2")) {
9497 Slog.v(TAG, "****************** KILLING "
9498 + cpr.name.flattenToShortString());
9499 Process.killProcess(cpr.proc.pid);
9502 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9503 boolean success = updateOomAdjLocked(cpr.proc);
9504 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9505 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9506 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9507 // NOTE: there is still a race here where a signal could be
9508 // pending on the process even though we managed to update its
9509 // adj level. Not sure what to do about this, but at least
9510 // the race is now smaller.
9512 // Uh oh... it looks like the provider's process
9513 // has been killed on us. We need to wait for a new
9514 // process to be started, and make sure its death
9515 // doesn't kill our process.
9516 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9517 + " is crashing; detaching " + r);
9518 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9519 checkTime(startTime, "getContentProviderImpl: before appDied");
9520 appDiedLocked(cpr.proc);
9521 checkTime(startTime, "getContentProviderImpl: after appDied");
9523 // This wasn't the last ref our process had on
9524 // the provider... we have now been killed, bail.
9527 providerRunning = false;
9532 Binder.restoreCallingIdentity(origId);
9536 if (!providerRunning) {
9538 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9539 cpi = AppGlobals.getPackageManager().
9540 resolveContentProvider(name,
9541 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9542 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9543 } catch (RemoteException ex) {
9548 // If the provider is a singleton AND
9549 // (it's a call within the same user || the provider is a
9551 // Then allow connecting to the singleton provider
9552 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9553 cpi.name, cpi.flags)
9554 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9556 userId = UserHandle.USER_OWNER;
9558 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9559 checkTime(startTime, "getContentProviderImpl: got app info for user");
9562 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9563 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9565 throw new SecurityException(msg);
9567 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9569 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9570 && !cpi.processName.equals("system")) {
9571 // If this content provider does not run in the system
9572 // process, and the system is not yet ready to run other
9573 // processes, then fail fast instead of hanging.
9574 throw new IllegalArgumentException(
9575 "Attempt to launch content provider before system ready");
9578 // Make sure that the user who owns this provider is running. If not,
9579 // we don't want to allow it to run.
9580 if (!isUserRunningLocked(userId, false)) {
9581 Slog.w(TAG, "Unable to launch app "
9582 + cpi.applicationInfo.packageName + "/"
9583 + cpi.applicationInfo.uid + " for provider "
9584 + name + ": user " + userId + " is stopped");
9588 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9589 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9590 cpr = mProviderMap.getProviderByClass(comp, userId);
9591 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9592 final boolean firstClass = cpr == null;
9594 final long ident = Binder.clearCallingIdentity();
9596 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9597 ApplicationInfo ai =
9598 AppGlobals.getPackageManager().
9600 cpi.applicationInfo.packageName,
9601 STOCK_PM_FLAGS, userId);
9602 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9604 Slog.w(TAG, "No package info for content provider "
9608 ai = getAppInfoForUser(ai, userId);
9609 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9610 } catch (RemoteException ex) {
9611 // pm is in same process, this will never happen.
9613 Binder.restoreCallingIdentity(ident);
9617 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9619 if (r != null && cpr.canRunHere(r)) {
9620 // If this is a multiprocess provider, then just return its
9621 // info and allow the caller to instantiate it. Only do
9622 // this if the provider is the same user as the caller's
9623 // process, or can run as root (so can be in any process).
9624 return cpr.newHolder(null);
9627 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9628 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9629 + cpr.info.name + " callers=" + Debug.getCallers(6));
9631 // This is single process, and our app is now connecting to it.
9632 // See if we are already in the process of launching this
9634 final int N = mLaunchingProviders.size();
9636 for (i = 0; i < N; i++) {
9637 if (mLaunchingProviders.get(i) == cpr) {
9642 // If the provider is not already being launched, then get it
9645 final long origId = Binder.clearCallingIdentity();
9648 // Content provider is now in use, its package can't be stopped.
9650 checkTime(startTime, "getContentProviderImpl: before set stopped state");
9651 AppGlobals.getPackageManager().setPackageStoppedState(
9652 cpr.appInfo.packageName, false, userId);
9653 checkTime(startTime, "getContentProviderImpl: after set stopped state");
9654 } catch (RemoteException e) {
9655 } catch (IllegalArgumentException e) {
9656 Slog.w(TAG, "Failed trying to unstop package "
9657 + cpr.appInfo.packageName + ": " + e);
9660 // Use existing process if already started
9661 checkTime(startTime, "getContentProviderImpl: looking for process record");
9662 ProcessRecord proc = getProcessRecordLocked(
9663 cpi.processName, cpr.appInfo.uid, false);
9664 if (proc != null && proc.thread != null) {
9665 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9666 "Installing in existing process " + proc);
9667 if (!proc.pubProviders.containsKey(cpi.name)) {
9668 checkTime(startTime, "getContentProviderImpl: scheduling install");
9669 proc.pubProviders.put(cpi.name, cpr);
9671 proc.thread.scheduleInstallProvider(cpi);
9672 } catch (RemoteException e) {
9676 checkTime(startTime, "getContentProviderImpl: before start process");
9677 proc = startProcessLocked(cpi.processName,
9678 cpr.appInfo, false, 0, "content provider",
9679 new ComponentName(cpi.applicationInfo.packageName,
9680 cpi.name), false, false, false);
9681 checkTime(startTime, "getContentProviderImpl: after start process");
9683 Slog.w(TAG, "Unable to launch app "
9684 + cpi.applicationInfo.packageName + "/"
9685 + cpi.applicationInfo.uid + " for provider "
9686 + name + ": process is bad");
9690 cpr.launchingApp = proc;
9691 mLaunchingProviders.add(cpr);
9693 Binder.restoreCallingIdentity(origId);
9697 checkTime(startTime, "getContentProviderImpl: updating data structures");
9699 // Make sure the provider is published (the same provider class
9700 // may be published under multiple names).
9702 mProviderMap.putProviderByClass(comp, cpr);
9705 mProviderMap.putProviderByName(name, cpr);
9706 conn = incProviderCountLocked(r, cpr, token, stable);
9708 conn.waiting = true;
9711 checkTime(startTime, "getContentProviderImpl: done!");
9714 // Wait for the provider to be published...
9715 synchronized (cpr) {
9716 while (cpr.provider == null) {
9717 if (cpr.launchingApp == null) {
9718 Slog.w(TAG, "Unable to launch app "
9719 + cpi.applicationInfo.packageName + "/"
9720 + cpi.applicationInfo.uid + " for provider "
9721 + name + ": launching app became null");
9722 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9723 UserHandle.getUserId(cpi.applicationInfo.uid),
9724 cpi.applicationInfo.packageName,
9725 cpi.applicationInfo.uid, name);
9729 if (DEBUG_MU) Slog.v(TAG_MU,
9730 "Waiting to start provider " + cpr
9731 + " launchingApp=" + cpr.launchingApp);
9733 conn.waiting = true;
9736 } catch (InterruptedException ex) {
9739 conn.waiting = false;
9744 return cpr != null ? cpr.newHolder(conn) : null;
9748 public final ContentProviderHolder getContentProvider(
9749 IApplicationThread caller, String name, int userId, boolean stable) {
9750 enforceNotIsolatedCaller("getContentProvider");
9751 if (caller == null) {
9752 String msg = "null IApplicationThread when getting content provider "
9755 throw new SecurityException(msg);
9757 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9758 // with cross-user grant.
9759 return getContentProviderImpl(caller, name, null, stable, userId);
9762 public ContentProviderHolder getContentProviderExternal(
9763 String name, int userId, IBinder token) {
9764 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9765 "Do not have permission in call getContentProviderExternal()");
9766 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9767 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9768 return getContentProviderExternalUnchecked(name, token, userId);
9771 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9772 IBinder token, int userId) {
9773 return getContentProviderImpl(null, name, token, true, userId);
9777 * Drop a content provider from a ProcessRecord's bookkeeping
9779 public void removeContentProvider(IBinder connection, boolean stable) {
9780 enforceNotIsolatedCaller("removeContentProvider");
9781 long ident = Binder.clearCallingIdentity();
9783 synchronized (this) {
9784 ContentProviderConnection conn;
9786 conn = (ContentProviderConnection)connection;
9787 } catch (ClassCastException e) {
9788 String msg ="removeContentProvider: " + connection
9789 + " not a ContentProviderConnection";
9791 throw new IllegalArgumentException(msg);
9794 throw new NullPointerException("connection is null");
9796 if (decProviderCountLocked(conn, null, null, stable)) {
9797 updateOomAdjLocked();
9801 Binder.restoreCallingIdentity(ident);
9805 public void removeContentProviderExternal(String name, IBinder token) {
9806 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9807 "Do not have permission in call removeContentProviderExternal()");
9808 int userId = UserHandle.getCallingUserId();
9809 long ident = Binder.clearCallingIdentity();
9811 removeContentProviderExternalUnchecked(name, token, userId);
9813 Binder.restoreCallingIdentity(ident);
9817 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9818 synchronized (this) {
9819 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9821 //remove from mProvidersByClass
9822 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9826 //update content provider record entry info
9827 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9828 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9829 if (localCpr.hasExternalProcessHandles()) {
9830 if (localCpr.removeExternalProcessHandleLocked(token)) {
9831 updateOomAdjLocked();
9833 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9834 + " with no external reference for token: "
9838 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9839 + " with no external references.");
9844 public final void publishContentProviders(IApplicationThread caller,
9845 List<ContentProviderHolder> providers) {
9846 if (providers == null) {
9850 enforceNotIsolatedCaller("publishContentProviders");
9851 synchronized (this) {
9852 final ProcessRecord r = getRecordForAppLocked(caller);
9853 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9855 throw new SecurityException(
9856 "Unable to find app for caller " + caller
9857 + " (pid=" + Binder.getCallingPid()
9858 + ") when publishing content providers");
9861 final long origId = Binder.clearCallingIdentity();
9863 final int N = providers.size();
9864 for (int i=0; i<N; i++) {
9865 ContentProviderHolder src = providers.get(i);
9866 if (src == null || src.info == null || src.provider == null) {
9869 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9870 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9872 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9873 mProviderMap.putProviderByClass(comp, dst);
9874 String names[] = dst.info.authority.split(";");
9875 for (int j = 0; j < names.length; j++) {
9876 mProviderMap.putProviderByName(names[j], dst);
9879 int NL = mLaunchingProviders.size();
9881 for (j=0; j<NL; j++) {
9882 if (mLaunchingProviders.get(j) == dst) {
9883 mLaunchingProviders.remove(j);
9888 synchronized (dst) {
9889 dst.provider = src.provider;
9893 updateOomAdjLocked(r);
9894 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9895 src.info.authority);
9899 Binder.restoreCallingIdentity(origId);
9903 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9904 ContentProviderConnection conn;
9906 conn = (ContentProviderConnection)connection;
9907 } catch (ClassCastException e) {
9908 String msg ="refContentProvider: " + connection
9909 + " not a ContentProviderConnection";
9911 throw new IllegalArgumentException(msg);
9914 throw new NullPointerException("connection is null");
9917 synchronized (this) {
9919 conn.numStableIncs += stable;
9921 stable = conn.stableCount + stable;
9923 throw new IllegalStateException("stableCount < 0: " + stable);
9927 conn.numUnstableIncs += unstable;
9929 unstable = conn.unstableCount + unstable;
9931 throw new IllegalStateException("unstableCount < 0: " + unstable);
9934 if ((stable+unstable) <= 0) {
9935 throw new IllegalStateException("ref counts can't go to zero here: stable="
9936 + stable + " unstable=" + unstable);
9938 conn.stableCount = stable;
9939 conn.unstableCount = unstable;
9944 public void unstableProviderDied(IBinder connection) {
9945 ContentProviderConnection conn;
9947 conn = (ContentProviderConnection)connection;
9948 } catch (ClassCastException e) {
9949 String msg ="refContentProvider: " + connection
9950 + " not a ContentProviderConnection";
9952 throw new IllegalArgumentException(msg);
9955 throw new NullPointerException("connection is null");
9958 // Safely retrieve the content provider associated with the connection.
9959 IContentProvider provider;
9960 synchronized (this) {
9961 provider = conn.provider.provider;
9964 if (provider == null) {
9965 // Um, yeah, we're way ahead of you.
9969 // Make sure the caller is being honest with us.
9970 if (provider.asBinder().pingBinder()) {
9971 // Er, no, still looks good to us.
9972 synchronized (this) {
9973 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9974 + " says " + conn + " died, but we don't agree");
9979 // Well look at that! It's dead!
9980 synchronized (this) {
9981 if (conn.provider.provider != provider) {
9982 // But something changed... good enough.
9986 ProcessRecord proc = conn.provider.proc;
9987 if (proc == null || proc.thread == null) {
9988 // Seems like the process is already cleaned up.
9992 // As far as we're concerned, this is just like receiving a
9993 // death notification... just a bit prematurely.
9994 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9995 + ") early provider death");
9996 final long ident = Binder.clearCallingIdentity();
9998 appDiedLocked(proc);
10000 Binder.restoreCallingIdentity(ident);
10006 public void appNotRespondingViaProvider(IBinder connection) {
10007 enforceCallingPermission(
10008 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10010 final ContentProviderConnection conn = (ContentProviderConnection) connection;
10011 if (conn == null) {
10012 Slog.w(TAG, "ContentProviderConnection is null");
10016 final ProcessRecord host = conn.provider.proc;
10017 if (host == null) {
10018 Slog.w(TAG, "Failed to find hosting ProcessRecord");
10022 final long token = Binder.clearCallingIdentity();
10024 appNotResponding(host, null, null, false, "ContentProvider not responding");
10026 Binder.restoreCallingIdentity(token);
10030 public final void installSystemProviders() {
10031 List<ProviderInfo> providers;
10032 synchronized (this) {
10033 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10034 providers = generateApplicationProvidersLocked(app);
10035 if (providers != null) {
10036 for (int i=providers.size()-1; i>=0; i--) {
10037 ProviderInfo pi = (ProviderInfo)providers.get(i);
10038 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10039 Slog.w(TAG, "Not installing system proc provider " + pi.name
10040 + ": not system .apk");
10041 providers.remove(i);
10046 if (providers != null) {
10047 mSystemThread.installSystemProviders(providers);
10050 mCoreSettingsObserver = new CoreSettingsObserver(this);
10052 //mUsageStatsService.monitorPackages();
10056 * Allows apps to retrieve the MIME type of a URI.
10057 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10058 * users, then it does not need permission to access the ContentProvider.
10059 * Either, it needs cross-user uri grants.
10061 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10063 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10064 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10066 public String getProviderMimeType(Uri uri, int userId) {
10067 enforceNotIsolatedCaller("getProviderMimeType");
10068 final String name = uri.getAuthority();
10069 int callingUid = Binder.getCallingUid();
10070 int callingPid = Binder.getCallingPid();
10072 boolean clearedIdentity = false;
10073 userId = unsafeConvertIncomingUser(userId);
10074 if (canClearIdentity(callingPid, callingUid, userId)) {
10075 clearedIdentity = true;
10076 ident = Binder.clearCallingIdentity();
10078 ContentProviderHolder holder = null;
10080 holder = getContentProviderExternalUnchecked(name, null, userId);
10081 if (holder != null) {
10082 return holder.provider.getType(uri);
10084 } catch (RemoteException e) {
10085 Log.w(TAG, "Content provider dead retrieving " + uri, e);
10088 // We need to clear the identity to call removeContentProviderExternalUnchecked
10089 if (!clearedIdentity) {
10090 ident = Binder.clearCallingIdentity();
10093 if (holder != null) {
10094 removeContentProviderExternalUnchecked(name, null, userId);
10097 Binder.restoreCallingIdentity(ident);
10104 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10105 if (UserHandle.getUserId(callingUid) == userId) {
10108 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10109 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10110 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10111 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10117 // =========================================================
10118 // GLOBAL MANAGEMENT
10119 // =========================================================
10121 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10122 boolean isolated, int isolatedUid) {
10123 String proc = customProcess != null ? customProcess : info.processName;
10124 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10125 final int userId = UserHandle.getUserId(info.uid);
10126 int uid = info.uid;
10128 if (isolatedUid == 0) {
10129 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10131 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10132 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10133 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10135 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10136 mNextIsolatedProcessUid++;
10137 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10138 // No process for this uid, use it.
10142 if (stepsLeft <= 0) {
10147 // Special case for startIsolatedProcess (internal only), where
10148 // the uid of the isolated process is specified by the caller.
10152 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10153 if (!mBooted && !mBooting
10154 && userId == UserHandle.USER_OWNER
10155 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10156 r.persistent = true;
10158 addProcessNameLocked(r);
10162 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10163 String abiOverride) {
10166 app = getProcessRecordLocked(info.processName, info.uid, true);
10172 app = newProcessRecordLocked(info, null, isolated, 0);
10173 updateLruProcessLocked(app, false, null);
10174 updateOomAdjLocked();
10177 // This package really, really can not be stopped.
10179 AppGlobals.getPackageManager().setPackageStoppedState(
10180 info.packageName, false, UserHandle.getUserId(app.uid));
10181 } catch (RemoteException e) {
10182 } catch (IllegalArgumentException e) {
10183 Slog.w(TAG, "Failed trying to unstop package "
10184 + info.packageName + ": " + e);
10187 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10188 app.persistent = true;
10189 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10191 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10192 mPersistentStartingProcesses.add(app);
10193 startProcessLocked(app, "added application", app.processName, abiOverride,
10194 null /* entryPoint */, null /* entryPointArgs */);
10200 public void unhandledBack() {
10201 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10202 "unhandledBack()");
10204 synchronized(this) {
10205 final long origId = Binder.clearCallingIdentity();
10207 getFocusedStack().unhandledBackLocked();
10209 Binder.restoreCallingIdentity(origId);
10214 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10215 enforceNotIsolatedCaller("openContentUri");
10216 final int userId = UserHandle.getCallingUserId();
10217 String name = uri.getAuthority();
10218 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10219 ParcelFileDescriptor pfd = null;
10221 // We record the binder invoker's uid in thread-local storage before
10222 // going to the content provider to open the file. Later, in the code
10223 // that handles all permissions checks, we look for this uid and use
10224 // that rather than the Activity Manager's own uid. The effect is that
10225 // we do the check against the caller's permissions even though it looks
10226 // to the content provider like the Activity Manager itself is making
10228 Binder token = new Binder();
10229 sCallerIdentity.set(new Identity(
10230 token, Binder.getCallingPid(), Binder.getCallingUid()));
10232 pfd = cph.provider.openFile(null, uri, "r", null, token);
10233 } catch (FileNotFoundException e) {
10234 // do nothing; pfd will be returned null
10236 // Ensure that whatever happens, we clean up the identity state
10237 sCallerIdentity.remove();
10238 // Ensure we're done with the provider.
10239 removeContentProviderExternalUnchecked(name, null, userId);
10242 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10247 // Actually is sleeping or shutting down or whatever else in the future
10248 // is an inactive state.
10249 public boolean isSleepingOrShuttingDown() {
10250 return isSleeping() || mShuttingDown;
10253 public boolean isSleeping() {
10257 void onWakefulnessChanged(int wakefulness) {
10258 synchronized(this) {
10259 mWakefulness = wakefulness;
10260 updateSleepIfNeededLocked();
10264 void finishRunningVoiceLocked() {
10265 if (mRunningVoice != null) {
10266 mRunningVoice = null;
10267 mVoiceWakeLock.release();
10268 updateSleepIfNeededLocked();
10272 void startTimeTrackingFocusedActivityLocked() {
10273 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10274 mCurAppTimeTracker.start(mFocusedActivity.packageName);
10278 void updateSleepIfNeededLocked() {
10279 if (mSleeping && !shouldSleepLocked()) {
10281 startTimeTrackingFocusedActivityLocked();
10282 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10283 mStackSupervisor.comeOutOfSleepIfNeededLocked();
10284 updateOomAdjLocked();
10285 } else if (!mSleeping && shouldSleepLocked()) {
10287 if (mCurAppTimeTracker != null) {
10288 mCurAppTimeTracker.stop();
10290 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10291 mStackSupervisor.goingToSleepLocked();
10292 updateOomAdjLocked();
10294 // Initialize the wake times of all processes.
10295 checkExcessivePowerUsageLocked(false);
10296 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10297 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10298 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10302 private boolean shouldSleepLocked() {
10303 // Resume applications while running a voice interactor.
10304 if (mRunningVoice != null) {
10308 // TODO: Transform the lock screen state into a sleep token instead.
10309 switch (mWakefulness) {
10310 case PowerManagerInternal.WAKEFULNESS_AWAKE:
10311 case PowerManagerInternal.WAKEFULNESS_DREAMING:
10312 case PowerManagerInternal.WAKEFULNESS_DOZING:
10313 // Pause applications whenever the lock screen is shown or any sleep
10314 // tokens have been acquired.
10315 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10316 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10318 // If we're asleep then pause applications unconditionally.
10323 /** Pokes the task persister. */
10324 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10325 if (task != null && task.stack != null && task.stack.isHomeStack()) {
10326 // Never persist the home stack.
10329 mTaskPersister.wakeup(task, flush);
10332 /** Notifies all listeners when the task stack has changed. */
10333 void notifyTaskStackChangedLocked() {
10334 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10335 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10336 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10340 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10341 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10345 public boolean shutdown(int timeout) {
10346 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10347 != PackageManager.PERMISSION_GRANTED) {
10348 throw new SecurityException("Requires permission "
10349 + android.Manifest.permission.SHUTDOWN);
10352 boolean timedout = false;
10354 synchronized(this) {
10355 mShuttingDown = true;
10356 updateEventDispatchingLocked();
10357 timedout = mStackSupervisor.shutdownLocked(timeout);
10360 mAppOpsService.shutdown();
10361 if (mUsageStatsService != null) {
10362 mUsageStatsService.prepareShutdown();
10364 mBatteryStatsService.shutdown();
10365 synchronized (this) {
10366 mProcessStats.shutdownLocked();
10367 notifyTaskPersisterLocked(null, true);
10373 public final void activitySlept(IBinder token) {
10374 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10376 final long origId = Binder.clearCallingIdentity();
10378 synchronized (this) {
10379 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10381 mStackSupervisor.activitySleptLocked(r);
10385 Binder.restoreCallingIdentity(origId);
10388 private String lockScreenShownToString() {
10389 switch (mLockScreenShown) {
10390 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10391 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10392 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10393 default: return "Unknown=" + mLockScreenShown;
10397 void logLockScreen(String msg) {
10398 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10399 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10400 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10401 + " mSleeping=" + mSleeping);
10404 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10405 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10406 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10407 boolean wasRunningVoice = mRunningVoice != null;
10408 mRunningVoice = session;
10409 if (!wasRunningVoice) {
10410 mVoiceWakeLock.acquire();
10411 updateSleepIfNeededLocked();
10416 private void updateEventDispatchingLocked() {
10417 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10420 public void setLockScreenShown(boolean shown) {
10421 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10422 != PackageManager.PERMISSION_GRANTED) {
10423 throw new SecurityException("Requires permission "
10424 + android.Manifest.permission.DEVICE_POWER);
10427 synchronized(this) {
10428 long ident = Binder.clearCallingIdentity();
10430 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10431 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10432 updateSleepIfNeededLocked();
10434 Binder.restoreCallingIdentity(ident);
10440 public void stopAppSwitches() {
10441 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10442 != PackageManager.PERMISSION_GRANTED) {
10443 throw new SecurityException("Requires permission "
10444 + android.Manifest.permission.STOP_APP_SWITCHES);
10447 synchronized(this) {
10448 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10449 + APP_SWITCH_DELAY_TIME;
10450 mDidAppSwitch = false;
10451 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10452 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10453 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10457 public void resumeAppSwitches() {
10458 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10459 != PackageManager.PERMISSION_GRANTED) {
10460 throw new SecurityException("Requires permission "
10461 + android.Manifest.permission.STOP_APP_SWITCHES);
10464 synchronized(this) {
10465 // Note that we don't execute any pending app switches... we will
10466 // let those wait until either the timeout, or the next start
10467 // activity request.
10468 mAppSwitchesAllowedTime = 0;
10472 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10473 int callingPid, int callingUid, String name) {
10474 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10478 int perm = checkComponentPermission(
10479 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10480 sourceUid, -1, true);
10481 if (perm == PackageManager.PERMISSION_GRANTED) {
10485 // If the actual IPC caller is different from the logical source, then
10486 // also see if they are allowed to control app switches.
10487 if (callingUid != -1 && callingUid != sourceUid) {
10488 perm = checkComponentPermission(
10489 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10490 callingUid, -1, true);
10491 if (perm == PackageManager.PERMISSION_GRANTED) {
10496 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10500 public void setDebugApp(String packageName, boolean waitForDebugger,
10501 boolean persistent) {
10502 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10505 long ident = Binder.clearCallingIdentity();
10507 // Note that this is not really thread safe if there are multiple
10508 // callers into it at the same time, but that's not a situation we
10511 final ContentResolver resolver = mContext.getContentResolver();
10512 Settings.Global.putString(
10513 resolver, Settings.Global.DEBUG_APP,
10515 Settings.Global.putInt(
10516 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10517 waitForDebugger ? 1 : 0);
10520 synchronized (this) {
10522 mOrigDebugApp = mDebugApp;
10523 mOrigWaitForDebugger = mWaitForDebugger;
10525 mDebugApp = packageName;
10526 mWaitForDebugger = waitForDebugger;
10527 mDebugTransient = !persistent;
10528 if (packageName != null) {
10529 forceStopPackageLocked(packageName, -1, false, false, true, true,
10530 false, UserHandle.USER_ALL, "set debug app");
10534 Binder.restoreCallingIdentity(ident);
10538 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10539 synchronized (this) {
10540 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10541 if (!isDebuggable) {
10542 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10543 throw new SecurityException("Process not debuggable: " + app.packageName);
10547 mOpenGlTraceApp = processName;
10551 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10552 synchronized (this) {
10553 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10554 if (!isDebuggable) {
10555 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10556 throw new SecurityException("Process not debuggable: " + app.packageName);
10559 mProfileApp = processName;
10560 mProfileFile = profilerInfo.profileFile;
10561 if (mProfileFd != null) {
10563 mProfileFd.close();
10564 } catch (IOException e) {
10568 mProfileFd = profilerInfo.profileFd;
10569 mSamplingInterval = profilerInfo.samplingInterval;
10570 mAutoStopProfiler = profilerInfo.autoStopProfiler;
10576 public void setAlwaysFinish(boolean enabled) {
10577 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10578 "setAlwaysFinish()");
10580 Settings.Global.putInt(
10581 mContext.getContentResolver(),
10582 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10584 synchronized (this) {
10585 mAlwaysFinishActivities = enabled;
10590 public void setActivityController(IActivityController controller) {
10591 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10592 "setActivityController()");
10593 synchronized (this) {
10594 mController = controller;
10595 Watchdog.getInstance().setActivityController(controller);
10600 public void setUserIsMonkey(boolean userIsMonkey) {
10601 synchronized (this) {
10602 synchronized (mPidsSelfLocked) {
10603 final int callingPid = Binder.getCallingPid();
10604 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10605 if (precessRecord == null) {
10606 throw new SecurityException("Unknown process: " + callingPid);
10608 if (precessRecord.instrumentationUiAutomationConnection == null) {
10609 throw new SecurityException("Only an instrumentation process "
10610 + "with a UiAutomation can call setUserIsMonkey");
10613 mUserIsMonkey = userIsMonkey;
10618 public boolean isUserAMonkey() {
10619 synchronized (this) {
10620 // If there is a controller also implies the user is a monkey.
10621 return (mUserIsMonkey || mController != null);
10625 public void requestBugReport() {
10626 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10627 SystemProperties.set("ctl.start", "bugreport");
10630 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10631 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10634 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10635 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10636 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10638 return KEY_DISPATCHING_TIMEOUT;
10642 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10643 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10644 != PackageManager.PERMISSION_GRANTED) {
10645 throw new SecurityException("Requires permission "
10646 + android.Manifest.permission.FILTER_EVENTS);
10648 ProcessRecord proc;
10650 synchronized (this) {
10651 synchronized (mPidsSelfLocked) {
10652 proc = mPidsSelfLocked.get(pid);
10654 timeout = getInputDispatchingTimeoutLocked(proc);
10657 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10665 * Handle input dispatching timeouts.
10666 * Returns whether input dispatching should be aborted or not.
10668 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10669 final ActivityRecord activity, final ActivityRecord parent,
10670 final boolean aboveSystem, String reason) {
10671 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10672 != PackageManager.PERMISSION_GRANTED) {
10673 throw new SecurityException("Requires permission "
10674 + android.Manifest.permission.FILTER_EVENTS);
10677 final String annotation;
10678 if (reason == null) {
10679 annotation = "Input dispatching timed out";
10681 annotation = "Input dispatching timed out (" + reason + ")";
10684 if (proc != null) {
10685 synchronized (this) {
10686 if (proc.debugging) {
10691 // Give more time since we were dexopting.
10692 mDidDexOpt = false;
10696 if (proc.instrumentationClass != null) {
10697 Bundle info = new Bundle();
10698 info.putString("shortMsg", "keyDispatchingTimedOut");
10699 info.putString("longMsg", annotation);
10700 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10704 mHandler.post(new Runnable() {
10706 public void run() {
10707 appNotResponding(proc, activity, parent, aboveSystem, annotation);
10716 public Bundle getAssistContextExtras(int requestType) {
10717 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10718 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10722 synchronized (pae) {
10723 while (!pae.haveResult) {
10726 } catch (InterruptedException e) {
10730 synchronized (this) {
10731 buildAssistBundleLocked(pae, pae.result);
10732 mPendingAssistExtras.remove(pae);
10733 mUiHandler.removeCallbacks(pae);
10739 public boolean isAssistDataAllowedOnCurrentActivity() {
10740 int userId = mCurrentUserId;
10741 synchronized (this) {
10742 ActivityRecord activity = getFocusedStack().topActivity();
10743 if (activity == null) {
10746 userId = activity.userId;
10748 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10749 Context.DEVICE_POLICY_SERVICE);
10750 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10754 public boolean showAssistFromActivity(IBinder token, Bundle args) {
10755 long ident = Binder.clearCallingIdentity();
10757 synchronized (this) {
10758 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10759 ActivityRecord top = getFocusedStack().topActivity();
10760 if (top != caller) {
10761 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10762 + " is not current top " + top);
10765 if (!top.nowVisible) {
10766 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10767 + " is not visible");
10771 AssistUtils utils = new AssistUtils(mContext);
10772 return utils.showSessionForActiveService(args,
10773 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10775 Binder.restoreCallingIdentity(ident);
10780 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10781 IBinder activityToken) {
10782 return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10783 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10786 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10787 IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10789 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10790 "enqueueAssistContext()");
10791 synchronized (this) {
10792 ActivityRecord activity = getFocusedStack().topActivity();
10793 if (activity == null) {
10794 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10797 if (activity.app == null || activity.app.thread == null) {
10798 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10801 if (activityToken != null) {
10802 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10803 if (activity != caller) {
10804 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10805 + " is not current top " + activity);
10809 PendingAssistExtras pae;
10810 Bundle extras = new Bundle();
10811 if (args != null) {
10812 extras.putAll(args);
10814 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10815 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10816 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10818 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10820 mPendingAssistExtras.add(pae);
10821 mUiHandler.postDelayed(pae, timeout);
10822 } catch (RemoteException e) {
10823 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10830 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10831 IResultReceiver receiver;
10832 synchronized (this) {
10833 mPendingAssistExtras.remove(pae);
10834 receiver = pae.receiver;
10836 if (receiver != null) {
10837 // Caller wants result sent back to them.
10839 pae.receiver.send(0, null);
10840 } catch (RemoteException e) {
10845 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10846 if (result != null) {
10847 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10849 if (pae.hint != null) {
10850 pae.extras.putBoolean(pae.hint, true);
10854 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10855 AssistContent content, Uri referrer) {
10856 PendingAssistExtras pae = (PendingAssistExtras)token;
10857 synchronized (pae) {
10858 pae.result = extras;
10859 pae.structure = structure;
10860 pae.content = content;
10861 if (referrer != null) {
10862 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10864 pae.haveResult = true;
10866 if (pae.intent == null && pae.receiver == null) {
10867 // Caller is just waiting for the result.
10872 // We are now ready to launch the assist activity.
10873 IResultReceiver sendReceiver = null;
10874 Bundle sendBundle = null;
10875 synchronized (this) {
10876 buildAssistBundleLocked(pae, extras);
10877 boolean exists = mPendingAssistExtras.remove(pae);
10878 mUiHandler.removeCallbacks(pae);
10883 if ((sendReceiver=pae.receiver) != null) {
10884 // Caller wants result sent back to them.
10885 sendBundle = new Bundle();
10886 sendBundle.putBundle("data", pae.extras);
10887 sendBundle.putParcelable("structure", pae.structure);
10888 sendBundle.putParcelable("content", pae.content);
10891 if (sendReceiver != null) {
10893 sendReceiver.send(0, sendBundle);
10894 } catch (RemoteException e) {
10899 long ident = Binder.clearCallingIdentity();
10901 pae.intent.replaceExtras(pae.extras);
10902 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10903 | Intent.FLAG_ACTIVITY_SINGLE_TOP
10904 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10905 closeSystemDialogs("assist");
10907 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10908 } catch (ActivityNotFoundException e) {
10909 Slog.w(TAG, "No activity to handle assist action.", e);
10912 Binder.restoreCallingIdentity(ident);
10916 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10918 return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10919 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10922 public void registerProcessObserver(IProcessObserver observer) {
10923 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10924 "registerProcessObserver()");
10925 synchronized (this) {
10926 mProcessObservers.register(observer);
10931 public void unregisterProcessObserver(IProcessObserver observer) {
10932 synchronized (this) {
10933 mProcessObservers.unregister(observer);
10937 public void registerUidObserver(IUidObserver observer) {
10938 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10939 "registerUidObserver()");
10940 synchronized (this) {
10941 mUidObservers.register(observer);
10946 public void unregisterUidObserver(IUidObserver observer) {
10947 synchronized (this) {
10948 mUidObservers.unregister(observer);
10953 public boolean convertFromTranslucent(IBinder token) {
10954 final long origId = Binder.clearCallingIdentity();
10956 synchronized (this) {
10957 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10961 final boolean translucentChanged = r.changeWindowTranslucency(true);
10962 if (translucentChanged) {
10963 r.task.stack.releaseBackgroundResources(r);
10964 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10966 mWindowManager.setAppFullscreen(token, true);
10967 return translucentChanged;
10970 Binder.restoreCallingIdentity(origId);
10975 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10976 final long origId = Binder.clearCallingIdentity();
10978 synchronized (this) {
10979 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10983 int index = r.task.mActivities.lastIndexOf(r);
10985 ActivityRecord under = r.task.mActivities.get(index - 1);
10986 under.returningOptions = options;
10988 final boolean translucentChanged = r.changeWindowTranslucency(false);
10989 if (translucentChanged) {
10990 r.task.stack.convertActivityToTranslucent(r);
10992 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10993 mWindowManager.setAppFullscreen(token, false);
10994 return translucentChanged;
10997 Binder.restoreCallingIdentity(origId);
11002 public boolean requestVisibleBehind(IBinder token, boolean visible) {
11003 final long origId = Binder.clearCallingIdentity();
11005 synchronized (this) {
11006 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11008 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11013 Binder.restoreCallingIdentity(origId);
11018 public boolean isBackgroundVisibleBehind(IBinder token) {
11019 final long origId = Binder.clearCallingIdentity();
11021 synchronized (this) {
11022 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11023 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11024 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11025 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11029 Binder.restoreCallingIdentity(origId);
11034 public ActivityOptions getActivityOptions(IBinder token) {
11035 final long origId = Binder.clearCallingIdentity();
11037 synchronized (this) {
11038 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11040 final ActivityOptions activityOptions = r.pendingOptions;
11041 r.pendingOptions = null;
11042 return activityOptions;
11047 Binder.restoreCallingIdentity(origId);
11052 public void setImmersive(IBinder token, boolean immersive) {
11053 synchronized(this) {
11054 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11056 throw new IllegalArgumentException();
11058 r.immersive = immersive;
11060 // update associated state if we're frontmost
11061 if (r == mFocusedActivity) {
11062 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11063 applyUpdateLockStateLocked(r);
11069 public boolean isImmersive(IBinder token) {
11070 synchronized (this) {
11071 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11073 throw new IllegalArgumentException();
11075 return r.immersive;
11079 public boolean isTopActivityImmersive() {
11080 enforceNotIsolatedCaller("startActivity");
11081 synchronized (this) {
11082 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11083 return (r != null) ? r.immersive : false;
11088 public boolean isTopOfTask(IBinder token) {
11089 synchronized (this) {
11090 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11092 throw new IllegalArgumentException();
11094 return r.task.getTopActivity() == r;
11098 public final void enterSafeMode() {
11099 synchronized(this) {
11100 // It only makes sense to do this before the system is ready
11101 // and started launching other packages.
11102 if (!mSystemReady) {
11104 AppGlobals.getPackageManager().enterSafeMode();
11105 } catch (RemoteException e) {
11113 public final void showSafeModeOverlay() {
11114 View v = LayoutInflater.from(mContext).inflate(
11115 com.android.internal.R.layout.safe_mode, null);
11116 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11117 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11118 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11119 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11120 lp.gravity = Gravity.BOTTOM | Gravity.START;
11121 lp.format = v.getBackground().getOpacity();
11122 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11123 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11124 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11125 ((WindowManager)mContext.getSystemService(
11126 Context.WINDOW_SERVICE)).addView(v, lp);
11129 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11130 if (!(sender instanceof PendingIntentRecord)) {
11133 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11134 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11135 synchronized (stats) {
11136 if (mBatteryStatsService.isOnBattery()) {
11137 mBatteryStatsService.enforceCallingPermission();
11138 int MY_UID = Binder.getCallingUid();
11139 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11140 BatteryStatsImpl.Uid.Pkg pkg =
11141 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11142 sourcePkg != null ? sourcePkg : rec.key.packageName);
11143 pkg.noteWakeupAlarmLocked(tag);
11148 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11149 if (!(sender instanceof PendingIntentRecord)) {
11152 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11153 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11154 synchronized (stats) {
11155 mBatteryStatsService.enforceCallingPermission();
11156 int MY_UID = Binder.getCallingUid();
11157 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11158 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11162 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11163 if (!(sender instanceof PendingIntentRecord)) {
11166 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11167 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11168 synchronized (stats) {
11169 mBatteryStatsService.enforceCallingPermission();
11170 int MY_UID = Binder.getCallingUid();
11171 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11172 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11176 public boolean killPids(int[] pids, String pReason, boolean secure) {
11177 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11178 throw new SecurityException("killPids only available to the system");
11180 String reason = (pReason == null) ? "Unknown" : pReason;
11181 // XXX Note: don't acquire main activity lock here, because the window
11182 // manager calls in with its locks held.
11184 boolean killed = false;
11185 synchronized (mPidsSelfLocked) {
11186 int[] types = new int[pids.length];
11188 for (int i=0; i<pids.length; i++) {
11189 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11190 if (proc != null) {
11191 int type = proc.setAdj;
11193 if (type > worstType) {
11199 // If the worst oom_adj is somewhere in the cached proc LRU range,
11200 // then constrain it so we will kill all cached procs.
11201 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11202 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11203 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11206 // If this is not a secure call, don't let it kill processes that
11208 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11209 worstType = ProcessList.SERVICE_ADJ;
11212 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11213 for (int i=0; i<pids.length; i++) {
11214 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11215 if (proc == null) {
11218 int adj = proc.setAdj;
11219 if (adj >= worstType && !proc.killedByAm) {
11220 proc.kill(reason, true);
11229 public void killUid(int appId, int userId, String reason) {
11230 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11231 synchronized (this) {
11232 final long identity = Binder.clearCallingIdentity();
11234 killPackageProcessesLocked(null, appId, userId,
11235 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11236 reason != null ? reason : "kill uid");
11238 Binder.restoreCallingIdentity(identity);
11244 public boolean killProcessesBelowForeground(String reason) {
11245 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11246 throw new SecurityException("killProcessesBelowForeground() only available to system");
11249 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11252 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11253 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11254 throw new SecurityException("killProcessesBelowAdj() only available to system");
11257 boolean killed = false;
11258 synchronized (mPidsSelfLocked) {
11259 final int size = mPidsSelfLocked.size();
11260 for (int i = 0; i < size; i++) {
11261 final int pid = mPidsSelfLocked.keyAt(i);
11262 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11263 if (proc == null) continue;
11265 final int adj = proc.setAdj;
11266 if (adj > belowAdj && !proc.killedByAm) {
11267 proc.kill(reason, true);
11276 public void hang(final IBinder who, boolean allowRestart) {
11277 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11278 != PackageManager.PERMISSION_GRANTED) {
11279 throw new SecurityException("Requires permission "
11280 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11283 final IBinder.DeathRecipient death = new DeathRecipient() {
11285 public void binderDied() {
11286 synchronized (this) {
11293 who.linkToDeath(death, 0);
11294 } catch (RemoteException e) {
11295 Slog.w(TAG, "hang: given caller IBinder is already dead.");
11299 synchronized (this) {
11300 Watchdog.getInstance().setAllowRestart(allowRestart);
11301 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11302 synchronized (death) {
11303 while (who.isBinderAlive()) {
11306 } catch (InterruptedException e) {
11310 Watchdog.getInstance().setAllowRestart(true);
11315 public void restart() {
11316 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11317 != PackageManager.PERMISSION_GRANTED) {
11318 throw new SecurityException("Requires permission "
11319 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11322 Log.i(TAG, "Sending shutdown broadcast...");
11324 BroadcastReceiver br = new BroadcastReceiver() {
11325 @Override public void onReceive(Context context, Intent intent) {
11326 // Now the broadcast is done, finish up the low-level shutdown.
11327 Log.i(TAG, "Shutting down activity manager...");
11329 Log.i(TAG, "Shutdown complete, restarting!");
11330 Process.killProcess(Process.myPid());
11335 // First send the high-level shut down broadcast.
11336 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11337 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11338 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11339 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11340 mContext.sendOrderedBroadcastAsUser(intent,
11341 UserHandle.ALL, null, br, mHandler, 0, null, null);
11343 br.onReceive(mContext, intent);
11346 private long getLowRamTimeSinceIdle(long now) {
11347 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11351 public void performIdleMaintenance() {
11352 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11353 != PackageManager.PERMISSION_GRANTED) {
11354 throw new SecurityException("Requires permission "
11355 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11358 synchronized (this) {
11359 final long now = SystemClock.uptimeMillis();
11360 final long timeSinceLastIdle = now - mLastIdleTime;
11361 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11362 mLastIdleTime = now;
11363 mLowRamTimeSinceLastIdle = 0;
11364 if (mLowRamStartTime != 0) {
11365 mLowRamStartTime = now;
11368 StringBuilder sb = new StringBuilder(128);
11369 sb.append("Idle maintenance over ");
11370 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11371 sb.append(" low RAM for ");
11372 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11373 Slog.i(TAG, sb.toString());
11375 // If at least 1/3 of our time since the last idle period has been spent
11376 // with RAM low, then we want to kill processes.
11377 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11379 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11380 ProcessRecord proc = mLruProcesses.get(i);
11381 if (proc.notCachedSinceIdle) {
11382 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11383 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11384 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11385 if (doKilling && proc.initialIdlePss != 0
11386 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11387 sb = new StringBuilder(128);
11389 sb.append(proc.processName);
11390 sb.append(" in idle maint: pss=");
11391 sb.append(proc.lastPss);
11392 sb.append(", initialPss=");
11393 sb.append(proc.initialIdlePss);
11394 sb.append(", period=");
11395 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11396 sb.append(", lowRamPeriod=");
11397 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11398 Slog.wtfQuiet(TAG, sb.toString());
11399 proc.kill("idle maint (pss " + proc.lastPss
11400 + " from " + proc.initialIdlePss + ")", true);
11403 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11404 proc.notCachedSinceIdle = true;
11405 proc.initialIdlePss = 0;
11406 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11407 mTestPssMode, isSleeping(), now);
11411 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11412 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11416 private void retrieveSettings() {
11417 final ContentResolver resolver = mContext.getContentResolver();
11418 String debugApp = Settings.Global.getString(
11419 resolver, Settings.Global.DEBUG_APP);
11420 boolean waitForDebugger = Settings.Global.getInt(
11421 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11422 boolean alwaysFinishActivities = Settings.Global.getInt(
11423 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11424 boolean forceRtl = Settings.Global.getInt(
11425 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11426 // Transfer any global setting for forcing RTL layout, into a System Property
11427 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11429 Configuration configuration = new Configuration();
11430 Settings.System.getConfiguration(resolver, configuration);
11432 // This will take care of setting the correct layout direction flags
11433 configuration.setLayoutDirection(configuration.locale);
11436 synchronized (this) {
11437 mDebugApp = mOrigDebugApp = debugApp;
11438 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11439 mAlwaysFinishActivities = alwaysFinishActivities;
11440 // This happens before any activities are started, so we can
11441 // change mConfiguration in-place.
11442 updateConfigurationLocked(configuration, null, false, true);
11443 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11444 "Initial config: " + mConfiguration);
11448 /** Loads resources after the current configuration has been set. */
11449 private void loadResourcesOnSystemReady() {
11450 final Resources res = mContext.getResources();
11451 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11452 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11453 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11456 public boolean testIsSystemReady() {
11457 // no need to synchronize(this) just to read & return the value
11458 return mSystemReady;
11461 private static File getCalledPreBootReceiversFile() {
11462 File dataDir = Environment.getDataDirectory();
11463 File systemDir = new File(dataDir, "system");
11464 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11468 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11469 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11470 File file = getCalledPreBootReceiversFile();
11471 FileInputStream fis = null;
11473 fis = new FileInputStream(file);
11474 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11475 int fvers = dis.readInt();
11476 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11477 String vers = dis.readUTF();
11478 String codename = dis.readUTF();
11479 String build = dis.readUTF();
11480 if (android.os.Build.VERSION.RELEASE.equals(vers)
11481 && android.os.Build.VERSION.CODENAME.equals(codename)
11482 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11483 int num = dis.readInt();
11486 String pkg = dis.readUTF();
11487 String cls = dis.readUTF();
11488 lastDoneReceivers.add(new ComponentName(pkg, cls));
11492 } catch (FileNotFoundException e) {
11493 } catch (IOException e) {
11494 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11499 } catch (IOException e) {
11503 return lastDoneReceivers;
11506 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11507 File file = getCalledPreBootReceiversFile();
11508 FileOutputStream fos = null;
11509 DataOutputStream dos = null;
11511 fos = new FileOutputStream(file);
11512 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11513 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11514 dos.writeUTF(android.os.Build.VERSION.RELEASE);
11515 dos.writeUTF(android.os.Build.VERSION.CODENAME);
11516 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11517 dos.writeInt(list.size());
11518 for (int i=0; i<list.size(); i++) {
11519 dos.writeUTF(list.get(i).getPackageName());
11520 dos.writeUTF(list.get(i).getClassName());
11522 } catch (IOException e) {
11523 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11526 FileUtils.sync(fos);
11530 } catch (IOException e) {
11531 // TODO Auto-generated catch block
11532 e.printStackTrace();
11538 final class PreBootContinuation extends IIntentReceiver.Stub {
11539 final Intent intent;
11540 final Runnable onFinishCallback;
11541 final ArrayList<ComponentName> doneReceivers;
11542 final List<ResolveInfo> ris;
11548 PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11549 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11551 onFinishCallback = _onFinishCallback;
11552 doneReceivers = _doneReceivers;
11558 if (lastRi != curRi) {
11559 ActivityInfo ai = ris.get(curRi).activityInfo;
11560 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11561 intent.setComponent(comp);
11562 doneReceivers.add(comp);
11564 CharSequence label = ai.loadLabel(mContext.getPackageManager());
11565 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11567 Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11568 + " for user " + users[curUser]);
11569 EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11570 broadcastIntentLocked(null, null, intent, null, this,
11571 0, null, null, null, AppOpsManager.OP_NONE,
11572 null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11575 public void performReceive(Intent intent, int resultCode,
11576 String data, Bundle extras, boolean ordered,
11577 boolean sticky, int sendingUser) {
11579 if (curUser >= users.length) {
11582 if (curRi >= ris.size()) {
11583 // All done sending broadcasts!
11584 if (onFinishCallback != null) {
11585 // The raw IIntentReceiver interface is called
11586 // with the AM lock held, so redispatch to
11587 // execute our code without the lock.
11588 mHandler.post(onFinishCallback);
11597 private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11598 ArrayList<ComponentName> doneReceivers, int userId) {
11599 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11600 List<ResolveInfo> ris = null;
11602 ris = AppGlobals.getPackageManager().queryIntentReceivers(
11603 intent, null, 0, userId);
11604 } catch (RemoteException e) {
11609 for (int i=ris.size()-1; i>=0; i--) {
11610 if ((ris.get(i).activityInfo.applicationInfo.flags
11611 &ApplicationInfo.FLAG_SYSTEM) == 0) {
11615 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11617 // For User 0, load the version number. When delivering to a new user, deliver
11618 // to all receivers.
11619 if (userId == UserHandle.USER_OWNER) {
11620 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11621 for (int i=0; i<ris.size(); i++) {
11622 ActivityInfo ai = ris.get(i).activityInfo;
11623 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11624 if (lastDoneReceivers.contains(comp)) {
11625 // We already did the pre boot receiver for this app with the current
11626 // platform version, so don't do it again...
11629 // ...however, do keep it as one that has been done, so we don't
11630 // forget about it when rewriting the file of last done receivers.
11631 doneReceivers.add(comp);
11636 if (ris.size() <= 0) {
11640 // If primary user, send broadcast to all available users, else just to userId
11641 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11642 : new int[] { userId };
11643 if (users.length <= 0) {
11647 PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11653 public void systemReady(final Runnable goingCallback) {
11654 synchronized(this) {
11655 if (mSystemReady) {
11656 // If we're done calling all the receivers, run the next "boot phase" passed in
11657 // by the SystemServer
11658 if (goingCallback != null) {
11659 goingCallback.run();
11664 mLocalDeviceIdleController
11665 = LocalServices.getService(DeviceIdleController.LocalService.class);
11667 // Make sure we have the current profile info, since it is needed for
11668 // security checks.
11669 updateCurrentProfileIdsLocked();
11671 mRecentTasks.clear();
11672 mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11673 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11674 mTaskPersister.startPersisting();
11676 // Check to see if there are any update receivers to run.
11678 if (mWaitingUpdate) {
11681 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11682 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11683 public void run() {
11684 synchronized (ActivityManagerService.this) {
11687 showBootMessage(mContext.getText(
11688 R.string.android_upgrading_complete),
11690 writeLastDonePreBootReceivers(doneReceivers);
11691 systemReady(goingCallback);
11693 }, doneReceivers, UserHandle.USER_OWNER);
11695 if (mWaitingUpdate) {
11701 mAppOpsService.systemReady();
11702 mSystemReady = true;
11705 ArrayList<ProcessRecord> procsToKill = null;
11706 synchronized(mPidsSelfLocked) {
11707 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11708 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11709 if (!isAllowedWhileBooting(proc.info)){
11710 if (procsToKill == null) {
11711 procsToKill = new ArrayList<ProcessRecord>();
11713 procsToKill.add(proc);
11718 synchronized(this) {
11719 if (procsToKill != null) {
11720 for (int i=procsToKill.size()-1; i>=0; i--) {
11721 ProcessRecord proc = procsToKill.get(i);
11722 Slog.i(TAG, "Removing system update proc: " + proc);
11723 removeProcessLocked(proc, true, false, "system update done");
11727 // Now that we have cleaned up any update processes, we
11728 // are ready to start launching real processes and know that
11729 // we won't trample on them any more.
11730 mProcessesReady = true;
11733 Slog.i(TAG, "System now ready");
11734 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11735 SystemClock.uptimeMillis());
11737 synchronized(this) {
11738 // Make sure we have no pre-ready processes sitting around.
11740 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11741 ResolveInfo ri = mContext.getPackageManager()
11742 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11744 CharSequence errorMsg = null;
11746 ActivityInfo ai = ri.activityInfo;
11747 ApplicationInfo app = ai.applicationInfo;
11748 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11749 mTopAction = Intent.ACTION_FACTORY_TEST;
11751 mTopComponent = new ComponentName(app.packageName,
11754 errorMsg = mContext.getResources().getText(
11755 com.android.internal.R.string.factorytest_not_system);
11758 errorMsg = mContext.getResources().getText(
11759 com.android.internal.R.string.factorytest_no_action);
11761 if (errorMsg != null) {
11764 mTopComponent = null;
11765 Message msg = Message.obtain();
11766 msg.what = SHOW_FACTORY_ERROR_MSG;
11767 msg.getData().putCharSequence("msg", errorMsg);
11768 mUiHandler.sendMessage(msg);
11773 retrieveSettings();
11774 loadResourcesOnSystemReady();
11776 synchronized (this) {
11777 readGrantedUriPermissionsLocked();
11780 if (goingCallback != null) goingCallback.run();
11782 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11783 Integer.toString(mCurrentUserId), mCurrentUserId);
11784 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11785 Integer.toString(mCurrentUserId), mCurrentUserId);
11786 mSystemServiceManager.startUser(mCurrentUserId);
11788 synchronized (this) {
11789 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11791 List apps = AppGlobals.getPackageManager().
11792 getPersistentApplications(STOCK_PM_FLAGS);
11793 if (apps != null) {
11794 int N = apps.size();
11796 for (i=0; i<N; i++) {
11797 ApplicationInfo info
11798 = (ApplicationInfo)apps.get(i);
11799 if (info != null &&
11800 !info.packageName.equals("android")) {
11801 addAppLocked(info, false, null /* ABI override */);
11805 } catch (RemoteException ex) {
11806 // pm is in same process, this will never happen.
11810 // Start up initial activity.
11812 startHomeActivityLocked(mCurrentUserId, "systemReady");
11815 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11816 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11817 + " data partition or your device will be unstable.");
11818 mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11820 } catch (RemoteException e) {
11823 if (!Build.isBuildConsistent()) {
11824 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11825 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11828 long ident = Binder.clearCallingIdentity();
11830 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11831 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11832 | Intent.FLAG_RECEIVER_FOREGROUND);
11833 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11834 broadcastIntentLocked(null, null, intent,
11835 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11836 null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11837 intent = new Intent(Intent.ACTION_USER_STARTING);
11838 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11839 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11840 broadcastIntentLocked(null, null, intent,
11841 null, new IIntentReceiver.Stub() {
11843 public void performReceive(Intent intent, int resultCode, String data,
11844 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11845 throws RemoteException {
11848 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11849 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11850 } catch (Throwable t) {
11851 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11853 Binder.restoreCallingIdentity(ident);
11855 mStackSupervisor.resumeTopActivitiesLocked();
11856 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11860 private boolean makeAppCrashingLocked(ProcessRecord app,
11861 String shortMsg, String longMsg, String stackTrace) {
11862 app.crashing = true;
11863 app.crashingReport = generateProcessError(app,
11864 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11865 startAppProblemLocked(app);
11866 app.stopFreezingAllLocked();
11867 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11870 private void makeAppNotRespondingLocked(ProcessRecord app,
11871 String activity, String shortMsg, String longMsg) {
11872 app.notResponding = true;
11873 app.notRespondingReport = generateProcessError(app,
11874 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11875 activity, shortMsg, longMsg, null);
11876 startAppProblemLocked(app);
11877 app.stopFreezingAllLocked();
11881 * Generate a process error record, suitable for attachment to a ProcessRecord.
11883 * @param app The ProcessRecord in which the error occurred.
11884 * @param condition Crashing, Application Not Responding, etc. Values are defined in
11885 * ActivityManager.AppErrorStateInfo
11886 * @param activity The activity associated with the crash, if known.
11887 * @param shortMsg Short message describing the crash.
11888 * @param longMsg Long message describing the crash.
11889 * @param stackTrace Full crash stack trace, may be null.
11891 * @return Returns a fully-formed AppErrorStateInfo record.
11893 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11894 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11895 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11897 report.condition = condition;
11898 report.processName = app.processName;
11899 report.pid = app.pid;
11900 report.uid = app.info.uid;
11901 report.tag = activity;
11902 report.shortMsg = shortMsg;
11903 report.longMsg = longMsg;
11904 report.stackTrace = stackTrace;
11909 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11910 synchronized (this) {
11911 app.crashing = false;
11912 app.crashingReport = null;
11913 app.notResponding = false;
11914 app.notRespondingReport = null;
11915 if (app.anrDialog == fromDialog) {
11916 app.anrDialog = null;
11918 if (app.waitDialog == fromDialog) {
11919 app.waitDialog = null;
11921 if (app.pid > 0 && app.pid != MY_PID) {
11922 handleAppCrashLocked(app, "user-terminated" /*reason*/,
11923 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11924 app.kill("user request after error", true);
11929 private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11930 String shortMsg, String longMsg, String stackTrace) {
11931 long now = SystemClock.uptimeMillis();
11934 if (!app.isolated) {
11935 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11939 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11940 // This process loses!
11941 Slog.w(TAG, "Process " + app.info.processName
11942 + " has crashed too many times: killing!");
11943 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11944 app.userId, app.info.processName, app.uid);
11945 mStackSupervisor.handleAppCrashLocked(app);
11946 if (!app.persistent) {
11947 // We don't want to start this process again until the user
11948 // explicitly does so... but for persistent process, we really
11949 // need to keep it running. If a persistent process is actually
11950 // repeatedly crashing, then badness for everyone.
11951 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11952 app.info.processName);
11953 if (!app.isolated) {
11954 // XXX We don't have a way to mark isolated processes
11955 // as bad, since they don't have a peristent identity.
11956 mBadProcesses.put(app.info.processName, app.uid,
11957 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11958 mProcessCrashTimes.remove(app.info.processName, app.uid);
11961 app.removed = true;
11962 // Don't let services in this process be restarted and potentially
11963 // annoy the user repeatedly. Unless it is persistent, since those
11964 // processes run critical code.
11965 removeProcessLocked(app, false, false, "crash");
11966 mStackSupervisor.resumeTopActivitiesLocked();
11969 mStackSupervisor.resumeTopActivitiesLocked();
11971 mStackSupervisor.finishTopRunningActivityLocked(app, reason);
11974 // Bump up the crash count of any services currently running in the proc.
11975 for (int i=app.services.size()-1; i>=0; i--) {
11976 // Any services running in the application need to be placed
11977 // back in the pending list.
11978 ServiceRecord sr = app.services.valueAt(i);
11982 // If the crashing process is what we consider to be the "home process" and it has been
11983 // replaced by a third-party app, clear the package preferred activities from packages
11984 // with a home activity running in the process to prevent a repeatedly crashing app
11985 // from blocking the user to manually clear the list.
11986 final ArrayList<ActivityRecord> activities = app.activities;
11987 if (app == mHomeProcess && activities.size() > 0
11988 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11989 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11990 final ActivityRecord r = activities.get(activityNdx);
11991 if (r.isHomeActivity()) {
11992 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11994 ActivityThread.getPackageManager()
11995 .clearPackagePreferredActivities(r.packageName);
11996 } catch (RemoteException c) {
11997 // pm is in same process, this will never happen.
12003 if (!app.isolated) {
12004 // XXX Can't keep track of crash times for isolated processes,
12005 // because they don't have a perisistent identity.
12006 mProcessCrashTimes.put(app.info.processName, app.uid, now);
12009 if (app.crashHandler != null) mHandler.post(app.crashHandler);
12013 void startAppProblemLocked(ProcessRecord app) {
12014 // If this app is not running under the current user, then we
12015 // can't give it a report button because that would require
12016 // launching the report UI under a different user.
12017 app.errorReportReceiver = null;
12019 for (int userId : mCurrentProfileIds) {
12020 if (app.userId == userId) {
12021 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12022 mContext, app.info.packageName, app.info.flags);
12025 skipCurrentReceiverLocked(app);
12028 void skipCurrentReceiverLocked(ProcessRecord app) {
12029 for (BroadcastQueue queue : mBroadcastQueues) {
12030 queue.skipCurrentReceiverLocked(app);
12035 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12036 * The application process will exit immediately after this call returns.
12037 * @param app object of the crashing app, null for the system server
12038 * @param crashInfo describing the exception
12040 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12041 ProcessRecord r = findAppProcess(app, "Crash");
12042 final String processName = app == null ? "system_server"
12043 : (r == null ? "unknown" : r.processName);
12045 handleApplicationCrashInner("crash", r, processName, crashInfo);
12048 /* Native crash reporting uses this inner version because it needs to be somewhat
12049 * decoupled from the AM-managed cleanup lifecycle
12051 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12052 ApplicationErrorReport.CrashInfo crashInfo) {
12053 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12054 UserHandle.getUserId(Binder.getCallingUid()), processName,
12055 r == null ? -1 : r.info.flags,
12056 crashInfo.exceptionClassName,
12057 crashInfo.exceptionMessage,
12058 crashInfo.throwFileName,
12059 crashInfo.throwLineNumber);
12061 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12063 crashApplication(r, crashInfo);
12066 public void handleApplicationStrictModeViolation(
12069 StrictMode.ViolationInfo info) {
12070 ProcessRecord r = findAppProcess(app, "StrictMode");
12075 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12076 Integer stackFingerprint = info.hashCode();
12077 boolean logIt = true;
12078 synchronized (mAlreadyLoggedViolatedStacks) {
12079 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12081 // TODO: sub-sample into EventLog for these, with
12082 // the info.durationMillis? Then we'd get
12083 // the relative pain numbers, without logging all
12084 // the stack traces repeatedly. We'd want to do
12085 // likewise in the client code, which also does
12086 // dup suppression, before the Binder call.
12088 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12089 mAlreadyLoggedViolatedStacks.clear();
12091 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12095 logStrictModeViolationToDropBox(r, info);
12099 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12100 AppErrorResult result = new AppErrorResult();
12101 synchronized (this) {
12102 final long origId = Binder.clearCallingIdentity();
12104 Message msg = Message.obtain();
12105 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12106 HashMap<String, Object> data = new HashMap<String, Object>();
12107 data.put("result", result);
12108 data.put("app", r);
12109 data.put("violationMask", violationMask);
12110 data.put("info", info);
12112 mUiHandler.sendMessage(msg);
12114 Binder.restoreCallingIdentity(origId);
12116 int res = result.get();
12117 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12121 // Depending on the policy in effect, there could be a bunch of
12122 // these in quick succession so we try to batch these together to
12123 // minimize disk writes, number of dropbox entries, and maximize
12124 // compression, by having more fewer, larger records.
12125 private void logStrictModeViolationToDropBox(
12126 ProcessRecord process,
12127 StrictMode.ViolationInfo info) {
12128 if (info == null) {
12131 final boolean isSystemApp = process == null ||
12132 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12133 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12134 final String processName = process == null ? "unknown" : process.processName;
12135 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12136 final DropBoxManager dbox = (DropBoxManager)
12137 mContext.getSystemService(Context.DROPBOX_SERVICE);
12139 // Exit early if the dropbox isn't configured to accept this report type.
12140 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12142 boolean bufferWasEmpty;
12143 boolean needsFlush;
12144 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12145 synchronized (sb) {
12146 bufferWasEmpty = sb.length() == 0;
12147 appendDropBoxProcessHeaders(process, processName, sb);
12148 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12149 sb.append("System-App: ").append(isSystemApp).append("\n");
12150 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12151 if (info.violationNumThisLoop != 0) {
12152 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12154 if (info.numAnimationsRunning != 0) {
12155 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12157 if (info.broadcastIntentAction != null) {
12158 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12160 if (info.durationMillis != -1) {
12161 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12163 if (info.numInstances != -1) {
12164 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12166 if (info.tags != null) {
12167 for (String tag : info.tags) {
12168 sb.append("Span-Tag: ").append(tag).append("\n");
12172 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12173 sb.append(info.crashInfo.stackTrace);
12176 if (info.message != null) {
12177 sb.append(info.message);
12181 // Only buffer up to ~64k. Various logging bits truncate
12183 needsFlush = (sb.length() > 64 * 1024);
12186 // Flush immediately if the buffer's grown too large, or this
12187 // is a non-system app. Non-system apps are isolated with a
12188 // different tag & policy and not batched.
12190 // Batching is useful during internal testing with
12191 // StrictMode settings turned up high. Without batching,
12192 // thousands of separate files could be created on boot.
12193 if (!isSystemApp || needsFlush) {
12194 new Thread("Error dump: " + dropboxTag) {
12196 public void run() {
12198 synchronized (sb) {
12199 report = sb.toString();
12200 sb.delete(0, sb.length());
12203 if (report.length() != 0) {
12204 dbox.addText(dropboxTag, report);
12211 // System app batching:
12212 if (!bufferWasEmpty) {
12213 // An existing dropbox-writing thread is outstanding, so
12214 // we don't need to start it up. The existing thread will
12215 // catch the buffer appends we just did.
12219 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12220 // (After this point, we shouldn't access AMS internal data structures.)
12221 new Thread("Error dump: " + dropboxTag) {
12223 public void run() {
12224 // 5 second sleep to let stacks arrive and be batched together
12226 Thread.sleep(5000); // 5 seconds
12227 } catch (InterruptedException e) {}
12229 String errorReport;
12230 synchronized (mStrictModeBuffer) {
12231 errorReport = mStrictModeBuffer.toString();
12232 if (errorReport.length() == 0) {
12235 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12236 mStrictModeBuffer.trimToSize();
12238 dbox.addText(dropboxTag, errorReport);
12244 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12245 * @param app object of the crashing app, null for the system server
12246 * @param tag reported by the caller
12247 * @param system whether this wtf is coming from the system
12248 * @param crashInfo describing the context of the error
12249 * @return true if the process should exit immediately (WTF is fatal)
12251 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12252 final ApplicationErrorReport.CrashInfo crashInfo) {
12253 final int callingUid = Binder.getCallingUid();
12254 final int callingPid = Binder.getCallingPid();
12257 // If this is coming from the system, we could very well have low-level
12258 // system locks held, so we want to do this all asynchronously. And we
12259 // never want this to become fatal, so there is that too.
12260 mHandler.post(new Runnable() {
12261 @Override public void run() {
12262 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12268 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12271 if (r != null && r.pid != Process.myPid() &&
12272 Settings.Global.getInt(mContext.getContentResolver(),
12273 Settings.Global.WTF_IS_FATAL, 0) != 0) {
12274 crashApplication(r, crashInfo);
12281 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12282 final ApplicationErrorReport.CrashInfo crashInfo) {
12283 final ProcessRecord r = findAppProcess(app, "WTF");
12284 final String processName = app == null ? "system_server"
12285 : (r == null ? "unknown" : r.processName);
12287 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12288 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12290 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12296 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12297 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12299 private ProcessRecord findAppProcess(IBinder app, String reason) {
12304 synchronized (this) {
12305 final int NP = mProcessNames.getMap().size();
12306 for (int ip=0; ip<NP; ip++) {
12307 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12308 final int NA = apps.size();
12309 for (int ia=0; ia<NA; ia++) {
12310 ProcessRecord p = apps.valueAt(ia);
12311 if (p.thread != null && p.thread.asBinder() == app) {
12317 Slog.w(TAG, "Can't find mystery application for " + reason
12318 + " from pid=" + Binder.getCallingPid()
12319 + " uid=" + Binder.getCallingUid() + ": " + app);
12325 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12326 * to append various headers to the dropbox log text.
12328 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12329 StringBuilder sb) {
12330 // Watchdog thread ends up invoking this function (with
12331 // a null ProcessRecord) to add the stack file to dropbox.
12332 // Do not acquire a lock on this (am) in such cases, as it
12333 // could cause a potential deadlock, if and when watchdog
12334 // is invoked due to unavailability of lock on am and it
12335 // would prevent watchdog from killing system_server.
12336 if (process == null) {
12337 sb.append("Process: ").append(processName).append("\n");
12340 // Note: ProcessRecord 'process' is guarded by the service
12341 // instance. (notably process.pkgList, which could otherwise change
12342 // concurrently during execution of this method)
12343 synchronized (this) {
12344 sb.append("Process: ").append(processName).append("\n");
12345 int flags = process.info.flags;
12346 IPackageManager pm = AppGlobals.getPackageManager();
12347 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12348 for (int ip=0; ip<process.pkgList.size(); ip++) {
12349 String pkg = process.pkgList.keyAt(ip);
12350 sb.append("Package: ").append(pkg);
12352 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12354 sb.append(" v").append(pi.versionCode);
12355 if (pi.versionName != null) {
12356 sb.append(" (").append(pi.versionName).append(")");
12359 } catch (RemoteException e) {
12360 Slog.e(TAG, "Error getting package info: " + pkg, e);
12367 private static String processClass(ProcessRecord process) {
12368 if (process == null || process.pid == MY_PID) {
12369 return "system_server";
12370 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12371 return "system_app";
12378 * Write a description of an error (crash, WTF, ANR) to the drop box.
12379 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12380 * @param process which caused the error, null means the system server
12381 * @param activity which triggered the error, null if unknown
12382 * @param parent activity related to the error, null if unknown
12383 * @param subject line related to the error, null if absent
12384 * @param report in long form describing the error, null if absent
12385 * @param logFile to include in the report, null if none
12386 * @param crashInfo giving an application stack trace, null if absent
12388 public void addErrorToDropBox(String eventType,
12389 ProcessRecord process, String processName, ActivityRecord activity,
12390 ActivityRecord parent, String subject,
12391 final String report, final File logFile,
12392 final ApplicationErrorReport.CrashInfo crashInfo) {
12393 // NOTE -- this must never acquire the ActivityManagerService lock,
12394 // otherwise the watchdog may be prevented from resetting the system.
12396 final String dropboxTag = processClass(process) + "_" + eventType;
12397 final DropBoxManager dbox = (DropBoxManager)
12398 mContext.getSystemService(Context.DROPBOX_SERVICE);
12400 // Exit early if the dropbox isn't configured to accept this report type.
12401 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12403 final StringBuilder sb = new StringBuilder(1024);
12404 appendDropBoxProcessHeaders(process, processName, sb);
12405 if (activity != null) {
12406 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12408 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12409 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12411 if (parent != null && parent != activity) {
12412 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12414 if (subject != null) {
12415 sb.append("Subject: ").append(subject).append("\n");
12417 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12418 if (Debug.isDebuggerConnected()) {
12419 sb.append("Debugger: Connected\n");
12423 // Do the rest in a worker thread to avoid blocking the caller on I/O
12424 // (After this point, we shouldn't access AMS internal data structures.)
12425 Thread worker = new Thread("Error dump: " + dropboxTag) {
12427 public void run() {
12428 if (report != null) {
12431 if (logFile != null) {
12433 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12434 "\n\n[[TRUNCATED]]"));
12435 } catch (IOException e) {
12436 Slog.e(TAG, "Error reading " + logFile, e);
12439 if (crashInfo != null && crashInfo.stackTrace != null) {
12440 sb.append(crashInfo.stackTrace);
12443 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12444 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12448 // Merge several logcat streams, and take the last N lines
12449 InputStreamReader input = null;
12451 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12452 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12454 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12456 try { logcat.getOutputStream().close(); } catch (IOException e) {}
12457 try { logcat.getErrorStream().close(); } catch (IOException e) {}
12458 input = new InputStreamReader(logcat.getInputStream());
12461 char[] buf = new char[8192];
12462 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12463 } catch (IOException e) {
12464 Slog.e(TAG, "Error running logcat", e);
12466 if (input != null) try { input.close(); } catch (IOException e) {}
12470 dbox.addText(dropboxTag, sb.toString());
12474 if (process == null) {
12475 // If process is null, we are being called from some internal code
12476 // and may be about to die -- run this synchronously.
12484 * Bring up the "unexpected error" dialog box for a crashing app.
12485 * Deal with edge cases (intercepts from instrumented applications,
12486 * ActivityController, error intent receivers, that sort of thing).
12487 * @param r the application crashing
12488 * @param crashInfo describing the failure
12490 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12491 long timeMillis = System.currentTimeMillis();
12492 String shortMsg = crashInfo.exceptionClassName;
12493 String longMsg = crashInfo.exceptionMessage;
12494 String stackTrace = crashInfo.stackTrace;
12495 if (shortMsg != null && longMsg != null) {
12496 longMsg = shortMsg + ": " + longMsg;
12497 } else if (shortMsg != null) {
12498 longMsg = shortMsg;
12501 AppErrorResult result = new AppErrorResult();
12502 synchronized (this) {
12503 if (mController != null) {
12505 String name = r != null ? r.processName : null;
12506 int pid = r != null ? r.pid : Binder.getCallingPid();
12507 int uid = r != null ? r.info.uid : Binder.getCallingUid();
12508 if (!mController.appCrashed(name, pid,
12509 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12510 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12511 && "Native crash".equals(crashInfo.exceptionClassName)) {
12512 Slog.w(TAG, "Skip killing native crashed app " + name
12513 + "(" + pid + ") during testing");
12515 Slog.w(TAG, "Force-killing crashed app " + name
12516 + " at watcher's request");
12518 r.kill("crash", true);
12521 Process.killProcess(pid);
12522 killProcessGroup(uid, pid);
12527 } catch (RemoteException e) {
12528 mController = null;
12529 Watchdog.getInstance().setActivityController(null);
12533 final long origId = Binder.clearCallingIdentity();
12535 // If this process is running instrumentation, finish it.
12536 if (r != null && r.instrumentationClass != null) {
12537 Slog.w(TAG, "Error in app " + r.processName
12538 + " running instrumentation " + r.instrumentationClass + ":");
12539 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
12540 if (longMsg != null) Slog.w(TAG, " " + longMsg);
12541 Bundle info = new Bundle();
12542 info.putString("shortMsg", shortMsg);
12543 info.putString("longMsg", longMsg);
12544 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12545 Binder.restoreCallingIdentity(origId);
12549 // Log crash in battery stats.
12551 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12554 // If we can't identify the process or it's already exceeded its crash quota,
12555 // quit right away without showing a crash dialog.
12556 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12557 Binder.restoreCallingIdentity(origId);
12561 Message msg = Message.obtain();
12562 msg.what = SHOW_ERROR_MSG;
12563 HashMap data = new HashMap();
12564 data.put("result", result);
12565 data.put("app", r);
12567 mUiHandler.sendMessage(msg);
12569 Binder.restoreCallingIdentity(origId);
12572 int res = result.get();
12574 Intent appErrorIntent = null;
12575 synchronized (this) {
12576 if (r != null && !r.isolated) {
12577 // XXX Can't keep track of crash time for isolated processes,
12578 // since they don't have a persistent identity.
12579 mProcessCrashTimes.put(r.info.processName, r.uid,
12580 SystemClock.uptimeMillis());
12582 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12583 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12587 if (appErrorIntent != null) {
12589 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12590 } catch (ActivityNotFoundException e) {
12591 Slog.w(TAG, "bug report receiver dissappeared", e);
12596 Intent createAppErrorIntentLocked(ProcessRecord r,
12597 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12598 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12599 if (report == null) {
12602 Intent result = new Intent(Intent.ACTION_APP_ERROR);
12603 result.setComponent(r.errorReportReceiver);
12604 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12605 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12609 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12610 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12611 if (r.errorReportReceiver == null) {
12615 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12619 ApplicationErrorReport report = new ApplicationErrorReport();
12620 report.packageName = r.info.packageName;
12621 report.installerPackageName = r.errorReportReceiver.getPackageName();
12622 report.processName = r.processName;
12623 report.time = timeMillis;
12624 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12626 if (r.crashing || r.forceCrashReport) {
12627 report.type = ApplicationErrorReport.TYPE_CRASH;
12628 report.crashInfo = crashInfo;
12629 } else if (r.notResponding) {
12630 report.type = ApplicationErrorReport.TYPE_ANR;
12631 report.anrInfo = new ApplicationErrorReport.AnrInfo();
12633 report.anrInfo.activity = r.notRespondingReport.tag;
12634 report.anrInfo.cause = r.notRespondingReport.shortMsg;
12635 report.anrInfo.info = r.notRespondingReport.longMsg;
12641 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12642 enforceNotIsolatedCaller("getProcessesInErrorState");
12643 // assume our apps are happy - lazy create the list
12644 List<ActivityManager.ProcessErrorStateInfo> errList = null;
12646 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12647 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12648 int userId = UserHandle.getUserId(Binder.getCallingUid());
12650 synchronized (this) {
12652 // iterate across all processes
12653 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12654 ProcessRecord app = mLruProcesses.get(i);
12655 if (!allUsers && app.userId != userId) {
12658 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12659 // This one's in trouble, so we'll generate a report for it
12660 // crashes are higher priority (in case there's a crash *and* an anr)
12661 ActivityManager.ProcessErrorStateInfo report = null;
12662 if (app.crashing) {
12663 report = app.crashingReport;
12664 } else if (app.notResponding) {
12665 report = app.notRespondingReport;
12668 if (report != null) {
12669 if (errList == null) {
12670 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12672 errList.add(report);
12674 Slog.w(TAG, "Missing app error report, app = " + app.processName +
12675 " crashing = " + app.crashing +
12676 " notResponding = " + app.notResponding);
12685 static int procStateToImportance(int procState, int memAdj,
12686 ActivityManager.RunningAppProcessInfo currApp) {
12687 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12688 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12689 currApp.lru = memAdj;
12696 private void fillInProcMemInfo(ProcessRecord app,
12697 ActivityManager.RunningAppProcessInfo outInfo) {
12698 outInfo.pid = app.pid;
12699 outInfo.uid = app.info.uid;
12700 if (mHeavyWeightProcess == app) {
12701 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12703 if (app.persistent) {
12704 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12706 if (app.activities.size() > 0) {
12707 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12709 outInfo.lastTrimLevel = app.trimMemoryLevel;
12710 int adj = app.curAdj;
12711 int procState = app.curProcState;
12712 outInfo.importance = procStateToImportance(procState, adj, outInfo);
12713 outInfo.importanceReasonCode = app.adjTypeCode;
12714 outInfo.processState = app.curProcState;
12717 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12718 enforceNotIsolatedCaller("getRunningAppProcesses");
12720 final int callingUid = Binder.getCallingUid();
12722 // Lazy instantiation of list
12723 List<ActivityManager.RunningAppProcessInfo> runList = null;
12724 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12725 callingUid) == PackageManager.PERMISSION_GRANTED;
12726 final int userId = UserHandle.getUserId(callingUid);
12727 final boolean allUids = isGetTasksAllowed(
12728 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12730 synchronized (this) {
12731 // Iterate across all processes
12732 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12733 ProcessRecord app = mLruProcesses.get(i);
12734 if ((!allUsers && app.userId != userId)
12735 || (!allUids && app.uid != callingUid)) {
12738 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12739 // Generate process state info for running application
12740 ActivityManager.RunningAppProcessInfo currApp =
12741 new ActivityManager.RunningAppProcessInfo(app.processName,
12742 app.pid, app.getPackageList());
12743 fillInProcMemInfo(app, currApp);
12744 if (app.adjSource instanceof ProcessRecord) {
12745 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12746 currApp.importanceReasonImportance =
12747 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12748 app.adjSourceProcState);
12749 } else if (app.adjSource instanceof ActivityRecord) {
12750 ActivityRecord r = (ActivityRecord)app.adjSource;
12751 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12753 if (app.adjTarget instanceof ComponentName) {
12754 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12756 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12757 // + " lru=" + currApp.lru);
12758 if (runList == null) {
12759 runList = new ArrayList<>();
12761 runList.add(currApp);
12768 public List<ApplicationInfo> getRunningExternalApplications() {
12769 enforceNotIsolatedCaller("getRunningExternalApplications");
12770 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12771 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12772 if (runningApps != null && runningApps.size() > 0) {
12773 Set<String> extList = new HashSet<String>();
12774 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12775 if (app.pkgList != null) {
12776 for (String pkg : app.pkgList) {
12781 IPackageManager pm = AppGlobals.getPackageManager();
12782 for (String pkg : extList) {
12784 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12785 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12788 } catch (RemoteException e) {
12796 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12797 enforceNotIsolatedCaller("getMyMemoryState");
12798 synchronized (this) {
12799 ProcessRecord proc;
12800 synchronized (mPidsSelfLocked) {
12801 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12803 fillInProcMemInfo(proc, outInfo);
12808 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12809 if (checkCallingPermission(android.Manifest.permission.DUMP)
12810 != PackageManager.PERMISSION_GRANTED) {
12811 pw.println("Permission Denial: can't dump ActivityManager from from pid="
12812 + Binder.getCallingPid()
12813 + ", uid=" + Binder.getCallingUid()
12814 + " without permission "
12815 + android.Manifest.permission.DUMP);
12819 boolean dumpAll = false;
12820 boolean dumpClient = false;
12821 String dumpPackage = null;
12824 while (opti < args.length) {
12825 String opt = args[opti];
12826 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12830 if ("-a".equals(opt)) {
12832 } else if ("-c".equals(opt)) {
12834 } else if ("-p".equals(opt)) {
12835 if (opti < args.length) {
12836 dumpPackage = args[opti];
12839 pw.println("Error: -p option requires package argument");
12843 } else if ("-h".equals(opt)) {
12844 pw.println("Activity manager dump options:");
12845 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ...");
12846 pw.println(" cmd may be one of:");
12847 pw.println(" a[ctivities]: activity stack state");
12848 pw.println(" r[recents]: recent activities state");
12849 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12850 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
12851 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
12852 pw.println(" o[om]: out of memory management");
12853 pw.println(" perm[issions]: URI permission grant state");
12854 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
12855 pw.println(" provider [COMP_SPEC]: provider client-side state");
12856 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
12857 pw.println(" as[sociations]: tracked app associations");
12858 pw.println(" service [COMP_SPEC]: service client-side state");
12859 pw.println(" package [PACKAGE_NAME]: all state related to given package");
12860 pw.println(" all: dump all activities");
12861 pw.println(" top: dump the top activity");
12862 pw.println(" write: write all pending state to storage");
12863 pw.println(" track-associations: enable association tracking");
12864 pw.println(" untrack-associations: disable and clear association tracking");
12865 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
12866 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
12867 pw.println(" a partial substring in a component name, a");
12868 pw.println(" hex object identifier.");
12869 pw.println(" -a: include all available server state.");
12870 pw.println(" -c: include client state.");
12871 pw.println(" -p: limit output to given package.");
12874 pw.println("Unknown argument: " + opt + "; use -h for help");
12878 long origId = Binder.clearCallingIdentity();
12879 boolean more = false;
12880 // Is the caller requesting to dump a particular piece of data?
12881 if (opti < args.length) {
12882 String cmd = args[opti];
12884 if ("activities".equals(cmd) || "a".equals(cmd)) {
12885 synchronized (this) {
12886 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12888 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12889 synchronized (this) {
12890 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12892 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12895 if (opti >= args.length) {
12897 newArgs = EMPTY_STRING_ARRAY;
12899 dumpPackage = args[opti];
12901 newArgs = new String[args.length - opti];
12902 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12903 args.length - opti);
12905 synchronized (this) {
12906 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12908 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12911 if (opti >= args.length) {
12913 newArgs = EMPTY_STRING_ARRAY;
12915 dumpPackage = args[opti];
12917 newArgs = new String[args.length - opti];
12918 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12919 args.length - opti);
12921 synchronized (this) {
12922 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12924 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12927 if (opti >= args.length) {
12929 newArgs = EMPTY_STRING_ARRAY;
12931 dumpPackage = args[opti];
12933 newArgs = new String[args.length - opti];
12934 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12935 args.length - opti);
12937 synchronized (this) {
12938 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12940 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12941 synchronized (this) {
12942 dumpOomLocked(fd, pw, args, opti, true);
12944 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
12945 synchronized (this) {
12946 dumpPermissionsLocked(fd, pw, args, opti, true, null);
12948 } else if ("provider".equals(cmd)) {
12951 if (opti >= args.length) {
12953 newArgs = EMPTY_STRING_ARRAY;
12957 newArgs = new String[args.length - opti];
12958 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12960 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12961 pw.println("No providers match: " + name);
12962 pw.println("Use -h for help.");
12964 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12965 synchronized (this) {
12966 dumpProvidersLocked(fd, pw, args, opti, true, null);
12968 } else if ("service".equals(cmd)) {
12971 if (opti >= args.length) {
12973 newArgs = EMPTY_STRING_ARRAY;
12977 newArgs = new String[args.length - opti];
12978 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12979 args.length - opti);
12981 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12982 pw.println("No services match: " + name);
12983 pw.println("Use -h for help.");
12985 } else if ("package".equals(cmd)) {
12987 if (opti >= args.length) {
12988 pw.println("package: no package name specified");
12989 pw.println("Use -h for help.");
12991 dumpPackage = args[opti];
12993 newArgs = new String[args.length - opti];
12994 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12995 args.length - opti);
13000 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13001 synchronized (this) {
13002 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13004 } else if ("services".equals(cmd) || "s".equals(cmd)) {
13005 synchronized (this) {
13006 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13008 } else if ("write".equals(cmd)) {
13009 mTaskPersister.flush();
13010 pw.println("All tasks persisted.");
13012 } else if ("track-associations".equals(cmd)) {
13013 synchronized (this) {
13014 if (!mTrackingAssociations) {
13015 mTrackingAssociations = true;
13016 pw.println("Association tracking started.");
13018 pw.println("Association tracking already enabled.");
13022 } else if ("untrack-associations".equals(cmd)) {
13023 synchronized (this) {
13024 if (mTrackingAssociations) {
13025 mTrackingAssociations = false;
13026 mAssociations.clear();
13027 pw.println("Association tracking stopped.");
13029 pw.println("Association tracking not running.");
13034 // Dumping a single activity?
13035 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13036 pw.println("Bad activity command, or no activities match: " + cmd);
13037 pw.println("Use -h for help.");
13041 Binder.restoreCallingIdentity(origId);
13046 // No piece of data specified, dump everything.
13047 synchronized (this) {
13048 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13051 pw.println("-------------------------------------------------------------------------------");
13053 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13056 pw.println("-------------------------------------------------------------------------------");
13058 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13061 pw.println("-------------------------------------------------------------------------------");
13063 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13066 pw.println("-------------------------------------------------------------------------------");
13068 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13071 pw.println("-------------------------------------------------------------------------------");
13073 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13076 pw.println("-------------------------------------------------------------------------------");
13078 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13079 if (mAssociations.size() > 0) {
13082 pw.println("-------------------------------------------------------------------------------");
13084 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13088 pw.println("-------------------------------------------------------------------------------");
13090 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13092 Binder.restoreCallingIdentity(origId);
13095 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13096 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13097 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13099 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13101 boolean needSep = printedAnything;
13103 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13104 dumpPackage, needSep, " mFocusedActivity: ");
13106 printedAnything = true;
13110 if (dumpPackage == null) {
13115 printedAnything = true;
13116 mStackSupervisor.dump(pw, " ");
13119 if (!printedAnything) {
13120 pw.println(" (nothing)");
13124 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13125 int opti, boolean dumpAll, String dumpPackage) {
13126 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13128 boolean printedAnything = false;
13130 if (mRecentTasks != null && mRecentTasks.size() > 0) {
13131 boolean printedHeader = false;
13133 final int N = mRecentTasks.size();
13134 for (int i=0; i<N; i++) {
13135 TaskRecord tr = mRecentTasks.get(i);
13136 if (dumpPackage != null) {
13137 if (tr.realActivity == null ||
13138 !dumpPackage.equals(tr.realActivity)) {
13142 if (!printedHeader) {
13143 pw.println(" Recent tasks:");
13144 printedHeader = true;
13145 printedAnything = true;
13147 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
13150 mRecentTasks.get(i).dump(pw, " ");
13155 if (!printedAnything) {
13156 pw.println(" (nothing)");
13160 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13161 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13162 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13165 if (dumpPackage != null) {
13166 IPackageManager pm = AppGlobals.getPackageManager();
13168 dumpUid = pm.getPackageUid(dumpPackage, 0);
13169 } catch (RemoteException e) {
13173 boolean printedAnything = false;
13175 final long now = SystemClock.uptimeMillis();
13177 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13178 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13179 = mAssociations.valueAt(i1);
13180 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13181 SparseArray<ArrayMap<String, Association>> sourceUids
13182 = targetComponents.valueAt(i2);
13183 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13184 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13185 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13186 Association ass = sourceProcesses.valueAt(i4);
13187 if (dumpPackage != null) {
13188 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13189 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13193 printedAnything = true;
13195 pw.print(ass.mTargetProcess);
13197 UserHandle.formatUid(pw, ass.mTargetUid);
13199 pw.print(ass.mSourceProcess);
13201 UserHandle.formatUid(pw, ass.mSourceUid);
13204 pw.print(ass.mTargetComponent.flattenToShortString());
13207 long dur = ass.mTime;
13208 if (ass.mNesting > 0) {
13209 dur += now - ass.mStartTime;
13211 TimeUtils.formatDuration(dur, pw);
13213 pw.print(ass.mCount);
13214 pw.println(" times)");
13215 if (ass.mNesting > 0) {
13217 pw.print(" Currently active: ");
13218 TimeUtils.formatDuration(now - ass.mStartTime, pw);
13227 if (!printedAnything) {
13228 pw.println(" (nothing)");
13232 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13233 int opti, boolean dumpAll, String dumpPackage) {
13234 boolean needSep = false;
13235 boolean printedAnything = false;
13238 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13241 final int NP = mProcessNames.getMap().size();
13242 for (int ip=0; ip<NP; ip++) {
13243 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13244 final int NA = procs.size();
13245 for (int ia=0; ia<NA; ia++) {
13246 ProcessRecord r = procs.valueAt(ia);
13247 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13251 pw.println(" All known processes:");
13253 printedAnything = true;
13255 pw.print(r.persistent ? " *PERS*" : " *APP*");
13256 pw.print(" UID "); pw.print(procs.keyAt(ia));
13257 pw.print(" "); pw.println(r);
13259 if (r.persistent) {
13266 if (mIsolatedProcesses.size() > 0) {
13267 boolean printed = false;
13268 for (int i=0; i<mIsolatedProcesses.size(); i++) {
13269 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13270 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13277 pw.println(" Isolated process list (sorted by uid):");
13278 printedAnything = true;
13282 pw.println(String.format("%sIsolated #%2d: %s",
13283 " ", i, r.toString()));
13287 if (mActiveUids.size() > 0) {
13291 pw.println(" UID states:");
13292 for (int i=0; i<mActiveUids.size(); i++) {
13293 UidRecord uidRec = mActiveUids.valueAt(i);
13294 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
13295 pw.print(": "); pw.println(uidRec);
13298 printedAnything = true;
13301 if (mLruProcesses.size() > 0) {
13305 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13306 pw.print(" total, non-act at ");
13307 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13308 pw.print(", non-svc at ");
13309 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13311 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
13313 printedAnything = true;
13316 if (dumpAll || dumpPackage != null) {
13317 synchronized (mPidsSelfLocked) {
13318 boolean printed = false;
13319 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13320 ProcessRecord r = mPidsSelfLocked.valueAt(i);
13321 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13325 if (needSep) pw.println();
13327 pw.println(" PID mappings:");
13329 printedAnything = true;
13331 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13332 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13337 if (mForegroundProcesses.size() > 0) {
13338 synchronized (mPidsSelfLocked) {
13339 boolean printed = false;
13340 for (int i=0; i<mForegroundProcesses.size(); i++) {
13341 ProcessRecord r = mPidsSelfLocked.get(
13342 mForegroundProcesses.valueAt(i).pid);
13343 if (dumpPackage != null && (r == null
13344 || !r.pkgList.containsKey(dumpPackage))) {
13348 if (needSep) pw.println();
13350 pw.println(" Foreground Processes:");
13352 printedAnything = true;
13354 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
13355 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13360 if (mPersistentStartingProcesses.size() > 0) {
13361 if (needSep) pw.println();
13363 printedAnything = true;
13364 pw.println(" Persisent processes that are starting:");
13365 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
13366 "Starting Norm", "Restarting PERS", dumpPackage);
13369 if (mRemovedProcesses.size() > 0) {
13370 if (needSep) pw.println();
13372 printedAnything = true;
13373 pw.println(" Processes that are being removed:");
13374 dumpProcessList(pw, this, mRemovedProcesses, " ",
13375 "Removed Norm", "Removed PERS", dumpPackage);
13378 if (mProcessesOnHold.size() > 0) {
13379 if (needSep) pw.println();
13381 printedAnything = true;
13382 pw.println(" Processes that are on old until the system is ready:");
13383 dumpProcessList(pw, this, mProcessesOnHold, " ",
13384 "OnHold Norm", "OnHold PERS", dumpPackage);
13387 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13389 if (mProcessCrashTimes.getMap().size() > 0) {
13390 boolean printed = false;
13391 long now = SystemClock.uptimeMillis();
13392 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13393 final int NP = pmap.size();
13394 for (int ip=0; ip<NP; ip++) {
13395 String pname = pmap.keyAt(ip);
13396 SparseArray<Long> uids = pmap.valueAt(ip);
13397 final int N = uids.size();
13398 for (int i=0; i<N; i++) {
13399 int puid = uids.keyAt(i);
13400 ProcessRecord r = mProcessNames.get(pname, puid);
13401 if (dumpPackage != null && (r == null
13402 || !r.pkgList.containsKey(dumpPackage))) {
13406 if (needSep) pw.println();
13408 pw.println(" Time since processes crashed:");
13410 printedAnything = true;
13412 pw.print(" Process "); pw.print(pname);
13413 pw.print(" uid "); pw.print(puid);
13414 pw.print(": last crashed ");
13415 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13416 pw.println(" ago");
13421 if (mBadProcesses.getMap().size() > 0) {
13422 boolean printed = false;
13423 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13424 final int NP = pmap.size();
13425 for (int ip=0; ip<NP; ip++) {
13426 String pname = pmap.keyAt(ip);
13427 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13428 final int N = uids.size();
13429 for (int i=0; i<N; i++) {
13430 int puid = uids.keyAt(i);
13431 ProcessRecord r = mProcessNames.get(pname, puid);
13432 if (dumpPackage != null && (r == null
13433 || !r.pkgList.containsKey(dumpPackage))) {
13437 if (needSep) pw.println();
13439 pw.println(" Bad processes:");
13440 printedAnything = true;
13442 BadProcessInfo info = uids.valueAt(i);
13443 pw.print(" Bad process "); pw.print(pname);
13444 pw.print(" uid "); pw.print(puid);
13445 pw.print(": crashed at time "); pw.println(info.time);
13446 if (info.shortMsg != null) {
13447 pw.print(" Short msg: "); pw.println(info.shortMsg);
13449 if (info.longMsg != null) {
13450 pw.print(" Long msg: "); pw.println(info.longMsg);
13452 if (info.stack != null) {
13453 pw.println(" Stack:");
13455 for (int pos=0; pos<info.stack.length(); pos++) {
13456 if (info.stack.charAt(pos) == '\n') {
13458 pw.write(info.stack, lastPos, pos-lastPos);
13463 if (lastPos < info.stack.length()) {
13465 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13473 if (dumpPackage == null) {
13476 pw.println(" mStartedUsers:");
13477 for (int i=0; i<mStartedUsers.size(); i++) {
13478 UserState uss = mStartedUsers.valueAt(i);
13479 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
13480 pw.print(": "); uss.dump("", pw);
13482 pw.print(" mStartedUserArray: [");
13483 for (int i=0; i<mStartedUserArray.length; i++) {
13484 if (i > 0) pw.print(", ");
13485 pw.print(mStartedUserArray[i]);
13488 pw.print(" mUserLru: [");
13489 for (int i=0; i<mUserLru.size(); i++) {
13490 if (i > 0) pw.print(", ");
13491 pw.print(mUserLru.get(i));
13495 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13497 synchronized (mUserProfileGroupIdsSelfLocked) {
13498 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13499 pw.println(" mUserProfileGroupIds:");
13500 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13501 pw.print(" User #");
13502 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13503 pw.print(" -> profile #");
13504 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13509 if (mHomeProcess != null && (dumpPackage == null
13510 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13515 pw.println(" mHomeProcess: " + mHomeProcess);
13517 if (mPreviousProcess != null && (dumpPackage == null
13518 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13523 pw.println(" mPreviousProcess: " + mPreviousProcess);
13526 StringBuilder sb = new StringBuilder(128);
13527 sb.append(" mPreviousProcessVisibleTime: ");
13528 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13531 if (mHeavyWeightProcess != null && (dumpPackage == null
13532 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13537 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13539 if (dumpPackage == null) {
13540 pw.println(" mConfiguration: " + mConfiguration);
13543 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13544 if (mCompatModePackages.getPackages().size() > 0) {
13545 boolean printed = false;
13546 for (Map.Entry<String, Integer> entry
13547 : mCompatModePackages.getPackages().entrySet()) {
13548 String pkg = entry.getKey();
13549 int mode = entry.getValue();
13550 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13554 pw.println(" mScreenCompatPackages:");
13557 pw.print(" "); pw.print(pkg); pw.print(": ");
13558 pw.print(mode); pw.println();
13562 if (dumpPackage == null) {
13563 pw.println(" mWakefulness="
13564 + PowerManagerInternal.wakefulnessToString(mWakefulness));
13565 pw.println(" mSleepTokens=" + mSleepTokens);
13566 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
13567 + lockScreenShownToString());
13568 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13569 if (mRunningVoice != null) {
13570 pw.println(" mRunningVoice=" + mRunningVoice);
13571 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
13574 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13575 || mOrigWaitForDebugger) {
13576 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13577 || dumpPackage.equals(mOrigDebugApp)) {
13582 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13583 + " mDebugTransient=" + mDebugTransient
13584 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13587 if (mCurAppTimeTracker != null) {
13588 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
13590 if (mMemWatchProcesses.getMap().size() > 0) {
13591 pw.println(" Mem watch processes:");
13592 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13593 = mMemWatchProcesses.getMap();
13594 for (int i=0; i<procs.size(); i++) {
13595 final String proc = procs.keyAt(i);
13596 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13597 for (int j=0; j<uids.size(); j++) {
13602 StringBuilder sb = new StringBuilder();
13603 sb.append(" ").append(proc).append('/');
13604 UserHandle.formatUid(sb, uids.keyAt(j));
13605 Pair<Long, String> val = uids.valueAt(j);
13606 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13607 if (val.second != null) {
13608 sb.append(", report to ").append(val.second);
13610 pw.println(sb.toString());
13613 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13614 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13615 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13616 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13618 if (mOpenGlTraceApp != null) {
13619 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13624 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
13627 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13628 || mProfileFd != null) {
13629 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13634 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13635 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13636 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13637 + mAutoStopProfiler);
13638 pw.println(" mProfileType=" + mProfileType);
13641 if (dumpPackage == null) {
13642 if (mAlwaysFinishActivities || mController != null) {
13643 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
13644 + " mController=" + mController);
13647 pw.println(" Total persistent processes: " + numPers);
13648 pw.println(" mProcessesReady=" + mProcessesReady
13649 + " mSystemReady=" + mSystemReady
13650 + " mBooted=" + mBooted
13651 + " mFactoryTest=" + mFactoryTest);
13652 pw.println(" mBooting=" + mBooting
13653 + " mCallFinishBooting=" + mCallFinishBooting
13654 + " mBootAnimationComplete=" + mBootAnimationComplete);
13655 pw.print(" mLastPowerCheckRealtime=");
13656 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13658 pw.print(" mLastPowerCheckUptime=");
13659 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13661 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13662 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13663 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13664 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
13665 + " (" + mLruProcesses.size() + " total)"
13666 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13667 + " mNumServiceProcs=" + mNumServiceProcs
13668 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13669 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
13670 + " mLastMemoryLevel" + mLastMemoryLevel
13671 + " mLastNumProcesses" + mLastNumProcesses);
13672 long now = SystemClock.uptimeMillis();
13673 pw.print(" mLastIdleTime=");
13674 TimeUtils.formatDuration(now, mLastIdleTime, pw);
13675 pw.print(" mLowRamSinceLastIdle=");
13676 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13681 if (!printedAnything) {
13682 pw.println(" (nothing)");
13686 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13687 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13688 if (mProcessesToGc.size() > 0) {
13689 boolean printed = false;
13690 long now = SystemClock.uptimeMillis();
13691 for (int i=0; i<mProcessesToGc.size(); i++) {
13692 ProcessRecord proc = mProcessesToGc.get(i);
13693 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13697 if (needSep) pw.println();
13699 pw.println(" Processes that are waiting to GC:");
13702 pw.print(" Process "); pw.println(proc);
13703 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
13704 pw.print(", last gced=");
13705 pw.print(now-proc.lastRequestedGc);
13706 pw.print(" ms ago, last lowMem=");
13707 pw.print(now-proc.lastLowMemory);
13708 pw.println(" ms ago");
13715 void printOomLevel(PrintWriter pw, String name, int adj) {
13719 if (adj < 10) pw.print(' ');
13721 if (adj > -10) pw.print(' ');
13727 pw.print(mProcessList.getMemLevel(adj)/1024);
13728 pw.println(" kB)");
13731 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13732 int opti, boolean dumpAll) {
13733 boolean needSep = false;
13735 if (mLruProcesses.size() > 0) {
13736 if (needSep) pw.println();
13738 pw.println(" OOM levels:");
13739 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13740 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13741 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13742 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13743 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13744 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13745 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13746 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13747 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13748 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13749 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13750 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13751 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13752 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13754 if (needSep) pw.println();
13755 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
13756 pw.print(" total, non-act at ");
13757 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13758 pw.print(", non-svc at ");
13759 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13761 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
13765 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13768 pw.println(" mHomeProcess: " + mHomeProcess);
13769 pw.println(" mPreviousProcess: " + mPreviousProcess);
13770 if (mHeavyWeightProcess != null) {
13771 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13778 * There are three ways to call this:
13779 * - no provider specified: dump all the providers
13780 * - a flattened component name that matched an existing provider was specified as the
13781 * first arg: dump that one provider
13782 * - the first arg isn't the flattened component name of an existing provider:
13783 * dump all providers whose component contains the first arg as a substring
13785 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13786 int opti, boolean dumpAll) {
13787 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13790 static class ItemMatcher {
13791 ArrayList<ComponentName> components;
13792 ArrayList<String> strings;
13793 ArrayList<Integer> objects;
13800 void build(String name) {
13801 ComponentName componentName = ComponentName.unflattenFromString(name);
13802 if (componentName != null) {
13803 if (components == null) {
13804 components = new ArrayList<ComponentName>();
13806 components.add(componentName);
13810 // Not a '/' separated full component name; maybe an object ID?
13812 objectId = Integer.parseInt(name, 16);
13813 if (objects == null) {
13814 objects = new ArrayList<Integer>();
13816 objects.add(objectId);
13818 } catch (RuntimeException e) {
13819 // Not an integer; just do string match.
13820 if (strings == null) {
13821 strings = new ArrayList<String>();
13829 int build(String[] args, int opti) {
13830 for (; opti<args.length; opti++) {
13831 String name = args[opti];
13832 if ("--".equals(name)) {
13840 boolean match(Object object, ComponentName comp) {
13844 if (components != null) {
13845 for (int i=0; i<components.size(); i++) {
13846 if (components.get(i).equals(comp)) {
13851 if (objects != null) {
13852 for (int i=0; i<objects.size(); i++) {
13853 if (System.identityHashCode(object) == objects.get(i)) {
13858 if (strings != null) {
13859 String flat = comp.flattenToString();
13860 for (int i=0; i<strings.size(); i++) {
13861 if (flat.contains(strings.get(i))) {
13871 * There are three things that cmd can be:
13872 * - a flattened component name that matches an existing activity
13873 * - the cmd arg isn't the flattened component name of an existing activity:
13874 * dump all activity whose component contains the cmd as a substring
13875 * - A hex number of the ActivityRecord object instance.
13877 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13878 int opti, boolean dumpAll) {
13879 ArrayList<ActivityRecord> activities;
13881 synchronized (this) {
13882 activities = mStackSupervisor.getDumpActivitiesLocked(name);
13885 if (activities.size() <= 0) {
13889 String[] newArgs = new String[args.length - opti];
13890 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13892 TaskRecord lastTask = null;
13893 boolean needSep = false;
13894 for (int i=activities.size()-1; i>=0; i--) {
13895 ActivityRecord r = activities.get(i);
13900 synchronized (this) {
13901 if (lastTask != r.task) {
13903 pw.print("TASK "); pw.print(lastTask.affinity);
13904 pw.print(" id="); pw.println(lastTask.taskId);
13906 lastTask.dump(pw, " ");
13910 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
13916 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13917 * there is a thread associated with the activity.
13919 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13920 final ActivityRecord r, String[] args, boolean dumpAll) {
13921 String innerPrefix = prefix + " ";
13922 synchronized (this) {
13923 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13924 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13926 if (r.app != null) pw.println(r.app.pid);
13927 else pw.println("(not running)");
13929 r.dump(pw, innerPrefix);
13932 if (r.app != null && r.app.thread != null) {
13933 // flush anything that is already in the PrintWriter since the thread is going
13934 // to write to the file descriptor directly
13937 TransferPipe tp = new TransferPipe();
13939 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13940 r.appToken, innerPrefix, args);
13945 } catch (IOException e) {
13946 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13947 } catch (RemoteException e) {
13948 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13953 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13954 int opti, boolean dumpAll, String dumpPackage) {
13955 boolean needSep = false;
13956 boolean onlyHistory = false;
13957 boolean printedAnything = false;
13959 if ("history".equals(dumpPackage)) {
13960 if (opti < args.length && "-s".equals(args[opti])) {
13963 onlyHistory = true;
13964 dumpPackage = null;
13967 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13968 if (!onlyHistory && dumpAll) {
13969 if (mRegisteredReceivers.size() > 0) {
13970 boolean printed = false;
13971 Iterator it = mRegisteredReceivers.values().iterator();
13972 while (it.hasNext()) {
13973 ReceiverList r = (ReceiverList)it.next();
13974 if (dumpPackage != null && (r.app == null ||
13975 !dumpPackage.equals(r.app.info.packageName))) {
13979 pw.println(" Registered Receivers:");
13982 printedAnything = true;
13984 pw.print(" * "); pw.println(r);
13989 if (mReceiverResolver.dump(pw, needSep ?
13990 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
13991 " ", dumpPackage, false, false)) {
13993 printedAnything = true;
13997 for (BroadcastQueue q : mBroadcastQueues) {
13998 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13999 printedAnything |= needSep;
14004 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14005 for (int user=0; user<mStickyBroadcasts.size(); user++) {
14010 printedAnything = true;
14011 pw.print(" Sticky broadcasts for user ");
14012 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14013 StringBuilder sb = new StringBuilder(128);
14014 for (Map.Entry<String, ArrayList<Intent>> ent
14015 : mStickyBroadcasts.valueAt(user).entrySet()) {
14016 pw.print(" * Sticky action "); pw.print(ent.getKey());
14019 ArrayList<Intent> intents = ent.getValue();
14020 final int N = intents.size();
14021 for (int i=0; i<N; i++) {
14023 sb.append(" Intent: ");
14024 intents.get(i).toShortString(sb, false, true, false, false);
14025 pw.println(sb.toString());
14026 Bundle bundle = intents.get(i).getExtras();
14027 if (bundle != null) {
14029 pw.println(bundle.toString());
14039 if (!onlyHistory && dumpAll) {
14041 for (BroadcastQueue queue : mBroadcastQueues) {
14042 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
14043 + queue.mBroadcastsScheduled);
14045 pw.println(" mHandler:");
14046 mHandler.dump(new PrintWriterPrinter(pw), " ");
14048 printedAnything = true;
14051 if (!printedAnything) {
14052 pw.println(" (nothing)");
14056 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14057 int opti, boolean dumpAll, String dumpPackage) {
14059 boolean printedAnything = false;
14061 ItemMatcher matcher = new ItemMatcher();
14062 matcher.build(args, opti);
14064 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14066 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14067 printedAnything |= needSep;
14069 if (mLaunchingProviders.size() > 0) {
14070 boolean printed = false;
14071 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14072 ContentProviderRecord r = mLaunchingProviders.get(i);
14073 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14077 if (needSep) pw.println();
14079 pw.println(" Launching content providers:");
14081 printedAnything = true;
14083 pw.print(" Launching #"); pw.print(i); pw.print(": ");
14088 if (!printedAnything) {
14089 pw.println(" (nothing)");
14093 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14094 int opti, boolean dumpAll, String dumpPackage) {
14095 boolean needSep = false;
14096 boolean printedAnything = false;
14098 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14100 if (mGrantedUriPermissions.size() > 0) {
14101 boolean printed = false;
14103 if (dumpPackage != null) {
14105 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14106 } catch (NameNotFoundException e) {
14110 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14111 int uid = mGrantedUriPermissions.keyAt(i);
14112 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14115 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14117 if (needSep) pw.println();
14119 pw.println(" Granted Uri Permissions:");
14121 printedAnything = true;
14123 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
14124 for (UriPermission perm : perms.values()) {
14125 pw.print(" "); pw.println(perm);
14127 perm.dump(pw, " ");
14133 if (!printedAnything) {
14134 pw.println(" (nothing)");
14138 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14139 int opti, boolean dumpAll, String dumpPackage) {
14140 boolean printed = false;
14142 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14144 if (mIntentSenderRecords.size() > 0) {
14145 Iterator<WeakReference<PendingIntentRecord>> it
14146 = mIntentSenderRecords.values().iterator();
14147 while (it.hasNext()) {
14148 WeakReference<PendingIntentRecord> ref = it.next();
14149 PendingIntentRecord rec = ref != null ? ref.get(): null;
14150 if (dumpPackage != null && (rec == null
14151 || !dumpPackage.equals(rec.key.packageName))) {
14156 pw.print(" * "); pw.println(rec);
14161 pw.print(" * "); pw.println(ref);
14167 pw.println(" (nothing)");
14171 private static final int dumpProcessList(PrintWriter pw,
14172 ActivityManagerService service, List list,
14173 String prefix, String normalLabel, String persistentLabel,
14174 String dumpPackage) {
14176 final int N = list.size()-1;
14177 for (int i=N; i>=0; i--) {
14178 ProcessRecord r = (ProcessRecord)list.get(i);
14179 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14182 pw.println(String.format("%s%s #%2d: %s",
14183 prefix, (r.persistent ? persistentLabel : normalLabel),
14185 if (r.persistent) {
14192 private static final boolean dumpProcessOomList(PrintWriter pw,
14193 ActivityManagerService service, List<ProcessRecord> origList,
14194 String prefix, String normalLabel, String persistentLabel,
14195 boolean inclDetails, String dumpPackage) {
14197 ArrayList<Pair<ProcessRecord, Integer>> list
14198 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14199 for (int i=0; i<origList.size(); i++) {
14200 ProcessRecord r = origList.get(i);
14201 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14204 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14207 if (list.size() <= 0) {
14211 Comparator<Pair<ProcessRecord, Integer>> comparator
14212 = new Comparator<Pair<ProcessRecord, Integer>>() {
14214 public int compare(Pair<ProcessRecord, Integer> object1,
14215 Pair<ProcessRecord, Integer> object2) {
14216 if (object1.first.setAdj != object2.first.setAdj) {
14217 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14219 if (object1.second.intValue() != object2.second.intValue()) {
14220 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14226 Collections.sort(list, comparator);
14228 final long curRealtime = SystemClock.elapsedRealtime();
14229 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14230 final long curUptime = SystemClock.uptimeMillis();
14231 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14233 for (int i=list.size()-1; i>=0; i--) {
14234 ProcessRecord r = list.get(i).first;
14235 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14237 switch (r.setSchedGroup) {
14238 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14241 case Process.THREAD_GROUP_DEFAULT:
14249 if (r.foregroundActivities) {
14251 } else if (r.foregroundServices) {
14256 String procState = ProcessList.makeProcStateString(r.curProcState);
14258 pw.print(r.persistent ? persistentLabel : normalLabel);
14260 int num = (origList.size()-1)-list.get(i).second;
14261 if (num < 10) pw.print(' ');
14266 pw.print(schedGroup);
14268 pw.print(foreground);
14270 pw.print(procState);
14272 if (r.trimMemoryLevel < 10) pw.print(' ');
14273 pw.print(r.trimMemoryLevel);
14275 pw.print(r.toShortString());
14277 pw.print(r.adjType);
14279 if (r.adjSource != null || r.adjTarget != null) {
14282 if (r.adjTarget instanceof ComponentName) {
14283 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14284 } else if (r.adjTarget != null) {
14285 pw.print(r.adjTarget.toString());
14287 pw.print("{null}");
14290 if (r.adjSource instanceof ProcessRecord) {
14292 pw.print(((ProcessRecord)r.adjSource).toShortString());
14294 } else if (r.adjSource != null) {
14295 pw.println(r.adjSource.toString());
14297 pw.println("{null}");
14303 pw.print("oom: max="); pw.print(r.maxAdj);
14304 pw.print(" curRaw="); pw.print(r.curRawAdj);
14305 pw.print(" setRaw="); pw.print(r.setRawAdj);
14306 pw.print(" cur="); pw.print(r.curAdj);
14307 pw.print(" set="); pw.println(r.setAdj);
14310 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14311 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14312 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14313 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14317 pw.print("cached="); pw.print(r.cached);
14318 pw.print(" empty="); pw.print(r.empty);
14319 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14321 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14322 if (r.lastWakeTime != 0) {
14324 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14325 synchronized (stats) {
14326 wtime = stats.getProcessWakeTime(r.info.uid,
14327 r.pid, curRealtime);
14329 long timeUsed = wtime - r.lastWakeTime;
14332 pw.print("keep awake over ");
14333 TimeUtils.formatDuration(realtimeSince, pw);
14334 pw.print(" used ");
14335 TimeUtils.formatDuration(timeUsed, pw);
14337 pw.print((timeUsed*100)/realtimeSince);
14340 if (r.lastCpuTime != 0) {
14341 long timeUsed = r.curCpuTime - r.lastCpuTime;
14344 pw.print("run cpu over ");
14345 TimeUtils.formatDuration(uptimeSince, pw);
14346 pw.print(" used ");
14347 TimeUtils.formatDuration(timeUsed, pw);
14349 pw.print((timeUsed*100)/uptimeSince);
14358 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14360 ArrayList<ProcessRecord> procs;
14361 synchronized (this) {
14362 if (args != null && args.length > start
14363 && args[start].charAt(0) != '-') {
14364 procs = new ArrayList<ProcessRecord>();
14367 pid = Integer.parseInt(args[start]);
14368 } catch (NumberFormatException e) {
14370 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14371 ProcessRecord proc = mLruProcesses.get(i);
14372 if (proc.pid == pid) {
14374 } else if (allPkgs && proc.pkgList != null
14375 && proc.pkgList.containsKey(args[start])) {
14377 } else if (proc.processName.equals(args[start])) {
14381 if (procs.size() <= 0) {
14385 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14391 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14392 PrintWriter pw, String[] args) {
14393 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14394 if (procs == null) {
14395 pw.println("No process found for: " + args[0]);
14399 long uptime = SystemClock.uptimeMillis();
14400 long realtime = SystemClock.elapsedRealtime();
14401 pw.println("Applications Graphics Acceleration Info:");
14402 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14404 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14405 ProcessRecord r = procs.get(i);
14406 if (r.thread != null) {
14407 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14410 TransferPipe tp = new TransferPipe();
14412 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14417 } catch (IOException e) {
14418 pw.println("Failure while dumping the app: " + r);
14420 } catch (RemoteException e) {
14421 pw.println("Got a RemoteException while dumping the app " + r);
14428 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14429 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14430 if (procs == null) {
14431 pw.println("No process found for: " + args[0]);
14435 pw.println("Applications Database Info:");
14437 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14438 ProcessRecord r = procs.get(i);
14439 if (r.thread != null) {
14440 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14443 TransferPipe tp = new TransferPipe();
14445 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14450 } catch (IOException e) {
14451 pw.println("Failure while dumping the app: " + r);
14453 } catch (RemoteException e) {
14454 pw.println("Got a RemoteException while dumping the app " + r);
14461 final static class MemItem {
14462 final boolean isProc;
14463 final String label;
14464 final String shortLabel;
14467 final boolean hasActivities;
14468 ArrayList<MemItem> subitems;
14470 public MemItem(String _label, String _shortLabel, long _pss, int _id,
14471 boolean _hasActivities) {
14474 shortLabel = _shortLabel;
14477 hasActivities = _hasActivities;
14480 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14483 shortLabel = _shortLabel;
14486 hasActivities = false;
14490 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14491 ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14492 if (sort && !isCompact) {
14493 Collections.sort(items, new Comparator<MemItem>() {
14495 public int compare(MemItem lhs, MemItem rhs) {
14496 if (lhs.pss < rhs.pss) {
14498 } else if (lhs.pss > rhs.pss) {
14506 for (int i=0; i<items.size(); i++) {
14507 MemItem mi = items.get(i);
14509 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14510 } else if (mi.isProc) {
14511 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14512 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14513 pw.println(mi.hasActivities ? ",a" : ",e");
14515 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14516 pw.println(mi.pss);
14518 if (mi.subitems != null) {
14519 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
14525 // These are in KB.
14526 static final long[] DUMP_MEM_BUCKETS = new long[] {
14527 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14528 120*1024, 160*1024, 200*1024,
14529 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14530 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14533 static final void appendMemBucket(StringBuilder out, long memKB, String label,
14534 boolean stackLike) {
14535 int start = label.lastIndexOf('.');
14536 if (start >= 0) start++;
14538 int end = label.length();
14539 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14540 if (DUMP_MEM_BUCKETS[i] >= memKB) {
14541 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14542 out.append(bucket);
14543 out.append(stackLike ? "MB." : "MB ");
14544 out.append(label, start, end);
14548 out.append(memKB/1024);
14549 out.append(stackLike ? "MB." : "MB ");
14550 out.append(label, start, end);
14553 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14554 ProcessList.NATIVE_ADJ,
14555 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14556 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14557 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14558 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14559 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14560 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14562 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14564 "System", "Persistent", "Persistent Service", "Foreground",
14565 "Visible", "Perceptible",
14566 "Heavy Weight", "Backup",
14567 "A Services", "Home",
14568 "Previous", "B Services", "Cached"
14570 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14572 "sys", "pers", "persvc", "fore",
14575 "servicea", "home",
14576 "prev", "serviceb", "cached"
14579 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14580 long realtime, boolean isCheckinRequest, boolean isCompact) {
14581 if (isCheckinRequest || isCompact) {
14582 // short checkin version
14583 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14585 pw.println("Applications Memory Usage (kB):");
14586 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14590 private static final int KSM_SHARED = 0;
14591 private static final int KSM_SHARING = 1;
14592 private static final int KSM_UNSHARED = 2;
14593 private static final int KSM_VOLATILE = 3;
14595 private final long[] getKsmInfo() {
14596 long[] longOut = new long[4];
14597 final int[] SINGLE_LONG_FORMAT = new int[] {
14598 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14600 long[] longTmp = new long[1];
14601 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14602 SINGLE_LONG_FORMAT, null, longTmp, null);
14603 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14605 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14606 SINGLE_LONG_FORMAT, null, longTmp, null);
14607 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14609 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14610 SINGLE_LONG_FORMAT, null, longTmp, null);
14611 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14613 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14614 SINGLE_LONG_FORMAT, null, longTmp, null);
14615 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14619 final void dumpApplicationMemoryUsage(FileDescriptor fd,
14620 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14621 boolean dumpDetails = false;
14622 boolean dumpFullDetails = false;
14623 boolean dumpDalvik = false;
14624 boolean dumpSummaryOnly = false;
14625 boolean oomOnly = false;
14626 boolean isCompact = false;
14627 boolean localOnly = false;
14628 boolean packages = false;
14631 while (opti < args.length) {
14632 String opt = args[opti];
14633 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14637 if ("-a".equals(opt)) {
14638 dumpDetails = true;
14639 dumpFullDetails = true;
14641 } else if ("-d".equals(opt)) {
14643 } else if ("-c".equals(opt)) {
14645 } else if ("-s".equals(opt)) {
14646 dumpDetails = true;
14647 dumpSummaryOnly = true;
14648 } else if ("--oom".equals(opt)) {
14650 } else if ("--local".equals(opt)) {
14652 } else if ("--package".equals(opt)) {
14654 } else if ("-h".equals(opt)) {
14655 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14656 pw.println(" -a: include all available information for each process.");
14657 pw.println(" -d: include dalvik details.");
14658 pw.println(" -c: dump in a compact machine-parseable representation.");
14659 pw.println(" -s: dump only summary of application memory usage.");
14660 pw.println(" --oom: only show processes organized by oom adj.");
14661 pw.println(" --local: only collect details locally, don't call process.");
14662 pw.println(" --package: interpret process arg as package, dumping all");
14663 pw.println(" processes that have loaded that package.");
14664 pw.println("If [process] is specified it can be the name or ");
14665 pw.println("pid of a specific process to dump.");
14668 pw.println("Unknown argument: " + opt + "; use -h for help");
14672 final boolean isCheckinRequest = scanArgs(args, "--checkin");
14673 long uptime = SystemClock.uptimeMillis();
14674 long realtime = SystemClock.elapsedRealtime();
14675 final long[] tmpLong = new long[1];
14677 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14678 if (procs == null) {
14679 // No Java processes. Maybe they want to print a native process.
14680 if (args != null && args.length > opti
14681 && args[opti].charAt(0) != '-') {
14682 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14683 = new ArrayList<ProcessCpuTracker.Stats>();
14684 updateCpuStatsNow();
14687 findPid = Integer.parseInt(args[opti]);
14688 } catch (NumberFormatException e) {
14690 synchronized (mProcessCpuTracker) {
14691 final int N = mProcessCpuTracker.countStats();
14692 for (int i=0; i<N; i++) {
14693 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14694 if (st.pid == findPid || (st.baseName != null
14695 && st.baseName.equals(args[opti]))) {
14696 nativeProcs.add(st);
14700 if (nativeProcs.size() > 0) {
14701 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14703 Debug.MemoryInfo mi = null;
14704 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14705 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14706 final int pid = r.pid;
14707 if (!isCheckinRequest && dumpDetails) {
14708 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14711 mi = new Debug.MemoryInfo();
14713 if (dumpDetails || (!brief && !oomOnly)) {
14714 Debug.getMemoryInfo(pid, mi);
14716 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14717 mi.dalvikPrivateDirty = (int)tmpLong[0];
14719 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14720 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14721 if (isCheckinRequest) {
14728 pw.println("No process found for: " + args[opti]);
14732 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14733 dumpDetails = true;
14736 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14738 String[] innerArgs = new String[args.length-opti];
14739 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14741 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14742 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14743 long nativePss = 0;
14744 long dalvikPss = 0;
14745 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14748 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14750 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14751 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14752 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14755 long cachedPss = 0;
14757 Debug.MemoryInfo mi = null;
14758 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14759 final ProcessRecord r = procs.get(i);
14760 final IApplicationThread thread;
14763 final boolean hasActivities;
14764 synchronized (this) {
14767 oomAdj = r.getSetAdjWithServices();
14768 hasActivities = r.activities.size() > 0;
14770 if (thread != null) {
14771 if (!isCheckinRequest && dumpDetails) {
14772 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14775 mi = new Debug.MemoryInfo();
14777 if (dumpDetails || (!brief && !oomOnly)) {
14778 Debug.getMemoryInfo(pid, mi);
14780 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14781 mi.dalvikPrivateDirty = (int)tmpLong[0];
14785 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14786 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14787 if (isCheckinRequest) {
14793 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14794 dumpDalvik, dumpSummaryOnly, innerArgs);
14795 } catch (RemoteException e) {
14796 if (!isCheckinRequest) {
14797 pw.println("Got RemoteException!");
14804 final long myTotalPss = mi.getTotalPss();
14805 final long myTotalUss = mi.getTotalUss();
14807 synchronized (this) {
14808 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14809 // Record this for posterity if the process has been stable.
14810 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14814 if (!isCheckinRequest && mi != null) {
14815 totalPss += myTotalPss;
14816 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14817 (hasActivities ? " / activities)" : ")"),
14818 r.processName, myTotalPss, pid, hasActivities);
14819 procMems.add(pssItem);
14820 procMemsMap.put(pid, pssItem);
14822 nativePss += mi.nativePss;
14823 dalvikPss += mi.dalvikPss;
14824 for (int j=0; j<dalvikSubitemPss.length; j++) {
14825 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14827 otherPss += mi.otherPss;
14828 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14829 long mem = mi.getOtherPss(j);
14834 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14835 cachedPss += myTotalPss;
14838 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14839 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14840 || oomIndex == (oomPss.length-1)) {
14841 oomPss[oomIndex] += myTotalPss;
14842 if (oomProcs[oomIndex] == null) {
14843 oomProcs[oomIndex] = new ArrayList<MemItem>();
14845 oomProcs[oomIndex].add(pssItem);
14853 long nativeProcTotalPss = 0;
14855 if (!isCheckinRequest && procs.size() > 1 && !packages) {
14856 // If we are showing aggregations, also look for native processes to
14857 // include so that our aggregations are more accurate.
14858 updateCpuStatsNow();
14860 synchronized (mProcessCpuTracker) {
14861 final int N = mProcessCpuTracker.countStats();
14862 for (int i=0; i<N; i++) {
14863 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14864 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14866 mi = new Debug.MemoryInfo();
14868 if (!brief && !oomOnly) {
14869 Debug.getMemoryInfo(st.pid, mi);
14871 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14872 mi.nativePrivateDirty = (int)tmpLong[0];
14875 final long myTotalPss = mi.getTotalPss();
14876 totalPss += myTotalPss;
14877 nativeProcTotalPss += myTotalPss;
14879 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14880 st.name, myTotalPss, st.pid, false);
14881 procMems.add(pssItem);
14883 nativePss += mi.nativePss;
14884 dalvikPss += mi.dalvikPss;
14885 for (int j=0; j<dalvikSubitemPss.length; j++) {
14886 dalvikSubitemPss[j] += mi.getOtherPss(
14887 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14889 otherPss += mi.otherPss;
14890 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14891 long mem = mi.getOtherPss(j);
14895 oomPss[0] += myTotalPss;
14896 if (oomProcs[0] == null) {
14897 oomProcs[0] = new ArrayList<MemItem>();
14899 oomProcs[0].add(pssItem);
14904 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14906 catMems.add(new MemItem("Native", "Native", nativePss, -1));
14907 final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14908 if (dalvikSubitemPss.length > 0) {
14909 dalvikItem.subitems = new ArrayList<MemItem>();
14910 for (int j=0; j<dalvikSubitemPss.length; j++) {
14911 final String name = Debug.MemoryInfo.getOtherLabel(
14912 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14913 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14916 catMems.add(dalvikItem);
14917 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14918 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14919 String label = Debug.MemoryInfo.getOtherLabel(j);
14920 catMems.add(new MemItem(label, label, miscPss[j], j));
14923 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14924 for (int j=0; j<oomPss.length; j++) {
14925 if (oomPss[j] != 0) {
14926 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14927 : DUMP_MEM_OOM_LABEL[j];
14928 MemItem item = new MemItem(label, label, oomPss[j],
14929 DUMP_MEM_OOM_ADJ[j]);
14930 item.subitems = oomProcs[j];
14935 if (!brief && !oomOnly && !isCompact) {
14937 pw.println("Total PSS by process:");
14938 dumpMemItems(pw, " ", "proc", procMems, true, isCompact);
14942 pw.println("Total PSS by OOM adjustment:");
14944 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact);
14945 if (!brief && !oomOnly) {
14946 PrintWriter out = categoryPw != null ? categoryPw : pw;
14949 out.println("Total PSS by category:");
14951 dumpMemItems(out, " ", "cat", catMems, true, isCompact);
14956 MemInfoReader memInfo = new MemInfoReader();
14957 memInfo.readMemInfo();
14958 if (nativeProcTotalPss > 0) {
14959 synchronized (this) {
14960 final long cachedKb = memInfo.getCachedSizeKb();
14961 final long freeKb = memInfo.getFreeSizeKb();
14962 final long zramKb = memInfo.getZramTotalSizeKb();
14963 final long kernelKb = memInfo.getKernelUsedSizeKb();
14964 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
14965 kernelKb*1024, nativeProcTotalPss*1024);
14966 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
14967 nativeProcTotalPss);
14972 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14973 pw.print(" kB (status ");
14974 switch (mLastMemoryLevel) {
14975 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14976 pw.println("normal)");
14978 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14979 pw.println("moderate)");
14981 case ProcessStats.ADJ_MEM_FACTOR_LOW:
14982 pw.println("low)");
14984 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14985 pw.println("critical)");
14988 pw.print(mLastMemoryLevel);
14992 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14993 + memInfo.getFreeSizeKb()); pw.print(" kB (");
14994 pw.print(cachedPss); pw.print(" cached pss + ");
14995 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14996 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14998 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14999 pw.print(cachedPss + memInfo.getCachedSizeKb()
15000 + memInfo.getFreeSizeKb()); pw.print(",");
15001 pw.println(totalPss - cachedPss);
15005 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15006 + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15007 pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15008 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15009 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15010 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15011 - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15014 if (memInfo.getZramTotalSizeKb() != 0) {
15016 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15017 pw.print(" kB physical used for ");
15018 pw.print(memInfo.getSwapTotalSizeKb()
15019 - memInfo.getSwapFreeSizeKb());
15020 pw.print(" kB in swap (");
15021 pw.print(memInfo.getSwapTotalSizeKb());
15022 pw.println(" kB total swap)");
15024 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15025 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15026 pw.println(memInfo.getSwapFreeSizeKb());
15029 final long[] ksm = getKsmInfo();
15031 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15032 || ksm[KSM_VOLATILE] != 0) {
15033 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]);
15034 pw.print(" kB saved from shared ");
15035 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15036 pw.print(" "); pw.print(ksm[KSM_UNSHARED]);
15037 pw.print(" kB unshared; ");
15038 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15040 pw.print(" Tuning: ");
15041 pw.print(ActivityManager.staticGetMemoryClass());
15042 pw.print(" (large ");
15043 pw.print(ActivityManager.staticGetLargeMemoryClass());
15044 pw.print("), oom ");
15045 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15047 pw.print(", restore limit ");
15048 pw.print(mProcessList.getCachedRestoreThresholdKb());
15050 if (ActivityManager.isLowRamDeviceStatic()) {
15051 pw.print(" (low-ram)");
15053 if (ActivityManager.isHighEndGfx()) {
15054 pw.print(" (high-end-gfx)");
15058 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15059 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15060 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15061 pw.print("tuning,");
15062 pw.print(ActivityManager.staticGetMemoryClass());
15064 pw.print(ActivityManager.staticGetLargeMemoryClass());
15066 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15067 if (ActivityManager.isLowRamDeviceStatic()) {
15068 pw.print(",low-ram");
15070 if (ActivityManager.isHighEndGfx()) {
15071 pw.print(",high-end-gfx");
15079 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15080 long memtrack, String name) {
15082 sb.append(ProcessList.makeOomAdjString(oomAdj));
15084 sb.append(ProcessList.makeProcStateString(procState));
15086 ProcessList.appendRamKb(sb, pss);
15087 sb.append(" kB: ");
15089 if (memtrack > 0) {
15091 sb.append(memtrack);
15092 sb.append(" kB memtrack)");
15096 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15097 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15098 sb.append(" (pid ");
15101 sb.append(mi.adjType);
15103 if (mi.adjReason != null) {
15105 sb.append(mi.adjReason);
15110 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15111 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15112 for (int i=0, N=memInfos.size(); i<N; i++) {
15113 ProcessMemInfo mi = memInfos.get(i);
15114 infoMap.put(mi.pid, mi);
15116 updateCpuStatsNow();
15117 long[] memtrackTmp = new long[1];
15118 synchronized (mProcessCpuTracker) {
15119 final int N = mProcessCpuTracker.countStats();
15120 for (int i=0; i<N; i++) {
15121 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15122 if (st.vsize > 0) {
15123 long pss = Debug.getPss(st.pid, null, memtrackTmp);
15125 if (infoMap.indexOfKey(st.pid) < 0) {
15126 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15127 ProcessList.NATIVE_ADJ, -1, "native", null);
15129 mi.memtrack = memtrackTmp[0];
15138 long totalMemtrack = 0;
15139 for (int i=0, N=memInfos.size(); i<N; i++) {
15140 ProcessMemInfo mi = memInfos.get(i);
15142 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15143 mi.memtrack = memtrackTmp[0];
15145 totalPss += mi.pss;
15146 totalMemtrack += mi.memtrack;
15148 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15149 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15150 if (lhs.oomAdj != rhs.oomAdj) {
15151 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15153 if (lhs.pss != rhs.pss) {
15154 return lhs.pss < rhs.pss ? 1 : -1;
15160 StringBuilder tag = new StringBuilder(128);
15161 StringBuilder stack = new StringBuilder(128);
15162 tag.append("Low on memory -- ");
15163 appendMemBucket(tag, totalPss, "total", false);
15164 appendMemBucket(stack, totalPss, "total", true);
15166 StringBuilder fullNativeBuilder = new StringBuilder(1024);
15167 StringBuilder shortNativeBuilder = new StringBuilder(1024);
15168 StringBuilder fullJavaBuilder = new StringBuilder(1024);
15170 boolean firstLine = true;
15171 int lastOomAdj = Integer.MIN_VALUE;
15172 long extraNativeRam = 0;
15173 long extraNativeMemtrack = 0;
15174 long cachedPss = 0;
15175 for (int i=0, N=memInfos.size(); i<N; i++) {
15176 ProcessMemInfo mi = memInfos.get(i);
15178 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15179 cachedPss += mi.pss;
15182 if (mi.oomAdj != ProcessList.NATIVE_ADJ
15183 && (mi.oomAdj < ProcessList.SERVICE_ADJ
15184 || mi.oomAdj == ProcessList.HOME_APP_ADJ
15185 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15186 if (lastOomAdj != mi.oomAdj) {
15187 lastOomAdj = mi.oomAdj;
15188 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15191 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15196 stack.append("\n\t at ");
15204 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15205 appendMemBucket(tag, mi.pss, mi.name, false);
15207 appendMemBucket(stack, mi.pss, mi.name, true);
15208 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15209 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15211 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15212 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15213 stack.append(DUMP_MEM_OOM_LABEL[k]);
15215 stack.append(DUMP_MEM_OOM_ADJ[k]);
15222 appendMemInfo(fullNativeBuilder, mi);
15223 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15224 // The short form only has native processes that are >= 512K.
15225 if (mi.pss >= 512) {
15226 appendMemInfo(shortNativeBuilder, mi);
15228 extraNativeRam += mi.pss;
15229 extraNativeMemtrack += mi.memtrack;
15232 // Short form has all other details, but if we have collected RAM
15233 // from smaller native processes let's dump a summary of that.
15234 if (extraNativeRam > 0) {
15235 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15236 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15237 shortNativeBuilder.append('\n');
15238 extraNativeRam = 0;
15240 appendMemInfo(fullJavaBuilder, mi);
15244 fullJavaBuilder.append(" ");
15245 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15246 fullJavaBuilder.append(" kB: TOTAL");
15247 if (totalMemtrack > 0) {
15248 fullJavaBuilder.append(" (");
15249 fullJavaBuilder.append(totalMemtrack);
15250 fullJavaBuilder.append(" kB memtrack)");
15253 fullJavaBuilder.append("\n");
15255 MemInfoReader memInfo = new MemInfoReader();
15256 memInfo.readMemInfo();
15257 final long[] infos = memInfo.getRawInfo();
15259 StringBuilder memInfoBuilder = new StringBuilder(1024);
15260 Debug.getMemInfo(infos);
15261 memInfoBuilder.append(" MemInfo: ");
15262 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15263 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15264 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15265 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15266 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15267 memInfoBuilder.append(" ");
15268 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15269 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15270 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15271 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15272 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15273 memInfoBuilder.append(" ZRAM: ");
15274 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15275 memInfoBuilder.append(" kB RAM, ");
15276 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15277 memInfoBuilder.append(" kB swap total, ");
15278 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15279 memInfoBuilder.append(" kB swap free\n");
15281 final long[] ksm = getKsmInfo();
15282 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15283 || ksm[KSM_VOLATILE] != 0) {
15284 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15285 memInfoBuilder.append(" kB saved from shared ");
15286 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15287 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15288 memInfoBuilder.append(" kB unshared; ");
15289 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15291 memInfoBuilder.append(" Free RAM: ");
15292 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15293 + memInfo.getFreeSizeKb());
15294 memInfoBuilder.append(" kB\n");
15295 memInfoBuilder.append(" Used RAM: ");
15296 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15297 memInfoBuilder.append(" kB\n");
15298 memInfoBuilder.append(" Lost RAM: ");
15299 memInfoBuilder.append(memInfo.getTotalSizeKb()
15300 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15301 - memInfo.getKernelUsedSizeKb());
15302 memInfoBuilder.append(" kB\n");
15303 Slog.i(TAG, "Low on memory:");
15304 Slog.i(TAG, shortNativeBuilder.toString());
15305 Slog.i(TAG, fullJavaBuilder.toString());
15306 Slog.i(TAG, memInfoBuilder.toString());
15308 StringBuilder dropBuilder = new StringBuilder(1024);
15310 StringWriter oomSw = new StringWriter();
15311 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15312 StringWriter catSw = new StringWriter();
15313 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15314 String[] emptyArgs = new String[] { };
15315 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
15317 String oomString = oomSw.toString();
15319 dropBuilder.append("Low on memory:");
15320 dropBuilder.append(stack);
15321 dropBuilder.append('\n');
15322 dropBuilder.append(fullNativeBuilder);
15323 dropBuilder.append(fullJavaBuilder);
15324 dropBuilder.append('\n');
15325 dropBuilder.append(memInfoBuilder);
15326 dropBuilder.append('\n');
15328 dropBuilder.append(oomString);
15329 dropBuilder.append('\n');
15331 StringWriter catSw = new StringWriter();
15332 synchronized (ActivityManagerService.this) {
15333 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15334 String[] emptyArgs = new String[] { };
15336 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15338 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15339 false, false, null);
15341 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15344 dropBuilder.append(catSw.toString());
15345 addErrorToDropBox("lowmem", null, "system_server", null,
15346 null, tag.toString(), dropBuilder.toString(), null, null);
15347 //Slog.i(TAG, "Sent to dropbox:");
15348 //Slog.i(TAG, dropBuilder.toString());
15349 synchronized (ActivityManagerService.this) {
15350 long now = SystemClock.uptimeMillis();
15351 if (mLastMemUsageReportTime < now) {
15352 mLastMemUsageReportTime = now;
15358 * Searches array of arguments for the specified string
15359 * @param args array of argument strings
15360 * @param value value to search for
15361 * @return true if the value is contained in the array
15363 private static boolean scanArgs(String[] args, String value) {
15364 if (args != null) {
15365 for (String arg : args) {
15366 if (value.equals(arg)) {
15374 private final boolean removeDyingProviderLocked(ProcessRecord proc,
15375 ContentProviderRecord cpr, boolean always) {
15376 final boolean inLaunching = mLaunchingProviders.contains(cpr);
15378 if (!inLaunching || always) {
15379 synchronized (cpr) {
15380 cpr.launchingApp = null;
15383 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15384 String names[] = cpr.info.authority.split(";");
15385 for (int j = 0; j < names.length; j++) {
15386 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15390 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15391 ContentProviderConnection conn = cpr.connections.get(i);
15392 if (conn.waiting) {
15393 // If this connection is waiting for the provider, then we don't
15394 // need to mess with its process unless we are always removing
15395 // or for some reason the provider is not currently launching.
15396 if (inLaunching && !always) {
15400 ProcessRecord capp = conn.client;
15402 if (conn.stableCount > 0) {
15403 if (!capp.persistent && capp.thread != null
15405 && capp.pid != MY_PID) {
15406 capp.kill("depends on provider "
15407 + cpr.name.flattenToShortString()
15408 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15410 } else if (capp.thread != null && conn.provider.provider != null) {
15412 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15413 } catch (RemoteException e) {
15415 // In the protocol here, we don't expect the client to correctly
15416 // clean up this connection, we'll just remove it.
15417 cpr.connections.remove(i);
15418 if (conn.client.conProviders.remove(conn)) {
15419 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15424 if (inLaunching && always) {
15425 mLaunchingProviders.remove(cpr);
15427 return inLaunching;
15431 * Main code for cleaning up a process when it has gone away. This is
15432 * called both as a result of the process dying, or directly when stopping
15433 * a process when running in single process mode.
15435 * @return Returns true if the given process has been restarted, so the
15436 * app that was passed in must remain on the process lists.
15438 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15439 boolean restarting, boolean allowRestart, int index) {
15441 removeLruProcessLocked(app);
15442 ProcessList.remove(app.pid);
15445 mProcessesToGc.remove(app);
15446 mPendingPssProcesses.remove(app);
15448 // Dismiss any open dialogs.
15449 if (app.crashDialog != null && !app.forceCrashReport) {
15450 app.crashDialog.dismiss();
15451 app.crashDialog = null;
15453 if (app.anrDialog != null) {
15454 app.anrDialog.dismiss();
15455 app.anrDialog = null;
15457 if (app.waitDialog != null) {
15458 app.waitDialog.dismiss();
15459 app.waitDialog = null;
15462 app.crashing = false;
15463 app.notResponding = false;
15465 app.resetPackageList(mProcessStats);
15466 app.unlinkDeathRecipient();
15467 app.makeInactive(mProcessStats);
15468 app.waitingToKill = null;
15469 app.forcingToForeground = null;
15470 updateProcessForegroundLocked(app, false, false);
15471 app.foregroundActivities = false;
15472 app.hasShownUi = false;
15473 app.treatLikeActivity = false;
15474 app.hasAboveClient = false;
15475 app.hasClientActivities = false;
15477 mServices.killServicesLocked(app, allowRestart);
15479 boolean restart = false;
15481 // Remove published content providers.
15482 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15483 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15484 final boolean always = app.bad || !allowRestart;
15485 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15486 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15487 // We left the provider in the launching list, need to
15492 cpr.provider = null;
15495 app.pubProviders.clear();
15497 // Take care of any launching providers waiting for this process.
15498 if (checkAppInLaunchingProvidersLocked(app, false)) {
15502 // Unregister from connected content providers.
15503 if (!app.conProviders.isEmpty()) {
15504 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15505 ContentProviderConnection conn = app.conProviders.get(i);
15506 conn.provider.connections.remove(conn);
15507 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15508 conn.provider.name);
15510 app.conProviders.clear();
15513 // At this point there may be remaining entries in mLaunchingProviders
15514 // where we were the only one waiting, so they are no longer of use.
15515 // Look for these and clean up if found.
15516 // XXX Commented out for now. Trying to figure out a way to reproduce
15517 // the actual situation to identify what is actually going on.
15519 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15520 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15521 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15522 synchronized (cpr) {
15523 cpr.launchingApp = null;
15530 skipCurrentReceiverLocked(app);
15532 // Unregister any receivers.
15533 for (int i = app.receivers.size() - 1; i >= 0; i--) {
15534 removeReceiverLocked(app.receivers.valueAt(i));
15536 app.receivers.clear();
15538 // If the app is undergoing backup, tell the backup manager about it
15539 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15540 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15541 + mBackupTarget.appInfo + " died during backup");
15543 IBackupManager bm = IBackupManager.Stub.asInterface(
15544 ServiceManager.getService(Context.BACKUP_SERVICE));
15545 bm.agentDisconnected(app.info.packageName);
15546 } catch (RemoteException e) {
15547 // can't happen; backup manager is local
15551 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15552 ProcessChangeItem item = mPendingProcessChanges.get(i);
15553 if (item.pid == app.pid) {
15554 mPendingProcessChanges.remove(i);
15555 mAvailProcessChanges.add(item);
15558 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15560 // If the caller is restarting this app, then leave it in its
15561 // current lists and let the caller take care of it.
15566 if (!app.persistent || app.isolated) {
15567 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15568 "Removing non-persistent process during cleanup: " + app);
15569 removeProcessNameLocked(app.processName, app.uid);
15570 if (mHeavyWeightProcess == app) {
15571 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15572 mHeavyWeightProcess.userId, 0));
15573 mHeavyWeightProcess = null;
15575 } else if (!app.removed) {
15576 // This app is persistent, so we need to keep its record around.
15577 // If it is not already on the pending app list, add it there
15578 // and start a new process for it.
15579 if (mPersistentStartingProcesses.indexOf(app) < 0) {
15580 mPersistentStartingProcesses.add(app);
15584 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15585 TAG_CLEANUP, "Clean-up removing on hold: " + app);
15586 mProcessesOnHold.remove(app);
15588 if (app == mHomeProcess) {
15589 mHomeProcess = null;
15591 if (app == mPreviousProcess) {
15592 mPreviousProcess = null;
15595 if (restart && !app.isolated) {
15596 // We have components that still need to be running in the
15597 // process, so re-launch it.
15599 ProcessList.remove(app.pid);
15601 addProcessNameLocked(app);
15602 startProcessLocked(app, "restart", app.processName);
15604 } else if (app.pid > 0 && app.pid != MY_PID) {
15607 synchronized (mPidsSelfLocked) {
15608 mPidsSelfLocked.remove(app.pid);
15609 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15611 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15612 if (app.isolated) {
15613 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15620 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15621 // Look through the content providers we are waiting to have launched,
15622 // and if any run in this process then either schedule a restart of
15623 // the process or kill the client waiting for it if this process has
15625 boolean restart = false;
15626 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15627 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15628 if (cpr.launchingApp == app) {
15629 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15632 removeDyingProviderLocked(app, cpr, true);
15639 // =========================================================
15641 // =========================================================
15644 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15646 enforceNotIsolatedCaller("getServices");
15647 synchronized (this) {
15648 return mServices.getRunningServiceInfoLocked(maxNum, flags);
15653 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15654 enforceNotIsolatedCaller("getRunningServiceControlPanel");
15655 synchronized (this) {
15656 return mServices.getRunningServiceControlPanelLocked(name);
15661 public ComponentName startService(IApplicationThread caller, Intent service,
15662 String resolvedType, String callingPackage, int userId)
15663 throws TransactionTooLargeException {
15664 enforceNotIsolatedCaller("startService");
15665 // Refuse possible leaked file descriptors
15666 if (service != null && service.hasFileDescriptors() == true) {
15667 throw new IllegalArgumentException("File descriptors passed in Intent");
15670 if (callingPackage == null) {
15671 throw new IllegalArgumentException("callingPackage cannot be null");
15674 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15675 "startService: " + service + " type=" + resolvedType);
15676 synchronized(this) {
15677 final int callingPid = Binder.getCallingPid();
15678 final int callingUid = Binder.getCallingUid();
15679 final long origId = Binder.clearCallingIdentity();
15680 ComponentName res = mServices.startServiceLocked(caller, service,
15681 resolvedType, callingPid, callingUid, callingPackage, userId);
15682 Binder.restoreCallingIdentity(origId);
15687 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15688 String callingPackage, int userId)
15689 throws TransactionTooLargeException {
15690 synchronized(this) {
15691 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15692 "startServiceInPackage: " + service + " type=" + resolvedType);
15693 final long origId = Binder.clearCallingIdentity();
15694 ComponentName res = mServices.startServiceLocked(null, service,
15695 resolvedType, -1, uid, callingPackage, userId);
15696 Binder.restoreCallingIdentity(origId);
15702 public int stopService(IApplicationThread caller, Intent service,
15703 String resolvedType, int userId) {
15704 enforceNotIsolatedCaller("stopService");
15705 // Refuse possible leaked file descriptors
15706 if (service != null && service.hasFileDescriptors() == true) {
15707 throw new IllegalArgumentException("File descriptors passed in Intent");
15710 synchronized(this) {
15711 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15716 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15717 enforceNotIsolatedCaller("peekService");
15718 // Refuse possible leaked file descriptors
15719 if (service != null && service.hasFileDescriptors() == true) {
15720 throw new IllegalArgumentException("File descriptors passed in Intent");
15723 if (callingPackage == null) {
15724 throw new IllegalArgumentException("callingPackage cannot be null");
15727 synchronized(this) {
15728 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15733 public boolean stopServiceToken(ComponentName className, IBinder token,
15735 synchronized(this) {
15736 return mServices.stopServiceTokenLocked(className, token, startId);
15741 public void setServiceForeground(ComponentName className, IBinder token,
15742 int id, Notification notification, boolean removeNotification) {
15743 synchronized(this) {
15744 mServices.setServiceForegroundLocked(className, token, id, notification,
15745 removeNotification);
15750 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15751 boolean requireFull, String name, String callerPackage) {
15752 return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15753 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15756 int unsafeConvertIncomingUser(int userId) {
15757 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15758 ? mCurrentUserId : userId;
15761 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15762 int allowMode, String name, String callerPackage) {
15763 final int callingUserId = UserHandle.getUserId(callingUid);
15764 if (callingUserId == userId) {
15768 // Note that we may be accessing mCurrentUserId outside of a lock...
15769 // shouldn't be a big deal, if this is being called outside
15770 // of a locked context there is intrinsically a race with
15771 // the value the caller will receive and someone else changing it.
15772 // We assume that USER_CURRENT_OR_SELF will use the current user; later
15773 // we will switch to the calling user if access to the current user fails.
15774 int targetUserId = unsafeConvertIncomingUser(userId);
15776 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15777 final boolean allow;
15778 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15779 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15780 // If the caller has this permission, they always pass go. And collect $200.
15782 } else if (allowMode == ALLOW_FULL_ONLY) {
15783 // We require full access, sucks to be you.
15785 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15786 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15787 // If the caller does not have either permission, they are always doomed.
15789 } else if (allowMode == ALLOW_NON_FULL) {
15790 // We are blanket allowing non-full access, you lucky caller!
15792 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15793 // We may or may not allow this depending on whether the two users are
15794 // in the same profile.
15795 synchronized (mUserProfileGroupIdsSelfLocked) {
15796 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15797 UserInfo.NO_PROFILE_GROUP_ID);
15798 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15799 UserInfo.NO_PROFILE_GROUP_ID);
15800 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15801 && callingProfile == targetProfile;
15804 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15807 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15808 // In this case, they would like to just execute as their
15809 // owner user instead of failing.
15810 targetUserId = callingUserId;
15812 StringBuilder builder = new StringBuilder(128);
15813 builder.append("Permission Denial: ");
15814 builder.append(name);
15815 if (callerPackage != null) {
15816 builder.append(" from ");
15817 builder.append(callerPackage);
15819 builder.append(" asks to run as user ");
15820 builder.append(userId);
15821 builder.append(" but is calling from user ");
15822 builder.append(UserHandle.getUserId(callingUid));
15823 builder.append("; this requires ");
15824 builder.append(INTERACT_ACROSS_USERS_FULL);
15825 if (allowMode != ALLOW_FULL_ONLY) {
15826 builder.append(" or ");
15827 builder.append(INTERACT_ACROSS_USERS);
15829 String msg = builder.toString();
15831 throw new SecurityException(msg);
15835 if (!allowAll && targetUserId < 0) {
15836 throw new IllegalArgumentException(
15837 "Call does not support special user #" + targetUserId);
15839 // Check shell permission
15840 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15841 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15843 throw new SecurityException("Shell does not have permission to access user "
15844 + targetUserId + "\n " + Debug.getCallers(3));
15847 return targetUserId;
15850 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15851 String className, int flags) {
15852 boolean result = false;
15853 // For apps that don't have pre-defined UIDs, check for permission
15854 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15855 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15856 if (ActivityManager.checkUidPermission(
15857 INTERACT_ACROSS_USERS,
15858 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15859 ComponentName comp = new ComponentName(aInfo.packageName, className);
15860 String msg = "Permission Denial: Component " + comp.flattenToShortString()
15861 + " requests FLAG_SINGLE_USER, but app does not hold "
15862 + INTERACT_ACROSS_USERS;
15864 throw new SecurityException(msg);
15866 // Permission passed
15869 } else if ("system".equals(componentProcessName)) {
15871 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15872 // Phone app and persistent apps are allowed to export singleuser providers.
15873 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15874 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15876 if (DEBUG_MU) Slog.v(TAG_MU,
15877 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15878 + Integer.toHexString(flags) + ") = " + result);
15883 * Checks to see if the caller is in the same app as the singleton
15884 * component, or the component is in a special app. It allows special apps
15885 * to export singleton components but prevents exporting singleton
15886 * components for regular apps.
15888 boolean isValidSingletonCall(int callingUid, int componentUid) {
15889 int componentAppId = UserHandle.getAppId(componentUid);
15890 return UserHandle.isSameApp(callingUid, componentUid)
15891 || componentAppId == Process.SYSTEM_UID
15892 || componentAppId == Process.PHONE_UID
15893 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15894 == PackageManager.PERMISSION_GRANTED;
15897 public int bindService(IApplicationThread caller, IBinder token, Intent service,
15898 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15899 int userId) throws TransactionTooLargeException {
15900 enforceNotIsolatedCaller("bindService");
15902 // Refuse possible leaked file descriptors
15903 if (service != null && service.hasFileDescriptors() == true) {
15904 throw new IllegalArgumentException("File descriptors passed in Intent");
15907 if (callingPackage == null) {
15908 throw new IllegalArgumentException("callingPackage cannot be null");
15911 synchronized(this) {
15912 return mServices.bindServiceLocked(caller, token, service,
15913 resolvedType, connection, flags, callingPackage, userId);
15917 public boolean unbindService(IServiceConnection connection) {
15918 synchronized (this) {
15919 return mServices.unbindServiceLocked(connection);
15923 public void publishService(IBinder token, Intent intent, IBinder service) {
15924 // Refuse possible leaked file descriptors
15925 if (intent != null && intent.hasFileDescriptors() == true) {
15926 throw new IllegalArgumentException("File descriptors passed in Intent");
15929 synchronized(this) {
15930 if (!(token instanceof ServiceRecord)) {
15931 throw new IllegalArgumentException("Invalid service token");
15933 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15937 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15938 // Refuse possible leaked file descriptors
15939 if (intent != null && intent.hasFileDescriptors() == true) {
15940 throw new IllegalArgumentException("File descriptors passed in Intent");
15943 synchronized(this) {
15944 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15948 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15949 synchronized(this) {
15950 if (!(token instanceof ServiceRecord)) {
15951 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15952 throw new IllegalArgumentException("Invalid service token");
15954 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15958 // =========================================================
15959 // BACKUP AND RESTORE
15960 // =========================================================
15962 // Cause the target app to be launched if necessary and its backup agent
15963 // instantiated. The backup agent will invoke backupAgentCreated() on the
15964 // activity manager to announce its creation.
15965 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15966 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
15967 "bindBackupAgent: app=" + app + " mode=" + backupMode);
15968 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15970 synchronized(this) {
15971 // !!! TODO: currently no check here that we're already bound
15972 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15973 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15974 synchronized (stats) {
15975 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15978 // Backup agent is now in use, its package can't be stopped.
15980 AppGlobals.getPackageManager().setPackageStoppedState(
15981 app.packageName, false, UserHandle.getUserId(app.uid));
15982 } catch (RemoteException e) {
15983 } catch (IllegalArgumentException e) {
15984 Slog.w(TAG, "Failed trying to unstop package "
15985 + app.packageName + ": " + e);
15988 BackupRecord r = new BackupRecord(ss, app, backupMode);
15989 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15990 ? new ComponentName(app.packageName, app.backupAgentName)
15991 : new ComponentName("android", "FullBackupAgent");
15992 // startProcessLocked() returns existing proc's record if it's already running
15993 ProcessRecord proc = startProcessLocked(app.processName, app,
15994 false, 0, "backup", hostingName, false, false, false);
15995 if (proc == null) {
15996 Slog.e(TAG, "Unable to start backup agent process " + r);
16002 mBackupAppName = app.packageName;
16004 // Try not to kill the process during backup
16005 updateOomAdjLocked(proc);
16007 // If the process is already attached, schedule the creation of the backup agent now.
16008 // If it is not yet live, this will be done when it attaches to the framework.
16009 if (proc.thread != null) {
16010 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16012 proc.thread.scheduleCreateBackupAgent(app,
16013 compatibilityInfoForPackageLocked(app), backupMode);
16014 } catch (RemoteException e) {
16015 // Will time out on the backup manager side
16018 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16020 // Invariants: at this point, the target app process exists and the application
16021 // is either already running or in the process of coming up. mBackupTarget and
16022 // mBackupAppName describe the app, so that when it binds back to the AM we
16023 // know that it's scheduled for a backup-agent operation.
16030 public void clearPendingBackup() {
16031 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16032 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16034 synchronized (this) {
16035 mBackupTarget = null;
16036 mBackupAppName = null;
16040 // A backup agent has just come up
16041 public void backupAgentCreated(String agentPackageName, IBinder agent) {
16042 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16045 synchronized(this) {
16046 if (!agentPackageName.equals(mBackupAppName)) {
16047 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16052 long oldIdent = Binder.clearCallingIdentity();
16054 IBackupManager bm = IBackupManager.Stub.asInterface(
16055 ServiceManager.getService(Context.BACKUP_SERVICE));
16056 bm.agentConnected(agentPackageName, agent);
16057 } catch (RemoteException e) {
16058 // can't happen; the backup manager service is local
16059 } catch (Exception e) {
16060 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16061 e.printStackTrace();
16063 Binder.restoreCallingIdentity(oldIdent);
16067 // done with this agent
16068 public void unbindBackupAgent(ApplicationInfo appInfo) {
16069 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16070 if (appInfo == null) {
16071 Slog.w(TAG, "unbind backup agent for null app");
16075 synchronized(this) {
16077 if (mBackupAppName == null) {
16078 Slog.w(TAG, "Unbinding backup agent with no active backup");
16082 if (!mBackupAppName.equals(appInfo.packageName)) {
16083 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16087 // Not backing this app up any more; reset its OOM adjustment
16088 final ProcessRecord proc = mBackupTarget.app;
16089 updateOomAdjLocked(proc);
16091 // If the app crashed during backup, 'thread' will be null here
16092 if (proc.thread != null) {
16094 proc.thread.scheduleDestroyBackupAgent(appInfo,
16095 compatibilityInfoForPackageLocked(appInfo));
16096 } catch (Exception e) {
16097 Slog.e(TAG, "Exception when unbinding backup agent:");
16098 e.printStackTrace();
16102 mBackupTarget = null;
16103 mBackupAppName = null;
16107 // =========================================================
16109 // =========================================================
16111 boolean isPendingBroadcastProcessLocked(int pid) {
16112 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16113 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16116 void skipPendingBroadcastLocked(int pid) {
16117 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16118 for (BroadcastQueue queue : mBroadcastQueues) {
16119 queue.skipPendingBroadcastLocked(pid);
16123 // The app just attached; send any pending broadcasts that it should receive
16124 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16125 boolean didSomething = false;
16126 for (BroadcastQueue queue : mBroadcastQueues) {
16127 didSomething |= queue.sendPendingBroadcastsLocked(app);
16129 return didSomething;
16132 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16133 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16134 enforceNotIsolatedCaller("registerReceiver");
16135 ArrayList<Intent> stickyIntents = null;
16136 ProcessRecord callerApp = null;
16139 synchronized(this) {
16140 if (caller != null) {
16141 callerApp = getRecordForAppLocked(caller);
16142 if (callerApp == null) {
16143 throw new SecurityException(
16144 "Unable to find app for caller " + caller
16145 + " (pid=" + Binder.getCallingPid()
16146 + ") when registering receiver " + receiver);
16148 if (callerApp.info.uid != Process.SYSTEM_UID &&
16149 !callerApp.pkgList.containsKey(callerPackage) &&
16150 !"android".equals(callerPackage)) {
16151 throw new SecurityException("Given caller package " + callerPackage
16152 + " is not running in process " + callerApp);
16154 callingUid = callerApp.info.uid;
16155 callingPid = callerApp.pid;
16157 callerPackage = null;
16158 callingUid = Binder.getCallingUid();
16159 callingPid = Binder.getCallingPid();
16162 userId = handleIncomingUser(callingPid, callingUid, userId,
16163 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16165 Iterator<String> actions = filter.actionsIterator();
16166 if (actions == null) {
16167 ArrayList<String> noAction = new ArrayList<String>(1);
16168 noAction.add(null);
16169 actions = noAction.iterator();
16172 // Collect stickies of users
16173 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16174 while (actions.hasNext()) {
16175 String action = actions.next();
16176 for (int id : userIds) {
16177 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16178 if (stickies != null) {
16179 ArrayList<Intent> intents = stickies.get(action);
16180 if (intents != null) {
16181 if (stickyIntents == null) {
16182 stickyIntents = new ArrayList<Intent>();
16184 stickyIntents.addAll(intents);
16191 ArrayList<Intent> allSticky = null;
16192 if (stickyIntents != null) {
16193 final ContentResolver resolver = mContext.getContentResolver();
16194 // Look for any matching sticky broadcasts...
16195 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16196 Intent intent = stickyIntents.get(i);
16197 // If intent has scheme "content", it will need to acccess
16198 // provider that needs to lock mProviderMap in ActivityThread
16199 // and also it may need to wait application response, so we
16200 // cannot lock ActivityManagerService here.
16201 if (filter.match(resolver, intent, true, TAG) >= 0) {
16202 if (allSticky == null) {
16203 allSticky = new ArrayList<Intent>();
16205 allSticky.add(intent);
16210 // The first sticky in the list is returned directly back to the client.
16211 Intent sticky = allSticky != null ? allSticky.get(0) : null;
16212 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16213 if (receiver == null) {
16217 synchronized (this) {
16218 if (callerApp != null && (callerApp.thread == null
16219 || callerApp.thread.asBinder() != caller.asBinder())) {
16220 // Original caller already died
16223 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16225 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16227 if (rl.app != null) {
16228 rl.app.receivers.add(rl);
16231 receiver.asBinder().linkToDeath(rl, 0);
16232 } catch (RemoteException e) {
16235 rl.linkedToDeath = true;
16237 mRegisteredReceivers.put(receiver.asBinder(), rl);
16238 } else if (rl.uid != callingUid) {
16239 throw new IllegalArgumentException(
16240 "Receiver requested to register for uid " + callingUid
16241 + " was previously registered for uid " + rl.uid);
16242 } else if (rl.pid != callingPid) {
16243 throw new IllegalArgumentException(
16244 "Receiver requested to register for pid " + callingPid
16245 + " was previously registered for pid " + rl.pid);
16246 } else if (rl.userId != userId) {
16247 throw new IllegalArgumentException(
16248 "Receiver requested to register for user " + userId
16249 + " was previously registered for user " + rl.userId);
16251 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16252 permission, callingUid, userId);
16254 if (!bf.debugCheck()) {
16255 Slog.w(TAG, "==> For Dynamic broadcast");
16257 mReceiverResolver.addFilter(bf);
16259 // Enqueue broadcasts for all existing stickies that match
16261 if (allSticky != null) {
16262 ArrayList receivers = new ArrayList();
16265 final int stickyCount = allSticky.size();
16266 for (int i = 0; i < stickyCount; i++) {
16267 Intent intent = allSticky.get(i);
16268 BroadcastQueue queue = broadcastQueueForIntent(intent);
16269 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16270 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16271 null, 0, null, null, false, true, true, -1);
16272 queue.enqueueParallelBroadcastLocked(r);
16273 queue.scheduleBroadcastsLocked();
16281 public void unregisterReceiver(IIntentReceiver receiver) {
16282 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16284 final long origId = Binder.clearCallingIdentity();
16286 boolean doTrim = false;
16288 synchronized(this) {
16289 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16291 final BroadcastRecord r = rl.curBroadcast;
16292 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16293 final boolean doNext = r.queue.finishReceiverLocked(
16294 r, r.resultCode, r.resultData, r.resultExtras,
16295 r.resultAbort, false);
16298 r.queue.processNextBroadcast(false);
16302 if (rl.app != null) {
16303 rl.app.receivers.remove(rl);
16305 removeReceiverLocked(rl);
16306 if (rl.linkedToDeath) {
16307 rl.linkedToDeath = false;
16308 rl.receiver.asBinder().unlinkToDeath(rl, 0);
16313 // If we actually concluded any broadcasts, we might now be able
16314 // to trim the recipients' apps from our working set
16316 trimApplications();
16321 Binder.restoreCallingIdentity(origId);
16325 void removeReceiverLocked(ReceiverList rl) {
16326 mRegisteredReceivers.remove(rl.receiver.asBinder());
16327 for (int i = rl.size() - 1; i >= 0; i--) {
16328 mReceiverResolver.removeFilter(rl.get(i));
16332 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16333 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16334 ProcessRecord r = mLruProcesses.get(i);
16335 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16337 r.thread.dispatchPackageBroadcast(cmd, packages);
16338 } catch (RemoteException ex) {
16344 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16345 int callingUid, int[] users) {
16346 List<ResolveInfo> receivers = null;
16348 HashSet<ComponentName> singleUserReceivers = null;
16349 boolean scannedFirstReceivers = false;
16350 for (int user : users) {
16351 // Skip users that have Shell restrictions
16352 if (callingUid == Process.SHELL_UID
16353 && getUserManagerLocked().hasUserRestriction(
16354 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16357 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16358 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16359 if (user != UserHandle.USER_OWNER && newReceivers != null) {
16360 // If this is not the primary user, we need to check for
16361 // any receivers that should be filtered out.
16362 for (int i=0; i<newReceivers.size(); i++) {
16363 ResolveInfo ri = newReceivers.get(i);
16364 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16365 newReceivers.remove(i);
16370 if (newReceivers != null && newReceivers.size() == 0) {
16371 newReceivers = null;
16373 if (receivers == null) {
16374 receivers = newReceivers;
16375 } else if (newReceivers != null) {
16376 // We need to concatenate the additional receivers
16377 // found with what we have do far. This would be easy,
16378 // but we also need to de-dup any receivers that are
16380 if (!scannedFirstReceivers) {
16381 // Collect any single user receivers we had already retrieved.
16382 scannedFirstReceivers = true;
16383 for (int i=0; i<receivers.size(); i++) {
16384 ResolveInfo ri = receivers.get(i);
16385 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16386 ComponentName cn = new ComponentName(
16387 ri.activityInfo.packageName, ri.activityInfo.name);
16388 if (singleUserReceivers == null) {
16389 singleUserReceivers = new HashSet<ComponentName>();
16391 singleUserReceivers.add(cn);
16395 // Add the new results to the existing results, tracking
16396 // and de-dupping single user receivers.
16397 for (int i=0; i<newReceivers.size(); i++) {
16398 ResolveInfo ri = newReceivers.get(i);
16399 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16400 ComponentName cn = new ComponentName(
16401 ri.activityInfo.packageName, ri.activityInfo.name);
16402 if (singleUserReceivers == null) {
16403 singleUserReceivers = new HashSet<ComponentName>();
16405 if (!singleUserReceivers.contains(cn)) {
16406 singleUserReceivers.add(cn);
16415 } catch (RemoteException ex) {
16416 // pm is in same process, this will never happen.
16421 private final int broadcastIntentLocked(ProcessRecord callerApp,
16422 String callerPackage, Intent intent, String resolvedType,
16423 IIntentReceiver resultTo, int resultCode, String resultData,
16424 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16425 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16426 intent = new Intent(intent);
16428 // By default broadcasts do not go to stopped apps.
16429 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16431 // If we have not finished booting, don't allow this to launch new processes.
16432 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16433 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16436 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16437 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16438 + " ordered=" + ordered + " userid=" + userId);
16439 if ((resultTo != null) && !ordered) {
16440 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16443 userId = handleIncomingUser(callingPid, callingUid, userId,
16444 true, ALLOW_NON_FULL, "broadcast", callerPackage);
16446 // Make sure that the user who is receiving this broadcast is running.
16447 // If not, we will just skip it. Make an exception for shutdown broadcasts
16448 // and upgrade steps.
16450 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16451 if ((callingUid != Process.SYSTEM_UID
16452 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16453 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16454 Slog.w(TAG, "Skipping broadcast of " + intent
16455 + ": user " + userId + " is stopped");
16456 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16460 BroadcastOptions brOptions = null;
16461 if (options != null) {
16462 brOptions = new BroadcastOptions(options);
16463 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16464 // See if the caller is allowed to do this. Note we are checking against
16465 // the actual real caller (not whoever provided the operation as say a
16466 // PendingIntent), because that who is actually supplied the arguments.
16467 if (checkComponentPermission(
16468 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16469 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16470 != PackageManager.PERMISSION_GRANTED) {
16471 String msg = "Permission Denial: " + intent.getAction()
16472 + " broadcast from " + callerPackage + " (pid=" + callingPid
16473 + ", uid=" + callingUid + ")"
16475 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16477 throw new SecurityException(msg);
16483 * Prevent non-system code (defined here to be non-persistent
16484 * processes) from sending protected broadcasts.
16486 int callingAppId = UserHandle.getAppId(callingUid);
16487 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16488 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16489 || callingAppId == Process.NFC_UID || callingUid == 0) {
16491 } else if (callerApp == null || !callerApp.persistent) {
16493 if (AppGlobals.getPackageManager().isProtectedBroadcast(
16494 intent.getAction())) {
16495 String msg = "Permission Denial: not allowed to send broadcast "
16496 + intent.getAction() + " from pid="
16497 + callingPid + ", uid=" + callingUid;
16499 throw new SecurityException(msg);
16500 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16501 // Special case for compatibility: we don't want apps to send this,
16502 // but historically it has not been protected and apps may be using it
16503 // to poke their own app widget. So, instead of making it protected,
16504 // just limit it to the caller.
16505 if (callerApp == null) {
16506 String msg = "Permission Denial: not allowed to send broadcast "
16507 + intent.getAction() + " from unknown caller.";
16509 throw new SecurityException(msg);
16510 } else if (intent.getComponent() != null) {
16511 // They are good enough to send to an explicit component... verify
16512 // it is being sent to the calling app.
16513 if (!intent.getComponent().getPackageName().equals(
16514 callerApp.info.packageName)) {
16515 String msg = "Permission Denial: not allowed to send broadcast "
16516 + intent.getAction() + " to "
16517 + intent.getComponent().getPackageName() + " from "
16518 + callerApp.info.packageName;
16520 throw new SecurityException(msg);
16523 // Limit broadcast to their own package.
16524 intent.setPackage(callerApp.info.packageName);
16527 } catch (RemoteException e) {
16528 Slog.w(TAG, "Remote exception", e);
16529 return ActivityManager.BROADCAST_SUCCESS;
16533 final String action = intent.getAction();
16534 if (action != null) {
16536 case Intent.ACTION_UID_REMOVED:
16537 case Intent.ACTION_PACKAGE_REMOVED:
16538 case Intent.ACTION_PACKAGE_CHANGED:
16539 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16540 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16541 // Handle special intents: if this broadcast is from the package
16542 // manager about a package being removed, we need to remove all of
16543 // its activities from the history stack.
16544 if (checkComponentPermission(
16545 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16546 callingPid, callingUid, -1, true)
16547 != PackageManager.PERMISSION_GRANTED) {
16548 String msg = "Permission Denial: " + intent.getAction()
16549 + " broadcast from " + callerPackage + " (pid=" + callingPid
16550 + ", uid=" + callingUid + ")"
16552 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16554 throw new SecurityException(msg);
16557 case Intent.ACTION_UID_REMOVED:
16558 final Bundle intentExtras = intent.getExtras();
16559 final int uid = intentExtras != null
16560 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16562 mBatteryStatsService.removeUid(uid);
16563 mAppOpsService.uidRemoved(uid);
16566 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16567 // If resources are unavailable just force stop all those packages
16568 // and flush the attribute cache as well.
16570 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16571 if (list != null && list.length > 0) {
16572 for (int i = 0; i < list.length; i++) {
16573 forceStopPackageLocked(list[i], -1, false, true, true,
16574 false, false, userId, "storage unmount");
16576 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16577 sendPackageBroadcastLocked(
16578 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16582 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16583 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16585 case Intent.ACTION_PACKAGE_REMOVED:
16586 case Intent.ACTION_PACKAGE_CHANGED:
16587 Uri data = intent.getData();
16589 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16590 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16591 boolean fullUninstall = removed &&
16592 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16593 final boolean killProcess =
16594 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16596 forceStopPackageLocked(ssp, UserHandle.getAppId(
16597 intent.getIntExtra(Intent.EXTRA_UID, -1)),
16598 false, true, true, false, fullUninstall, userId,
16599 removed ? "pkg removed" : "pkg changed");
16602 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16603 new String[] {ssp}, userId);
16604 if (fullUninstall) {
16605 mAppOpsService.packageRemoved(
16606 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16608 // Remove all permissions granted from/to this package
16609 removeUriPermissionsForPackageLocked(ssp, userId, true);
16611 removeTasksByPackageNameLocked(ssp, userId);
16612 mBatteryStatsService.notePackageUninstalled(ssp);
16615 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16616 intent.getStringArrayExtra(
16617 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16623 case Intent.ACTION_PACKAGE_ADDED:
16624 // Special case for adding a package: by default turn on compatibility mode.
16625 Uri data = intent.getData();
16627 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16628 final boolean replacing =
16629 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16630 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16633 ApplicationInfo ai = AppGlobals.getPackageManager().
16634 getApplicationInfo(ssp, 0, 0);
16635 mBatteryStatsService.notePackageInstalled(ssp,
16636 ai != null ? ai.versionCode : 0);
16637 } catch (RemoteException e) {
16641 case Intent.ACTION_TIMEZONE_CHANGED:
16642 // If this is the time zone changed action, queue up a message that will reset
16643 // the timezone of all currently running processes. This message will get
16644 // queued up before the broadcast happens.
16645 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16647 case Intent.ACTION_TIME_CHANGED:
16648 // If the user set the time, let all running processes know.
16649 final int is24Hour =
16650 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16652 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16653 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16654 synchronized (stats) {
16655 stats.noteCurrentTimeChangedLocked();
16658 case Intent.ACTION_CLEAR_DNS_CACHE:
16659 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16661 case Proxy.PROXY_CHANGE_ACTION:
16662 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16663 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16668 // Add to the sticky list if requested.
16670 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16671 callingPid, callingUid)
16672 != PackageManager.PERMISSION_GRANTED) {
16673 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16674 + callingPid + ", uid=" + callingUid
16675 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16677 throw new SecurityException(msg);
16679 if (requiredPermissions != null && requiredPermissions.length > 0) {
16680 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16681 + " and enforce permissions " + Arrays.toString(requiredPermissions));
16682 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16684 if (intent.getComponent() != null) {
16685 throw new SecurityException(
16686 "Sticky broadcasts can't target a specific component");
16688 // We use userId directly here, since the "all" target is maintained
16689 // as a separate set of sticky broadcasts.
16690 if (userId != UserHandle.USER_ALL) {
16691 // But first, if this is not a broadcast to all users, then
16692 // make sure it doesn't conflict with an existing broadcast to
16694 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16695 UserHandle.USER_ALL);
16696 if (stickies != null) {
16697 ArrayList<Intent> list = stickies.get(intent.getAction());
16698 if (list != null) {
16699 int N = list.size();
16701 for (i=0; i<N; i++) {
16702 if (intent.filterEquals(list.get(i))) {
16703 throw new IllegalArgumentException(
16704 "Sticky broadcast " + intent + " for user "
16705 + userId + " conflicts with existing global broadcast");
16711 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16712 if (stickies == null) {
16713 stickies = new ArrayMap<>();
16714 mStickyBroadcasts.put(userId, stickies);
16716 ArrayList<Intent> list = stickies.get(intent.getAction());
16717 if (list == null) {
16718 list = new ArrayList<>();
16719 stickies.put(intent.getAction(), list);
16721 final int stickiesCount = list.size();
16723 for (i = 0; i < stickiesCount; i++) {
16724 if (intent.filterEquals(list.get(i))) {
16725 // This sticky already exists, replace it.
16726 list.set(i, new Intent(intent));
16730 if (i >= stickiesCount) {
16731 list.add(new Intent(intent));
16736 if (userId == UserHandle.USER_ALL) {
16737 // Caller wants broadcast to go to all started users.
16738 users = mStartedUserArray;
16740 // Caller wants broadcast to go to one specific user.
16741 users = new int[] {userId};
16744 // Figure out who all will receive this broadcast.
16745 List receivers = null;
16746 List<BroadcastFilter> registeredReceivers = null;
16747 // Need to resolve the intent to interested receivers...
16748 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16750 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16752 if (intent.getComponent() == null) {
16753 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16754 // Query one target user at a time, excluding shell-restricted users
16755 UserManagerService ums = getUserManagerLocked();
16756 for (int i = 0; i < users.length; i++) {
16757 if (ums.hasUserRestriction(
16758 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16761 List<BroadcastFilter> registeredReceiversForUser =
16762 mReceiverResolver.queryIntent(intent,
16763 resolvedType, false, users[i]);
16764 if (registeredReceivers == null) {
16765 registeredReceivers = registeredReceiversForUser;
16766 } else if (registeredReceiversForUser != null) {
16767 registeredReceivers.addAll(registeredReceiversForUser);
16771 registeredReceivers = mReceiverResolver.queryIntent(intent,
16772 resolvedType, false, userId);
16776 final boolean replacePending =
16777 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16779 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16780 + " replacePending=" + replacePending);
16782 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16783 if (!ordered && NR > 0) {
16784 // If we are not serializing this broadcast, then send the
16785 // registered receivers separately so they don't wait for the
16786 // components to be launched.
16787 final BroadcastQueue queue = broadcastQueueForIntent(intent);
16788 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16789 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16790 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16791 resultExtras, ordered, sticky, false, userId);
16792 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16793 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16795 queue.enqueueParallelBroadcastLocked(r);
16796 queue.scheduleBroadcastsLocked();
16798 registeredReceivers = null;
16802 // Merge into one list.
16804 if (receivers != null) {
16805 // A special case for PACKAGE_ADDED: do not allow the package
16806 // being added to see this broadcast. This prevents them from
16807 // using this as a back door to get run as soon as they are
16808 // installed. Maybe in the future we want to have a special install
16809 // broadcast or such for apps, but we'd like to deliberately make
16811 String skipPackages[] = null;
16812 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16813 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16814 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16815 Uri data = intent.getData();
16816 if (data != null) {
16817 String pkgName = data.getSchemeSpecificPart();
16818 if (pkgName != null) {
16819 skipPackages = new String[] { pkgName };
16822 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16823 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16825 if (skipPackages != null && (skipPackages.length > 0)) {
16826 for (String skipPackage : skipPackages) {
16827 if (skipPackage != null) {
16828 int NT = receivers.size();
16829 for (int it=0; it<NT; it++) {
16830 ResolveInfo curt = (ResolveInfo)receivers.get(it);
16831 if (curt.activityInfo.packageName.equals(skipPackage)) {
16832 receivers.remove(it);
16841 int NT = receivers != null ? receivers.size() : 0;
16843 ResolveInfo curt = null;
16844 BroadcastFilter curr = null;
16845 while (it < NT && ir < NR) {
16846 if (curt == null) {
16847 curt = (ResolveInfo)receivers.get(it);
16849 if (curr == null) {
16850 curr = registeredReceivers.get(ir);
16852 if (curr.getPriority() >= curt.priority) {
16853 // Insert this broadcast record into the final list.
16854 receivers.add(it, curr);
16860 // Skip to the next ResolveInfo in the final list.
16867 if (receivers == null) {
16868 receivers = new ArrayList();
16870 receivers.add(registeredReceivers.get(ir));
16874 if ((receivers != null && receivers.size() > 0)
16875 || resultTo != null) {
16876 BroadcastQueue queue = broadcastQueueForIntent(intent);
16877 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16878 callerPackage, callingPid, callingUid, resolvedType,
16879 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16880 resultData, resultExtras, ordered, sticky, false, userId);
16882 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16883 + ": prev had " + queue.mOrderedBroadcasts.size());
16884 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16885 "Enqueueing broadcast " + r.intent.getAction());
16887 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16889 queue.enqueueOrderedBroadcastLocked(r);
16890 queue.scheduleBroadcastsLocked();
16894 return ActivityManager.BROADCAST_SUCCESS;
16897 final Intent verifyBroadcastLocked(Intent intent) {
16898 // Refuse possible leaked file descriptors
16899 if (intent != null && intent.hasFileDescriptors() == true) {
16900 throw new IllegalArgumentException("File descriptors passed in Intent");
16903 int flags = intent.getFlags();
16905 if (!mProcessesReady) {
16906 // if the caller really truly claims to know what they're doing, go
16907 // ahead and allow the broadcast without launching any receivers
16908 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16909 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16910 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16911 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16912 + " before boot completion");
16913 throw new IllegalStateException("Cannot broadcast before boot completed");
16917 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16918 throw new IllegalArgumentException(
16919 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16925 public final int broadcastIntent(IApplicationThread caller,
16926 Intent intent, String resolvedType, IIntentReceiver resultTo,
16927 int resultCode, String resultData, Bundle resultExtras,
16928 String[] requiredPermissions, int appOp, Bundle options,
16929 boolean serialized, boolean sticky, int userId) {
16930 enforceNotIsolatedCaller("broadcastIntent");
16931 synchronized(this) {
16932 intent = verifyBroadcastLocked(intent);
16934 final ProcessRecord callerApp = getRecordForAppLocked(caller);
16935 final int callingPid = Binder.getCallingPid();
16936 final int callingUid = Binder.getCallingUid();
16937 final long origId = Binder.clearCallingIdentity();
16938 int res = broadcastIntentLocked(callerApp,
16939 callerApp != null ? callerApp.info.packageName : null,
16940 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16941 requiredPermissions, appOp, null, serialized, sticky,
16942 callingPid, callingUid, userId);
16943 Binder.restoreCallingIdentity(origId);
16949 int broadcastIntentInPackage(String packageName, int uid,
16950 Intent intent, String resolvedType, IIntentReceiver resultTo,
16951 int resultCode, String resultData, Bundle resultExtras,
16952 String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16954 synchronized(this) {
16955 intent = verifyBroadcastLocked(intent);
16957 final long origId = Binder.clearCallingIdentity();
16958 String[] requiredPermissions = requiredPermission == null ? null
16959 : new String[] {requiredPermission};
16960 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16961 resultTo, resultCode, resultData, resultExtras,
16962 requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
16963 sticky, -1, uid, userId);
16964 Binder.restoreCallingIdentity(origId);
16969 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16970 // Refuse possible leaked file descriptors
16971 if (intent != null && intent.hasFileDescriptors() == true) {
16972 throw new IllegalArgumentException("File descriptors passed in Intent");
16975 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16976 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16978 synchronized(this) {
16979 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16980 != PackageManager.PERMISSION_GRANTED) {
16981 String msg = "Permission Denial: unbroadcastIntent() from pid="
16982 + Binder.getCallingPid()
16983 + ", uid=" + Binder.getCallingUid()
16984 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16986 throw new SecurityException(msg);
16988 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16989 if (stickies != null) {
16990 ArrayList<Intent> list = stickies.get(intent.getAction());
16991 if (list != null) {
16992 int N = list.size();
16994 for (i=0; i<N; i++) {
16995 if (intent.filterEquals(list.get(i))) {
17000 if (list.size() <= 0) {
17001 stickies.remove(intent.getAction());
17004 if (stickies.size() <= 0) {
17005 mStickyBroadcasts.remove(userId);
17011 void backgroundServicesFinishedLocked(int userId) {
17012 for (BroadcastQueue queue : mBroadcastQueues) {
17013 queue.backgroundServicesFinishedLocked(userId);
17017 public void finishReceiver(IBinder who, int resultCode, String resultData,
17018 Bundle resultExtras, boolean resultAbort, int flags) {
17019 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17021 // Refuse possible leaked file descriptors
17022 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17023 throw new IllegalArgumentException("File descriptors passed in Bundle");
17026 final long origId = Binder.clearCallingIdentity();
17028 boolean doNext = false;
17031 synchronized(this) {
17032 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17033 ? mFgBroadcastQueue : mBgBroadcastQueue;
17034 r = queue.getMatchingOrderedReceiver(who);
17036 doNext = r.queue.finishReceiverLocked(r, resultCode,
17037 resultData, resultExtras, resultAbort, true);
17042 r.queue.processNextBroadcast(false);
17044 trimApplications();
17046 Binder.restoreCallingIdentity(origId);
17050 // =========================================================
17052 // =========================================================
17054 public boolean startInstrumentation(ComponentName className,
17055 String profileFile, int flags, Bundle arguments,
17056 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17057 int userId, String abiOverride) {
17058 enforceNotIsolatedCaller("startInstrumentation");
17059 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17060 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17061 // Refuse possible leaked file descriptors
17062 if (arguments != null && arguments.hasFileDescriptors()) {
17063 throw new IllegalArgumentException("File descriptors passed in Bundle");
17066 synchronized(this) {
17067 InstrumentationInfo ii = null;
17068 ApplicationInfo ai = null;
17070 ii = mContext.getPackageManager().getInstrumentationInfo(
17071 className, STOCK_PM_FLAGS);
17072 ai = AppGlobals.getPackageManager().getApplicationInfo(
17073 ii.targetPackage, STOCK_PM_FLAGS, userId);
17074 } catch (PackageManager.NameNotFoundException e) {
17075 } catch (RemoteException e) {
17078 reportStartInstrumentationFailure(watcher, className,
17079 "Unable to find instrumentation info for: " + className);
17083 reportStartInstrumentationFailure(watcher, className,
17084 "Unable to find instrumentation target package: " + ii.targetPackage);
17088 int match = mContext.getPackageManager().checkSignatures(
17089 ii.targetPackage, ii.packageName);
17090 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17091 String msg = "Permission Denial: starting instrumentation "
17092 + className + " from pid="
17093 + Binder.getCallingPid()
17094 + ", uid=" + Binder.getCallingPid()
17095 + " not allowed because package " + ii.packageName
17096 + " does not have a signature matching the target "
17097 + ii.targetPackage;
17098 reportStartInstrumentationFailure(watcher, className, msg);
17099 throw new SecurityException(msg);
17102 final long origId = Binder.clearCallingIdentity();
17103 // Instrumentation can kill and relaunch even persistent processes
17104 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17106 ProcessRecord app = addAppLocked(ai, false, abiOverride);
17107 app.instrumentationClass = className;
17108 app.instrumentationInfo = ai;
17109 app.instrumentationProfileFile = profileFile;
17110 app.instrumentationArguments = arguments;
17111 app.instrumentationWatcher = watcher;
17112 app.instrumentationUiAutomationConnection = uiAutomationConnection;
17113 app.instrumentationResultClass = className;
17114 Binder.restoreCallingIdentity(origId);
17121 * Report errors that occur while attempting to start Instrumentation. Always writes the
17122 * error to the logs, but if somebody is watching, send the report there too. This enables
17123 * the "am" command to report errors with more information.
17125 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
17126 * @param cn The component name of the instrumentation.
17127 * @param report The error report.
17129 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17130 ComponentName cn, String report) {
17131 Slog.w(TAG, report);
17133 if (watcher != null) {
17134 Bundle results = new Bundle();
17135 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17136 results.putString("Error", report);
17137 watcher.instrumentationStatus(cn, -1, results);
17139 } catch (RemoteException e) {
17144 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17145 if (app.instrumentationWatcher != null) {
17147 // NOTE: IInstrumentationWatcher *must* be oneway here
17148 app.instrumentationWatcher.instrumentationFinished(
17149 app.instrumentationClass,
17152 } catch (RemoteException e) {
17156 // Can't call out of the system process with a lock held, so post a message.
17157 if (app.instrumentationUiAutomationConnection != null) {
17158 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17159 app.instrumentationUiAutomationConnection).sendToTarget();
17162 app.instrumentationWatcher = null;
17163 app.instrumentationUiAutomationConnection = null;
17164 app.instrumentationClass = null;
17165 app.instrumentationInfo = null;
17166 app.instrumentationProfileFile = null;
17167 app.instrumentationArguments = null;
17169 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17173 public void finishInstrumentation(IApplicationThread target,
17174 int resultCode, Bundle results) {
17175 int userId = UserHandle.getCallingUserId();
17176 // Refuse possible leaked file descriptors
17177 if (results != null && results.hasFileDescriptors()) {
17178 throw new IllegalArgumentException("File descriptors passed in Intent");
17181 synchronized(this) {
17182 ProcessRecord app = getRecordForAppLocked(target);
17184 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17187 final long origId = Binder.clearCallingIdentity();
17188 finishInstrumentationLocked(app, resultCode, results);
17189 Binder.restoreCallingIdentity(origId);
17193 // =========================================================
17195 // =========================================================
17197 public ConfigurationInfo getDeviceConfigurationInfo() {
17198 ConfigurationInfo config = new ConfigurationInfo();
17199 synchronized (this) {
17200 config.reqTouchScreen = mConfiguration.touchscreen;
17201 config.reqKeyboardType = mConfiguration.keyboard;
17202 config.reqNavigation = mConfiguration.navigation;
17203 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17204 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17205 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17207 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17208 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17209 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17211 config.reqGlEsVersion = GL_ES_VERSION;
17216 ActivityStack getFocusedStack() {
17217 return mStackSupervisor.getFocusedStack();
17221 public int getFocusedStackId() throws RemoteException {
17222 ActivityStack focusedStack = getFocusedStack();
17223 if (focusedStack != null) {
17224 return focusedStack.getStackId();
17229 public Configuration getConfiguration() {
17231 synchronized(this) {
17232 ci = new Configuration(mConfiguration);
17233 ci.userSetLocale = false;
17238 public void updatePersistentConfiguration(Configuration values) {
17239 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17240 "updateConfiguration()");
17241 enforceWriteSettingsPermission("updateConfiguration()");
17242 if (values == null) {
17243 throw new NullPointerException("Configuration must not be null");
17246 synchronized(this) {
17247 final long origId = Binder.clearCallingIdentity();
17248 updateConfigurationLocked(values, null, true, false);
17249 Binder.restoreCallingIdentity(origId);
17253 private void enforceWriteSettingsPermission(String func) {
17254 int uid = Binder.getCallingUid();
17255 if (uid == Process.ROOT_UID) {
17259 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17260 Settings.getPackageNameForUid(mContext, uid), false)) {
17264 String msg = "Permission Denial: " + func + " from pid="
17265 + Binder.getCallingPid()
17267 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17269 throw new SecurityException(msg);
17272 public void updateConfiguration(Configuration values) {
17273 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17274 "updateConfiguration()");
17276 synchronized(this) {
17277 if (values == null && mWindowManager != null) {
17278 // sentinel: fetch the current configuration from the window manager
17279 values = mWindowManager.computeNewConfiguration();
17282 if (mWindowManager != null) {
17283 mProcessList.applyDisplaySize(mWindowManager);
17286 final long origId = Binder.clearCallingIdentity();
17287 if (values != null) {
17288 Settings.System.clearConfiguration(values);
17290 updateConfigurationLocked(values, null, false, false);
17291 Binder.restoreCallingIdentity(origId);
17296 * Do either or both things: (1) change the current configuration, and (2)
17297 * make sure the given activity is running with the (now) current
17298 * configuration. Returns true if the activity has been left running, or
17299 * false if <var>starting</var> is being destroyed to match the new
17301 * @param persistent TODO
17303 boolean updateConfigurationLocked(Configuration values,
17304 ActivityRecord starting, boolean persistent, boolean initLocale) {
17307 if (values != null) {
17308 Configuration newConfig = new Configuration(mConfiguration);
17309 changes = newConfig.updateFrom(values);
17310 if (changes != 0) {
17311 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17312 "Updating configuration to: " + values);
17314 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17316 if (!initLocale && values.locale != null && values.userSetLocale) {
17317 final String languageTag = values.locale.toLanguageTag();
17318 SystemProperties.set("persist.sys.locale", languageTag);
17319 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17323 mConfigurationSeq++;
17324 if (mConfigurationSeq <= 0) {
17325 mConfigurationSeq = 1;
17327 newConfig.seq = mConfigurationSeq;
17328 mConfiguration = newConfig;
17329 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17330 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17331 //mUsageStatsService.noteStartConfig(newConfig);
17333 final Configuration configCopy = new Configuration(mConfiguration);
17335 // TODO: If our config changes, should we auto dismiss any currently
17336 // showing dialogs?
17337 mShowDialogs = shouldShowDialogs(newConfig);
17339 AttributeCache ac = AttributeCache.instance();
17341 ac.updateConfiguration(configCopy);
17344 // Make sure all resources in our process are updated
17345 // right now, so that anyone who is going to retrieve
17346 // resource values after we return will be sure to get
17347 // the new ones. This is especially important during
17348 // boot, where the first config change needs to guarantee
17349 // all resources have that config before following boot
17350 // code is executed.
17351 mSystemThread.applyConfigurationToResources(configCopy);
17353 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17354 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17355 msg.obj = new Configuration(configCopy);
17356 mHandler.sendMessage(msg);
17359 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17360 ProcessRecord app = mLruProcesses.get(i);
17362 if (app.thread != null) {
17363 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17364 + app.processName + " new config " + mConfiguration);
17365 app.thread.scheduleConfigurationChanged(configCopy);
17367 } catch (Exception e) {
17370 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17371 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17372 | Intent.FLAG_RECEIVER_REPLACE_PENDING
17373 | Intent.FLAG_RECEIVER_FOREGROUND);
17374 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17375 null, AppOpsManager.OP_NONE, null, false, false,
17376 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17377 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17378 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17379 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17380 if (!mProcessesReady) {
17381 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17383 broadcastIntentLocked(null, null, intent,
17384 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17385 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17390 boolean kept = true;
17391 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17392 // mainStack is null during startup.
17393 if (mainStack != null) {
17394 if (changes != 0 && starting == null) {
17395 // If the configuration changed, and the caller is not already
17396 // in the process of starting an activity, then find the top
17397 // activity to check if its configuration needs to change.
17398 starting = mainStack.topRunningActivityLocked(null);
17401 if (starting != null) {
17402 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17403 // And we need to make sure at this point that all other activities
17404 // are made visible with the correct configuration.
17405 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17409 if (values != null && mWindowManager != null) {
17410 mWindowManager.setNewConfiguration(mConfiguration);
17417 * Decide based on the configuration whether we should shouw the ANR,
17418 * crash, etc dialogs. The idea is that if there is no affordnace to
17419 * press the on-screen buttons, we shouldn't show the dialog.
17421 * A thought: SystemUI might also want to get told about this, the Power
17422 * dialog / global actions also might want different behaviors.
17424 private static final boolean shouldShowDialogs(Configuration config) {
17425 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17426 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17427 && config.navigation == Configuration.NAVIGATION_NONAV);
17431 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17432 synchronized (this) {
17433 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17434 if (srec != null) {
17435 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17441 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17442 Intent resultData) {
17444 synchronized (this) {
17445 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17447 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17453 public int getLaunchedFromUid(IBinder activityToken) {
17454 ActivityRecord srec;
17455 synchronized (this) {
17456 srec = ActivityRecord.forTokenLocked(activityToken);
17458 if (srec == null) {
17461 return srec.launchedFromUid;
17464 public String getLaunchedFromPackage(IBinder activityToken) {
17465 ActivityRecord srec;
17466 synchronized (this) {
17467 srec = ActivityRecord.forTokenLocked(activityToken);
17469 if (srec == null) {
17472 return srec.launchedFromPackage;
17475 // =========================================================
17476 // LIFETIME MANAGEMENT
17477 // =========================================================
17479 // Returns which broadcast queue the app is the current [or imminent] receiver
17480 // on, or 'null' if the app is not an active broadcast recipient.
17481 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17482 BroadcastRecord r = app.curReceiver;
17487 // It's not the current receiver, but it might be starting up to become one
17488 synchronized (this) {
17489 for (BroadcastQueue queue : mBroadcastQueues) {
17490 r = queue.mPendingBroadcast;
17491 if (r != null && r.curApp == app) {
17492 // found it; report which queue it's in
17501 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17502 ComponentName targetComponent, String targetProcess) {
17503 if (!mTrackingAssociations) {
17506 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17507 = mAssociations.get(targetUid);
17508 if (components == null) {
17509 components = new ArrayMap<>();
17510 mAssociations.put(targetUid, components);
17512 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17513 if (sourceUids == null) {
17514 sourceUids = new SparseArray<>();
17515 components.put(targetComponent, sourceUids);
17517 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17518 if (sourceProcesses == null) {
17519 sourceProcesses = new ArrayMap<>();
17520 sourceUids.put(sourceUid, sourceProcesses);
17522 Association ass = sourceProcesses.get(sourceProcess);
17524 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17526 sourceProcesses.put(sourceProcess, ass);
17530 if (ass.mNesting == 1) {
17531 ass.mStartTime = SystemClock.uptimeMillis();
17536 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17537 ComponentName targetComponent) {
17538 if (!mTrackingAssociations) {
17541 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17542 = mAssociations.get(targetUid);
17543 if (components == null) {
17546 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17547 if (sourceUids == null) {
17550 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17551 if (sourceProcesses == null) {
17554 Association ass = sourceProcesses.get(sourceProcess);
17555 if (ass == null || ass.mNesting <= 0) {
17559 if (ass.mNesting == 0) {
17560 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17564 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17565 boolean doingAll, long now) {
17566 if (mAdjSeq == app.adjSeq) {
17567 // This adjustment has already been computed.
17568 return app.curRawAdj;
17571 if (app.thread == null) {
17572 app.adjSeq = mAdjSeq;
17573 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17574 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17575 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17578 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17579 app.adjSource = null;
17580 app.adjTarget = null;
17582 app.cached = false;
17584 final int activitiesSize = app.activities.size();
17586 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17587 // The max adjustment doesn't allow this app to be anything
17588 // below foreground, so it is not worth doing work for it.
17589 app.adjType = "fixed";
17590 app.adjSeq = mAdjSeq;
17591 app.curRawAdj = app.maxAdj;
17592 app.foregroundActivities = false;
17593 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17594 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17595 // System processes can do UI, and when they do we want to have
17596 // them trim their memory after the user leaves the UI. To
17597 // facilitate this, here we need to determine whether or not it
17598 // is currently showing UI.
17599 app.systemNoUi = true;
17600 if (app == TOP_APP) {
17601 app.systemNoUi = false;
17602 } else if (activitiesSize > 0) {
17603 for (int j = 0; j < activitiesSize; j++) {
17604 final ActivityRecord r = app.activities.get(j);
17606 app.systemNoUi = false;
17610 if (!app.systemNoUi) {
17611 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17613 return (app.curAdj=app.maxAdj);
17616 app.systemNoUi = false;
17618 final int PROCESS_STATE_TOP = mTopProcessState;
17620 // Determine the importance of the process, starting with most
17621 // important to least, and assign an appropriate OOM adjustment.
17625 boolean foregroundActivities = false;
17626 BroadcastQueue queue;
17627 if (app == TOP_APP) {
17628 // The last app on the list is the foreground app.
17629 adj = ProcessList.FOREGROUND_APP_ADJ;
17630 schedGroup = Process.THREAD_GROUP_DEFAULT;
17631 app.adjType = "top-activity";
17632 foregroundActivities = true;
17633 procState = PROCESS_STATE_TOP;
17634 } else if (app.instrumentationClass != null) {
17635 // Don't want to kill running instrumentation.
17636 adj = ProcessList.FOREGROUND_APP_ADJ;
17637 schedGroup = Process.THREAD_GROUP_DEFAULT;
17638 app.adjType = "instrumentation";
17639 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17640 } else if ((queue = isReceivingBroadcast(app)) != null) {
17641 // An app that is currently receiving a broadcast also
17642 // counts as being in the foreground for OOM killer purposes.
17643 // It's placed in a sched group based on the nature of the
17644 // broadcast as reflected by which queue it's active in.
17645 adj = ProcessList.FOREGROUND_APP_ADJ;
17646 schedGroup = (queue == mFgBroadcastQueue)
17647 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17648 app.adjType = "broadcast";
17649 procState = ActivityManager.PROCESS_STATE_RECEIVER;
17650 } else if (app.executingServices.size() > 0) {
17651 // An app that is currently executing a service callback also
17652 // counts as being in the foreground.
17653 adj = ProcessList.FOREGROUND_APP_ADJ;
17654 schedGroup = app.execServicesFg ?
17655 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17656 app.adjType = "exec-service";
17657 procState = ActivityManager.PROCESS_STATE_SERVICE;
17658 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17660 // As far as we know the process is empty. We may change our mind later.
17661 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17662 // At this point we don't actually know the adjustment. Use the cached adj
17663 // value that the caller wants us to.
17665 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17668 app.adjType = "cch-empty";
17671 // Examine all activities if not already foreground.
17672 if (!foregroundActivities && activitiesSize > 0) {
17673 for (int j = 0; j < activitiesSize; j++) {
17674 final ActivityRecord r = app.activities.get(j);
17675 if (r.app != app) {
17676 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17677 + app + "?!? Using " + r.app + " instead.");
17681 // App has a visible activity; only upgrade adjustment.
17682 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17683 adj = ProcessList.VISIBLE_APP_ADJ;
17684 app.adjType = "visible";
17686 if (procState > PROCESS_STATE_TOP) {
17687 procState = PROCESS_STATE_TOP;
17689 schedGroup = Process.THREAD_GROUP_DEFAULT;
17690 app.cached = false;
17692 foregroundActivities = true;
17694 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17695 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17696 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17697 app.adjType = "pausing";
17699 if (procState > PROCESS_STATE_TOP) {
17700 procState = PROCESS_STATE_TOP;
17702 schedGroup = Process.THREAD_GROUP_DEFAULT;
17703 app.cached = false;
17705 foregroundActivities = true;
17706 } else if (r.state == ActivityState.STOPPING) {
17707 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17708 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17709 app.adjType = "stopping";
17711 // For the process state, we will at this point consider the
17712 // process to be cached. It will be cached either as an activity
17713 // or empty depending on whether the activity is finishing. We do
17714 // this so that we can treat the process as cached for purposes of
17715 // memory trimming (determing current memory level, trim command to
17716 // send to process) since there can be an arbitrary number of stopping
17717 // processes and they should soon all go into the cached state.
17718 if (!r.finishing) {
17719 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17720 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17723 app.cached = false;
17725 foregroundActivities = true;
17727 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17728 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17729 app.adjType = "cch-act";
17735 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17736 if (app.foregroundServices) {
17737 // The user is aware of this app, so make it visible.
17738 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17739 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17740 app.cached = false;
17741 app.adjType = "fg-service";
17742 schedGroup = Process.THREAD_GROUP_DEFAULT;
17743 } else if (app.forcingToForeground != null) {
17744 // The user is aware of this app, so make it visible.
17745 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17746 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17747 app.cached = false;
17748 app.adjType = "force-fg";
17749 app.adjSource = app.forcingToForeground;
17750 schedGroup = Process.THREAD_GROUP_DEFAULT;
17754 if (app == mHeavyWeightProcess) {
17755 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17756 // We don't want to kill the current heavy-weight process.
17757 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17758 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17759 app.cached = false;
17760 app.adjType = "heavy";
17762 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17763 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17767 if (app == mHomeProcess) {
17768 if (adj > ProcessList.HOME_APP_ADJ) {
17769 // This process is hosting what we currently consider to be the
17770 // home app, so we don't want to let it go into the background.
17771 adj = ProcessList.HOME_APP_ADJ;
17772 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17773 app.cached = false;
17774 app.adjType = "home";
17776 if (procState > ActivityManager.PROCESS_STATE_HOME) {
17777 procState = ActivityManager.PROCESS_STATE_HOME;
17781 if (app == mPreviousProcess && app.activities.size() > 0) {
17782 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17783 // This was the previous process that showed UI to the user.
17784 // We want to try to keep it around more aggressively, to give
17785 // a good experience around switching between two apps.
17786 adj = ProcessList.PREVIOUS_APP_ADJ;
17787 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17788 app.cached = false;
17789 app.adjType = "previous";
17791 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17792 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17796 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17797 + " reason=" + app.adjType);
17799 // By default, we use the computed adjustment. It may be changed if
17800 // there are applications dependent on our services or providers, but
17801 // this gives us a baseline and makes sure we don't get into an
17802 // infinite recursion.
17803 app.adjSeq = mAdjSeq;
17804 app.curRawAdj = adj;
17805 app.hasStartedServices = false;
17807 if (mBackupTarget != null && app == mBackupTarget.app) {
17808 // If possible we want to avoid killing apps while they're being backed up
17809 if (adj > ProcessList.BACKUP_APP_ADJ) {
17810 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17811 adj = ProcessList.BACKUP_APP_ADJ;
17812 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17813 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17815 app.adjType = "backup";
17816 app.cached = false;
17818 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17819 procState = ActivityManager.PROCESS_STATE_BACKUP;
17823 boolean mayBeTop = false;
17825 for (int is = app.services.size()-1;
17826 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17827 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17828 || procState > ActivityManager.PROCESS_STATE_TOP);
17830 ServiceRecord s = app.services.valueAt(is);
17831 if (s.startRequested) {
17832 app.hasStartedServices = true;
17833 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17834 procState = ActivityManager.PROCESS_STATE_SERVICE;
17836 if (app.hasShownUi && app != mHomeProcess) {
17837 // If this process has shown some UI, let it immediately
17838 // go to the LRU list because it may be pretty heavy with
17839 // UI stuff. We'll tag it with a label just to help
17840 // debug and understand what is going on.
17841 if (adj > ProcessList.SERVICE_ADJ) {
17842 app.adjType = "cch-started-ui-services";
17845 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17846 // This service has seen some activity within
17847 // recent memory, so we will keep its process ahead
17848 // of the background processes.
17849 if (adj > ProcessList.SERVICE_ADJ) {
17850 adj = ProcessList.SERVICE_ADJ;
17851 app.adjType = "started-services";
17852 app.cached = false;
17855 // If we have let the service slide into the background
17856 // state, still have some text describing what it is doing
17857 // even though the service no longer has an impact.
17858 if (adj > ProcessList.SERVICE_ADJ) {
17859 app.adjType = "cch-started-services";
17863 for (int conni = s.connections.size()-1;
17864 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17865 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17866 || procState > ActivityManager.PROCESS_STATE_TOP);
17868 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17870 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17871 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17872 || procState > ActivityManager.PROCESS_STATE_TOP);
17874 // XXX should compute this based on the max of
17875 // all connected clients.
17876 ConnectionRecord cr = clist.get(i);
17877 if (cr.binding.client == app) {
17878 // Binding to ourself is not interesting.
17881 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17882 ProcessRecord client = cr.binding.client;
17883 int clientAdj = computeOomAdjLocked(client, cachedAdj,
17884 TOP_APP, doingAll, now);
17885 int clientProcState = client.curProcState;
17886 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17887 // If the other app is cached for any reason, for purposes here
17888 // we are going to consider it empty. The specific cached state
17889 // doesn't propagate except under certain conditions.
17890 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17892 String adjType = null;
17893 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17894 // Not doing bind OOM management, so treat
17895 // this guy more like a started service.
17896 if (app.hasShownUi && app != mHomeProcess) {
17897 // If this process has shown some UI, let it immediately
17898 // go to the LRU list because it may be pretty heavy with
17899 // UI stuff. We'll tag it with a label just to help
17900 // debug and understand what is going on.
17901 if (adj > clientAdj) {
17902 adjType = "cch-bound-ui-services";
17904 app.cached = false;
17906 clientProcState = procState;
17908 if (now >= (s.lastActivity
17909 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17910 // This service has not seen activity within
17911 // recent memory, so allow it to drop to the
17912 // LRU list if there is no other reason to keep
17913 // it around. We'll also tag it with a label just
17914 // to help debug and undertand what is going on.
17915 if (adj > clientAdj) {
17916 adjType = "cch-bound-services";
17922 if (adj > clientAdj) {
17923 // If this process has recently shown UI, and
17924 // the process that is binding to it is less
17925 // important than being visible, then we don't
17926 // care about the binding as much as we care
17927 // about letting this process get into the LRU
17928 // list to be killed and restarted if needed for
17930 if (app.hasShownUi && app != mHomeProcess
17931 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17932 adjType = "cch-bound-ui-services";
17934 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17935 |Context.BIND_IMPORTANT)) != 0) {
17936 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17937 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17938 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17939 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17940 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17941 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17942 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17945 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17946 adj = ProcessList.VISIBLE_APP_ADJ;
17949 if (!client.cached) {
17950 app.cached = false;
17952 adjType = "service";
17955 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17956 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17957 schedGroup = Process.THREAD_GROUP_DEFAULT;
17959 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17960 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17961 // Special handling of clients who are in the top state.
17962 // We *may* want to consider this process to be in the
17963 // top state as well, but only if there is not another
17964 // reason for it to be running. Being on the top is a
17965 // special state, meaning you are specifically running
17966 // for the current top app. If the process is already
17967 // running in the background for some other reason, it
17968 // is more important to continue considering it to be
17969 // in the background state.
17971 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17973 // Special handling for above-top states (persistent
17974 // processes). These should not bring the current process
17975 // into the top state, since they are not on top. Instead
17976 // give them the best state after that.
17977 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
17979 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17980 } else if (mWakefulness
17981 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
17982 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
17985 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
17988 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17993 if (clientProcState <
17994 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17996 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17999 if (procState > clientProcState) {
18000 procState = clientProcState;
18002 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18003 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18004 app.pendingUiClean = true;
18006 if (adjType != null) {
18007 app.adjType = adjType;
18008 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18009 .REASON_SERVICE_IN_USE;
18010 app.adjSource = cr.binding.client;
18011 app.adjSourceProcState = clientProcState;
18012 app.adjTarget = s.name;
18015 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18016 app.treatLikeActivity = true;
18018 final ActivityRecord a = cr.activity;
18019 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18020 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18021 (a.visible || a.state == ActivityState.RESUMED
18022 || a.state == ActivityState.PAUSING)) {
18023 adj = ProcessList.FOREGROUND_APP_ADJ;
18024 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18025 schedGroup = Process.THREAD_GROUP_DEFAULT;
18027 app.cached = false;
18028 app.adjType = "service";
18029 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18030 .REASON_SERVICE_IN_USE;
18032 app.adjSourceProcState = procState;
18033 app.adjTarget = s.name;
18040 for (int provi = app.pubProviders.size()-1;
18041 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18042 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18043 || procState > ActivityManager.PROCESS_STATE_TOP);
18045 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18046 for (int i = cpr.connections.size()-1;
18047 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18048 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18049 || procState > ActivityManager.PROCESS_STATE_TOP);
18051 ContentProviderConnection conn = cpr.connections.get(i);
18052 ProcessRecord client = conn.client;
18053 if (client == app) {
18054 // Being our own client is not interesting.
18057 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18058 int clientProcState = client.curProcState;
18059 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18060 // If the other app is cached for any reason, for purposes here
18061 // we are going to consider it empty.
18062 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18064 if (adj > clientAdj) {
18065 if (app.hasShownUi && app != mHomeProcess
18066 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18067 app.adjType = "cch-ui-provider";
18069 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18070 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18071 app.adjType = "provider";
18073 app.cached &= client.cached;
18074 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18075 .REASON_PROVIDER_IN_USE;
18076 app.adjSource = client;
18077 app.adjSourceProcState = clientProcState;
18078 app.adjTarget = cpr.name;
18080 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18081 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18082 // Special handling of clients who are in the top state.
18083 // We *may* want to consider this process to be in the
18084 // top state as well, but only if there is not another
18085 // reason for it to be running. Being on the top is a
18086 // special state, meaning you are specifically running
18087 // for the current top app. If the process is already
18088 // running in the background for some other reason, it
18089 // is more important to continue considering it to be
18090 // in the background state.
18092 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18094 // Special handling for above-top states (persistent
18095 // processes). These should not bring the current process
18096 // into the top state, since they are not on top. Instead
18097 // give them the best state after that.
18099 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18102 if (procState > clientProcState) {
18103 procState = clientProcState;
18105 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18106 schedGroup = Process.THREAD_GROUP_DEFAULT;
18109 // If the provider has external (non-framework) process
18110 // dependencies, ensure that its adjustment is at least
18111 // FOREGROUND_APP_ADJ.
18112 if (cpr.hasExternalProcessHandles()) {
18113 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18114 adj = ProcessList.FOREGROUND_APP_ADJ;
18115 schedGroup = Process.THREAD_GROUP_DEFAULT;
18116 app.cached = false;
18117 app.adjType = "provider";
18118 app.adjTarget = cpr.name;
18120 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18121 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18126 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18127 // A client of one of our services or providers is in the top state. We
18128 // *may* want to be in the top state, but not if we are already running in
18129 // the background for some other reason. For the decision here, we are going
18130 // to pick out a few specific states that we want to remain in when a client
18131 // is top (states that tend to be longer-term) and otherwise allow it to go
18132 // to the top state.
18133 switch (procState) {
18134 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18135 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18136 case ActivityManager.PROCESS_STATE_SERVICE:
18137 // These all are longer-term states, so pull them up to the top
18138 // of the background states, but not all the way to the top state.
18139 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18142 // Otherwise, top is a better choice, so take it.
18143 procState = ActivityManager.PROCESS_STATE_TOP;
18148 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18149 if (app.hasClientActivities) {
18150 // This is a cached process, but with client activities. Mark it so.
18151 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18152 app.adjType = "cch-client-act";
18153 } else if (app.treatLikeActivity) {
18154 // This is a cached process, but somebody wants us to treat it like it has
18155 // an activity, okay!
18156 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18157 app.adjType = "cch-as-act";
18161 if (adj == ProcessList.SERVICE_ADJ) {
18163 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18164 mNewNumServiceProcs++;
18165 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18166 if (!app.serviceb) {
18167 // This service isn't far enough down on the LRU list to
18168 // normally be a B service, but if we are low on RAM and it
18169 // is large we want to force it down since we would prefer to
18170 // keep launcher over it.
18171 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18172 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18173 app.serviceHighRam = true;
18174 app.serviceb = true;
18175 //Slog.i(TAG, "ADJ " + app + " high ram!");
18177 mNewNumAServiceProcs++;
18178 //Slog.i(TAG, "ADJ " + app + " not high ram!");
18181 app.serviceHighRam = false;
18184 if (app.serviceb) {
18185 adj = ProcessList.SERVICE_B_ADJ;
18189 app.curRawAdj = adj;
18191 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18192 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18193 if (adj > app.maxAdj) {
18195 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18196 schedGroup = Process.THREAD_GROUP_DEFAULT;
18200 // Do final modification to adj. Everything we do between here and applying
18201 // the final setAdj must be done in this function, because we will also use
18202 // it when computing the final cached adj later. Note that we don't need to
18203 // worry about this for max adj above, since max adj will always be used to
18204 // keep it out of the cached vaues.
18205 app.curAdj = app.modifyRawOomAdj(adj);
18206 app.curSchedGroup = schedGroup;
18207 app.curProcState = procState;
18208 app.foregroundActivities = foregroundActivities;
18210 return app.curRawAdj;
18214 * Record new PSS sample for a process.
18216 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18217 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18218 proc.lastPssTime = now;
18219 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18220 if (DEBUG_PSS) Slog.d(TAG_PSS,
18221 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18222 + " state=" + ProcessList.makeProcStateString(procState));
18223 if (proc.initialIdlePss == 0) {
18224 proc.initialIdlePss = pss;
18226 proc.lastPss = pss;
18227 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18228 proc.lastCachedPss = pss;
18231 final SparseArray<Pair<Long, String>> watchUids
18232 = mMemWatchProcesses.getMap().get(proc.processName);
18234 if (watchUids != null) {
18235 Pair<Long, String> val = watchUids.get(proc.uid);
18237 val = watchUids.get(0);
18243 if (check != null) {
18244 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18245 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18246 if (!isDebuggable) {
18247 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18248 isDebuggable = true;
18251 if (isDebuggable) {
18252 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18253 final ProcessRecord myProc = proc;
18254 final File heapdumpFile = DumpHeapProvider.getJavaFile();
18255 mMemWatchDumpProcName = proc.processName;
18256 mMemWatchDumpFile = heapdumpFile.toString();
18257 mMemWatchDumpPid = proc.pid;
18258 mMemWatchDumpUid = proc.uid;
18259 BackgroundThread.getHandler().post(new Runnable() {
18261 public void run() {
18262 revokeUriPermission(ActivityThread.currentActivityThread()
18263 .getApplicationThread(),
18264 DumpHeapActivity.JAVA_URI,
18265 Intent.FLAG_GRANT_READ_URI_PERMISSION
18266 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18267 UserHandle.myUserId());
18268 ParcelFileDescriptor fd = null;
18270 heapdumpFile.delete();
18271 fd = ParcelFileDescriptor.open(heapdumpFile,
18272 ParcelFileDescriptor.MODE_CREATE |
18273 ParcelFileDescriptor.MODE_TRUNCATE |
18274 ParcelFileDescriptor.MODE_WRITE_ONLY |
18275 ParcelFileDescriptor.MODE_APPEND);
18276 IApplicationThread thread = myProc.thread;
18277 if (thread != null) {
18279 if (DEBUG_PSS) Slog.d(TAG_PSS,
18280 "Requesting dump heap from "
18281 + myProc + " to " + heapdumpFile);
18282 thread.dumpHeap(true, heapdumpFile.toString(), fd);
18283 } catch (RemoteException e) {
18286 } catch (FileNotFoundException e) {
18287 e.printStackTrace();
18292 } catch (IOException e) {
18299 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18300 + ", but debugging not enabled");
18307 * Schedule PSS collection of a process.
18309 void requestPssLocked(ProcessRecord proc, int procState) {
18310 if (mPendingPssProcesses.contains(proc)) {
18313 if (mPendingPssProcesses.size() == 0) {
18314 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18316 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18317 proc.pssProcState = procState;
18318 mPendingPssProcesses.add(proc);
18322 * Schedule PSS collection of all processes.
18324 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18326 if (now < (mLastFullPssTime +
18327 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18331 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
18332 mLastFullPssTime = now;
18333 mFullPssPending = true;
18334 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18335 mPendingPssProcesses.clear();
18336 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18337 ProcessRecord app = mLruProcesses.get(i);
18338 if (app.thread == null
18339 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18342 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18343 app.pssProcState = app.setProcState;
18344 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18345 mTestPssMode, isSleeping(), now);
18346 mPendingPssProcesses.add(app);
18349 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18352 public void setTestPssMode(boolean enabled) {
18353 synchronized (this) {
18354 mTestPssMode = enabled;
18356 // Whenever we enable the mode, we want to take a snapshot all of current
18357 // process mem use.
18358 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18364 * Ask a given process to GC right now.
18366 final void performAppGcLocked(ProcessRecord app) {
18368 app.lastRequestedGc = SystemClock.uptimeMillis();
18369 if (app.thread != null) {
18370 if (app.reportLowMemory) {
18371 app.reportLowMemory = false;
18372 app.thread.scheduleLowMemory();
18374 app.thread.processInBackground();
18377 } catch (Exception e) {
18383 * Returns true if things are idle enough to perform GCs.
18385 private final boolean canGcNowLocked() {
18386 boolean processingBroadcasts = false;
18387 for (BroadcastQueue q : mBroadcastQueues) {
18388 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18389 processingBroadcasts = true;
18392 return !processingBroadcasts
18393 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18397 * Perform GCs on all processes that are waiting for it, but only
18398 * if things are idle.
18400 final void performAppGcsLocked() {
18401 final int N = mProcessesToGc.size();
18405 if (canGcNowLocked()) {
18406 while (mProcessesToGc.size() > 0) {
18407 ProcessRecord proc = mProcessesToGc.remove(0);
18408 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18409 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18410 <= SystemClock.uptimeMillis()) {
18411 // To avoid spamming the system, we will GC processes one
18412 // at a time, waiting a few seconds between each.
18413 performAppGcLocked(proc);
18414 scheduleAppGcsLocked();
18417 // It hasn't been long enough since we last GCed this
18418 // process... put it in the list to wait for its time.
18419 addProcessToGcListLocked(proc);
18425 scheduleAppGcsLocked();
18430 * If all looks good, perform GCs on all processes waiting for them.
18432 final void performAppGcsIfAppropriateLocked() {
18433 if (canGcNowLocked()) {
18434 performAppGcsLocked();
18437 // Still not idle, wait some more.
18438 scheduleAppGcsLocked();
18442 * Schedule the execution of all pending app GCs.
18444 final void scheduleAppGcsLocked() {
18445 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18447 if (mProcessesToGc.size() > 0) {
18448 // Schedule a GC for the time to the next process.
18449 ProcessRecord proc = mProcessesToGc.get(0);
18450 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18452 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18453 long now = SystemClock.uptimeMillis();
18454 if (when < (now+GC_TIMEOUT)) {
18455 when = now + GC_TIMEOUT;
18457 mHandler.sendMessageAtTime(msg, when);
18462 * Add a process to the array of processes waiting to be GCed. Keeps the
18463 * list in sorted order by the last GC time. The process can't already be
18466 final void addProcessToGcListLocked(ProcessRecord proc) {
18467 boolean added = false;
18468 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18469 if (mProcessesToGc.get(i).lastRequestedGc <
18470 proc.lastRequestedGc) {
18472 mProcessesToGc.add(i+1, proc);
18477 mProcessesToGc.add(0, proc);
18482 * Set up to ask a process to GC itself. This will either do it
18483 * immediately, or put it on the list of processes to gc the next
18484 * time things are idle.
18486 final void scheduleAppGcLocked(ProcessRecord app) {
18487 long now = SystemClock.uptimeMillis();
18488 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18491 if (!mProcessesToGc.contains(app)) {
18492 addProcessToGcListLocked(app);
18493 scheduleAppGcsLocked();
18497 final void checkExcessivePowerUsageLocked(boolean doKills) {
18498 updateCpuStatsNow();
18500 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18501 boolean doWakeKills = doKills;
18502 boolean doCpuKills = doKills;
18503 if (mLastPowerCheckRealtime == 0) {
18504 doWakeKills = false;
18506 if (mLastPowerCheckUptime == 0) {
18507 doCpuKills = false;
18509 if (stats.isScreenOn()) {
18510 doWakeKills = false;
18512 final long curRealtime = SystemClock.elapsedRealtime();
18513 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18514 final long curUptime = SystemClock.uptimeMillis();
18515 final long uptimeSince = curUptime - mLastPowerCheckUptime;
18516 mLastPowerCheckRealtime = curRealtime;
18517 mLastPowerCheckUptime = curUptime;
18518 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18519 doWakeKills = false;
18521 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18522 doCpuKills = false;
18524 int i = mLruProcesses.size();
18527 ProcessRecord app = mLruProcesses.get(i);
18528 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18530 synchronized (stats) {
18531 wtime = stats.getProcessWakeTime(app.info.uid,
18532 app.pid, curRealtime);
18534 long wtimeUsed = wtime - app.lastWakeTime;
18535 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18537 StringBuilder sb = new StringBuilder(128);
18538 sb.append("Wake for ");
18539 app.toShortString(sb);
18540 sb.append(": over ");
18541 TimeUtils.formatDuration(realtimeSince, sb);
18542 sb.append(" used ");
18543 TimeUtils.formatDuration(wtimeUsed, sb);
18545 sb.append((wtimeUsed*100)/realtimeSince);
18547 Slog.i(TAG_POWER, sb.toString());
18549 sb.append("CPU for ");
18550 app.toShortString(sb);
18551 sb.append(": over ");
18552 TimeUtils.formatDuration(uptimeSince, sb);
18553 sb.append(" used ");
18554 TimeUtils.formatDuration(cputimeUsed, sb);
18556 sb.append((cputimeUsed*100)/uptimeSince);
18558 Slog.i(TAG_POWER, sb.toString());
18560 // If a process has held a wake lock for more
18561 // than 50% of the time during this period,
18562 // that sounds bad. Kill!
18563 if (doWakeKills && realtimeSince > 0
18564 && ((wtimeUsed*100)/realtimeSince) >= 50) {
18565 synchronized (stats) {
18566 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18567 realtimeSince, wtimeUsed);
18569 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18570 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18571 } else if (doCpuKills && uptimeSince > 0
18572 && ((cputimeUsed*100)/uptimeSince) >= 25) {
18573 synchronized (stats) {
18574 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18575 uptimeSince, cputimeUsed);
18577 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18578 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18580 app.lastWakeTime = wtime;
18581 app.lastCpuTime = app.curCpuTime;
18587 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18588 boolean success = true;
18590 if (app.curRawAdj != app.setRawAdj) {
18591 app.setRawAdj = app.curRawAdj;
18596 if (app.curAdj != app.setAdj) {
18597 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18598 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18599 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18601 app.setAdj = app.curAdj;
18604 if (app.setSchedGroup != app.curSchedGroup) {
18605 app.setSchedGroup = app.curSchedGroup;
18606 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18607 "Setting process group of " + app.processName
18608 + " to " + app.curSchedGroup);
18609 if (app.waitingToKill != null && app.curReceiver == null
18610 && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18611 app.kill(app.waitingToKill, true);
18615 long oldId = Binder.clearCallingIdentity();
18617 Process.setProcessGroup(app.pid, app.curSchedGroup);
18618 } catch (Exception e) {
18619 Slog.w(TAG, "Failed setting process group of " + app.pid
18620 + " to " + app.curSchedGroup);
18621 e.printStackTrace();
18623 Binder.restoreCallingIdentity(oldId);
18626 if (app.thread != null) {
18628 app.thread.setSchedulingGroup(app.curSchedGroup);
18629 } catch (RemoteException e) {
18633 Process.setSwappiness(app.pid,
18634 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18637 if (app.repForegroundActivities != app.foregroundActivities) {
18638 app.repForegroundActivities = app.foregroundActivities;
18639 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18641 if (app.repProcState != app.curProcState) {
18642 app.repProcState = app.curProcState;
18643 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18644 if (app.thread != null) {
18647 //RuntimeException h = new RuntimeException("here");
18648 Slog.i(TAG, "Sending new process state " + app.repProcState
18649 + " to " + app /*, h*/);
18651 app.thread.setProcessState(app.repProcState);
18652 } catch (RemoteException e) {
18656 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18657 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18658 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18659 // Experimental code to more aggressively collect pss while
18660 // running test... the problem is that this tends to collect
18661 // the data right when a process is transitioning between process
18662 // states, which well tend to give noisy data.
18663 long start = SystemClock.uptimeMillis();
18664 long pss = Debug.getPss(app.pid, mTmpLong, null);
18665 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18666 mPendingPssProcesses.remove(app);
18667 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18668 + " to " + app.curProcState + ": "
18669 + (SystemClock.uptimeMillis()-start) + "ms");
18671 app.lastStateTime = now;
18672 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18673 mTestPssMode, isSleeping(), now);
18674 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18675 + ProcessList.makeProcStateString(app.setProcState) + " to "
18676 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18677 + (app.nextPssTime-now) + ": " + app);
18679 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18680 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18682 requestPssLocked(app, app.setProcState);
18683 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18684 mTestPssMode, isSleeping(), now);
18685 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18686 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18688 if (app.setProcState != app.curProcState) {
18689 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18690 "Proc state change of " + app.processName
18691 + " to " + app.curProcState);
18692 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18693 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18694 if (setImportant && !curImportant) {
18695 // This app is no longer something we consider important enough to allow to
18696 // use arbitrary amounts of battery power. Note
18697 // its current wake lock time to later know to kill it if
18698 // it is not behaving well.
18699 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18700 synchronized (stats) {
18701 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18702 app.pid, SystemClock.elapsedRealtime());
18704 app.lastCpuTime = app.curCpuTime;
18707 // Inform UsageStats of important process state change
18708 // Must be called before updating setProcState
18709 maybeUpdateUsageStatsLocked(app);
18711 app.setProcState = app.curProcState;
18712 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18713 app.notCachedSinceIdle = false;
18716 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18718 app.procStateChanged = true;
18722 if (changes != 0) {
18723 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18724 "Changes in " + app + ": " + changes);
18725 int i = mPendingProcessChanges.size()-1;
18726 ProcessChangeItem item = null;
18728 item = mPendingProcessChanges.get(i);
18729 if (item.pid == app.pid) {
18730 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18731 "Re-using existing item: " + item);
18737 // No existing item in pending changes; need a new one.
18738 final int NA = mAvailProcessChanges.size();
18740 item = mAvailProcessChanges.remove(NA-1);
18741 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18742 "Retrieving available item: " + item);
18744 item = new ProcessChangeItem();
18745 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18746 "Allocating new item: " + item);
18749 item.pid = app.pid;
18750 item.uid = app.info.uid;
18751 if (mPendingProcessChanges.size() == 0) {
18752 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18753 "*** Enqueueing dispatch processes changed!");
18754 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18756 mPendingProcessChanges.add(item);
18758 item.changes |= changes;
18759 item.processState = app.repProcState;
18760 item.foregroundActivities = app.repForegroundActivities;
18761 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18762 "Item " + Integer.toHexString(System.identityHashCode(item))
18763 + " " + app.toShortString() + ": changes=" + item.changes
18764 + " procState=" + item.processState
18765 + " foreground=" + item.foregroundActivities
18766 + " type=" + app.adjType + " source=" + app.adjSource
18767 + " target=" + app.adjTarget);
18773 private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18774 if (uidRec.pendingChange == null) {
18775 if (mPendingUidChanges.size() == 0) {
18776 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18777 "*** Enqueueing dispatch uid changed!");
18778 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18780 final int NA = mAvailUidChanges.size();
18782 uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18783 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18784 "Retrieving available item: " + uidRec.pendingChange);
18786 uidRec.pendingChange = new UidRecord.ChangeItem();
18787 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18788 "Allocating new item: " + uidRec.pendingChange);
18790 uidRec.pendingChange.uidRecord = uidRec;
18791 uidRec.pendingChange.uid = uidRec.uid;
18792 mPendingUidChanges.add(uidRec.pendingChange);
18794 uidRec.pendingChange.gone = gone;
18795 uidRec.pendingChange.processState = uidRec.setProcState;
18798 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18799 String authority) {
18800 if (app == null) return;
18801 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18802 UserState userState = mStartedUsers.get(app.userId);
18803 if (userState == null) return;
18804 final long now = SystemClock.elapsedRealtime();
18805 Long lastReported = userState.mProviderLastReportedFg.get(authority);
18806 if (lastReported == null || lastReported < now - 60 * 1000L) {
18807 mUsageStatsService.reportContentProviderUsage(
18808 authority, providerPkgName, app.userId);
18809 userState.mProviderLastReportedFg.put(authority, now);
18814 private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18815 if (DEBUG_USAGE_STATS) {
18816 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18817 + "] state changes: old = " + app.setProcState + ", new = "
18818 + app.curProcState);
18820 if (mUsageStatsService == null) {
18823 boolean isInteraction;
18824 // To avoid some abuse patterns, we are going to be careful about what we consider
18825 // to be an app interaction. Being the top activity doesn't count while the display
18826 // is sleeping, nor do short foreground services.
18827 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18828 isInteraction = true;
18829 app.fgInteractionTime = 0;
18830 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18831 final long now = SystemClock.elapsedRealtime();
18832 if (app.fgInteractionTime == 0) {
18833 app.fgInteractionTime = now;
18834 isInteraction = false;
18836 isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18839 isInteraction = app.curProcState
18840 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18841 app.fgInteractionTime = 0;
18843 if (isInteraction && !app.reportedInteraction) {
18844 String[] packages = app.getPackageList();
18845 if (packages != null) {
18846 for (int i = 0; i < packages.length; i++) {
18847 mUsageStatsService.reportEvent(packages[i], app.userId,
18848 UsageEvents.Event.SYSTEM_INTERACTION);
18852 app.reportedInteraction = isInteraction;
18855 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18856 if (proc.thread != null) {
18857 if (proc.baseProcessTracker != null) {
18858 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18860 if (proc.repProcState >= 0) {
18861 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18862 proc.repProcState);
18867 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18868 ProcessRecord TOP_APP, boolean doingAll, long now) {
18869 if (app.thread == null) {
18873 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18875 return applyOomAdjLocked(app, doingAll, now);
18878 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18880 if (isForeground != proc.foregroundServices) {
18881 proc.foregroundServices = isForeground;
18882 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18884 if (isForeground) {
18885 if (curProcs == null) {
18886 curProcs = new ArrayList<ProcessRecord>();
18887 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18889 if (!curProcs.contains(proc)) {
18890 curProcs.add(proc);
18891 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18892 proc.info.packageName, proc.info.uid);
18895 if (curProcs != null) {
18896 if (curProcs.remove(proc)) {
18897 mBatteryStatsService.noteEvent(
18898 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18899 proc.info.packageName, proc.info.uid);
18900 if (curProcs.size() <= 0) {
18901 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18907 updateOomAdjLocked();
18912 private final ActivityRecord resumedAppLocked() {
18913 ActivityRecord act = mStackSupervisor.resumedAppLocked();
18917 pkg = act.packageName;
18918 uid = act.info.applicationInfo.uid;
18923 // Has the UID or resumed package name changed?
18924 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18925 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18926 if (mCurResumedPackage != null) {
18927 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18928 mCurResumedPackage, mCurResumedUid);
18930 mCurResumedPackage = pkg;
18931 mCurResumedUid = uid;
18932 if (mCurResumedPackage != null) {
18933 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18934 mCurResumedPackage, mCurResumedUid);
18940 final boolean updateOomAdjLocked(ProcessRecord app) {
18941 final ActivityRecord TOP_ACT = resumedAppLocked();
18942 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18943 final boolean wasCached = app.cached;
18947 // This is the desired cached adjusment we want to tell it to use.
18948 // If our app is currently cached, we know it, and that is it. Otherwise,
18949 // we don't know it yet, and it needs to now be cached we will then
18950 // need to do a complete oom adj.
18951 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18952 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18953 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18954 SystemClock.uptimeMillis());
18955 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18956 // Changed to/from cached state, so apps after it in the LRU
18957 // list may also be changed.
18958 updateOomAdjLocked();
18963 final void updateOomAdjLocked() {
18964 final ActivityRecord TOP_ACT = resumedAppLocked();
18965 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18966 final long now = SystemClock.uptimeMillis();
18967 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18968 final int N = mLruProcesses.size();
18971 RuntimeException e = new RuntimeException();
18972 e.fillInStackTrace();
18973 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18976 // Reset state in all uid records.
18977 for (int i=mActiveUids.size()-1; i>=0; i--) {
18978 final UidRecord uidRec = mActiveUids.valueAt(i);
18979 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18980 "Starting update of " + uidRec);
18985 mNewNumServiceProcs = 0;
18986 mNewNumAServiceProcs = 0;
18988 final int emptyProcessLimit;
18989 final int cachedProcessLimit;
18990 if (mProcessLimit <= 0) {
18991 emptyProcessLimit = cachedProcessLimit = 0;
18992 } else if (mProcessLimit == 1) {
18993 emptyProcessLimit = 1;
18994 cachedProcessLimit = 0;
18996 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18997 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19000 // Let's determine how many processes we have running vs.
19001 // how many slots we have for background processes; we may want
19002 // to put multiple processes in a slot of there are enough of
19004 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19005 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19006 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19007 if (numEmptyProcs > cachedProcessLimit) {
19008 // If there are more empty processes than our limit on cached
19009 // processes, then use the cached process limit for the factor.
19010 // This ensures that the really old empty processes get pushed
19011 // down to the bottom, so if we are running low on memory we will
19012 // have a better chance at keeping around more cached processes
19013 // instead of a gazillion empty processes.
19014 numEmptyProcs = cachedProcessLimit;
19016 int emptyFactor = numEmptyProcs/numSlots;
19017 if (emptyFactor < 1) emptyFactor = 1;
19018 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19019 if (cachedFactor < 1) cachedFactor = 1;
19020 int stepCached = 0;
19024 int numTrimming = 0;
19026 mNumNonCachedProcs = 0;
19027 mNumCachedHiddenProcs = 0;
19029 // First update the OOM adjustment for each of the
19030 // application processes based on their current state.
19031 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19032 int nextCachedAdj = curCachedAdj+1;
19033 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19034 int nextEmptyAdj = curEmptyAdj+2;
19035 for (int i=N-1; i>=0; i--) {
19036 ProcessRecord app = mLruProcesses.get(i);
19037 if (!app.killedByAm && app.thread != null) {
19038 app.procStateChanged = false;
19039 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19041 // If we haven't yet assigned the final cached adj
19042 // to the process, do that now.
19043 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19044 switch (app.curProcState) {
19045 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19046 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19047 // This process is a cached process holding activities...
19048 // assign it the next cached value for that type, and then
19049 // step that cached level.
19050 app.curRawAdj = curCachedAdj;
19051 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19052 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19053 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19055 if (curCachedAdj != nextCachedAdj) {
19057 if (stepCached >= cachedFactor) {
19059 curCachedAdj = nextCachedAdj;
19060 nextCachedAdj += 2;
19061 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19062 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19068 // For everything else, assign next empty cached process
19069 // level and bump that up. Note that this means that
19070 // long-running services that have dropped down to the
19071 // cached level will be treated as empty (since their process
19072 // state is still as a service), which is what we want.
19073 app.curRawAdj = curEmptyAdj;
19074 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19075 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19076 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19078 if (curEmptyAdj != nextEmptyAdj) {
19080 if (stepEmpty >= emptyFactor) {
19082 curEmptyAdj = nextEmptyAdj;
19084 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19085 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19093 applyOomAdjLocked(app, true, now);
19095 // Count the number of process types.
19096 switch (app.curProcState) {
19097 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19098 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19099 mNumCachedHiddenProcs++;
19101 if (numCached > cachedProcessLimit) {
19102 app.kill("cached #" + numCached, true);
19105 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19106 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19107 && app.lastActivityTime < oldTime) {
19108 app.kill("empty for "
19109 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19110 / 1000) + "s", true);
19113 if (numEmpty > emptyProcessLimit) {
19114 app.kill("empty #" + numEmpty, true);
19119 mNumNonCachedProcs++;
19123 if (app.isolated && app.services.size() <= 0) {
19124 // If this is an isolated process, and there are no
19125 // services running in it, then the process is no longer
19126 // needed. We agressively kill these because we can by
19127 // definition not re-use the same process again, and it is
19128 // good to avoid having whatever code was running in them
19129 // left sitting around after no longer needed.
19130 app.kill("isolated not needed", true);
19132 // Keeping this process, update its uid.
19133 final UidRecord uidRec = app.uidRecord;
19134 if (uidRec != null && uidRec.curProcState > app.curProcState) {
19135 uidRec.curProcState = app.curProcState;
19139 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19140 && !app.killedByAm) {
19146 mNumServiceProcs = mNewNumServiceProcs;
19148 // Now determine the memory trimming level of background processes.
19149 // Unfortunately we need to start at the back of the list to do this
19150 // properly. We only do this if the number of background apps we
19151 // are managing to keep around is less than half the maximum we desire;
19152 // if we are keeping a good number around, we'll let them use whatever
19153 // memory they want.
19154 final int numCachedAndEmpty = numCached + numEmpty;
19156 if (numCached <= ProcessList.TRIM_CACHED_APPS
19157 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19158 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19159 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19160 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19161 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19163 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19166 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19168 // We always allow the memory level to go up (better). We only allow it to go
19169 // down if we are in a state where that is allowed, *and* the total number of processes
19170 // has gone down since last time.
19171 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19172 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19173 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19174 if (memFactor > mLastMemoryLevel) {
19175 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19176 memFactor = mLastMemoryLevel;
19177 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19180 mLastMemoryLevel = memFactor;
19181 mLastNumProcesses = mLruProcesses.size();
19182 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19183 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19184 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19185 if (mLowRamStartTime == 0) {
19186 mLowRamStartTime = now;
19190 switch (memFactor) {
19191 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19192 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19194 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19195 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19198 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19201 int factor = numTrimming/3;
19203 if (mHomeProcess != null) minFactor++;
19204 if (mPreviousProcess != null) minFactor++;
19205 if (factor < minFactor) factor = minFactor;
19206 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19207 for (int i=N-1; i>=0; i--) {
19208 ProcessRecord app = mLruProcesses.get(i);
19209 if (allChanged || app.procStateChanged) {
19210 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19211 app.procStateChanged = false;
19213 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19214 && !app.killedByAm) {
19215 if (app.trimMemoryLevel < curLevel && app.thread != null) {
19217 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19218 "Trimming memory of " + app.processName + " to " + curLevel);
19219 app.thread.scheduleTrimMemory(curLevel);
19220 } catch (RemoteException e) {
19223 // For now we won't do this; our memory trimming seems
19224 // to be good enough at this point that destroying
19225 // activities causes more harm than good.
19226 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19227 && app != mHomeProcess && app != mPreviousProcess) {
19228 // Need to do this on its own message because the stack may not
19229 // be in a consistent state at this point.
19230 // For these apps we will also finish their activities
19231 // to help them free memory.
19232 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19236 app.trimMemoryLevel = curLevel;
19238 if (step >= factor) {
19240 switch (curLevel) {
19241 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19242 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19244 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19245 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19249 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19250 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19251 && app.thread != null) {
19253 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19254 "Trimming memory of heavy-weight " + app.processName
19255 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19256 app.thread.scheduleTrimMemory(
19257 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19258 } catch (RemoteException e) {
19261 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19263 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19264 || app.systemNoUi) && app.pendingUiClean) {
19265 // If this application is now in the background and it
19266 // had done UI, then give it the special trim level to
19267 // have it free UI resources.
19268 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19269 if (app.trimMemoryLevel < level && app.thread != null) {
19271 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19272 "Trimming memory of bg-ui " + app.processName
19274 app.thread.scheduleTrimMemory(level);
19275 } catch (RemoteException e) {
19278 app.pendingUiClean = false;
19280 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19282 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19283 "Trimming memory of fg " + app.processName
19284 + " to " + fgTrimLevel);
19285 app.thread.scheduleTrimMemory(fgTrimLevel);
19286 } catch (RemoteException e) {
19289 app.trimMemoryLevel = fgTrimLevel;
19293 if (mLowRamStartTime != 0) {
19294 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19295 mLowRamStartTime = 0;
19297 for (int i=N-1; i>=0; i--) {
19298 ProcessRecord app = mLruProcesses.get(i);
19299 if (allChanged || app.procStateChanged) {
19300 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19301 app.procStateChanged = false;
19303 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19304 || app.systemNoUi) && app.pendingUiClean) {
19305 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19306 && app.thread != null) {
19308 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19309 "Trimming memory of ui hidden " + app.processName
19310 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19311 app.thread.scheduleTrimMemory(
19312 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19313 } catch (RemoteException e) {
19316 app.pendingUiClean = false;
19318 app.trimMemoryLevel = 0;
19322 if (mAlwaysFinishActivities) {
19323 // Need to do this on its own message because the stack may not
19324 // be in a consistent state at this point.
19325 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19329 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19332 // Update from any uid changes.
19333 for (int i=mActiveUids.size()-1; i>=0; i--) {
19334 final UidRecord uidRec = mActiveUids.valueAt(i);
19335 if (uidRec.setProcState != uidRec.curProcState) {
19336 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19337 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19338 + " to " + uidRec.curProcState);
19339 uidRec.setProcState = uidRec.curProcState;
19340 enqueueUidChangeLocked(uidRec, false);
19344 if (mProcessStats.shouldWriteNowLocked(now)) {
19345 mHandler.post(new Runnable() {
19346 @Override public void run() {
19347 synchronized (ActivityManagerService.this) {
19348 mProcessStats.writeStateAsyncLocked();
19354 if (DEBUG_OOM_ADJ) {
19355 final long duration = SystemClock.uptimeMillis() - now;
19357 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19358 new RuntimeException("here").fillInStackTrace());
19360 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19365 final void trimApplications() {
19366 synchronized (this) {
19369 // First remove any unused application processes whose package
19370 // has been removed.
19371 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19372 final ProcessRecord app = mRemovedProcesses.get(i);
19373 if (app.activities.size() == 0
19374 && app.curReceiver == null && app.services.size() == 0) {
19376 TAG, "Exiting empty application process "
19377 + app.processName + " ("
19378 + (app.thread != null ? app.thread.asBinder() : null)
19380 if (app.pid > 0 && app.pid != MY_PID) {
19381 app.kill("empty", false);
19384 app.thread.scheduleExit();
19385 } catch (Exception e) {
19386 // Ignore exceptions.
19389 cleanUpApplicationRecordLocked(app, false, true, -1);
19390 mRemovedProcesses.remove(i);
19392 if (app.persistent) {
19393 addAppLocked(app.info, false, null /* ABI override */);
19398 // Now update the oom adj for all processes.
19399 updateOomAdjLocked();
19403 /** This method sends the specified signal to each of the persistent apps */
19404 public void signalPersistentProcesses(int sig) throws RemoteException {
19405 if (sig != Process.SIGNAL_USR1) {
19406 throw new SecurityException("Only SIGNAL_USR1 is allowed");
19409 synchronized (this) {
19410 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19411 != PackageManager.PERMISSION_GRANTED) {
19412 throw new SecurityException("Requires permission "
19413 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19416 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19417 ProcessRecord r = mLruProcesses.get(i);
19418 if (r.thread != null && r.persistent) {
19419 Process.sendSignal(r.pid, sig);
19425 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19426 if (proc == null || proc == mProfileProc) {
19427 proc = mProfileProc;
19428 profileType = mProfileType;
19429 clearProfilerLocked();
19431 if (proc == null) {
19435 proc.thread.profilerControl(false, null, profileType);
19436 } catch (RemoteException e) {
19437 throw new IllegalStateException("Process disappeared");
19441 private void clearProfilerLocked() {
19442 if (mProfileFd != null) {
19444 mProfileFd.close();
19445 } catch (IOException e) {
19448 mProfileApp = null;
19449 mProfileProc = null;
19450 mProfileFile = null;
19452 mAutoStopProfiler = false;
19453 mSamplingInterval = 0;
19456 public boolean profileControl(String process, int userId, boolean start,
19457 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19460 synchronized (this) {
19461 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19462 // its own permission.
19463 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19464 != PackageManager.PERMISSION_GRANTED) {
19465 throw new SecurityException("Requires permission "
19466 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19469 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19470 throw new IllegalArgumentException("null profile info or fd");
19473 ProcessRecord proc = null;
19474 if (process != null) {
19475 proc = findProcessLocked(process, userId, "profileControl");
19478 if (start && (proc == null || proc.thread == null)) {
19479 throw new IllegalArgumentException("Unknown process: " + process);
19483 stopProfilerLocked(null, 0);
19484 setProfileApp(proc.info, proc.processName, profilerInfo);
19485 mProfileProc = proc;
19486 mProfileType = profileType;
19487 ParcelFileDescriptor fd = profilerInfo.profileFd;
19490 } catch (IOException e) {
19493 profilerInfo.profileFd = fd;
19494 proc.thread.profilerControl(start, profilerInfo, profileType);
19498 stopProfilerLocked(proc, profileType);
19499 if (profilerInfo != null && profilerInfo.profileFd != null) {
19501 profilerInfo.profileFd.close();
19502 } catch (IOException e) {
19509 } catch (RemoteException e) {
19510 throw new IllegalStateException("Process disappeared");
19512 if (profilerInfo != null && profilerInfo.profileFd != null) {
19514 profilerInfo.profileFd.close();
19515 } catch (IOException e) {
19521 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19522 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19523 userId, true, ALLOW_FULL_ONLY, callName, null);
19524 ProcessRecord proc = null;
19526 int pid = Integer.parseInt(process);
19527 synchronized (mPidsSelfLocked) {
19528 proc = mPidsSelfLocked.get(pid);
19530 } catch (NumberFormatException e) {
19533 if (proc == null) {
19534 ArrayMap<String, SparseArray<ProcessRecord>> all
19535 = mProcessNames.getMap();
19536 SparseArray<ProcessRecord> procs = all.get(process);
19537 if (procs != null && procs.size() > 0) {
19538 proc = procs.valueAt(0);
19539 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19540 for (int i=1; i<procs.size(); i++) {
19541 ProcessRecord thisProc = procs.valueAt(i);
19542 if (thisProc.userId == userId) {
19554 public boolean dumpHeap(String process, int userId, boolean managed,
19555 String path, ParcelFileDescriptor fd) throws RemoteException {
19558 synchronized (this) {
19559 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19560 // its own permission (same as profileControl).
19561 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19562 != PackageManager.PERMISSION_GRANTED) {
19563 throw new SecurityException("Requires permission "
19564 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19568 throw new IllegalArgumentException("null fd");
19571 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19572 if (proc == null || proc.thread == null) {
19573 throw new IllegalArgumentException("Unknown process: " + process);
19576 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19577 if (!isDebuggable) {
19578 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19579 throw new SecurityException("Process not debuggable: " + proc);
19583 proc.thread.dumpHeap(managed, path, fd);
19587 } catch (RemoteException e) {
19588 throw new IllegalStateException("Process disappeared");
19593 } catch (IOException e) {
19600 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19601 String reportPackage) {
19602 if (processName != null) {
19603 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19604 "setDumpHeapDebugLimit()");
19606 synchronized (mPidsSelfLocked) {
19607 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19608 if (proc == null) {
19609 throw new SecurityException("No process found for calling pid "
19610 + Binder.getCallingPid());
19612 if (!Build.IS_DEBUGGABLE
19613 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19614 throw new SecurityException("Not running a debuggable build");
19616 processName = proc.processName;
19618 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19619 throw new SecurityException("Package " + reportPackage + " is not running in "
19624 synchronized (this) {
19625 if (maxMemSize > 0) {
19626 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19629 mMemWatchProcesses.remove(processName, uid);
19631 mMemWatchProcesses.getMap().remove(processName);
19638 public void dumpHeapFinished(String path) {
19639 synchronized (this) {
19640 if (Binder.getCallingPid() != mMemWatchDumpPid) {
19641 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19642 + " does not match last pid " + mMemWatchDumpPid);
19645 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19646 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19647 + " does not match last path " + mMemWatchDumpFile);
19650 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19651 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19655 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19656 public void monitor() {
19657 synchronized (this) { }
19660 void onCoreSettingsChange(Bundle settings) {
19661 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19662 ProcessRecord processRecord = mLruProcesses.get(i);
19664 if (processRecord.thread != null) {
19665 processRecord.thread.setCoreSettings(settings);
19667 } catch (RemoteException re) {
19673 // Multi-user methods
19676 * Start user, if its not already running, but don't bring it to foreground.
19679 public boolean startUserInBackground(final int userId) {
19680 return startUser(userId, /* foreground */ false);
19684 * Start user, if its not already running, and bring it to foreground.
19686 boolean startUserInForeground(final int userId, Dialog dlg) {
19687 boolean result = startUser(userId, /* foreground */ true);
19693 * Refreshes the list of users related to the current user when either a
19694 * user switch happens or when a new related user is started in the
19697 private void updateCurrentProfileIdsLocked() {
19698 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19699 mCurrentUserId, false /* enabledOnly */);
19700 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19701 for (int i = 0; i < currentProfileIds.length; i++) {
19702 currentProfileIds[i] = profiles.get(i).id;
19704 mCurrentProfileIds = currentProfileIds;
19706 synchronized (mUserProfileGroupIdsSelfLocked) {
19707 mUserProfileGroupIdsSelfLocked.clear();
19708 final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19709 for (int i = 0; i < users.size(); i++) {
19710 UserInfo user = users.get(i);
19711 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19712 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19718 private Set<Integer> getProfileIdsLocked(int userId) {
19719 Set<Integer> userIds = new HashSet<Integer>();
19720 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19721 userId, false /* enabledOnly */);
19722 for (UserInfo user : profiles) {
19723 userIds.add(Integer.valueOf(user.id));
19729 public boolean switchUser(final int userId) {
19730 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19732 synchronized (this) {
19733 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19734 if (userInfo == null) {
19735 Slog.w(TAG, "No user info for user #" + userId);
19738 if (userInfo.isManagedProfile()) {
19739 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19742 userName = userInfo.name;
19743 mTargetUserId = userId;
19745 mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19746 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19750 private void showUserSwitchDialog(int userId, String userName) {
19751 // The dialog will show and then initiate the user switch by calling startUserInForeground
19752 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19753 true /* above system */);
19757 private boolean startUser(final int userId, final boolean foreground) {
19758 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19759 != PackageManager.PERMISSION_GRANTED) {
19760 String msg = "Permission Denial: switchUser() from pid="
19761 + Binder.getCallingPid()
19762 + ", uid=" + Binder.getCallingUid()
19763 + " requires " + INTERACT_ACROSS_USERS_FULL;
19765 throw new SecurityException(msg);
19768 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19770 final long ident = Binder.clearCallingIdentity();
19772 synchronized (this) {
19773 final int oldUserId = mCurrentUserId;
19774 if (oldUserId == userId) {
19778 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19779 "startUser", false);
19781 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19782 if (userInfo == null) {
19783 Slog.w(TAG, "No user info for user #" + userId);
19786 if (foreground && userInfo.isManagedProfile()) {
19787 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19792 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19793 R.anim.screen_user_enter);
19796 boolean needStart = false;
19798 // If the user we are switching to is not currently started, then
19799 // we need to start it now.
19800 if (mStartedUsers.get(userId) == null) {
19801 mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19802 updateStartedUserArrayLocked();
19806 final Integer userIdInt = Integer.valueOf(userId);
19807 mUserLru.remove(userIdInt);
19808 mUserLru.add(userIdInt);
19811 mCurrentUserId = userId;
19812 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19813 updateCurrentProfileIdsLocked();
19814 mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19815 // Once the internal notion of the active user has switched, we lock the device
19816 // with the option to show the user switcher on the keyguard.
19817 mWindowManager.lockNow(null);
19819 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19820 updateCurrentProfileIdsLocked();
19821 mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19822 mUserLru.remove(currentUserIdInt);
19823 mUserLru.add(currentUserIdInt);
19826 final UserState uss = mStartedUsers.get(userId);
19828 // Make sure user is in the started state. If it is currently
19829 // stopping, we need to knock that off.
19830 if (uss.mState == UserState.STATE_STOPPING) {
19831 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19832 // so we can just fairly silently bring the user back from
19833 // the almost-dead.
19834 uss.mState = UserState.STATE_RUNNING;
19835 updateStartedUserArrayLocked();
19837 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19838 // This means ACTION_SHUTDOWN has been sent, so we will
19839 // need to treat this as a new boot of the user.
19840 uss.mState = UserState.STATE_BOOTING;
19841 updateStartedUserArrayLocked();
19845 if (uss.mState == UserState.STATE_BOOTING) {
19846 // Booting up a new user, need to tell system services about it.
19847 // Note that this is on the same handler as scheduling of broadcasts,
19848 // which is important because it needs to go first.
19849 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19853 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19855 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19856 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19857 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19858 oldUserId, userId, uss));
19859 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19860 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19864 // Send USER_STARTED broadcast
19865 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19866 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19867 | Intent.FLAG_RECEIVER_FOREGROUND);
19868 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19869 broadcastIntentLocked(null, null, intent,
19870 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19871 null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19874 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19875 if (userId != UserHandle.USER_OWNER) {
19876 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19877 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19878 broadcastIntentLocked(null, null, intent, null,
19879 new IIntentReceiver.Stub() {
19880 public void performReceive(Intent intent, int resultCode,
19881 String data, Bundle extras, boolean ordered,
19882 boolean sticky, int sendingUser) {
19883 onUserInitialized(uss, foreground, oldUserId, userId);
19885 }, 0, null, null, null, AppOpsManager.OP_NONE,
19886 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19887 uss.initializing = true;
19889 getUserManagerLocked().makeInitialized(userInfo.id);
19894 if (!uss.initializing) {
19895 moveUserToForeground(uss, oldUserId, userId);
19898 mStackSupervisor.startBackgroundUserLocked(userId, uss);
19902 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19903 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19904 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19905 broadcastIntentLocked(null, null, intent,
19906 null, new IIntentReceiver.Stub() {
19908 public void performReceive(Intent intent, int resultCode,
19909 String data, Bundle extras, boolean ordered, boolean sticky,
19910 int sendingUser) throws RemoteException {
19913 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
19914 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19918 Binder.restoreCallingIdentity(ident);
19924 void dispatchForegroundProfileChanged(int userId) {
19925 final int N = mUserSwitchObservers.beginBroadcast();
19926 for (int i = 0; i < N; i++) {
19928 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19929 } catch (RemoteException e) {
19933 mUserSwitchObservers.finishBroadcast();
19936 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19937 long ident = Binder.clearCallingIdentity();
19940 if (oldUserId >= 0) {
19941 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19942 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19943 int count = profiles.size();
19944 for (int i = 0; i < count; i++) {
19945 int profileUserId = profiles.get(i).id;
19946 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19947 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19948 | Intent.FLAG_RECEIVER_FOREGROUND);
19949 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19950 broadcastIntentLocked(null, null, intent,
19951 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19952 null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19955 if (newUserId >= 0) {
19956 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19957 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19958 int count = profiles.size();
19959 for (int i = 0; i < count; i++) {
19960 int profileUserId = profiles.get(i).id;
19961 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19962 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19963 | Intent.FLAG_RECEIVER_FOREGROUND);
19964 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19965 broadcastIntentLocked(null, null, intent,
19966 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19967 null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19969 intent = new Intent(Intent.ACTION_USER_SWITCHED);
19970 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19971 | Intent.FLAG_RECEIVER_FOREGROUND);
19972 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19973 broadcastIntentLocked(null, null, intent,
19974 null, null, 0, null, null,
19975 new String[] {android.Manifest.permission.MANAGE_USERS},
19976 AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
19977 UserHandle.USER_ALL);
19980 Binder.restoreCallingIdentity(ident);
19984 void dispatchUserSwitch(final UserState uss, final int oldUserId,
19985 final int newUserId) {
19986 final int N = mUserSwitchObservers.beginBroadcast();
19988 final IRemoteCallback callback = new IRemoteCallback.Stub() {
19991 public void sendResult(Bundle data) throws RemoteException {
19992 synchronized (ActivityManagerService.this) {
19993 if (mCurUserSwitchCallback == this) {
19996 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20002 synchronized (this) {
20003 uss.switching = true;
20004 mCurUserSwitchCallback = callback;
20006 for (int i=0; i<N; i++) {
20008 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20009 newUserId, callback);
20010 } catch (RemoteException e) {
20014 synchronized (this) {
20015 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20018 mUserSwitchObservers.finishBroadcast();
20021 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20022 synchronized (this) {
20023 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20024 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20028 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20029 mCurUserSwitchCallback = null;
20030 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20031 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20032 oldUserId, newUserId, uss));
20035 void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20036 synchronized (this) {
20038 moveUserToForeground(uss, oldUserId, newUserId);
20042 completeSwitchAndInitialize(uss, newUserId, true, false);
20045 void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20046 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20048 startHomeActivityLocked(newUserId, "moveUserToFroreground");
20050 mStackSupervisor.resumeTopActivitiesLocked();
20052 EventLogTags.writeAmSwitchUser(newUserId);
20053 getUserManagerLocked().onUserForeground(newUserId);
20054 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20057 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20058 completeSwitchAndInitialize(uss, newUserId, false, true);
20061 void completeSwitchAndInitialize(UserState uss, int newUserId,
20062 boolean clearInitializing, boolean clearSwitching) {
20063 boolean unfrozen = false;
20064 synchronized (this) {
20065 if (clearInitializing) {
20066 uss.initializing = false;
20067 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20069 if (clearSwitching) {
20070 uss.switching = false;
20072 if (!uss.switching && !uss.initializing) {
20073 mWindowManager.stopFreezingScreen();
20078 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20079 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20082 stopGuestUserIfBackground();
20085 /** Called on handler thread */
20086 void dispatchUserSwitchComplete(int userId) {
20087 final int observerCount = mUserSwitchObservers.beginBroadcast();
20088 for (int i = 0; i < observerCount; i++) {
20090 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20091 } catch (RemoteException e) {
20094 mUserSwitchObservers.finishBroadcast();
20098 * Stops the guest user if it has gone to the background.
20100 private void stopGuestUserIfBackground() {
20101 synchronized (this) {
20102 final int num = mUserLru.size();
20103 for (int i = 0; i < num; i++) {
20104 Integer oldUserId = mUserLru.get(i);
20105 UserState oldUss = mStartedUsers.get(oldUserId);
20106 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20107 || oldUss.mState == UserState.STATE_STOPPING
20108 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20111 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20112 if (userInfo.isGuest()) {
20113 // This is a user to be stopped.
20114 stopUserLocked(oldUserId, null);
20121 void scheduleStartProfilesLocked() {
20122 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20123 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20124 DateUtils.SECOND_IN_MILLIS);
20128 void startProfilesLocked() {
20129 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20130 List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20131 mCurrentUserId, false /* enabledOnly */);
20132 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20133 for (UserInfo user : profiles) {
20134 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20135 && user.id != mCurrentUserId) {
20139 final int n = toStart.size();
20141 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20142 startUserInBackground(toStart.get(i).id);
20145 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20149 void finishUserBoot(UserState uss) {
20150 synchronized (this) {
20151 if (uss.mState == UserState.STATE_BOOTING
20152 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20153 uss.mState = UserState.STATE_RUNNING;
20154 final int userId = uss.mHandle.getIdentifier();
20155 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20156 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20157 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20158 broadcastIntentLocked(null, null, intent,
20159 null, null, 0, null, null,
20160 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20161 AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20167 void finishUserSwitch(UserState uss) {
20168 synchronized (this) {
20169 finishUserBoot(uss);
20171 startProfilesLocked();
20173 int num = mUserLru.size();
20175 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20176 Integer oldUserId = mUserLru.get(i);
20177 UserState oldUss = mStartedUsers.get(oldUserId);
20178 if (oldUss == null) {
20179 // Shouldn't happen, but be sane if it does.
20180 mUserLru.remove(i);
20184 if (oldUss.mState == UserState.STATE_STOPPING
20185 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20186 // This user is already stopping, doesn't count.
20191 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20192 // Owner and current can't be stopped, but count as running.
20196 // This is a user to be stopped.
20197 stopUserLocked(oldUserId, null);
20205 public int stopUser(final int userId, final IStopUserCallback callback) {
20206 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20207 != PackageManager.PERMISSION_GRANTED) {
20208 String msg = "Permission Denial: switchUser() from pid="
20209 + Binder.getCallingPid()
20210 + ", uid=" + Binder.getCallingUid()
20211 + " requires " + INTERACT_ACROSS_USERS_FULL;
20213 throw new SecurityException(msg);
20215 if (userId < 0 || userId == UserHandle.USER_OWNER) {
20216 throw new IllegalArgumentException("Can't stop primary user " + userId);
20218 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20219 synchronized (this) {
20220 return stopUserLocked(userId, callback);
20224 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20225 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20226 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20227 return ActivityManager.USER_OP_IS_CURRENT;
20230 final UserState uss = mStartedUsers.get(userId);
20232 // User is not started, nothing to do... but we do need to
20233 // callback if requested.
20234 if (callback != null) {
20235 mHandler.post(new Runnable() {
20237 public void run() {
20239 callback.userStopped(userId);
20240 } catch (RemoteException e) {
20245 return ActivityManager.USER_OP_SUCCESS;
20248 if (callback != null) {
20249 uss.mStopCallbacks.add(callback);
20252 if (uss.mState != UserState.STATE_STOPPING
20253 && uss.mState != UserState.STATE_SHUTDOWN) {
20254 uss.mState = UserState.STATE_STOPPING;
20255 updateStartedUserArrayLocked();
20257 long ident = Binder.clearCallingIdentity();
20259 // We are going to broadcast ACTION_USER_STOPPING and then
20260 // once that is done send a final ACTION_SHUTDOWN and then
20262 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20263 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20264 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20265 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20266 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20267 // This is the result receiver for the final shutdown broadcast.
20268 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20270 public void performReceive(Intent intent, int resultCode, String data,
20271 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20272 finishUserStop(uss);
20275 // This is the result receiver for the initial stopping broadcast.
20276 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20278 public void performReceive(Intent intent, int resultCode, String data,
20279 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20281 synchronized (ActivityManagerService.this) {
20282 if (uss.mState != UserState.STATE_STOPPING) {
20283 // Whoops, we are being started back up. Abort, abort!
20286 uss.mState = UserState.STATE_SHUTDOWN;
20288 mBatteryStatsService.noteEvent(
20289 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20290 Integer.toString(userId), userId);
20291 mSystemServiceManager.stopUser(userId);
20292 broadcastIntentLocked(null, null, shutdownIntent,
20293 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20294 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20297 // Kick things off.
20298 broadcastIntentLocked(null, null, stoppingIntent,
20299 null, stoppingReceiver, 0, null, null,
20300 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20301 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20303 Binder.restoreCallingIdentity(ident);
20307 return ActivityManager.USER_OP_SUCCESS;
20310 void finishUserStop(UserState uss) {
20311 final int userId = uss.mHandle.getIdentifier();
20313 ArrayList<IStopUserCallback> callbacks;
20314 synchronized (this) {
20315 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20316 if (mStartedUsers.get(userId) != uss) {
20318 } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20322 // User can no longer run.
20323 mStartedUsers.remove(userId);
20324 mUserLru.remove(Integer.valueOf(userId));
20325 updateStartedUserArrayLocked();
20327 // Clean up all state and processes associated with the user.
20328 // Kill all the processes for the user.
20329 forceStopUserLocked(userId, "finish user");
20332 // Explicitly remove the old information in mRecentTasks.
20333 mRecentTasks.removeTasksForUserLocked(userId);
20336 for (int i=0; i<callbacks.size(); i++) {
20338 if (stopped) callbacks.get(i).userStopped(userId);
20339 else callbacks.get(i).userStopAborted(userId);
20340 } catch (RemoteException e) {
20345 mSystemServiceManager.cleanupUser(userId);
20346 synchronized (this) {
20347 mStackSupervisor.removeUserLocked(userId);
20353 public UserInfo getCurrentUser() {
20354 if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20355 != PackageManager.PERMISSION_GRANTED) && (
20356 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20357 != PackageManager.PERMISSION_GRANTED)) {
20358 String msg = "Permission Denial: getCurrentUser() from pid="
20359 + Binder.getCallingPid()
20360 + ", uid=" + Binder.getCallingUid()
20361 + " requires " + INTERACT_ACROSS_USERS;
20363 throw new SecurityException(msg);
20365 synchronized (this) {
20366 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20367 return getUserManagerLocked().getUserInfo(userId);
20371 int getCurrentUserIdLocked() {
20372 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20376 public boolean isUserRunning(int userId, boolean orStopped) {
20377 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20378 != PackageManager.PERMISSION_GRANTED) {
20379 String msg = "Permission Denial: isUserRunning() from pid="
20380 + Binder.getCallingPid()
20381 + ", uid=" + Binder.getCallingUid()
20382 + " requires " + INTERACT_ACROSS_USERS;
20384 throw new SecurityException(msg);
20386 synchronized (this) {
20387 return isUserRunningLocked(userId, orStopped);
20391 boolean isUserRunningLocked(int userId, boolean orStopped) {
20392 UserState state = mStartedUsers.get(userId);
20393 if (state == null) {
20399 return state.mState != UserState.STATE_STOPPING
20400 && state.mState != UserState.STATE_SHUTDOWN;
20404 public int[] getRunningUserIds() {
20405 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20406 != PackageManager.PERMISSION_GRANTED) {
20407 String msg = "Permission Denial: isUserRunning() from pid="
20408 + Binder.getCallingPid()
20409 + ", uid=" + Binder.getCallingUid()
20410 + " requires " + INTERACT_ACROSS_USERS;
20412 throw new SecurityException(msg);
20414 synchronized (this) {
20415 return mStartedUserArray;
20419 private void updateStartedUserArrayLocked() {
20421 for (int i=0; i<mStartedUsers.size(); i++) {
20422 UserState uss = mStartedUsers.valueAt(i);
20423 // This list does not include stopping users.
20424 if (uss.mState != UserState.STATE_STOPPING
20425 && uss.mState != UserState.STATE_SHUTDOWN) {
20429 mStartedUserArray = new int[num];
20431 for (int i=0; i<mStartedUsers.size(); i++) {
20432 UserState uss = mStartedUsers.valueAt(i);
20433 if (uss.mState != UserState.STATE_STOPPING
20434 && uss.mState != UserState.STATE_SHUTDOWN) {
20435 mStartedUserArray[num] = mStartedUsers.keyAt(i);
20442 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20443 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20444 != PackageManager.PERMISSION_GRANTED) {
20445 String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20446 + Binder.getCallingPid()
20447 + ", uid=" + Binder.getCallingUid()
20448 + " requires " + INTERACT_ACROSS_USERS_FULL;
20450 throw new SecurityException(msg);
20453 mUserSwitchObservers.register(observer);
20457 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20458 mUserSwitchObservers.unregister(observer);
20461 int[] getUsersLocked() {
20462 UserManagerService ums = getUserManagerLocked();
20463 return ums != null ? ums.getUserIds() : new int[] { 0 };
20466 UserManagerService getUserManagerLocked() {
20467 if (mUserManager == null) {
20468 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20469 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20471 return mUserManager;
20474 private int applyUserId(int uid, int userId) {
20475 return UserHandle.getUid(userId, uid);
20478 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20479 if (info == null) return null;
20480 ApplicationInfo newInfo = new ApplicationInfo(info);
20481 newInfo.uid = applyUserId(info.uid, userId);
20482 newInfo.dataDir = Environment
20483 .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20484 .getAbsolutePath();
20488 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20490 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20494 ActivityInfo info = new ActivityInfo(aInfo);
20495 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20499 private final class LocalService extends ActivityManagerInternal {
20501 public void onWakefulnessChanged(int wakefulness) {
20502 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20506 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20507 String processName, String abiOverride, int uid, Runnable crashHandler) {
20508 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20509 processName, abiOverride, uid, crashHandler);
20513 public SleepToken acquireSleepToken(String tag) {
20514 Preconditions.checkNotNull(tag);
20516 synchronized (ActivityManagerService.this) {
20517 SleepTokenImpl token = new SleepTokenImpl(tag);
20518 mSleepTokens.add(token);
20519 updateSleepIfNeededLocked();
20525 public ComponentName getHomeActivityForUser(int userId) {
20526 synchronized (ActivityManagerService.this) {
20527 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20528 return homeActivity == null ? null : homeActivity.realActivity;
20533 private final class SleepTokenImpl extends SleepToken {
20534 private final String mTag;
20535 private final long mAcquireTime;
20537 public SleepTokenImpl(String tag) {
20539 mAcquireTime = SystemClock.uptimeMillis();
20543 public void release() {
20544 synchronized (ActivityManagerService.this) {
20545 if (mSleepTokens.remove(this)) {
20546 updateSleepIfNeededLocked();
20552 public String toString() {
20553 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20558 * An implementation of IAppTask, that allows an app to manage its own tasks via
20559 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
20560 * only the process that calls getAppTasks() can call the AppTask methods.
20562 class AppTaskImpl extends IAppTask.Stub {
20563 private int mTaskId;
20564 private int mCallingUid;
20566 public AppTaskImpl(int taskId, int callingUid) {
20568 mCallingUid = callingUid;
20571 private void checkCaller() {
20572 if (mCallingUid != Binder.getCallingUid()) {
20573 throw new SecurityException("Caller " + mCallingUid
20574 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20579 public void finishAndRemoveTask() {
20582 synchronized (ActivityManagerService.this) {
20583 long origId = Binder.clearCallingIdentity();
20585 if (!removeTaskByIdLocked(mTaskId, false)) {
20586 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20589 Binder.restoreCallingIdentity(origId);
20595 public ActivityManager.RecentTaskInfo getTaskInfo() {
20598 synchronized (ActivityManagerService.this) {
20599 long origId = Binder.clearCallingIdentity();
20601 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20603 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20605 return createRecentTaskInfoFromTaskRecord(tr);
20607 Binder.restoreCallingIdentity(origId);
20613 public void moveToFront() {
20615 // Will bring task to front if it already has a root activity.
20616 startActivityFromRecentsInner(mTaskId, null);
20620 public int startActivity(IBinder whoThread, String callingPackage,
20621 Intent intent, String resolvedType, Bundle options) {
20624 int callingUser = UserHandle.getCallingUserId();
20626 IApplicationThread appThread;
20627 synchronized (ActivityManagerService.this) {
20628 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20630 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20632 appThread = ApplicationThreadNative.asInterface(whoThread);
20633 if (appThread == null) {
20634 throw new IllegalArgumentException("Bad app thread " + appThread);
20637 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20638 resolvedType, null, null, null, null, 0, 0, null, null,
20639 null, options, false, callingUser, null, tr);
20643 public void setExcludeFromRecents(boolean exclude) {
20646 synchronized (ActivityManagerService.this) {
20647 long origId = Binder.clearCallingIdentity();
20649 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20651 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20653 Intent intent = tr.getBaseIntent();
20655 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20657 intent.setFlags(intent.getFlags()
20658 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20661 Binder.restoreCallingIdentity(origId);