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;
404 // Delay to disable app launch boost
405 static final int APP_BOOST_MESSAGE_DELAY = 3000;
406 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
407 static final int APP_BOOST_TIMEOUT = 2500;
409 private static native int nativeMigrateToBoost();
410 private static native int nativeMigrateFromBoost();
411 private boolean mIsBoosted = false;
412 private long mBoostStartTime = 0;
414 /** All system services */
415 SystemServiceManager mSystemServiceManager;
417 private Installer mInstaller;
419 /** Run all ActivityStacks through this */
420 ActivityStackSupervisor mStackSupervisor;
422 /** Task stack change listeners. */
423 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
424 new RemoteCallbackList<ITaskStackListener>();
426 public IntentFirewall mIntentFirewall;
428 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
429 // default actuion automatically. Important for devices without direct input
431 private boolean mShowDialogs = true;
433 BroadcastQueue mFgBroadcastQueue;
434 BroadcastQueue mBgBroadcastQueue;
435 // Convenient for easy iteration over the queues. Foreground is first
436 // so that dispatch of foreground broadcasts gets precedence.
437 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
439 BroadcastQueue broadcastQueueForIntent(Intent intent) {
440 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
441 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
442 "Broadcast intent " + intent + " on "
443 + (isFg ? "foreground" : "background") + " queue");
444 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
448 * Activity we have told the window manager to have key focus.
450 ActivityRecord mFocusedActivity = null;
453 * User id of the last activity mFocusedActivity was set to.
455 private int mLastFocusedUserId;
458 * If non-null, we are tracking the time the user spends in the currently focused app.
460 private AppTimeTracker mCurAppTimeTracker;
463 * List of intents that were used to start the most recent tasks.
465 private final RecentTasks mRecentTasks;
468 * For addAppTask: cached of the last activity component that was added.
470 ComponentName mLastAddedTaskComponent;
473 * For addAppTask: cached of the last activity uid that was added.
475 int mLastAddedTaskUid;
478 * For addAppTask: cached of the last ActivityInfo that was added.
480 ActivityInfo mLastAddedTaskActivity;
483 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
485 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
488 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
490 String mDeviceOwnerName;
492 public class PendingAssistExtras extends Binder implements Runnable {
493 public final ActivityRecord activity;
494 public final Bundle extras;
495 public final Intent intent;
496 public final String hint;
497 public final IResultReceiver receiver;
498 public final int userHandle;
499 public boolean haveResult = false;
500 public Bundle result = null;
501 public AssistStructure structure = null;
502 public AssistContent content = null;
503 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
504 String _hint, IResultReceiver _receiver, int _userHandle) {
505 activity = _activity;
509 receiver = _receiver;
510 userHandle = _userHandle;
514 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
515 synchronized (this) {
519 pendingAssistExtrasTimedOut(this);
523 final ArrayList<PendingAssistExtras> mPendingAssistExtras
524 = new ArrayList<PendingAssistExtras>();
527 * Process management.
529 final ProcessList mProcessList = new ProcessList();
532 * All of the applications we currently have running organized by name.
533 * The keys are strings of the application package name (as
534 * returned by the package manager), and the keys are ApplicationRecord
537 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
540 * Tracking long-term execution of processes to look for abuse and other
543 final ProcessStatsService mProcessStats;
546 * The currently running isolated processes.
548 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
551 * Counter for assigning isolated process uids, to avoid frequently reusing the
554 int mNextIsolatedProcessUid = 0;
557 * The currently running heavy-weight process, if any.
559 ProcessRecord mHeavyWeightProcess = null;
562 * The last time that various processes have crashed.
564 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
567 * Information about a process that is currently marked as bad.
569 static final class BadProcessInfo {
570 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
572 this.shortMsg = shortMsg;
573 this.longMsg = longMsg;
578 final String shortMsg;
579 final String longMsg;
584 * Set of applications that we consider to be bad, and will reject
585 * incoming broadcasts from (which the user has no control over).
586 * Processes are added to this set when they have crashed twice within
587 * a minimum amount of time; they are removed from it when they are
588 * later restarted (hopefully due to some user action). The value is the
589 * time it was added to the list.
591 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
594 * All of the processes we currently have running organized by pid.
595 * The keys are the pid running the application.
597 * <p>NOTE: This object is protected by its own lock, NOT the global
598 * activity manager lock!
600 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
603 * All of the processes that have been forced to be foreground. The key
604 * is the pid of the caller who requested it (we hold a death
607 abstract class ForegroundToken implements IBinder.DeathRecipient {
611 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
614 * List of records for processes that someone had tried to start before the
615 * system was ready. We don't start them at that point, but ensure they
616 * are started by the time booting is complete.
618 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
621 * List of persistent applications that are in the process
624 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
627 * Processes that are being forcibly torn down.
629 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
632 * List of running applications, sorted by recent usage.
633 * The first entry in the list is the least recently used.
635 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
638 * Where in mLruProcesses that the processes hosting activities start.
640 int mLruProcessActivityStart = 0;
643 * Where in mLruProcesses that the processes hosting services start.
644 * This is after (lower index) than mLruProcessesActivityStart.
646 int mLruProcessServiceStart = 0;
649 * List of processes that should gc as soon as things are idle.
651 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
654 * Processes we want to collect PSS data from.
656 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
659 * Last time we requested PSS data of all processes.
661 long mLastFullPssTime = SystemClock.uptimeMillis();
664 * If set, the next time we collect PSS data we should do a full collection
665 * with data from native processes and the kernel.
667 boolean mFullPssPending = false;
670 * This is the process holding what we currently consider to be
671 * the "home" activity.
673 ProcessRecord mHomeProcess;
676 * This is the process holding the activity the user last visited that
677 * is in a different process from the one they are currently in.
679 ProcessRecord mPreviousProcess;
682 * The time at which the previous process was last visible.
684 long mPreviousProcessVisibleTime;
687 * Track all uids that have actively running processes.
689 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
692 * Which users have been started, so are allowed to run code.
694 final SparseArray<UserState> mStartedUsers = new SparseArray<>();
697 * LRU list of history of current users. Most recently current is at the end.
699 final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
702 * Constant array of the users that are currently started.
704 int[] mStartedUserArray = new int[] { 0 };
707 * Registered observers of the user switching mechanics.
709 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
710 = new RemoteCallbackList<IUserSwitchObserver>();
713 * Currently active user switch.
715 Object mCurUserSwitchCallback;
718 * Packages that the user has asked to have run in screen size
719 * compatibility mode instead of filling the screen.
721 final CompatModePackages mCompatModePackages;
724 * Set of IntentSenderRecord objects that are currently active.
726 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
727 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
730 * Fingerprints (hashCode()) of stack traces that we've
731 * already logged DropBox entries for. Guarded by itself. If
732 * something (rogue user app) forces this over
733 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
735 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
736 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
739 * Strict Mode background batched logging state.
741 * The string buffer is guarded by itself, and its lock is also
742 * used to determine if another batched write is already
745 private final StringBuilder mStrictModeBuffer = new StringBuilder();
748 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
749 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
751 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
754 * Resolver for broadcast intents to registered receivers.
755 * Holds BroadcastFilter (subclass of IntentFilter).
757 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
758 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
760 protected boolean allowFilterResult(
761 BroadcastFilter filter, List<BroadcastFilter> dest) {
762 IBinder target = filter.receiverList.receiver.asBinder();
763 for (int i = dest.size() - 1; i >= 0; i--) {
764 if (dest.get(i).receiverList.receiver.asBinder() == target) {
772 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
773 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
774 || userId == filter.owningUserId) {
775 return super.newResult(filter, match, userId);
781 protected BroadcastFilter[] newArray(int size) {
782 return new BroadcastFilter[size];
786 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
787 return packageName.equals(filter.packageName);
792 * State of all active sticky broadcasts per user. Keys are the action of the
793 * sticky Intent, values are an ArrayList of all broadcasted intents with
794 * that action (which should usually be one). The SparseArray is keyed
795 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
796 * for stickies that are sent to all users.
798 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
799 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
801 final ActiveServices mServices;
803 final static class Association {
804 final int mSourceUid;
805 final String mSourceProcess;
806 final int mTargetUid;
807 final ComponentName mTargetComponent;
808 final String mTargetProcess;
816 Association(int sourceUid, String sourceProcess, int targetUid,
817 ComponentName targetComponent, String targetProcess) {
818 mSourceUid = sourceUid;
819 mSourceProcess = sourceProcess;
820 mTargetUid = targetUid;
821 mTargetComponent = targetComponent;
822 mTargetProcess = targetProcess;
827 * When service association tracking is enabled, this is all of the associations we
828 * have seen. Mapping is target uid -> target component -> source uid -> source process name
829 * -> association data.
831 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
832 mAssociations = new SparseArray<>();
833 boolean mTrackingAssociations;
836 * Backup/restore process management
838 String mBackupAppName = null;
839 BackupRecord mBackupTarget = null;
841 final ProviderMap mProviderMap;
844 * List of content providers who have clients waiting for them. The
845 * application is currently being launched and the provider will be
846 * removed from this list once it is published.
848 final ArrayList<ContentProviderRecord> mLaunchingProviders
849 = new ArrayList<ContentProviderRecord>();
852 * File storing persisted {@link #mGrantedUriPermissions}.
854 private final AtomicFile mGrantFile;
856 /** XML constants used in {@link #mGrantFile} */
857 private static final String TAG_URI_GRANTS = "uri-grants";
858 private static final String TAG_URI_GRANT = "uri-grant";
859 private static final String ATTR_USER_HANDLE = "userHandle";
860 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
861 private static final String ATTR_TARGET_USER_ID = "targetUserId";
862 private static final String ATTR_SOURCE_PKG = "sourcePkg";
863 private static final String ATTR_TARGET_PKG = "targetPkg";
864 private static final String ATTR_URI = "uri";
865 private static final String ATTR_MODE_FLAGS = "modeFlags";
866 private static final String ATTR_CREATED_TIME = "createdTime";
867 private static final String ATTR_PREFIX = "prefix";
870 * Global set of specific {@link Uri} permissions that have been granted.
871 * This optimized lookup structure maps from {@link UriPermission#targetUid}
872 * to {@link UriPermission#uri} to {@link UriPermission}.
875 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
876 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
878 public static class GrantUri {
879 public final int sourceUserId;
880 public final Uri uri;
881 public boolean prefix;
883 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
884 this.sourceUserId = sourceUserId;
886 this.prefix = prefix;
890 public int hashCode() {
892 hashCode = 31 * hashCode + sourceUserId;
893 hashCode = 31 * hashCode + uri.hashCode();
894 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
899 public boolean equals(Object o) {
900 if (o instanceof GrantUri) {
901 GrantUri other = (GrantUri) o;
902 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
903 && prefix == other.prefix;
909 public String toString() {
910 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
911 if (prefix) result += " [prefix]";
915 public String toSafeString() {
916 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
917 if (prefix) result += " [prefix]";
921 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
922 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
923 ContentProvider.getUriWithoutUserId(uri), false);
927 CoreSettingsObserver mCoreSettingsObserver;
930 * Thread-local storage used to carry caller permissions over through
931 * indirect content-provider access.
933 private class Identity {
934 public final IBinder token;
935 public final int pid;
936 public final int uid;
938 Identity(IBinder _token, int _pid, int _uid) {
945 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
948 * All information we have collected about the runtime performance of
949 * any user id that can impact battery performance.
951 final BatteryStatsService mBatteryStatsService;
954 * Information about component usage
956 UsageStatsManagerInternal mUsageStatsService;
959 * Access to DeviceIdleController service.
961 DeviceIdleController.LocalService mLocalDeviceIdleController;
964 * Information about and control over application operations
966 final AppOpsService mAppOpsService;
969 * Save recent tasks information across reboots.
971 final TaskPersister mTaskPersister;
974 * Current configuration information. HistoryRecord objects are given
975 * a reference to this object to indicate which configuration they are
976 * currently running in, so this object must be kept immutable.
978 Configuration mConfiguration = new Configuration();
981 * Current sequencing integer of the configuration, for skipping old
984 int mConfigurationSeq = 0;
987 * Hardware-reported OpenGLES version.
989 final int GL_ES_VERSION;
992 * List of initialization arguments to pass to all processes when binding applications to them.
993 * For example, references to the commonly used services.
995 HashMap<String, IBinder> mAppBindArgs;
998 * Temporary to avoid allocations. Protected by main lock.
1000 final StringBuilder mStringBuilder = new StringBuilder(256);
1003 * Used to control how we initialize the service.
1005 ComponentName mTopComponent;
1006 String mTopAction = Intent.ACTION_MAIN;
1008 boolean mProcessesReady = false;
1009 boolean mSystemReady = false;
1010 boolean mBooting = false;
1011 boolean mCallFinishBooting = false;
1012 boolean mBootAnimationComplete = false;
1013 boolean mWaitingUpdate = false;
1014 boolean mDidUpdate = false;
1015 boolean mOnBattery = false;
1016 boolean mLaunchWarningShown = false;
1022 boolean mCheckedForSetup;
1025 * The time at which we will allow normal application switches again,
1026 * after a call to {@link #stopAppSwitches()}.
1028 long mAppSwitchesAllowedTime;
1031 * This is set to true after the first switch after mAppSwitchesAllowedTime
1032 * is set; any switches after that will clear the time.
1034 boolean mDidAppSwitch;
1037 * Last time (in realtime) at which we checked for power usage.
1039 long mLastPowerCheckRealtime;
1042 * Last time (in uptime) at which we checked for power usage.
1044 long mLastPowerCheckUptime;
1047 * Set while we are wanting to sleep, to prevent any
1048 * activities from being started/resumed.
1050 private boolean mSleeping = false;
1053 * The process state used for processes that are running the top activities.
1054 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1056 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1059 * Set while we are running a voice interaction. This overrides
1060 * sleeping while it is active.
1062 private IVoiceInteractionSession mRunningVoice;
1065 * For some direct access we need to power manager.
1067 PowerManagerInternal mLocalPowerManager;
1070 * We want to hold a wake lock while running a voice interaction session, since
1071 * this may happen with the screen off and we need to keep the CPU running to
1072 * be able to continue to interact with the user.
1074 PowerManager.WakeLock mVoiceWakeLock;
1077 * State of external calls telling us if the device is awake or asleep.
1079 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1082 * A list of tokens that cause the top activity to be put to sleep.
1083 * They are used by components that may hide and block interaction with underlying
1086 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1088 static final int LOCK_SCREEN_HIDDEN = 0;
1089 static final int LOCK_SCREEN_LEAVING = 1;
1090 static final int LOCK_SCREEN_SHOWN = 2;
1092 * State of external call telling us if the lock screen is shown.
1094 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1097 * Set if we are shutting down the system, similar to sleeping.
1099 boolean mShuttingDown = false;
1102 * Current sequence id for oom_adj computation traversal.
1107 * Current sequence id for process LRU updating.
1112 * Keep track of the non-cached/empty process we last found, to help
1113 * determine how to distribute cached/empty processes next time.
1115 int mNumNonCachedProcs = 0;
1118 * Keep track of the number of cached hidden procs, to balance oom adj
1119 * distribution between those and empty procs.
1121 int mNumCachedHiddenProcs = 0;
1124 * Keep track of the number of service processes we last found, to
1125 * determine on the next iteration which should be B services.
1127 int mNumServiceProcs = 0;
1128 int mNewNumAServiceProcs = 0;
1129 int mNewNumServiceProcs = 0;
1132 * Allow the current computed overall memory level of the system to go down?
1133 * This is set to false when we are killing processes for reasons other than
1134 * memory management, so that the now smaller process list will not be taken as
1135 * an indication that memory is tighter.
1137 boolean mAllowLowerMemLevel = false;
1140 * The last computed memory level, for holding when we are in a state that
1141 * processes are going away for other reasons.
1143 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1146 * The last total number of process we have, to determine if changes actually look
1147 * like a shrinking number of process due to lower RAM.
1149 int mLastNumProcesses;
1152 * The uptime of the last time we performed idle maintenance.
1154 long mLastIdleTime = SystemClock.uptimeMillis();
1157 * Total time spent with RAM that has been added in the past since the last idle time.
1159 long mLowRamTimeSinceLastIdle = 0;
1162 * If RAM is currently low, when that horrible situation started.
1164 long mLowRamStartTime = 0;
1167 * For reporting to battery stats the current top application.
1169 private String mCurResumedPackage = null;
1170 private int mCurResumedUid = -1;
1173 * For reporting to battery stats the apps currently running foreground
1174 * service. The ProcessMap is package/uid tuples; each of these contain
1175 * an array of the currently foreground processes.
1177 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1178 = new ProcessMap<ArrayList<ProcessRecord>>();
1181 * This is set if we had to do a delayed dexopt of an app before launching
1182 * it, to increase the ANR timeouts in that case.
1187 * Set if the systemServer made a call to enterSafeMode.
1192 * If true, we are running under a test environment so will sample PSS from processes
1193 * much more rapidly to try to collect better data when the tests are rapidly
1194 * running through apps.
1196 boolean mTestPssMode = false;
1198 String mDebugApp = null;
1199 boolean mWaitForDebugger = false;
1200 boolean mDebugTransient = false;
1201 String mOrigDebugApp = null;
1202 boolean mOrigWaitForDebugger = false;
1203 boolean mAlwaysFinishActivities = false;
1204 IActivityController mController = null;
1205 String mProfileApp = null;
1206 ProcessRecord mProfileProc = null;
1207 String mProfileFile;
1208 ParcelFileDescriptor mProfileFd;
1209 int mSamplingInterval = 0;
1210 boolean mAutoStopProfiler = false;
1211 int mProfileType = 0;
1212 String mOpenGlTraceApp = null;
1213 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1214 String mMemWatchDumpProcName;
1215 String mMemWatchDumpFile;
1216 int mMemWatchDumpPid;
1217 int mMemWatchDumpUid;
1219 final long[] mTmpLong = new long[1];
1221 static final class ProcessChangeItem {
1222 static final int CHANGE_ACTIVITIES = 1<<0;
1223 static final int CHANGE_PROCESS_STATE = 1<<1;
1228 boolean foregroundActivities;
1231 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1232 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1234 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1235 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1237 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1238 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1240 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1241 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1244 * Runtime CPU use collection thread. This object's lock is used to
1245 * perform synchronization with the thread (notifying it to run).
1247 final Thread mProcessCpuThread;
1250 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1251 * Must acquire this object's lock when accessing it.
1252 * NOTE: this lock will be held while doing long operations (trawling
1253 * through all processes in /proc), so it should never be acquired by
1254 * any critical paths such as when holding the main activity manager lock.
1256 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1257 MONITOR_THREAD_CPU_USAGE);
1258 final AtomicLong mLastCpuTime = new AtomicLong(0);
1259 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1261 long mLastWriteTime = 0;
1264 * Used to retain an update lock when the foreground activity is in
1267 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1270 * Set to true after the system has finished booting.
1272 boolean mBooted = false;
1274 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1275 int mProcessLimitOverride = -1;
1277 WindowManagerService mWindowManager;
1279 final ActivityThread mSystemThread;
1281 // Holds the current foreground user's id
1282 int mCurrentUserId = 0;
1283 // Holds the target user's id during a user switch
1284 int mTargetUserId = UserHandle.USER_NULL;
1285 // If there are multiple profiles for the current user, their ids are here
1286 // Currently only the primary user can have managed profiles
1287 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1290 * Mapping from each known user ID to the profile group ID it is associated with.
1292 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1294 private UserManagerService mUserManager;
1296 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1297 final ProcessRecord mApp;
1299 final IApplicationThread mAppThread;
1301 AppDeathRecipient(ProcessRecord app, int pid,
1302 IApplicationThread thread) {
1303 if (DEBUG_ALL) Slog.v(
1304 TAG, "New death recipient " + this
1305 + " for thread " + thread.asBinder());
1308 mAppThread = thread;
1312 public void binderDied() {
1313 if (DEBUG_ALL) Slog.v(
1314 TAG, "Death received in " + this
1315 + " for thread " + mAppThread.asBinder());
1316 synchronized(ActivityManagerService.this) {
1317 appDiedLocked(mApp, mPid, mAppThread, true);
1322 static final int SHOW_ERROR_MSG = 1;
1323 static final int SHOW_NOT_RESPONDING_MSG = 2;
1324 static final int SHOW_FACTORY_ERROR_MSG = 3;
1325 static final int UPDATE_CONFIGURATION_MSG = 4;
1326 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1327 static final int WAIT_FOR_DEBUGGER_MSG = 6;
1328 static final int SERVICE_TIMEOUT_MSG = 12;
1329 static final int UPDATE_TIME_ZONE = 13;
1330 static final int SHOW_UID_ERROR_MSG = 14;
1331 static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1332 static final int PROC_START_TIMEOUT_MSG = 20;
1333 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1334 static final int KILL_APPLICATION_MSG = 22;
1335 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1336 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1337 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1338 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1339 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1340 static final int CLEAR_DNS_CACHE_MSG = 28;
1341 static final int UPDATE_HTTP_PROXY_MSG = 29;
1342 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1343 static final int DISPATCH_PROCESSES_CHANGED = 31;
1344 static final int DISPATCH_PROCESS_DIED = 32;
1345 static final int REPORT_MEM_USAGE_MSG = 33;
1346 static final int REPORT_USER_SWITCH_MSG = 34;
1347 static final int CONTINUE_USER_SWITCH_MSG = 35;
1348 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1349 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1350 static final int PERSIST_URI_GRANTS_MSG = 38;
1351 static final int REQUEST_ALL_PSS_MSG = 39;
1352 static final int START_PROFILES_MSG = 40;
1353 static final int UPDATE_TIME = 41;
1354 static final int SYSTEM_USER_START_MSG = 42;
1355 static final int SYSTEM_USER_CURRENT_MSG = 43;
1356 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1357 static final int FINISH_BOOTING_MSG = 45;
1358 static final int START_USER_SWITCH_MSG = 46;
1359 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1360 static final int DISMISS_DIALOG_MSG = 48;
1361 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1362 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1363 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1364 static final int DELETE_DUMPHEAP_MSG = 52;
1365 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1366 static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1367 static final int REPORT_TIME_TRACKER_MSG = 55;
1368 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1369 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1370 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1372 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1373 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1374 static final int FIRST_COMPAT_MODE_MSG = 300;
1375 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1377 CompatModeDialog mCompatModeDialog;
1378 long mLastMemUsageReportTime = 0;
1381 * Flag whether the current user is a "monkey", i.e. whether
1382 * the UI is driven by a UI automation tool.
1384 private boolean mUserIsMonkey;
1386 /** Flag whether the device has a Recents UI */
1387 boolean mHasRecents;
1389 /** The dimensions of the thumbnails in the Recents UI. */
1390 int mThumbnailWidth;
1391 int mThumbnailHeight;
1393 final ServiceThread mHandlerThread;
1394 final MainHandler mHandler;
1395 final UiHandler mUiHandler;
1397 final class UiHandler extends Handler {
1398 public UiHandler() {
1399 super(com.android.server.UiThread.get().getLooper(), null, true);
1403 public void handleMessage(Message msg) {
1405 case SHOW_ERROR_MSG: {
1406 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1407 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1408 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1409 synchronized (ActivityManagerService.this) {
1410 ProcessRecord proc = (ProcessRecord)data.get("app");
1411 AppErrorResult res = (AppErrorResult) data.get("result");
1412 if (proc != null && proc.crashDialog != null) {
1413 Slog.e(TAG, "App already has crash dialog: " + proc);
1419 boolean isBackground = (UserHandle.getAppId(proc.uid)
1420 >= Process.FIRST_APPLICATION_UID
1421 && proc.pid != MY_PID);
1422 for (int userId : mCurrentProfileIds) {
1423 isBackground &= (proc.userId != userId);
1425 if (isBackground && !showBackground) {
1426 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1432 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1433 Dialog d = new AppErrorDialog(mContext,
1434 ActivityManagerService.this, res, proc);
1436 proc.crashDialog = d;
1438 // The device is asleep, so just pretend that the user
1439 // saw a crash dialog and hit "force quit".
1446 ensureBootCompleted();
1448 case SHOW_NOT_RESPONDING_MSG: {
1449 synchronized (ActivityManagerService.this) {
1450 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1451 ProcessRecord proc = (ProcessRecord)data.get("app");
1452 if (proc != null && proc.anrDialog != null) {
1453 Slog.e(TAG, "App already has anr dialog: " + proc);
1457 Intent intent = new Intent("android.intent.action.ANR");
1458 if (!mProcessesReady) {
1459 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1460 | Intent.FLAG_RECEIVER_FOREGROUND);
1462 broadcastIntentLocked(null, null, intent,
1463 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1464 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1467 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1468 mContext, proc, (ActivityRecord)data.get("activity"),
1473 // Just kill the app if there is no dialog to be shown.
1474 killAppAtUsersRequest(proc, null);
1478 ensureBootCompleted();
1480 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1481 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1482 synchronized (ActivityManagerService.this) {
1483 ProcessRecord proc = (ProcessRecord) data.get("app");
1485 Slog.e(TAG, "App not found when showing strict mode dialog.");
1488 if (proc.crashDialog != null) {
1489 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1492 AppErrorResult res = (AppErrorResult) data.get("result");
1493 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1494 Dialog d = new StrictModeViolationDialog(mContext,
1495 ActivityManagerService.this, res, proc);
1497 proc.crashDialog = d;
1499 // The device is asleep, so just pretend that the user
1500 // saw a crash dialog and hit "force quit".
1504 ensureBootCompleted();
1506 case SHOW_FACTORY_ERROR_MSG: {
1507 Dialog d = new FactoryErrorDialog(
1508 mContext, msg.getData().getCharSequence("msg"));
1510 ensureBootCompleted();
1512 case WAIT_FOR_DEBUGGER_MSG: {
1513 synchronized (ActivityManagerService.this) {
1514 ProcessRecord app = (ProcessRecord)msg.obj;
1515 if (msg.arg1 != 0) {
1516 if (!app.waitedForDebugger) {
1517 Dialog d = new AppWaitingForDebuggerDialog(
1518 ActivityManagerService.this,
1521 app.waitedForDebugger = true;
1525 if (app.waitDialog != null) {
1526 app.waitDialog.dismiss();
1527 app.waitDialog = null;
1532 case SHOW_UID_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_wipe_data));
1539 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1540 obtainMessage(DISMISS_DIALOG_MSG, d));
1544 case SHOW_FINGERPRINT_ERROR_MSG: {
1546 AlertDialog d = new BaseErrorDialog(mContext);
1547 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1548 d.setCancelable(false);
1549 d.setTitle(mContext.getText(R.string.android_system_label));
1550 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1551 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1552 obtainMessage(DISMISS_DIALOG_MSG, d));
1556 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1557 synchronized (ActivityManagerService.this) {
1558 ActivityRecord ar = (ActivityRecord) msg.obj;
1559 if (mCompatModeDialog != null) {
1560 if (mCompatModeDialog.mAppInfo.packageName.equals(
1561 ar.info.applicationInfo.packageName)) {
1564 mCompatModeDialog.dismiss();
1565 mCompatModeDialog = null;
1567 if (ar != null && false) {
1568 if (mCompatModePackages.getPackageAskCompatModeLocked(
1570 int mode = mCompatModePackages.computeCompatModeLocked(
1571 ar.info.applicationInfo);
1572 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1573 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1574 mCompatModeDialog = new CompatModeDialog(
1575 ActivityManagerService.this, mContext,
1576 ar.info.applicationInfo);
1577 mCompatModeDialog.show();
1584 case START_USER_SWITCH_MSG: {
1585 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1588 case DISMISS_DIALOG_MSG: {
1589 final Dialog d = (Dialog) msg.obj;
1593 case DISPATCH_PROCESSES_CHANGED: {
1594 dispatchProcessesChanged();
1597 case DISPATCH_PROCESS_DIED: {
1598 final int pid = msg.arg1;
1599 final int uid = msg.arg2;
1600 dispatchProcessDied(pid, uid);
1603 case DISPATCH_UIDS_CHANGED_MSG: {
1604 dispatchUidsChanged();
1610 final class MainHandler extends Handler {
1611 public MainHandler(Looper looper) {
1612 super(looper, null, true);
1616 public void handleMessage(Message msg) {
1618 case UPDATE_CONFIGURATION_MSG: {
1619 final ContentResolver resolver = mContext.getContentResolver();
1620 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1622 case GC_BACKGROUND_PROCESSES_MSG: {
1623 synchronized (ActivityManagerService.this) {
1624 performAppGcsIfAppropriateLocked();
1627 case SERVICE_TIMEOUT_MSG: {
1630 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1632 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1635 mServices.serviceTimeout((ProcessRecord)msg.obj);
1637 case UPDATE_TIME_ZONE: {
1638 synchronized (ActivityManagerService.this) {
1639 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1640 ProcessRecord r = mLruProcesses.get(i);
1641 if (r.thread != null) {
1643 r.thread.updateTimeZone();
1644 } catch (RemoteException ex) {
1645 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1651 case CLEAR_DNS_CACHE_MSG: {
1652 synchronized (ActivityManagerService.this) {
1653 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1654 ProcessRecord r = mLruProcesses.get(i);
1655 if (r.thread != null) {
1657 r.thread.clearDnsCache();
1658 } catch (RemoteException ex) {
1659 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1665 case UPDATE_HTTP_PROXY_MSG: {
1666 ProxyInfo proxy = (ProxyInfo)msg.obj;
1669 String exclList = "";
1670 Uri pacFileUrl = Uri.EMPTY;
1671 if (proxy != null) {
1672 host = proxy.getHost();
1673 port = Integer.toString(proxy.getPort());
1674 exclList = proxy.getExclusionListAsString();
1675 pacFileUrl = proxy.getPacFileUrl();
1677 synchronized (ActivityManagerService.this) {
1678 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1679 ProcessRecord r = mLruProcesses.get(i);
1680 if (r.thread != null) {
1682 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1683 } catch (RemoteException ex) {
1684 Slog.w(TAG, "Failed to update http proxy for: " +
1685 r.info.processName);
1691 case PROC_START_TIMEOUT_MSG: {
1694 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1696 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1699 ProcessRecord app = (ProcessRecord)msg.obj;
1700 synchronized (ActivityManagerService.this) {
1701 processStartTimedOutLocked(app);
1704 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1705 synchronized (ActivityManagerService.this) {
1706 mStackSupervisor.doPendingActivityLaunchesLocked(true);
1709 case KILL_APPLICATION_MSG: {
1710 synchronized (ActivityManagerService.this) {
1711 int appid = msg.arg1;
1712 boolean restart = (msg.arg2 == 1);
1713 Bundle bundle = (Bundle)msg.obj;
1714 String pkg = bundle.getString("pkg");
1715 String reason = bundle.getString("reason");
1716 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1717 false, UserHandle.USER_ALL, reason);
1720 case FINALIZE_PENDING_INTENT_MSG: {
1721 ((PendingIntentRecord)msg.obj).completeFinalize();
1723 case POST_HEAVY_NOTIFICATION_MSG: {
1724 INotificationManager inm = NotificationManager.getService();
1729 ActivityRecord root = (ActivityRecord)msg.obj;
1730 ProcessRecord process = root.app;
1731 if (process == null) {
1736 Context context = mContext.createPackageContext(process.info.packageName, 0);
1737 String text = mContext.getString(R.string.heavy_weight_notification,
1738 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1739 Notification notification = new Notification.Builder(context)
1740 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1744 .setColor(mContext.getColor(
1745 com.android.internal.R.color.system_notification_accent_color))
1746 .setContentTitle(text)
1748 mContext.getText(R.string.heavy_weight_notification_detail))
1749 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1750 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1751 new UserHandle(root.userId)))
1754 int[] outId = new int[1];
1755 inm.enqueueNotificationWithTag("android", "android", null,
1756 R.string.heavy_weight_notification,
1757 notification, outId, root.userId);
1758 } catch (RuntimeException e) {
1759 Slog.w(ActivityManagerService.TAG,
1760 "Error showing notification for heavy-weight app", e);
1761 } catch (RemoteException e) {
1763 } catch (NameNotFoundException e) {
1764 Slog.w(TAG, "Unable to create context for heavy notification", e);
1767 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1768 INotificationManager inm = NotificationManager.getService();
1773 inm.cancelNotificationWithTag("android", null,
1774 R.string.heavy_weight_notification, msg.arg1);
1775 } catch (RuntimeException e) {
1776 Slog.w(ActivityManagerService.TAG,
1777 "Error canceling notification for service", e);
1778 } catch (RemoteException e) {
1781 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1782 synchronized (ActivityManagerService.this) {
1783 checkExcessivePowerUsageLocked(true);
1784 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1785 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1786 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1789 case REPORT_MEM_USAGE_MSG: {
1790 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1791 Thread thread = new Thread() {
1792 @Override public void run() {
1793 reportMemUsage(memInfos);
1799 case REPORT_USER_SWITCH_MSG: {
1800 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1803 case CONTINUE_USER_SWITCH_MSG: {
1804 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1807 case USER_SWITCH_TIMEOUT_MSG: {
1808 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1811 case IMMERSIVE_MODE_LOCK_MSG: {
1812 final boolean nextState = (msg.arg1 != 0);
1813 if (mUpdateLock.isHeld() != nextState) {
1814 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1815 "Applying new update lock state '" + nextState
1816 + "' for " + (ActivityRecord)msg.obj);
1818 mUpdateLock.acquire();
1820 mUpdateLock.release();
1825 case PERSIST_URI_GRANTS_MSG: {
1826 writeGrantedUriPermissions();
1829 case REQUEST_ALL_PSS_MSG: {
1830 synchronized (ActivityManagerService.this) {
1831 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1835 case START_PROFILES_MSG: {
1836 synchronized (ActivityManagerService.this) {
1837 startProfilesLocked();
1842 synchronized (ActivityManagerService.this) {
1843 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1844 ProcessRecord r = mLruProcesses.get(i);
1845 if (r.thread != null) {
1847 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1848 } catch (RemoteException ex) {
1849 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1856 case SYSTEM_USER_START_MSG: {
1857 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1858 Integer.toString(msg.arg1), msg.arg1);
1859 mSystemServiceManager.startUser(msg.arg1);
1862 case SYSTEM_USER_CURRENT_MSG: {
1863 mBatteryStatsService.noteEvent(
1864 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1865 Integer.toString(msg.arg2), msg.arg2);
1866 mBatteryStatsService.noteEvent(
1867 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1868 Integer.toString(msg.arg1), msg.arg1);
1869 mSystemServiceManager.switchUser(msg.arg1);
1872 case ENTER_ANIMATION_COMPLETE_MSG: {
1873 synchronized (ActivityManagerService.this) {
1874 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1875 if (r != null && r.app != null && r.app.thread != null) {
1877 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1878 } catch (RemoteException e) {
1884 case FINISH_BOOTING_MSG: {
1885 if (msg.arg1 != 0) {
1888 if (msg.arg2 != 0) {
1889 enableScreenAfterBoot();
1893 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1895 Locale l = (Locale) msg.obj;
1896 IBinder service = ServiceManager.getService("mount");
1897 IMountService mountService = IMountService.Stub.asInterface(service);
1898 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1899 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1900 } catch (RemoteException e) {
1901 Log.e(TAG, "Error storing locale for decryption UI", e);
1905 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1906 synchronized (ActivityManagerService.this) {
1907 int i = mTaskStackListeners.beginBroadcast();
1911 // Make a one-way callback to the listener
1912 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1913 } catch (RemoteException e){
1914 // Handled by the RemoteCallbackList
1917 mTaskStackListeners.finishBroadcast();
1921 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1922 final int uid = msg.arg1;
1923 final byte[] firstPacket = (byte[]) msg.obj;
1925 synchronized (mPidsSelfLocked) {
1926 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1927 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1930 p.thread.notifyCleartextNetwork(firstPacket);
1931 } catch (RemoteException ignored) {
1938 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1939 final String procName;
1941 final long memLimit;
1942 final String reportPackage;
1943 synchronized (ActivityManagerService.this) {
1944 procName = mMemWatchDumpProcName;
1945 uid = mMemWatchDumpUid;
1946 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1948 val = mMemWatchProcesses.get(procName, 0);
1951 memLimit = val.first;
1952 reportPackage = val.second;
1955 reportPackage = null;
1958 if (procName == null) {
1962 if (DEBUG_PSS) Slog.d(TAG_PSS,
1963 "Showing dump heap notification from " + procName + "/" + uid);
1965 INotificationManager inm = NotificationManager.getService();
1970 String text = mContext.getString(R.string.dump_heap_notification, procName);
1973 Intent deleteIntent = new Intent();
1974 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1975 Intent intent = new Intent();
1976 intent.setClassName("android", DumpHeapActivity.class.getName());
1977 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1978 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1979 if (reportPackage != null) {
1980 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1982 int userId = UserHandle.getUserId(uid);
1983 Notification notification = new Notification.Builder(mContext)
1984 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1987 .setAutoCancel(true)
1989 .setColor(mContext.getColor(
1990 com.android.internal.R.color.system_notification_accent_color))
1991 .setContentTitle(text)
1993 mContext.getText(R.string.dump_heap_notification_detail))
1994 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1995 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1996 new UserHandle(userId)))
1997 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
1998 deleteIntent, 0, UserHandle.OWNER))
2002 int[] outId = new int[1];
2003 inm.enqueueNotificationWithTag("android", "android", null,
2004 R.string.dump_heap_notification,
2005 notification, outId, userId);
2006 } catch (RuntimeException e) {
2007 Slog.w(ActivityManagerService.TAG,
2008 "Error showing notification for dump heap", e);
2009 } catch (RemoteException e) {
2012 case DELETE_DUMPHEAP_MSG: {
2013 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2014 DumpHeapActivity.JAVA_URI,
2015 Intent.FLAG_GRANT_READ_URI_PERMISSION
2016 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2017 UserHandle.myUserId());
2018 synchronized (ActivityManagerService.this) {
2019 mMemWatchDumpFile = null;
2020 mMemWatchDumpProcName = null;
2021 mMemWatchDumpPid = -1;
2022 mMemWatchDumpUid = -1;
2025 case FOREGROUND_PROFILE_CHANGED_MSG: {
2026 dispatchForegroundProfileChanged(msg.arg1);
2028 case REPORT_TIME_TRACKER_MSG: {
2029 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2030 tracker.deliverResult(mContext);
2032 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2033 dispatchUserSwitchComplete(msg.arg1);
2035 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2036 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2038 connection.shutdown();
2039 } catch (RemoteException e) {
2040 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2042 // Only a UiAutomation can set this flag and now that
2043 // it is finished we make sure it is reset to its default.
2044 mUserIsMonkey = false;
2046 case APP_BOOST_DEACTIVATE_MSG : {
2047 synchronized(ActivityManagerService.this) {
2049 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2050 nativeMigrateFromBoost();
2052 mBoostStartTime = 0;
2054 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2055 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2064 static final int COLLECT_PSS_BG_MSG = 1;
2066 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2068 public void handleMessage(Message msg) {
2070 case COLLECT_PSS_BG_MSG: {
2071 long start = SystemClock.uptimeMillis();
2072 MemInfoReader memInfo = null;
2073 synchronized (ActivityManagerService.this) {
2074 if (mFullPssPending) {
2075 mFullPssPending = false;
2076 memInfo = new MemInfoReader();
2079 if (memInfo != null) {
2080 updateCpuStatsNow();
2081 long nativeTotalPss = 0;
2082 synchronized (mProcessCpuTracker) {
2083 final int N = mProcessCpuTracker.countStats();
2084 for (int j=0; j<N; j++) {
2085 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2086 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2087 // This is definitely an application process; skip it.
2090 synchronized (mPidsSelfLocked) {
2091 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2092 // This is one of our own processes; skip it.
2096 nativeTotalPss += Debug.getPss(st.pid, null, null);
2099 memInfo.readMemInfo();
2100 synchronized (ActivityManagerService.this) {
2101 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2102 + (SystemClock.uptimeMillis()-start) + "ms");
2103 final long cachedKb = memInfo.getCachedSizeKb();
2104 final long freeKb = memInfo.getFreeSizeKb();
2105 final long zramKb = memInfo.getZramTotalSizeKb();
2106 final long kernelKb = memInfo.getKernelUsedSizeKb();
2107 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2108 kernelKb*1024, nativeTotalPss*1024);
2109 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2115 long[] tmp = new long[1];
2121 synchronized (ActivityManagerService.this) {
2122 if (mPendingPssProcesses.size() <= 0) {
2123 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2124 "Collected PSS of " + num + " processes in "
2125 + (SystemClock.uptimeMillis() - start) + "ms");
2126 mPendingPssProcesses.clear();
2129 proc = mPendingPssProcesses.remove(0);
2130 procState = proc.pssProcState;
2131 lastPssTime = proc.lastPssTime;
2132 if (proc.thread != null && procState == proc.setProcState
2133 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2134 < SystemClock.uptimeMillis()) {
2142 long pss = Debug.getPss(pid, tmp, null);
2143 synchronized (ActivityManagerService.this) {
2144 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2145 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2147 recordPssSampleLocked(proc, procState, pss, tmp[0],
2148 SystemClock.uptimeMillis());
2158 public void setSystemProcess() {
2160 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2161 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2162 ServiceManager.addService("meminfo", new MemBinder(this));
2163 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2164 ServiceManager.addService("dbinfo", new DbBinder(this));
2165 if (MONITOR_CPU_USAGE) {
2166 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2168 ServiceManager.addService("permission", new PermissionController(this));
2169 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2171 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2172 "android", STOCK_PM_FLAGS);
2173 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2175 synchronized (this) {
2176 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2177 app.persistent = true;
2179 app.maxAdj = ProcessList.SYSTEM_ADJ;
2180 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2181 synchronized (mPidsSelfLocked) {
2182 mPidsSelfLocked.put(app.pid, app);
2184 updateLruProcessLocked(app, false, null);
2185 updateOomAdjLocked();
2187 } catch (PackageManager.NameNotFoundException e) {
2188 throw new RuntimeException(
2189 "Unable to find android system package", e);
2193 public void setWindowManager(WindowManagerService wm) {
2194 mWindowManager = wm;
2195 mStackSupervisor.setWindowManager(wm);
2198 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2199 mUsageStatsService = usageStatsManager;
2202 public void startObservingNativeCrashes() {
2203 final NativeCrashListener ncl = new NativeCrashListener(this);
2207 public IAppOpsService getAppOpsService() {
2208 return mAppOpsService;
2211 static class MemBinder extends Binder {
2212 ActivityManagerService mActivityManagerService;
2213 MemBinder(ActivityManagerService activityManagerService) {
2214 mActivityManagerService = activityManagerService;
2218 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2219 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2220 != PackageManager.PERMISSION_GRANTED) {
2221 pw.println("Permission Denial: can't dump meminfo from from pid="
2222 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2223 + " without permission " + android.Manifest.permission.DUMP);
2227 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2231 static class GraphicsBinder extends Binder {
2232 ActivityManagerService mActivityManagerService;
2233 GraphicsBinder(ActivityManagerService activityManagerService) {
2234 mActivityManagerService = activityManagerService;
2238 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2239 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2240 != PackageManager.PERMISSION_GRANTED) {
2241 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2242 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2243 + " without permission " + android.Manifest.permission.DUMP);
2247 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2251 static class DbBinder extends Binder {
2252 ActivityManagerService mActivityManagerService;
2253 DbBinder(ActivityManagerService activityManagerService) {
2254 mActivityManagerService = activityManagerService;
2258 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2259 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2260 != PackageManager.PERMISSION_GRANTED) {
2261 pw.println("Permission Denial: can't dump dbinfo from from pid="
2262 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2263 + " without permission " + android.Manifest.permission.DUMP);
2267 mActivityManagerService.dumpDbInfo(fd, pw, args);
2271 static class CpuBinder extends Binder {
2272 ActivityManagerService mActivityManagerService;
2273 CpuBinder(ActivityManagerService activityManagerService) {
2274 mActivityManagerService = activityManagerService;
2278 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2279 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2280 != PackageManager.PERMISSION_GRANTED) {
2281 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2282 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2283 + " without permission " + android.Manifest.permission.DUMP);
2287 synchronized (mActivityManagerService.mProcessCpuTracker) {
2288 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2289 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2290 SystemClock.uptimeMillis()));
2295 public static final class Lifecycle extends SystemService {
2296 private final ActivityManagerService mService;
2298 public Lifecycle(Context context) {
2300 mService = new ActivityManagerService(context);
2304 public void onStart() {
2308 public ActivityManagerService getService() {
2313 // Note: This method is invoked on the main thread but may need to attach various
2314 // handlers to other threads. So take care to be explicit about the looper.
2315 public ActivityManagerService(Context systemContext) {
2316 mContext = systemContext;
2317 mFactoryTest = FactoryTest.getMode();
2318 mSystemThread = ActivityThread.currentActivityThread();
2320 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2322 mHandlerThread = new ServiceThread(TAG,
2323 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2324 mHandlerThread.start();
2325 mHandler = new MainHandler(mHandlerThread.getLooper());
2326 mUiHandler = new UiHandler();
2328 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2329 "foreground", BROADCAST_FG_TIMEOUT, false);
2330 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2331 "background", BROADCAST_BG_TIMEOUT, true);
2332 mBroadcastQueues[0] = mFgBroadcastQueue;
2333 mBroadcastQueues[1] = mBgBroadcastQueue;
2335 mServices = new ActiveServices(this);
2336 mProviderMap = new ProviderMap(this);
2338 // TODO: Move creation of battery stats service outside of activity manager service.
2339 File dataDir = Environment.getDataDirectory();
2340 File systemDir = new File(dataDir, "system");
2342 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2343 mBatteryStatsService.getActiveStatistics().readLocked();
2344 mBatteryStatsService.scheduleWriteToDisk();
2345 mOnBattery = DEBUG_POWER ? true
2346 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2347 mBatteryStatsService.getActiveStatistics().setCallback(this);
2349 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2351 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2353 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2355 // User 0 is the first and only user that runs at boot.
2356 mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2357 mUserLru.add(UserHandle.USER_OWNER);
2358 updateStartedUserArrayLocked();
2360 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2361 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2363 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2365 mConfiguration.setToDefaults();
2366 mConfiguration.setLocale(Locale.getDefault());
2368 mConfigurationSeq = mConfiguration.seq = 1;
2369 mProcessCpuTracker.init();
2371 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2372 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2373 mRecentTasks = new RecentTasks(this);
2374 mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2375 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2377 mProcessCpuThread = new Thread("CpuTracker") {
2383 synchronized(this) {
2384 final long now = SystemClock.uptimeMillis();
2385 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2386 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2387 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2388 // + ", write delay=" + nextWriteDelay);
2389 if (nextWriteDelay < nextCpuDelay) {
2390 nextCpuDelay = nextWriteDelay;
2392 if (nextCpuDelay > 0) {
2393 mProcessCpuMutexFree.set(true);
2394 this.wait(nextCpuDelay);
2397 } catch (InterruptedException e) {
2399 updateCpuStatsNow();
2400 } catch (Exception e) {
2401 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2407 Watchdog.getInstance().addMonitor(this);
2408 Watchdog.getInstance().addThread(mHandler);
2411 public void setSystemServiceManager(SystemServiceManager mgr) {
2412 mSystemServiceManager = mgr;
2415 public void setInstaller(Installer installer) {
2416 mInstaller = installer;
2419 private void start() {
2420 Process.removeAllProcessGroups();
2421 mProcessCpuThread.start();
2423 mBatteryStatsService.publish(mContext);
2424 mAppOpsService.publish(mContext);
2425 Slog.d("AppOps", "AppOpsService published");
2426 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2429 public void initPowerManagement() {
2430 mStackSupervisor.initPowerManagement();
2431 mBatteryStatsService.initPowerManagement();
2432 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2433 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2434 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2435 mVoiceWakeLock.setReferenceCounted(false);
2439 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2440 throws RemoteException {
2441 if (code == SYSPROPS_TRANSACTION) {
2442 // We need to tell all apps about the system property change.
2443 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2444 synchronized(this) {
2445 final int NP = mProcessNames.getMap().size();
2446 for (int ip=0; ip<NP; ip++) {
2447 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2448 final int NA = apps.size();
2449 for (int ia=0; ia<NA; ia++) {
2450 ProcessRecord app = apps.valueAt(ia);
2451 if (app.thread != null) {
2452 procs.add(app.thread.asBinder());
2458 int N = procs.size();
2459 for (int i=0; i<N; i++) {
2460 Parcel data2 = Parcel.obtain();
2462 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2463 } catch (RemoteException e) {
2469 return super.onTransact(code, data, reply, flags);
2470 } catch (RuntimeException e) {
2471 // The activity manager only throws security exceptions, so let's
2473 if (!(e instanceof SecurityException)) {
2474 Slog.wtf(TAG, "Activity Manager Crash", e);
2480 void updateCpuStats() {
2481 final long now = SystemClock.uptimeMillis();
2482 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2485 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2486 synchronized (mProcessCpuThread) {
2487 mProcessCpuThread.notify();
2492 void updateCpuStatsNow() {
2493 synchronized (mProcessCpuTracker) {
2494 mProcessCpuMutexFree.set(false);
2495 final long now = SystemClock.uptimeMillis();
2496 boolean haveNewCpuStats = false;
2498 if (MONITOR_CPU_USAGE &&
2499 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2500 mLastCpuTime.set(now);
2501 mProcessCpuTracker.update();
2502 if (mProcessCpuTracker.hasGoodLastStats()) {
2503 haveNewCpuStats = true;
2504 //Slog.i(TAG, mProcessCpu.printCurrentState());
2505 //Slog.i(TAG, "Total CPU usage: "
2506 // + mProcessCpu.getTotalCpuPercent() + "%");
2508 // Slog the cpu usage if the property is set.
2509 if ("true".equals(SystemProperties.get("events.cpu"))) {
2510 int user = mProcessCpuTracker.getLastUserTime();
2511 int system = mProcessCpuTracker.getLastSystemTime();
2512 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2513 int irq = mProcessCpuTracker.getLastIrqTime();
2514 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2515 int idle = mProcessCpuTracker.getLastIdleTime();
2517 int total = user + system + iowait + irq + softIrq + idle;
2518 if (total == 0) total = 1;
2520 EventLog.writeEvent(EventLogTags.CPU,
2521 ((user+system+iowait+irq+softIrq) * 100) / total,
2522 (user * 100) / total,
2523 (system * 100) / total,
2524 (iowait * 100) / total,
2525 (irq * 100) / total,
2526 (softIrq * 100) / total);
2531 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2532 synchronized(bstats) {
2533 synchronized(mPidsSelfLocked) {
2534 if (haveNewCpuStats) {
2535 if (bstats.startAddingCpuLocked()) {
2538 final int N = mProcessCpuTracker.countStats();
2539 for (int i=0; i<N; i++) {
2540 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2544 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2545 totalUTime += st.rel_utime;
2546 totalSTime += st.rel_stime;
2548 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2549 if (ps == null || !ps.isActive()) {
2550 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2551 pr.info.uid, pr.processName);
2553 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2554 pr.curCpuTime += st.rel_utime + st.rel_stime;
2556 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2557 if (ps == null || !ps.isActive()) {
2558 st.batteryStats = ps = bstats.getProcessStatsLocked(
2559 bstats.mapUid(st.uid), st.name);
2561 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2564 final int userTime = mProcessCpuTracker.getLastUserTime();
2565 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2566 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2567 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2568 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2569 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2570 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2571 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2576 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2577 mLastWriteTime = now;
2578 mBatteryStatsService.scheduleWriteToDisk();
2585 public void batteryNeedsCpuUpdate() {
2586 updateCpuStatsNow();
2590 public void batteryPowerChanged(boolean onBattery) {
2591 // When plugging in, update the CPU stats first before changing
2593 updateCpuStatsNow();
2594 synchronized (this) {
2595 synchronized(mPidsSelfLocked) {
2596 mOnBattery = DEBUG_POWER ? true : onBattery;
2602 public void batterySendBroadcast(Intent intent) {
2603 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2604 AppOpsManager.OP_NONE, null, false, false,
2605 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2609 * Initialize the application bind args. These are passed to each
2610 * process when the bindApplication() IPC is sent to the process. They're
2611 * lazily setup to make sure the services are running when they're asked for.
2613 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2614 if (mAppBindArgs == null) {
2615 mAppBindArgs = new HashMap<>();
2617 // Isolated processes won't get this optimization, so that we don't
2618 // violate the rules about which services they have access to.
2620 // Setup the application init args
2621 mAppBindArgs.put("package", ServiceManager.getService("package"));
2622 mAppBindArgs.put("window", ServiceManager.getService("window"));
2623 mAppBindArgs.put(Context.ALARM_SERVICE,
2624 ServiceManager.getService(Context.ALARM_SERVICE));
2627 return mAppBindArgs;
2630 final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2631 if (r != null && mFocusedActivity != r) {
2632 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2633 ActivityRecord last = mFocusedActivity;
2634 mFocusedActivity = r;
2635 if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2636 && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2637 if (mCurAppTimeTracker != r.appTimeTracker) {
2638 // We are switching app tracking. Complete the current one.
2639 if (mCurAppTimeTracker != null) {
2640 mCurAppTimeTracker.stop();
2641 mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2642 mCurAppTimeTracker).sendToTarget();
2643 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2644 mCurAppTimeTracker = null;
2646 if (r.appTimeTracker != null) {
2647 mCurAppTimeTracker = r.appTimeTracker;
2648 startTimeTrackingFocusedActivityLocked();
2651 startTimeTrackingFocusedActivityLocked();
2654 r.appTimeTracker = null;
2656 if (r.task != null && r.task.voiceInteractor != null) {
2657 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2659 finishRunningVoiceLocked();
2660 if (last != null && last.task.voiceSession != null) {
2661 // We had been in a voice interaction session, but now focused has
2662 // move to something different. Just finish the session, we can't
2663 // return to it and retain the proper state and synchronization with
2664 // the voice interaction service.
2665 finishVoiceTask(last.task.voiceSession);
2668 if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2669 mWindowManager.setFocusedApp(r.appToken, true);
2671 applyUpdateLockStateLocked(r);
2672 if (mFocusedActivity.userId != mLastFocusedUserId) {
2673 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2674 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2675 mFocusedActivity.userId, 0));
2676 mLastFocusedUserId = mFocusedActivity.userId;
2679 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2680 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2681 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2684 final void clearFocusedActivity(ActivityRecord r) {
2685 if (mFocusedActivity == r) {
2686 ActivityStack stack = mStackSupervisor.getFocusedStack();
2687 if (stack != null) {
2688 ActivityRecord top = stack.topActivity();
2689 if (top != null && top.userId != mLastFocusedUserId) {
2690 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2691 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2693 mLastFocusedUserId = top.userId;
2696 mFocusedActivity = null;
2697 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2702 public void setFocusedStack(int stackId) {
2703 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2704 synchronized (ActivityManagerService.this) {
2705 ActivityStack stack = mStackSupervisor.getStack(stackId);
2706 if (stack != null) {
2707 ActivityRecord r = stack.topRunningActivityLocked(null);
2709 setFocusedActivityLocked(r, "setFocusedStack");
2710 mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2716 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2718 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2719 synchronized (ActivityManagerService.this) {
2720 if (listener != null) {
2721 mTaskStackListeners.register(listener);
2727 public void notifyActivityDrawn(IBinder token) {
2728 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2729 synchronized (this) {
2730 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2732 r.task.stack.notifyActivityDrawnLocked(r);
2737 final void applyUpdateLockStateLocked(ActivityRecord r) {
2738 // Modifications to the UpdateLock state are done on our handler, outside
2739 // the activity manager's locks. The new state is determined based on the
2740 // state *now* of the relevant activity record. The object is passed to
2741 // the handler solely for logging detail, not to be consulted/modified.
2742 final boolean nextState = r != null && r.immersive;
2743 mHandler.sendMessage(
2744 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2747 final void showAskCompatModeDialogLocked(ActivityRecord r) {
2748 Message msg = Message.obtain();
2749 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2750 msg.obj = r.task.askedCompatMode ? null : r;
2751 mUiHandler.sendMessage(msg);
2754 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2755 String what, Object obj, ProcessRecord srcApp) {
2756 app.lastActivityTime = now;
2758 if (app.activities.size() > 0) {
2759 // Don't want to touch dependent processes that are hosting activities.
2763 int lrui = mLruProcesses.lastIndexOf(app);
2765 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2766 + what + " " + obj + " from " + srcApp);
2770 if (lrui >= index) {
2771 // Don't want to cause this to move dependent processes *back* in the
2772 // list as if they were less frequently used.
2776 if (lrui >= mLruProcessActivityStart) {
2777 // Don't want to touch dependent processes that are hosting activities.
2781 mLruProcesses.remove(lrui);
2785 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2786 + " in LRU list: " + app);
2787 mLruProcesses.add(index, app);
2791 private static void killProcessGroup(int uid, int pid) {
2792 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2793 Process.killProcessGroup(uid, pid);
2794 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2797 final void removeLruProcessLocked(ProcessRecord app) {
2798 int lrui = mLruProcesses.lastIndexOf(app);
2801 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2802 Process.killProcessQuiet(app.pid);
2803 killProcessGroup(app.info.uid, app.pid);
2805 if (lrui <= mLruProcessActivityStart) {
2806 mLruProcessActivityStart--;
2808 if (lrui <= mLruProcessServiceStart) {
2809 mLruProcessServiceStart--;
2811 mLruProcesses.remove(lrui);
2815 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2816 ProcessRecord client) {
2817 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2818 || app.treatLikeActivity;
2819 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2820 if (!activityChange && hasActivity) {
2821 // The process has activities, so we are only allowing activity-based adjustments
2822 // to move it. It should be kept in the front of the list with other
2823 // processes that have activities, and we don't want those to change their
2824 // order except due to activity operations.
2829 final long now = SystemClock.uptimeMillis();
2830 app.lastActivityTime = now;
2832 // First a quick reject: if the app is already at the position we will
2833 // put it, then there is nothing to do.
2835 final int N = mLruProcesses.size();
2836 if (N > 0 && mLruProcesses.get(N-1) == app) {
2837 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2841 if (mLruProcessServiceStart > 0
2842 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2843 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2848 int lrui = mLruProcesses.lastIndexOf(app);
2850 if (app.persistent && lrui >= 0) {
2851 // We don't care about the position of persistent processes, as long as
2852 // they are in the list.
2853 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2857 /* In progress: compute new position first, so we can avoid doing work
2858 if the process is not actually going to move. Not yet working.
2861 boolean inActivity = false, inService = false;
2863 // Process has activities, put it at the very tipsy-top.
2864 addIndex = mLruProcesses.size();
2865 nextIndex = mLruProcessServiceStart;
2867 } else if (hasService) {
2868 // Process has services, put it at the top of the service list.
2869 addIndex = mLruProcessActivityStart;
2870 nextIndex = mLruProcessServiceStart;
2874 // Process not otherwise of interest, it goes to the top of the non-service area.
2875 addIndex = mLruProcessServiceStart;
2876 if (client != null) {
2877 int clientIndex = mLruProcesses.lastIndexOf(client);
2878 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2880 if (clientIndex >= 0 && addIndex > clientIndex) {
2881 addIndex = clientIndex;
2884 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2887 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2888 + mLruProcessActivityStart + "): " + app);
2892 if (lrui < mLruProcessActivityStart) {
2893 mLruProcessActivityStart--;
2895 if (lrui < mLruProcessServiceStart) {
2896 mLruProcessServiceStart--;
2899 if (addIndex > lrui) {
2902 if (nextIndex > lrui) {
2906 mLruProcesses.remove(lrui);
2910 mLruProcesses.add(addIndex, app);
2912 mLruProcessActivityStart++;
2915 mLruProcessActivityStart++;
2921 final int N = mLruProcesses.size();
2922 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2923 // Process doesn't have activities, but has clients with
2924 // activities... move it up, but one below the top (the top
2925 // should always have a real activity).
2926 if (DEBUG_LRU) Slog.d(TAG_LRU,
2927 "Adding to second-top of LRU activity list: " + app);
2928 mLruProcesses.add(N - 1, app);
2929 // To keep it from spamming the LRU list (by making a bunch of clients),
2930 // we will push down any other entries owned by the app.
2931 final int uid = app.info.uid;
2932 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2933 ProcessRecord subProc = mLruProcesses.get(i);
2934 if (subProc.info.uid == uid) {
2935 // We want to push this one down the list. If the process after
2936 // it is for the same uid, however, don't do so, because we don't
2937 // want them internally to be re-ordered.
2938 if (mLruProcesses.get(i - 1).info.uid != uid) {
2939 if (DEBUG_LRU) Slog.d(TAG_LRU,
2940 "Pushing uid " + uid + " swapping at " + i + ": "
2941 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2942 ProcessRecord tmp = mLruProcesses.get(i);
2943 mLruProcesses.set(i, mLruProcesses.get(i - 1));
2944 mLruProcesses.set(i - 1, tmp);
2948 // A gap, we can stop here.
2953 // Process has activities, put it at the very tipsy-top.
2954 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2955 mLruProcesses.add(app);
2957 nextIndex = mLruProcessServiceStart;
2958 } else if (hasService) {
2959 // Process has services, put it at the top of the service list.
2960 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2961 mLruProcesses.add(mLruProcessActivityStart, app);
2962 nextIndex = mLruProcessServiceStart;
2963 mLruProcessActivityStart++;
2965 // Process not otherwise of interest, it goes to the top of the non-service area.
2966 int index = mLruProcessServiceStart;
2967 if (client != null) {
2968 // If there is a client, don't allow the process to be moved up higher
2969 // in the list than that client.
2970 int clientIndex = mLruProcesses.lastIndexOf(client);
2971 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2972 + " when updating " + app);
2973 if (clientIndex <= lrui) {
2974 // Don't allow the client index restriction to push it down farther in the
2975 // list than it already is.
2978 if (clientIndex >= 0 && index > clientIndex) {
2979 index = clientIndex;
2982 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2983 mLruProcesses.add(index, app);
2984 nextIndex = index-1;
2985 mLruProcessActivityStart++;
2986 mLruProcessServiceStart++;
2989 // If the app is currently using a content provider or service,
2990 // bump those processes as well.
2991 for (int j=app.connections.size()-1; j>=0; j--) {
2992 ConnectionRecord cr = app.connections.valueAt(j);
2993 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2994 && cr.binding.service.app != null
2995 && cr.binding.service.app.lruSeq != mLruSeq
2996 && !cr.binding.service.app.persistent) {
2997 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2998 "service connection", cr, app);
3001 for (int j=app.conProviders.size()-1; j>=0; j--) {
3002 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3003 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3004 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3005 "provider reference", cpr, app);
3010 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3011 if (uid == Process.SYSTEM_UID) {
3012 // The system gets to run in any process. If there are multiple
3013 // processes with the same uid, just pick the first (this
3014 // should never happen).
3015 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3016 if (procs == null) return null;
3017 final int procCount = procs.size();
3018 for (int i = 0; i < procCount; i++) {
3019 final int procUid = procs.keyAt(i);
3020 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3021 // Don't use an app process or different user process for system component.
3024 return procs.valueAt(i);
3027 ProcessRecord proc = mProcessNames.get(processName, uid);
3028 if (false && proc != null && !keepIfLarge
3029 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3030 && proc.lastCachedPss >= 4000) {
3031 // Turn this condition on to cause killing to happen regularly, for testing.
3032 if (proc.baseProcessTracker != null) {
3033 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3035 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3036 } else if (proc != null && !keepIfLarge
3037 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3038 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3039 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3040 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3041 if (proc.baseProcessTracker != null) {
3042 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3044 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3050 void ensurePackageDexOpt(String packageName) {
3051 IPackageManager pm = AppGlobals.getPackageManager();
3053 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3056 } catch (RemoteException e) {
3060 boolean isNextTransitionForward() {
3061 int transit = mWindowManager.getPendingAppTransition();
3062 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3063 || transit == AppTransition.TRANSIT_TASK_OPEN
3064 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3067 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3068 String processName, String abiOverride, int uid, Runnable crashHandler) {
3069 synchronized(this) {
3070 ApplicationInfo info = new ApplicationInfo();
3071 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3072 // For isolated processes, the former contains the parent's uid and the latter the
3073 // actual uid of the isolated process.
3074 // In the special case introduced by this method (which is, starting an isolated
3075 // process directly from the SystemServer without an actual parent app process) the
3076 // closest thing to a parent's uid is SYSTEM_UID.
3077 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3078 // the |isolated| logic in the ProcessRecord constructor.
3079 info.uid = Process.SYSTEM_UID;
3080 info.processName = processName;
3081 info.className = entryPoint;
3082 info.packageName = "android";
3083 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3084 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3085 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3086 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3088 return proc != null ? proc.pid : 0;
3092 final ProcessRecord startProcessLocked(String processName,
3093 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3094 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3095 boolean isolated, boolean keepIfLarge) {
3096 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3097 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3098 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3099 null /* crashHandler */);
3102 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3103 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3104 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3105 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3106 long startTime = SystemClock.elapsedRealtime();
3109 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3110 checkTime(startTime, "startProcess: after getProcessRecord");
3112 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3113 // If we are in the background, then check to see if this process
3114 // is bad. If so, we will just silently fail.
3115 if (mBadProcesses.get(info.processName, info.uid) != null) {
3116 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3117 + "/" + info.processName);
3121 // When the user is explicitly starting a process, then clear its
3122 // crash count so that we won't make it bad until they see at
3123 // least one crash dialog again, and make the process good again
3124 // if it had been bad.
3125 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3126 + "/" + info.processName);
3127 mProcessCrashTimes.remove(info.processName, info.uid);
3128 if (mBadProcesses.get(info.processName, info.uid) != null) {
3129 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3130 UserHandle.getUserId(info.uid), info.uid,
3132 mBadProcesses.remove(info.processName, info.uid);
3139 // If this is an isolated process, it can't re-use an existing process.
3143 // app launch boost for big.little configurations
3144 // use cpusets to migrate freshly launched tasks to big cores
3145 synchronized(ActivityManagerService.this) {
3146 nativeMigrateToBoost();
3148 mBoostStartTime = SystemClock.uptimeMillis();
3149 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3150 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3153 // We don't have to do anything more if:
3154 // (1) There is an existing application record; and
3155 // (2) The caller doesn't think it is dead, OR there is no thread
3156 // object attached to it so we know it couldn't have crashed; and
3157 // (3) There is a pid assigned to it, so it is either starting or
3159 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3160 + " app=" + app + " knownToBeDead=" + knownToBeDead
3161 + " thread=" + (app != null ? app.thread : null)
3162 + " pid=" + (app != null ? app.pid : -1));
3163 if (app != null && app.pid > 0) {
3164 if (!knownToBeDead || app.thread == null) {
3165 // We already have the app running, or are waiting for it to
3166 // come up (we have a pid but not yet its thread), so keep it.
3167 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3168 // If this is a new package in the process, add the package to the list
3169 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3170 checkTime(startTime, "startProcess: done, added package to proc");
3174 // An application record is attached to a previous process,
3176 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3177 checkTime(startTime, "startProcess: bad proc running, killing");
3178 killProcessGroup(app.info.uid, app.pid);
3179 handleAppDiedLocked(app, true, true);
3180 checkTime(startTime, "startProcess: done killing old proc");
3183 String hostingNameStr = hostingName != null
3184 ? hostingName.flattenToShortString() : null;
3187 checkTime(startTime, "startProcess: creating new process record");
3188 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3190 Slog.w(TAG, "Failed making new process record for "
3191 + processName + "/" + info.uid + " isolated=" + isolated);
3194 app.crashHandler = crashHandler;
3195 checkTime(startTime, "startProcess: done creating new process record");
3197 // If this is a new package in the process, add the package to the list
3198 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3199 checkTime(startTime, "startProcess: added package to existing proc");
3202 // If the system is not ready yet, then hold off on starting this
3203 // process until it is.
3204 if (!mProcessesReady
3205 && !isAllowedWhileBooting(info)
3206 && !allowWhileBooting) {
3207 if (!mProcessesOnHold.contains(app)) {
3208 mProcessesOnHold.add(app);
3210 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3211 "System not ready, putting on hold: " + app);
3212 checkTime(startTime, "startProcess: returning with proc on hold");
3216 checkTime(startTime, "startProcess: stepping in to startProcess");
3218 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3219 checkTime(startTime, "startProcess: done starting proc!");
3220 return (app.pid != 0) ? app : null;
3223 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3224 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3227 private final void startProcessLocked(ProcessRecord app,
3228 String hostingType, String hostingNameStr) {
3229 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3230 null /* entryPoint */, null /* entryPointArgs */);
3233 private final void startProcessLocked(ProcessRecord app, String hostingType,
3234 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3235 long startTime = SystemClock.elapsedRealtime();
3236 if (app.pid > 0 && app.pid != MY_PID) {
3237 checkTime(startTime, "startProcess: removing from pids map");
3238 synchronized (mPidsSelfLocked) {
3239 mPidsSelfLocked.remove(app.pid);
3240 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3242 checkTime(startTime, "startProcess: done removing from pids map");
3246 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3247 "startProcessLocked removing on hold: " + app);
3248 mProcessesOnHold.remove(app);
3250 checkTime(startTime, "startProcess: starting to update cpu stats");
3252 checkTime(startTime, "startProcess: done updating cpu stats");
3256 if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3257 // This is caught below as if we had failed to fork zygote
3258 throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3260 } catch (RemoteException e) {
3261 throw e.rethrowAsRuntimeException();
3266 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3267 if (!app.isolated) {
3268 int[] permGids = null;
3270 checkTime(startTime, "startProcess: getting gids from package manager");
3271 final IPackageManager pm = AppGlobals.getPackageManager();
3272 permGids = pm.getPackageGids(app.info.packageName, app.userId);
3273 MountServiceInternal mountServiceInternal = LocalServices.getService(
3274 MountServiceInternal.class);
3275 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3276 app.info.packageName);
3277 } catch (RemoteException e) {
3278 throw e.rethrowAsRuntimeException();
3282 * Add shared application and profile GIDs so applications can share some
3283 * resources like shared libraries and access user-wide resources
3285 if (ArrayUtils.isEmpty(permGids)) {
3288 gids = new int[permGids.length + 2];
3289 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3291 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3292 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3294 checkTime(startTime, "startProcess: building args");
3295 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3296 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3297 && mTopComponent != null
3298 && app.processName.equals(mTopComponent.getPackageName())) {
3301 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3302 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3307 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3308 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3309 // Also turn on CheckJNI for debuggable apps. It's quite
3310 // awkward to turn on otherwise.
3311 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3313 // Run the app in safe mode if its manifest requests so or the
3314 // system is booted in safe mode.
3315 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3316 mSafeMode == true) {
3317 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3319 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3320 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3322 String jitDebugProperty = SystemProperties.get("debug.usejit");
3323 if ("true".equals(jitDebugProperty)) {
3324 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3325 } else if (!"false".equals(jitDebugProperty)) {
3326 // If we didn't force disable by setting false, defer to the dalvik vm options.
3327 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3328 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3331 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3332 if ("true".equals(genDebugInfoProperty)) {
3333 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3335 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3336 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3338 if ("1".equals(SystemProperties.get("debug.assert"))) {
3339 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3342 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3343 if (requiredAbi == null) {
3344 requiredAbi = Build.SUPPORTED_ABIS[0];
3347 String instructionSet = null;
3348 if (app.info.primaryCpuAbi != null) {
3349 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3353 app.requiredAbi = requiredAbi;
3354 app.instructionSet = instructionSet;
3356 // Start the process. It will either succeed and return a result containing
3357 // the PID of the new process, or else throw a RuntimeException.
3358 boolean isActivityProcess = (entryPoint == null);
3359 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3360 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3362 checkTime(startTime, "startProcess: asking zygote to start proc");
3363 Process.ProcessStartResult startResult = Process.start(entryPoint,
3364 app.processName, uid, uid, gids, debugFlags, mountExternal,
3365 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3366 app.info.dataDir, entryPointArgs);
3367 checkTime(startTime, "startProcess: returned from zygote!");
3368 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3371 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3373 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3374 checkTime(startTime, "startProcess: done updating battery stats");
3376 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3377 UserHandle.getUserId(uid), startResult.pid, uid,
3378 app.processName, hostingType,
3379 hostingNameStr != null ? hostingNameStr : "");
3381 if (app.persistent) {
3382 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3385 checkTime(startTime, "startProcess: building log message");
3386 StringBuilder buf = mStringBuilder;
3388 buf.append("Start proc ");
3389 buf.append(startResult.pid);
3391 buf.append(app.processName);
3393 UserHandle.formatUid(buf, uid);
3394 if (!isActivityProcess) {
3396 buf.append(entryPoint);
3399 buf.append(" for ");
3400 buf.append(hostingType);
3401 if (hostingNameStr != null) {
3403 buf.append(hostingNameStr);
3405 Slog.i(TAG, buf.toString());
3406 app.setPid(startResult.pid);
3407 app.usingWrapper = startResult.usingWrapper;
3408 app.removed = false;
3410 app.killedByAm = false;
3411 checkTime(startTime, "startProcess: starting to update pids map");
3412 synchronized (mPidsSelfLocked) {
3413 this.mPidsSelfLocked.put(startResult.pid, app);
3414 if (isActivityProcess) {
3415 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3417 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3418 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3421 checkTime(startTime, "startProcess: done updating pids map");
3422 } catch (RuntimeException e) {
3423 // XXX do better error recovery.
3425 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3427 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3429 Slog.e(TAG, "Failure starting process " + app.processName, e);
3433 void updateUsageStats(ActivityRecord component, boolean resumed) {
3434 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3435 "updateUsageStats: comp=" + component + "res=" + resumed);
3436 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3438 if (mUsageStatsService != null) {
3439 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3440 UsageEvents.Event.MOVE_TO_FOREGROUND);
3442 synchronized (stats) {
3443 stats.noteActivityResumedLocked(component.app.uid);
3446 if (mUsageStatsService != null) {
3447 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3448 UsageEvents.Event.MOVE_TO_BACKGROUND);
3450 synchronized (stats) {
3451 stats.noteActivityPausedLocked(component.app.uid);
3456 Intent getHomeIntent() {
3457 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3458 intent.setComponent(mTopComponent);
3459 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3460 intent.addCategory(Intent.CATEGORY_HOME);
3465 boolean startHomeActivityLocked(int userId, String reason) {
3466 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3467 && mTopAction == null) {
3468 // We are running in factory test mode, but unable to find
3469 // the factory test app, so just sit around displaying the
3470 // error message and don't try to start anything.
3473 Intent intent = getHomeIntent();
3474 ActivityInfo aInfo =
3475 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3476 if (aInfo != null) {
3477 intent.setComponent(new ComponentName(
3478 aInfo.applicationInfo.packageName, aInfo.name));
3479 // Don't do this if the home app is currently being
3481 aInfo = new ActivityInfo(aInfo);
3482 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3483 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3484 aInfo.applicationInfo.uid, true);
3485 if (app == null || app.instrumentationClass == null) {
3486 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3487 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3494 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3495 ActivityInfo ai = null;
3496 ComponentName comp = intent.getComponent();
3500 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3502 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3504 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3508 ai = info.activityInfo;
3511 } catch (RemoteException e) {
3519 * Starts the "new version setup screen" if appropriate.
3521 void startSetupActivityLocked() {
3522 // Only do this once per boot.
3523 if (mCheckedForSetup) {
3527 // We will show this screen if the current one is a different
3528 // version than the last one shown, and we are not running in
3529 // low-level factory test mode.
3530 final ContentResolver resolver = mContext.getContentResolver();
3531 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3532 Settings.Global.getInt(resolver,
3533 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3534 mCheckedForSetup = true;
3536 // See if we should be showing the platform update setup UI.
3537 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3538 List<ResolveInfo> ris = mContext.getPackageManager()
3539 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3541 // We don't allow third party apps to replace this.
3542 ResolveInfo ri = null;
3543 for (int i=0; ris != null && i<ris.size(); i++) {
3544 if ((ris.get(i).activityInfo.applicationInfo.flags
3545 & ApplicationInfo.FLAG_SYSTEM) != 0) {
3552 String vers = ri.activityInfo.metaData != null
3553 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3555 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3556 vers = ri.activityInfo.applicationInfo.metaData.getString(
3557 Intent.METADATA_SETUP_VERSION);
3559 String lastVers = Settings.Secure.getString(
3560 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3561 if (vers != null && !vers.equals(lastVers)) {
3562 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3563 intent.setComponent(new ComponentName(
3564 ri.activityInfo.packageName, ri.activityInfo.name));
3565 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3566 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3573 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3574 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3577 void enforceNotIsolatedCaller(String caller) {
3578 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3579 throw new SecurityException("Isolated process not allowed to call " + caller);
3583 void enforceShellRestriction(String restriction, int userHandle) {
3584 if (Binder.getCallingUid() == Process.SHELL_UID) {
3586 || mUserManager.hasUserRestriction(restriction, userHandle)) {
3587 throw new SecurityException("Shell does not have permission to access user "
3594 public int getFrontActivityScreenCompatMode() {
3595 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3596 synchronized (this) {
3597 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3602 public void setFrontActivityScreenCompatMode(int mode) {
3603 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3604 "setFrontActivityScreenCompatMode");
3605 synchronized (this) {
3606 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3611 public int getPackageScreenCompatMode(String packageName) {
3612 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3613 synchronized (this) {
3614 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3619 public void setPackageScreenCompatMode(String packageName, int mode) {
3620 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3621 "setPackageScreenCompatMode");
3622 synchronized (this) {
3623 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3628 public boolean getPackageAskScreenCompat(String packageName) {
3629 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3630 synchronized (this) {
3631 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3636 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3637 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3638 "setPackageAskScreenCompat");
3639 synchronized (this) {
3640 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3644 private boolean hasUsageStatsPermission(String callingPackage) {
3645 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3646 Binder.getCallingUid(), callingPackage);
3647 if (mode == AppOpsManager.MODE_DEFAULT) {
3648 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3649 == PackageManager.PERMISSION_GRANTED;
3651 return mode == AppOpsManager.MODE_ALLOWED;
3655 public int getPackageProcessState(String packageName, String callingPackage) {
3656 if (!hasUsageStatsPermission(callingPackage)) {
3657 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3658 "getPackageProcessState");
3661 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3662 synchronized (this) {
3663 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3664 final ProcessRecord proc = mLruProcesses.get(i);
3665 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3666 || procState > proc.setProcState) {
3667 boolean found = false;
3668 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3669 if (proc.pkgList.keyAt(j).equals(packageName)) {
3670 procState = proc.setProcState;
3674 if (proc.pkgDeps != null && !found) {
3675 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3676 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3677 procState = proc.setProcState;
3689 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3690 synchronized (this) {
3691 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3695 if (app.trimMemoryLevel < level && app.thread != null &&
3696 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3697 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3699 app.thread.scheduleTrimMemory(level);
3700 app.trimMemoryLevel = level;
3702 } catch (RemoteException e) {
3703 // Fallthrough to failure case.
3710 private void dispatchProcessesChanged() {
3712 synchronized (this) {
3713 N = mPendingProcessChanges.size();
3714 if (mActiveProcessChanges.length < N) {
3715 mActiveProcessChanges = new ProcessChangeItem[N];
3717 mPendingProcessChanges.toArray(mActiveProcessChanges);
3718 mPendingProcessChanges.clear();
3719 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3720 "*** Delivering " + N + " process changes");
3723 int i = mProcessObservers.beginBroadcast();
3726 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3727 if (observer != null) {
3729 for (int j=0; j<N; j++) {
3730 ProcessChangeItem item = mActiveProcessChanges[j];
3731 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3732 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3733 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3734 + item.uid + ": " + item.foregroundActivities);
3735 observer.onForegroundActivitiesChanged(item.pid, item.uid,
3736 item.foregroundActivities);
3738 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3739 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3740 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3741 + ": " + item.processState);
3742 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3745 } catch (RemoteException e) {
3749 mProcessObservers.finishBroadcast();
3751 synchronized (this) {
3752 for (int j=0; j<N; j++) {
3753 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3758 private void dispatchProcessDied(int pid, int uid) {
3759 int i = mProcessObservers.beginBroadcast();
3762 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3763 if (observer != null) {
3765 observer.onProcessDied(pid, uid);
3766 } catch (RemoteException e) {
3770 mProcessObservers.finishBroadcast();
3773 private void dispatchUidsChanged() {
3775 synchronized (this) {
3776 N = mPendingUidChanges.size();
3777 if (mActiveUidChanges.length < N) {
3778 mActiveUidChanges = new UidRecord.ChangeItem[N];
3780 for (int i=0; i<N; i++) {
3781 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3782 mActiveUidChanges[i] = change;
3783 change.uidRecord.pendingChange = null;
3784 change.uidRecord = null;
3786 mPendingUidChanges.clear();
3787 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3788 "*** Delivering " + N + " uid changes");
3791 if (mLocalPowerManager != null) {
3792 for (int j=0; j<N; j++) {
3793 UidRecord.ChangeItem item = mActiveUidChanges[j];
3795 mLocalPowerManager.uidGone(item.uid);
3797 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3802 int i = mUidObservers.beginBroadcast();
3805 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3806 if (observer != null) {
3808 for (int j=0; j<N; j++) {
3809 UidRecord.ChangeItem item = mActiveUidChanges[j];
3811 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3812 "UID gone uid=" + item.uid);
3813 observer.onUidGone(item.uid);
3815 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3816 "UID CHANGED uid=" + item.uid
3817 + ": " + item.processState);
3818 observer.onUidStateChanged(item.uid, item.processState);
3821 } catch (RemoteException e) {
3825 mUidObservers.finishBroadcast();
3827 synchronized (this) {
3828 for (int j=0; j<N; j++) {
3829 mAvailUidChanges.add(mActiveUidChanges[j]);
3835 public final int startActivity(IApplicationThread caller, String callingPackage,
3836 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3837 int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3838 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3839 resultWho, requestCode, startFlags, profilerInfo, options,
3840 UserHandle.getCallingUserId());
3844 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3845 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3846 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3847 enforceNotIsolatedCaller("startActivity");
3848 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3849 false, ALLOW_FULL_ONLY, "startActivity", null);
3850 // TODO: Switch to user app stacks here.
3851 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3852 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3853 profilerInfo, null, null, options, false, userId, null, null);
3857 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3858 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3859 int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3862 // This is very dangerous -- it allows you to perform a start activity (including
3863 // permission grants) as any app that may launch one of your own activities. So
3864 // we will only allow this to be done from activities that are part of the core framework,
3865 // and then only when they are running as the system.
3866 final ActivityRecord sourceRecord;
3867 final int targetUid;
3868 final String targetPackage;
3869 synchronized (this) {
3870 if (resultTo == null) {
3871 throw new SecurityException("Must be called from an activity");
3873 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3874 if (sourceRecord == null) {
3875 throw new SecurityException("Called with bad activity token: " + resultTo);
3877 if (!sourceRecord.info.packageName.equals("android")) {
3878 throw new SecurityException(
3879 "Must be called from an activity that is declared in the android package");
3881 if (sourceRecord.app == null) {
3882 throw new SecurityException("Called without a process attached to activity");
3884 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3885 // This is still okay, as long as this activity is running under the
3886 // uid of the original calling activity.
3887 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3888 throw new SecurityException(
3889 "Calling activity in uid " + sourceRecord.app.uid
3890 + " must be system uid or original calling uid "
3891 + sourceRecord.launchedFromUid);
3894 if (ignoreTargetSecurity) {
3895 if (intent.getComponent() == null) {
3896 throw new SecurityException(
3897 "Component must be specified with ignoreTargetSecurity");
3899 if (intent.getSelector() != null) {
3900 throw new SecurityException(
3901 "Selector not allowed with ignoreTargetSecurity");
3904 targetUid = sourceRecord.launchedFromUid;
3905 targetPackage = sourceRecord.launchedFromPackage;
3908 if (userId == UserHandle.USER_NULL) {
3909 userId = UserHandle.getUserId(sourceRecord.app.uid);
3912 // TODO: Switch to user app stacks here.
3914 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3915 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3916 null, null, options, ignoreTargetSecurity, userId, null, null);
3918 } catch (SecurityException e) {
3919 // XXX need to figure out how to propagate to original app.
3920 // A SecurityException here is generally actually a fault of the original
3921 // calling activity (such as a fairly granting permissions), so propagate it
3924 StringBuilder msg = new StringBuilder();
3925 msg.append("While launching");
3926 msg.append(intent.toString());
3928 msg.append(e.getMessage());
3935 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3936 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3937 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3938 enforceNotIsolatedCaller("startActivityAndWait");
3939 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3940 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3941 WaitResult res = new WaitResult();
3942 // TODO: Switch to user app stacks here.
3943 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3944 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3945 options, false, userId, null, null);
3950 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3951 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3952 int startFlags, Configuration config, Bundle options, int userId) {
3953 enforceNotIsolatedCaller("startActivityWithConfig");
3954 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3955 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3956 // TODO: Switch to user app stacks here.
3957 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3958 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3959 null, null, config, options, false, userId, null, null);
3964 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3965 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3966 int requestCode, int flagsMask, int flagsValues, Bundle options)
3967 throws TransactionTooLargeException {
3968 enforceNotIsolatedCaller("startActivityIntentSender");
3969 // Refuse possible leaked file descriptors
3970 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3971 throw new IllegalArgumentException("File descriptors passed in Intent");
3974 IIntentSender sender = intent.getTarget();
3975 if (!(sender instanceof PendingIntentRecord)) {
3976 throw new IllegalArgumentException("Bad PendingIntent object");
3979 PendingIntentRecord pir = (PendingIntentRecord)sender;
3981 synchronized (this) {
3982 // If this is coming from the currently resumed activity, it is
3983 // effectively saying that app switches are allowed at this point.
3984 final ActivityStack stack = getFocusedStack();
3985 if (stack.mResumedActivity != null &&
3986 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3987 mAppSwitchesAllowedTime = 0;
3990 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3991 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3996 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3997 Intent intent, String resolvedType, IVoiceInteractionSession session,
3998 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3999 Bundle options, int userId) {
4000 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4001 != PackageManager.PERMISSION_GRANTED) {
4002 String msg = "Permission Denial: startVoiceActivity() from pid="
4003 + Binder.getCallingPid()
4004 + ", uid=" + Binder.getCallingUid()
4005 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4007 throw new SecurityException(msg);
4009 if (session == null || interactor == null) {
4010 throw new NullPointerException("null session or interactor");
4012 userId = handleIncomingUser(callingPid, callingUid, userId,
4013 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
4014 // TODO: Switch to user app stacks here.
4015 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4016 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4017 null, options, false, userId, null, null);
4021 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4022 synchronized (this) {
4023 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4025 mVoiceWakeLock.acquire();
4027 mVoiceWakeLock.release();
4034 public boolean startNextMatchingActivity(IBinder callingActivity,
4035 Intent intent, Bundle options) {
4036 // Refuse possible leaked file descriptors
4037 if (intent != null && intent.hasFileDescriptors() == true) {
4038 throw new IllegalArgumentException("File descriptors passed in Intent");
4041 synchronized (this) {
4042 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4044 ActivityOptions.abort(options);
4047 if (r.app == null || r.app.thread == null) {
4048 // The caller is not running... d'oh!
4049 ActivityOptions.abort(options);
4052 intent = new Intent(intent);
4053 // The caller is not allowed to change the data.
4054 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4055 // And we are resetting to find the next component...
4056 intent.setComponent(null);
4058 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4060 ActivityInfo aInfo = null;
4062 List<ResolveInfo> resolves =
4063 AppGlobals.getPackageManager().queryIntentActivities(
4064 intent, r.resolvedType,
4065 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4066 UserHandle.getCallingUserId());
4068 // Look for the original activity in the list...
4069 final int N = resolves != null ? resolves.size() : 0;
4070 for (int i=0; i<N; i++) {
4071 ResolveInfo rInfo = resolves.get(i);
4072 if (rInfo.activityInfo.packageName.equals(r.packageName)
4073 && rInfo.activityInfo.name.equals(r.info.name)) {
4074 // We found the current one... the next matching is
4078 aInfo = resolves.get(i).activityInfo;
4081 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4082 + "/" + r.info.name);
4083 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4084 + "/" + aInfo.name);
4089 } catch (RemoteException e) {
4092 if (aInfo == null) {
4093 // Nobody who is next!
4094 ActivityOptions.abort(options);
4095 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4099 intent.setComponent(new ComponentName(
4100 aInfo.applicationInfo.packageName, aInfo.name));
4101 intent.setFlags(intent.getFlags()&~(
4102 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4103 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4104 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4105 Intent.FLAG_ACTIVITY_NEW_TASK));
4107 // Okay now we need to start the new activity, replacing the
4108 // currently running activity. This is a little tricky because
4109 // we want to start the new one as if the current one is finished,
4110 // but not finish the current one first so that there is no flicker.
4112 final boolean wasFinishing = r.finishing;
4115 // Propagate reply information over to the new activity.
4116 final ActivityRecord resultTo = r.resultTo;
4117 final String resultWho = r.resultWho;
4118 final int requestCode = r.requestCode;
4120 if (resultTo != null) {
4121 resultTo.removeResultsLocked(r, resultWho, requestCode);
4124 final long origId = Binder.clearCallingIdentity();
4125 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4126 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4127 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4128 -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4129 Binder.restoreCallingIdentity(origId);
4131 r.finishing = wasFinishing;
4132 if (res != ActivityManager.START_SUCCESS) {
4140 public final int startActivityFromRecents(int taskId, Bundle options) {
4141 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4142 String msg = "Permission Denial: startActivityFromRecents called without " +
4143 START_TASKS_FROM_RECENTS;
4145 throw new SecurityException(msg);
4147 return startActivityFromRecentsInner(taskId, options);
4150 final int startActivityFromRecentsInner(int taskId, Bundle options) {
4151 final TaskRecord task;
4152 final int callingUid;
4153 final String callingPackage;
4154 final Intent intent;
4156 synchronized (this) {
4157 task = mStackSupervisor.anyTaskForIdLocked(taskId);
4159 throw new IllegalArgumentException("Task " + taskId + " not found.");
4161 if (task.getRootActivity() != null) {
4162 moveTaskToFrontLocked(task.taskId, 0, null);
4163 return ActivityManager.START_TASK_TO_FRONT;
4165 callingUid = task.mCallingUid;
4166 callingPackage = task.mCallingPackage;
4167 intent = task.intent;
4168 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4169 userId = task.userId;
4171 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4172 options, userId, null, task);
4175 final int startActivityInPackage(int uid, String callingPackage,
4176 Intent intent, String resolvedType, IBinder resultTo,
4177 String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4178 IActivityContainer container, TaskRecord inTask) {
4180 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4181 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4183 // TODO: Switch to user app stacks here.
4184 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4185 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4186 null, null, null, options, false, userId, container, inTask);
4191 public final int startActivities(IApplicationThread caller, String callingPackage,
4192 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4194 enforceNotIsolatedCaller("startActivities");
4195 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4196 false, ALLOW_FULL_ONLY, "startActivity", null);
4197 // TODO: Switch to user app stacks here.
4198 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4199 resolvedTypes, resultTo, options, userId);
4203 final int startActivitiesInPackage(int uid, String callingPackage,
4204 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4205 Bundle options, int userId) {
4207 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4208 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4209 // TODO: Switch to user app stacks here.
4210 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4211 resultTo, options, userId);
4216 public void reportActivityFullyDrawn(IBinder token) {
4217 synchronized (this) {
4218 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4222 r.reportFullyDrawnLocked();
4227 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4228 synchronized (this) {
4229 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4233 if (r.task != null && r.task.mResizeable) {
4234 // Fixed screen orientation isn't supported with resizeable activities.
4237 final long origId = Binder.clearCallingIdentity();
4238 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4239 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4240 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4241 if (config != null) {
4242 r.frozenBeforeDestroy = true;
4243 if (!updateConfigurationLocked(config, r, false, false)) {
4244 mStackSupervisor.resumeTopActivitiesLocked();
4247 Binder.restoreCallingIdentity(origId);
4252 public int getRequestedOrientation(IBinder token) {
4253 synchronized (this) {
4254 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4256 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4258 return mWindowManager.getAppOrientation(r.appToken);
4263 * This is the internal entry point for handling Activity.finish().
4265 * @param token The Binder token referencing the Activity we want to finish.
4266 * @param resultCode Result code, if any, from this Activity.
4267 * @param resultData Result data (Intent), if any, from this Activity.
4268 * @param finishTask Whether to finish the task associated with this Activity. Only applies to
4269 * the root Activity in the task.
4271 * @return Returns true if the activity successfully finished, or false if it is still running.
4274 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4275 boolean finishTask) {
4276 // Refuse possible leaked file descriptors
4277 if (resultData != null && resultData.hasFileDescriptors() == true) {
4278 throw new IllegalArgumentException("File descriptors passed in Intent");
4281 synchronized(this) {
4282 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4286 // Keep track of the root activity of the task before we finish it
4287 TaskRecord tr = r.task;
4288 ActivityRecord rootR = tr.getRootActivity();
4289 if (rootR == null) {
4290 Slog.w(TAG, "Finishing task with all activities already finished");
4292 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4294 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4295 mStackSupervisor.isLastLockedTask(tr)) {
4296 Slog.i(TAG, "Not finishing task in lock task mode");
4297 mStackSupervisor.showLockTaskToast();
4300 if (mController != null) {
4301 // Find the first activity that is not finishing.
4302 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4304 // ask watcher if this is allowed
4305 boolean resumeOK = true;
4307 resumeOK = mController.activityResuming(next.packageName);
4308 } catch (RemoteException e) {
4310 Watchdog.getInstance().setActivityController(null);
4314 Slog.i(TAG, "Not finishing activity because controller resumed");
4319 final long origId = Binder.clearCallingIdentity();
4322 if (finishTask && r == rootR) {
4323 // If requested, remove the task that is associated to this activity only if it
4324 // was the root activity in the task. The result code and data is ignored
4325 // because we don't support returning them across task boundaries.
4326 res = removeTaskByIdLocked(tr.taskId, false);
4328 Slog.i(TAG, "Removing task failed to finish activity");
4331 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4332 resultData, "app-request", true);
4334 Slog.i(TAG, "Failed to finish by app-request");
4339 Binder.restoreCallingIdentity(origId);
4345 public final void finishHeavyWeightApp() {
4346 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4347 != PackageManager.PERMISSION_GRANTED) {
4348 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4349 + Binder.getCallingPid()
4350 + ", uid=" + Binder.getCallingUid()
4351 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4353 throw new SecurityException(msg);
4356 synchronized(this) {
4357 if (mHeavyWeightProcess == null) {
4361 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4362 for (int i = 0; i < activities.size(); i++) {
4363 ActivityRecord r = activities.get(i);
4364 if (!r.finishing && r.isInStackLocked()) {
4365 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4366 null, "finish-heavy", true);
4370 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4371 mHeavyWeightProcess.userId, 0));
4372 mHeavyWeightProcess = null;
4377 public void crashApplication(int uid, int initialPid, String packageName,
4379 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4380 != PackageManager.PERMISSION_GRANTED) {
4381 String msg = "Permission Denial: crashApplication() from pid="
4382 + Binder.getCallingPid()
4383 + ", uid=" + Binder.getCallingUid()
4384 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4386 throw new SecurityException(msg);
4389 synchronized(this) {
4390 ProcessRecord proc = null;
4392 // Figure out which process to kill. We don't trust that initialPid
4393 // still has any relation to current pids, so must scan through the
4395 synchronized (mPidsSelfLocked) {
4396 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4397 ProcessRecord p = mPidsSelfLocked.valueAt(i);
4401 if (p.pid == initialPid) {
4405 if (p.pkgList.containsKey(packageName)) {
4412 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4413 + " initialPid=" + initialPid
4414 + " packageName=" + packageName);
4418 if (proc.thread != null) {
4419 if (proc.pid == Process.myPid()) {
4420 Log.w(TAG, "crashApplication: trying to crash self!");
4423 long ident = Binder.clearCallingIdentity();
4425 proc.thread.scheduleCrash(message);
4426 } catch (RemoteException e) {
4428 Binder.restoreCallingIdentity(ident);
4434 public final void finishSubActivity(IBinder token, String resultWho,
4436 synchronized(this) {
4437 final long origId = Binder.clearCallingIdentity();
4438 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4440 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4442 Binder.restoreCallingIdentity(origId);
4447 public boolean finishActivityAffinity(IBinder token) {
4448 synchronized(this) {
4449 final long origId = Binder.clearCallingIdentity();
4451 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4456 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4458 final TaskRecord task = r.task;
4459 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4460 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4461 mStackSupervisor.showLockTaskToast();
4464 return task.stack.finishActivityAffinityLocked(r);
4466 Binder.restoreCallingIdentity(origId);
4472 public void finishVoiceTask(IVoiceInteractionSession session) {
4473 synchronized(this) {
4474 final long origId = Binder.clearCallingIdentity();
4476 mStackSupervisor.finishVoiceTask(session);
4478 Binder.restoreCallingIdentity(origId);
4485 public boolean releaseActivityInstance(IBinder token) {
4486 synchronized(this) {
4487 final long origId = Binder.clearCallingIdentity();
4489 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4493 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4495 Binder.restoreCallingIdentity(origId);
4501 public void releaseSomeActivities(IApplicationThread appInt) {
4502 synchronized(this) {
4503 final long origId = Binder.clearCallingIdentity();
4505 ProcessRecord app = getRecordForAppLocked(appInt);
4506 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4508 Binder.restoreCallingIdentity(origId);
4514 public boolean willActivityBeVisible(IBinder token) {
4515 synchronized(this) {
4516 ActivityStack stack = ActivityRecord.getStackLocked(token);
4517 if (stack != null) {
4518 return stack.willActivityBeVisibleLocked(token);
4525 public void overridePendingTransition(IBinder token, String packageName,
4526 int enterAnim, int exitAnim) {
4527 synchronized(this) {
4528 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4533 final long origId = Binder.clearCallingIdentity();
4535 if (self.state == ActivityState.RESUMED
4536 || self.state == ActivityState.PAUSING) {
4537 mWindowManager.overridePendingAppTransition(packageName,
4538 enterAnim, exitAnim, null);
4541 Binder.restoreCallingIdentity(origId);
4546 * Main function for removing an existing process from the activity manager
4547 * as a result of that process going away. Clears out all connections
4550 private final void handleAppDiedLocked(ProcessRecord app,
4551 boolean restarting, boolean allowRestart) {
4553 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4554 if (!kept && !restarting) {
4555 removeLruProcessLocked(app);
4557 ProcessList.remove(pid);
4561 if (mProfileProc == app) {
4562 clearProfilerLocked();
4565 // Remove this application's activities from active lists.
4566 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4568 app.activities.clear();
4570 if (app.instrumentationClass != null) {
4571 Slog.w(TAG, "Crash of app " + app.processName
4572 + " running instrumentation " + app.instrumentationClass);
4573 Bundle info = new Bundle();
4574 info.putString("shortMsg", "Process crashed.");
4575 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4578 if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4579 // If there was nothing to resume, and we are not already
4580 // restarting this process, but there is a visible activity that
4581 // is hosted by the process... then make sure all visible
4582 // activities are running, taking care of restarting this
4584 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4588 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4589 IBinder threadBinder = thread.asBinder();
4590 // Find the application record.
4591 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4592 ProcessRecord rec = mLruProcesses.get(i);
4593 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4600 final ProcessRecord getRecordForAppLocked(
4601 IApplicationThread thread) {
4602 if (thread == null) {
4606 int appIndex = getLRURecordIndexForAppLocked(thread);
4607 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4610 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4611 // If there are no longer any background processes running,
4612 // and the app that died was not running instrumentation,
4613 // then tell everyone we are now low on memory.
4614 boolean haveBg = false;
4615 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4616 ProcessRecord rec = mLruProcesses.get(i);
4617 if (rec.thread != null
4618 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4625 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4627 long now = SystemClock.uptimeMillis();
4628 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4631 mLastMemUsageReportTime = now;
4634 final ArrayList<ProcessMemInfo> memInfos
4635 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4636 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4637 long now = SystemClock.uptimeMillis();
4638 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4639 ProcessRecord rec = mLruProcesses.get(i);
4640 if (rec == dyingProc || rec.thread == null) {
4644 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4645 rec.setProcState, rec.adjType, rec.makeAdjReason()));
4647 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4648 // The low memory report is overriding any current
4649 // state for a GC request. Make sure to do
4650 // heavy/important/visible/foreground processes first.
4651 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4652 rec.lastRequestedGc = 0;
4654 rec.lastRequestedGc = rec.lastLowMemory;
4656 rec.reportLowMemory = true;
4657 rec.lastLowMemory = now;
4658 mProcessesToGc.remove(rec);
4659 addProcessToGcListLocked(rec);
4663 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4664 mHandler.sendMessage(msg);
4666 scheduleAppGcsLocked();
4670 final void appDiedLocked(ProcessRecord app) {
4671 appDiedLocked(app, app.pid, app.thread, false);
4674 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4675 boolean fromBinderDied) {
4676 // First check if this ProcessRecord is actually active for the pid.
4677 synchronized (mPidsSelfLocked) {
4678 ProcessRecord curProc = mPidsSelfLocked.get(pid);
4679 if (curProc != app) {
4680 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4685 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4686 synchronized (stats) {
4687 stats.noteProcessDiedLocked(app.info.uid, pid);
4691 if (!fromBinderDied) {
4692 Process.killProcessQuiet(pid);
4694 killProcessGroup(app.info.uid, pid);
4698 // Clean up already done if the process has been re-started.
4699 if (app.pid == pid && app.thread != null &&
4700 app.thread.asBinder() == thread.asBinder()) {
4701 boolean doLowMem = app.instrumentationClass == null;
4702 boolean doOomAdj = doLowMem;
4703 if (!app.killedByAm) {
4704 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4706 mAllowLowerMemLevel = true;
4708 // Note that we always want to do oom adj to update our state with the
4709 // new number of procs.
4710 mAllowLowerMemLevel = false;
4713 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4714 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4715 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4716 handleAppDiedLocked(app, false, true);
4719 updateOomAdjLocked();
4722 doLowMemReportIfNeededLocked(app);
4724 } else if (app.pid != pid) {
4725 // A new process has already been started.
4726 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4727 + ") has died and restarted (pid " + app.pid + ").");
4728 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4729 } else if (DEBUG_PROCESSES) {
4730 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4731 + thread.asBinder());
4736 * If a stack trace dump file is configured, dump process stack traces.
4737 * @param clearTraces causes the dump file to be erased prior to the new
4738 * traces being written, if true; when false, the new traces will be
4739 * appended to any existing file content.
4740 * @param firstPids of dalvik VM processes to dump stack traces for first
4741 * @param lastPids of dalvik VM processes to dump stack traces for last
4742 * @param nativeProcs optional list of native process names to dump stack crawls
4743 * @return file containing stack traces, or null if no dump file is configured
4745 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4746 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4747 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4748 if (tracesPath == null || tracesPath.length() == 0) {
4752 File tracesFile = new File(tracesPath);
4754 File tracesDir = tracesFile.getParentFile();
4755 if (!tracesDir.exists()) {
4757 if (!SELinux.restorecon(tracesDir)) {
4761 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4763 if (clearTraces && tracesFile.exists()) tracesFile.delete();
4764 tracesFile.createNewFile();
4765 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4766 } catch (IOException e) {
4767 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4771 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4775 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4776 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4777 // Use a FileObserver to detect when traces finish writing.
4778 // The order of traces is considered important to maintain for legibility.
4779 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4781 public synchronized void onEvent(int event, String path) { notify(); }
4785 observer.startWatching();
4787 // First collect all of the stacks of the most important pids.
4788 if (firstPids != null) {
4790 int num = firstPids.size();
4791 for (int i = 0; i < num; i++) {
4792 synchronized (observer) {
4793 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4794 observer.wait(200); // Wait for write-close, give up after 200msec
4797 } catch (InterruptedException e) {
4802 // Next collect the stacks of the native pids
4803 if (nativeProcs != null) {
4804 int[] pids = Process.getPidsForCommands(nativeProcs);
4806 for (int pid : pids) {
4807 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4812 // Lastly, measure CPU usage.
4813 if (processCpuTracker != null) {
4814 processCpuTracker.init();
4816 processCpuTracker.update();
4818 synchronized (processCpuTracker) {
4819 processCpuTracker.wait(500); // measure over 1/2 second.
4821 } catch (InterruptedException e) {
4823 processCpuTracker.update();
4825 // We'll take the stack crawls of just the top apps using CPU.
4826 final int N = processCpuTracker.countWorkingStats();
4828 for (int i=0; i<N && numProcs<5; i++) {
4829 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4830 if (lastPids.indexOfKey(stats.pid) >= 0) {
4833 synchronized (observer) {
4834 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4835 observer.wait(200); // Wait for write-close, give up after 200msec
4837 } catch (InterruptedException e) {
4845 observer.stopWatching();
4849 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4850 if (true || IS_USER_BUILD) {
4853 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4854 if (tracesPath == null || tracesPath.length() == 0) {
4858 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4859 StrictMode.allowThreadDiskWrites();
4861 final File tracesFile = new File(tracesPath);
4862 final File tracesDir = tracesFile.getParentFile();
4863 final File tracesTmp = new File(tracesDir, "__tmp__");
4865 if (!tracesDir.exists()) {
4867 if (!SELinux.restorecon(tracesDir.getPath())) {
4871 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4873 if (tracesFile.exists()) {
4875 tracesFile.renameTo(tracesTmp);
4877 StringBuilder sb = new StringBuilder();
4878 Time tobj = new Time();
4879 tobj.set(System.currentTimeMillis());
4880 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4882 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4883 sb.append(" since ");
4885 FileOutputStream fos = new FileOutputStream(tracesFile);
4886 fos.write(sb.toString().getBytes());
4888 fos.write("\n*** No application process!".getBytes());
4891 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4892 } catch (IOException e) {
4893 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4898 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4899 firstPids.add(app.pid);
4900 dumpStackTraces(tracesPath, firstPids, null, null, null);
4903 File lastTracesFile = null;
4904 File curTracesFile = null;
4905 for (int i=9; i>=0; i--) {
4906 String name = String.format(Locale.US, "slow%02d.txt", i);
4907 curTracesFile = new File(tracesDir, name);
4908 if (curTracesFile.exists()) {
4909 if (lastTracesFile != null) {
4910 curTracesFile.renameTo(lastTracesFile);
4912 curTracesFile.delete();
4915 lastTracesFile = curTracesFile;
4917 tracesFile.renameTo(curTracesFile);
4918 if (tracesTmp.exists()) {
4919 tracesTmp.renameTo(tracesFile);
4922 StrictMode.setThreadPolicy(oldPolicy);
4926 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4927 ActivityRecord parent, boolean aboveSystem, final String annotation) {
4928 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4929 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4931 if (mController != null) {
4933 // 0 == continue, -1 = kill process immediately
4934 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4935 if (res < 0 && app.pid != MY_PID) {
4936 app.kill("anr", true);
4938 } catch (RemoteException e) {
4940 Watchdog.getInstance().setActivityController(null);
4944 long anrTime = SystemClock.uptimeMillis();
4945 if (MONITOR_CPU_USAGE) {
4946 updateCpuStatsNow();
4949 synchronized (this) {
4950 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4951 if (mShuttingDown) {
4952 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4954 } else if (app.notResponding) {
4955 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4957 } else if (app.crashing) {
4958 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4962 // In case we come through here for the same app before completing
4963 // this one, mark as anring now so we will bail out.
4964 app.notResponding = true;
4966 // Log the ANR to the event log.
4967 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4968 app.processName, app.info.flags, annotation);
4970 // Dump thread traces as quickly as we can, starting with "interesting" processes.
4971 firstPids.add(app.pid);
4973 int parentPid = app.pid;
4974 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4975 if (parentPid != app.pid) firstPids.add(parentPid);
4977 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4979 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4980 ProcessRecord r = mLruProcesses.get(i);
4981 if (r != null && r.thread != null) {
4983 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4987 lastPids.put(pid, Boolean.TRUE);
4994 // Log the ANR to the main log.
4995 StringBuilder info = new StringBuilder();
4997 info.append("ANR in ").append(app.processName);
4998 if (activity != null && activity.shortComponentName != null) {
4999 info.append(" (").append(activity.shortComponentName).append(")");
5002 info.append("PID: ").append(app.pid).append("\n");
5003 if (annotation != null) {
5004 info.append("Reason: ").append(annotation).append("\n");
5006 if (parent != null && parent != activity) {
5007 info.append("Parent: ").append(parent.shortComponentName).append("\n");
5010 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5012 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5013 NATIVE_STACKS_OF_INTEREST);
5015 String cpuInfo = null;
5016 if (MONITOR_CPU_USAGE) {
5017 updateCpuStatsNow();
5018 synchronized (mProcessCpuTracker) {
5019 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5021 info.append(processCpuTracker.printCurrentLoad());
5022 info.append(cpuInfo);
5025 info.append(processCpuTracker.printCurrentState(anrTime));
5027 Slog.e(TAG, info.toString());
5028 if (tracesFile == null) {
5029 // There is no trace file, so dump (only) the alleged culprit's threads to the log
5030 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5033 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5034 cpuInfo, tracesFile, null);
5036 if (mController != null) {
5038 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5039 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5041 if (res < 0 && app.pid != MY_PID) {
5042 app.kill("anr", true);
5044 synchronized (this) {
5045 mServices.scheduleServiceTimeoutLocked(app);
5050 } catch (RemoteException e) {
5052 Watchdog.getInstance().setActivityController(null);
5056 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5057 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5058 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5060 synchronized (this) {
5061 mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5063 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5064 app.kill("bg anr", true);
5068 // Set the app's notResponding state, and look up the errorReportReceiver
5069 makeAppNotRespondingLocked(app,
5070 activity != null ? activity.shortComponentName : null,
5071 annotation != null ? "ANR " + annotation : "ANR",
5074 // Bring up the infamous App Not Responding dialog
5075 Message msg = Message.obtain();
5076 HashMap<String, Object> map = new HashMap<String, Object>();
5077 msg.what = SHOW_NOT_RESPONDING_MSG;
5079 msg.arg1 = aboveSystem ? 1 : 0;
5080 map.put("app", app);
5081 if (activity != null) {
5082 map.put("activity", activity);
5085 mUiHandler.sendMessage(msg);
5089 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5090 if (!mLaunchWarningShown) {
5091 mLaunchWarningShown = true;
5092 mUiHandler.post(new Runnable() {
5095 synchronized (ActivityManagerService.this) {
5096 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5098 mUiHandler.postDelayed(new Runnable() {
5101 synchronized (ActivityManagerService.this) {
5103 mLaunchWarningShown = false;
5114 public boolean clearApplicationUserData(final String packageName,
5115 final IPackageDataObserver observer, int userId) {
5116 enforceNotIsolatedCaller("clearApplicationUserData");
5117 if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5118 throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5120 int uid = Binder.getCallingUid();
5121 int pid = Binder.getCallingPid();
5122 userId = handleIncomingUser(pid, uid,
5123 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5124 long callingId = Binder.clearCallingIdentity();
5126 IPackageManager pm = AppGlobals.getPackageManager();
5128 synchronized(this) {
5130 pkgUid = pm.getPackageUid(packageName, userId);
5131 } catch (RemoteException e) {
5134 Slog.w(TAG, "Invalid packageName: " + packageName);
5135 if (observer != null) {
5137 observer.onRemoveCompleted(packageName, false);
5138 } catch (RemoteException e) {
5139 Slog.i(TAG, "Observer no longer exists.");
5144 if (uid == pkgUid || checkComponentPermission(
5145 android.Manifest.permission.CLEAR_APP_USER_DATA,
5147 == PackageManager.PERMISSION_GRANTED) {
5148 forceStopPackageLocked(packageName, pkgUid, "clear data");
5150 throw new SecurityException("PID " + pid + " does not have permission "
5151 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5152 + " of package " + packageName);
5155 // Remove all tasks match the cleared application package and user
5156 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5157 final TaskRecord tr = mRecentTasks.get(i);
5158 final String taskPackageName =
5159 tr.getBaseIntent().getComponent().getPackageName();
5160 if (tr.userId != userId) continue;
5161 if (!taskPackageName.equals(packageName)) continue;
5162 removeTaskByIdLocked(tr.taskId, false);
5167 // Clear application user data
5168 pm.clearApplicationUserData(packageName, observer, userId);
5170 synchronized(this) {
5171 // Remove all permissions granted from/to this package
5172 removeUriPermissionsForPackageLocked(packageName, userId, true);
5175 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5176 Uri.fromParts("package", packageName, null));
5177 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5178 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5179 null, null, 0, null, null, null, null, false, false, userId);
5180 } catch (RemoteException e) {
5183 Binder.restoreCallingIdentity(callingId);
5189 public void killBackgroundProcesses(final String packageName, int userId) {
5190 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5191 != PackageManager.PERMISSION_GRANTED &&
5192 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5193 != PackageManager.PERMISSION_GRANTED) {
5194 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5195 + Binder.getCallingPid()
5196 + ", uid=" + Binder.getCallingUid()
5197 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5199 throw new SecurityException(msg);
5202 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5203 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5204 long callingId = Binder.clearCallingIdentity();
5206 IPackageManager pm = AppGlobals.getPackageManager();
5207 synchronized(this) {
5210 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5211 } catch (RemoteException e) {
5214 Slog.w(TAG, "Invalid packageName: " + packageName);
5217 killPackageProcessesLocked(packageName, appId, userId,
5218 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5221 Binder.restoreCallingIdentity(callingId);
5226 public void killAllBackgroundProcesses() {
5227 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5228 != PackageManager.PERMISSION_GRANTED) {
5229 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5230 + Binder.getCallingPid()
5231 + ", uid=" + Binder.getCallingUid()
5232 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5234 throw new SecurityException(msg);
5237 long callingId = Binder.clearCallingIdentity();
5239 synchronized(this) {
5240 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5241 final int NP = mProcessNames.getMap().size();
5242 for (int ip=0; ip<NP; ip++) {
5243 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5244 final int NA = apps.size();
5245 for (int ia=0; ia<NA; ia++) {
5246 ProcessRecord app = apps.valueAt(ia);
5247 if (app.persistent) {
5248 // we don't kill persistent processes
5253 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5260 int N = procs.size();
5261 for (int i=0; i<N; i++) {
5262 removeProcessLocked(procs.get(i), false, true, "kill all background");
5264 mAllowLowerMemLevel = true;
5265 updateOomAdjLocked();
5266 doLowMemReportIfNeededLocked(null);
5269 Binder.restoreCallingIdentity(callingId);
5274 public void forceStopPackage(final String packageName, int userId) {
5275 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5276 != PackageManager.PERMISSION_GRANTED) {
5277 String msg = "Permission Denial: forceStopPackage() from pid="
5278 + Binder.getCallingPid()
5279 + ", uid=" + Binder.getCallingUid()
5280 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5282 throw new SecurityException(msg);
5284 final int callingPid = Binder.getCallingPid();
5285 userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5286 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5287 long callingId = Binder.clearCallingIdentity();
5289 IPackageManager pm = AppGlobals.getPackageManager();
5290 synchronized(this) {
5291 int[] users = userId == UserHandle.USER_ALL
5292 ? getUsersLocked() : new int[] { userId };
5293 for (int user : users) {
5296 pkgUid = pm.getPackageUid(packageName, user);
5297 } catch (RemoteException e) {
5300 Slog.w(TAG, "Invalid packageName: " + packageName);
5304 pm.setPackageStoppedState(packageName, true, user);
5305 } catch (RemoteException e) {
5306 } catch (IllegalArgumentException e) {
5307 Slog.w(TAG, "Failed trying to unstop package "
5308 + packageName + ": " + e);
5310 if (isUserRunningLocked(user, false)) {
5311 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5316 Binder.restoreCallingIdentity(callingId);
5321 public void addPackageDependency(String packageName) {
5322 synchronized (this) {
5323 int callingPid = Binder.getCallingPid();
5324 if (callingPid == Process.myPid()) {
5329 synchronized (mPidsSelfLocked) {
5330 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5333 if (proc.pkgDeps == null) {
5334 proc.pkgDeps = new ArraySet<String>(1);
5336 proc.pkgDeps.add(packageName);
5342 * The pkg name and app id have to be specified.
5345 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5349 // Make sure the uid is valid.
5351 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5354 int callerUid = Binder.getCallingUid();
5355 // Only the system server can kill an application
5356 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5357 // Post an aysnc message to kill the application
5358 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5361 Bundle bundle = new Bundle();
5362 bundle.putString("pkg", pkg);
5363 bundle.putString("reason", reason);
5365 mHandler.sendMessage(msg);
5367 throw new SecurityException(callerUid + " cannot kill pkg: " +
5373 public void closeSystemDialogs(String reason) {
5374 enforceNotIsolatedCaller("closeSystemDialogs");
5376 final int pid = Binder.getCallingPid();
5377 final int uid = Binder.getCallingUid();
5378 final long origId = Binder.clearCallingIdentity();
5380 synchronized (this) {
5381 // Only allow this from foreground processes, so that background
5382 // applications can't abuse it to prevent system UI from being shown.
5383 if (uid >= Process.FIRST_APPLICATION_UID) {
5385 synchronized (mPidsSelfLocked) {
5386 proc = mPidsSelfLocked.get(pid);
5388 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5389 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5390 + " from background process " + proc);
5394 closeSystemDialogsLocked(reason);
5397 Binder.restoreCallingIdentity(origId);
5401 void closeSystemDialogsLocked(String reason) {
5402 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5403 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5404 | Intent.FLAG_RECEIVER_FOREGROUND);
5405 if (reason != null) {
5406 intent.putExtra("reason", reason);
5408 mWindowManager.closeSystemDialogs(reason);
5410 mStackSupervisor.closeSystemDialogsLocked();
5412 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5413 AppOpsManager.OP_NONE, null, false, false,
5414 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5418 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5419 enforceNotIsolatedCaller("getProcessMemoryInfo");
5420 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5421 for (int i=pids.length-1; i>=0; i--) {
5424 synchronized (this) {
5425 synchronized (mPidsSelfLocked) {
5426 proc = mPidsSelfLocked.get(pids[i]);
5427 oomAdj = proc != null ? proc.setAdj : 0;
5430 infos[i] = new Debug.MemoryInfo();
5431 Debug.getMemoryInfo(pids[i], infos[i]);
5433 synchronized (this) {
5434 if (proc.thread != null && proc.setAdj == oomAdj) {
5435 // Record this for posterity if the process has been stable.
5436 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5437 infos[i].getTotalUss(), false, proc.pkgList);
5446 public long[] getProcessPss(int[] pids) {
5447 enforceNotIsolatedCaller("getProcessPss");
5448 long[] pss = new long[pids.length];
5449 for (int i=pids.length-1; i>=0; i--) {
5452 synchronized (this) {
5453 synchronized (mPidsSelfLocked) {
5454 proc = mPidsSelfLocked.get(pids[i]);
5455 oomAdj = proc != null ? proc.setAdj : 0;
5458 long[] tmpUss = new long[1];
5459 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5461 synchronized (this) {
5462 if (proc.thread != null && proc.setAdj == oomAdj) {
5463 // Record this for posterity if the process has been stable.
5464 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5473 public void killApplicationProcess(String processName, int uid) {
5474 if (processName == null) {
5478 int callerUid = Binder.getCallingUid();
5479 // Only the system server can kill an application
5480 if (callerUid == Process.SYSTEM_UID) {
5481 synchronized (this) {
5482 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5483 if (app != null && app.thread != null) {
5485 app.thread.scheduleSuicide();
5486 } catch (RemoteException e) {
5487 // If the other end already died, then our work here is done.
5490 Slog.w(TAG, "Process/uid not found attempting kill of "
5491 + processName + " / " + uid);
5495 throw new SecurityException(callerUid + " cannot kill app process: " +
5500 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5501 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5502 false, true, false, false, UserHandle.getUserId(uid), reason);
5503 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5504 Uri.fromParts("package", packageName, null));
5505 if (!mProcessesReady) {
5506 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5507 | Intent.FLAG_RECEIVER_FOREGROUND);
5509 intent.putExtra(Intent.EXTRA_UID, uid);
5510 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5511 broadcastIntentLocked(null, null, intent,
5512 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5513 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5516 private void forceStopUserLocked(int userId, String reason) {
5517 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5518 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5519 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5520 | Intent.FLAG_RECEIVER_FOREGROUND);
5521 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5522 broadcastIntentLocked(null, null, intent,
5523 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5524 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5527 private final boolean killPackageProcessesLocked(String packageName, int appId,
5528 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5529 boolean doit, boolean evenPersistent, String reason) {
5530 ArrayList<ProcessRecord> procs = new ArrayList<>();
5532 // Remove all processes this package may have touched: all with the
5533 // same UID (except for the system or root user), and all whose name
5534 // matches the package name.
5535 final int NP = mProcessNames.getMap().size();
5536 for (int ip=0; ip<NP; ip++) {
5537 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5538 final int NA = apps.size();
5539 for (int ia=0; ia<NA; ia++) {
5540 ProcessRecord app = apps.valueAt(ia);
5541 if (app.persistent && !evenPersistent) {
5542 // we don't kill persistent processes
5552 // Skip process if it doesn't meet our oom adj requirement.
5553 if (app.setAdj < minOomAdj) {
5557 // If no package is specified, we call all processes under the
5559 if (packageName == null) {
5560 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5563 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5566 // Package has been specified, we want to hit all processes
5567 // that match it. We need to qualify this by the processes
5568 // that are running under the specified app and user ID.
5570 final boolean isDep = app.pkgDeps != null
5571 && app.pkgDeps.contains(packageName);
5572 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5575 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5578 if (!app.pkgList.containsKey(packageName) && !isDep) {
5583 // Process has passed all conditions, kill it!
5592 int N = procs.size();
5593 for (int i=0; i<N; i++) {
5594 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5596 updateOomAdjLocked();
5600 private void cleanupDisabledPackageComponentsLocked(
5601 String packageName, int userId, boolean killProcess, String[] changedClasses) {
5603 Set<String> disabledClasses = null;
5604 boolean packageDisabled = false;
5605 IPackageManager pm = AppGlobals.getPackageManager();
5607 if (changedClasses == null) {
5608 // Nothing changed...
5612 // Determine enable/disable state of the package and its components.
5613 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5614 for (int i = changedClasses.length - 1; i >= 0; i--) {
5615 final String changedClass = changedClasses[i];
5617 if (changedClass.equals(packageName)) {
5619 // Entire package setting changed
5620 enabled = pm.getApplicationEnabledSetting(packageName,
5621 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5622 } catch (Exception e) {
5623 // No such package/component; probably racing with uninstall. In any
5624 // event it means we have nothing further to do here.
5627 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5628 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5629 if (packageDisabled) {
5630 // Entire package is disabled.
5631 // No need to continue to check component states.
5632 disabledClasses = null;
5637 enabled = pm.getComponentEnabledSetting(
5638 new ComponentName(packageName, changedClass),
5639 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5640 } catch (Exception e) {
5641 // As above, probably racing with uninstall.
5644 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5645 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5646 if (disabledClasses == null) {
5647 disabledClasses = new ArraySet<>(changedClasses.length);
5649 disabledClasses.add(changedClass);
5654 if (!packageDisabled && disabledClasses == null) {
5655 // Nothing to do here...
5659 // Clean-up disabled activities.
5660 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5661 packageName, disabledClasses, true, false, userId) && mBooted) {
5662 mStackSupervisor.resumeTopActivitiesLocked();
5663 mStackSupervisor.scheduleIdleLocked();
5666 // Clean-up disabled tasks
5667 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5669 // Clean-up disabled services.
5670 mServices.bringDownDisabledPackageServicesLocked(
5671 packageName, disabledClasses, userId, false, killProcess, true);
5673 // Clean-up disabled providers.
5674 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5675 mProviderMap.collectPackageProvidersLocked(
5676 packageName, disabledClasses, true, false, userId, providers);
5677 for (int i = providers.size() - 1; i >= 0; i--) {
5678 removeDyingProviderLocked(null, providers.get(i), true);
5681 // Clean-up disabled broadcast receivers.
5682 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5683 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5684 packageName, disabledClasses, userId, true);
5689 private final boolean forceStopPackageLocked(String packageName, int appId,
5690 boolean callerWillRestart, boolean purgeCache, boolean doit,
5691 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5694 if (userId == UserHandle.USER_ALL && packageName == null) {
5695 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5698 if (appId < 0 && packageName != null) {
5700 appId = UserHandle.getAppId(
5701 AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5702 } catch (RemoteException e) {
5707 if (packageName != null) {
5708 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5709 + " user=" + userId + ": " + reason);
5711 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5714 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5715 for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5716 SparseArray<Long> ba = pmap.valueAt(ip);
5717 for (i = ba.size() - 1; i >= 0; i--) {
5718 boolean remove = false;
5719 final int entUid = ba.keyAt(i);
5720 if (packageName != null) {
5721 if (userId == UserHandle.USER_ALL) {
5722 if (UserHandle.getAppId(entUid) == appId) {
5726 if (entUid == UserHandle.getUid(userId, appId)) {
5730 } else if (UserHandle.getUserId(entUid) == userId) {
5737 if (ba.size() == 0) {
5743 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5744 -100, callerWillRestart, true, doit, evenPersistent,
5745 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5747 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5748 packageName, null, doit, evenPersistent, userId)) {
5752 didSomething = true;
5755 if (mServices.bringDownDisabledPackageServicesLocked(
5756 packageName, null, userId, evenPersistent, true, doit)) {
5760 didSomething = true;
5763 if (packageName == null) {
5764 // Remove all sticky broadcasts from this user.
5765 mStickyBroadcasts.remove(userId);
5768 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5769 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5770 userId, providers)) {
5774 didSomething = true;
5776 for (i = providers.size() - 1; i >= 0; i--) {
5777 removeDyingProviderLocked(null, providers.get(i), true);
5780 // Remove transient permissions granted from/to this package/user
5781 removeUriPermissionsForPackageLocked(packageName, userId, false);
5784 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5785 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5786 packageName, null, userId, doit);
5790 if (packageName == null || uninstalling) {
5791 // Remove pending intents. For now we only do this when force
5792 // stopping users, because we have some problems when doing this
5793 // for packages -- app widgets are not currently cleaned up for
5794 // such packages, so they can be left with bad pending intents.
5795 if (mIntentSenderRecords.size() > 0) {
5796 Iterator<WeakReference<PendingIntentRecord>> it
5797 = mIntentSenderRecords.values().iterator();
5798 while (it.hasNext()) {
5799 WeakReference<PendingIntentRecord> wpir = it.next();
5804 PendingIntentRecord pir = wpir.get();
5809 if (packageName == null) {
5810 // Stopping user, remove all objects for the user.
5811 if (pir.key.userId != userId) {
5812 // Not the same user, skip it.
5816 if (UserHandle.getAppId(pir.uid) != appId) {
5817 // Different app id, skip it.
5820 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5821 // Different user, skip it.
5824 if (!pir.key.packageName.equals(packageName)) {
5825 // Different package, skip it.
5832 didSomething = true;
5834 pir.canceled = true;
5835 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5836 pir.key.activity.pendingResults.remove(pir.ref);
5843 if (purgeCache && packageName != null) {
5844 AttributeCache ac = AttributeCache.instance();
5846 ac.removePackage(packageName);
5850 mStackSupervisor.resumeTopActivitiesLocked();
5851 mStackSupervisor.scheduleIdleLocked();
5855 return didSomething;
5858 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5859 ProcessRecord old = mProcessNames.remove(name, uid);
5861 old.uidRecord.numProcs--;
5862 if (old.uidRecord.numProcs == 0) {
5863 // No more processes using this uid, tell clients it is gone.
5864 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5865 "No more processes in " + old.uidRecord);
5866 enqueueUidChangeLocked(old.uidRecord, true);
5867 mActiveUids.remove(uid);
5869 old.uidRecord = null;
5871 mIsolatedProcesses.remove(uid);
5875 private final void addProcessNameLocked(ProcessRecord proc) {
5876 // We shouldn't already have a process under this name, but just in case we
5877 // need to clean up whatever may be there now.
5878 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5879 if (old == proc && proc.persistent) {
5880 // We are re-adding a persistent process. Whatevs! Just leave it there.
5881 Slog.w(TAG, "Re-adding persistent process " + proc);
5882 } else if (old != null) {
5883 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5885 UidRecord uidRec = mActiveUids.get(proc.uid);
5886 if (uidRec == null) {
5887 uidRec = new UidRecord(proc.uid);
5888 // This is the first appearance of the uid, report it now!
5889 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5890 "Creating new process uid: " + uidRec);
5891 mActiveUids.put(proc.uid, uidRec);
5892 enqueueUidChangeLocked(uidRec, false);
5894 proc.uidRecord = uidRec;
5896 mProcessNames.put(proc.processName, proc.uid, proc);
5897 if (proc.isolated) {
5898 mIsolatedProcesses.put(proc.uid, proc);
5902 private final boolean removeProcessLocked(ProcessRecord app,
5903 boolean callerWillRestart, boolean allowRestart, String reason) {
5904 final String name = app.processName;
5905 final int uid = app.uid;
5906 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5907 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5909 removeProcessNameLocked(name, uid);
5910 if (mHeavyWeightProcess == app) {
5911 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5912 mHeavyWeightProcess.userId, 0));
5913 mHeavyWeightProcess = null;
5915 boolean needRestart = false;
5916 if (app.pid > 0 && app.pid != MY_PID) {
5918 synchronized (mPidsSelfLocked) {
5919 mPidsSelfLocked.remove(pid);
5920 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5922 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5924 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5926 boolean willRestart = false;
5927 if (app.persistent && !app.isolated) {
5928 if (!callerWillRestart) {
5934 app.kill(reason, true);
5935 handleAppDiedLocked(app, willRestart, allowRestart);
5937 removeLruProcessLocked(app);
5938 addAppLocked(app.info, false, null /* ABI override */);
5941 mRemovedProcesses.add(app);
5947 private final void processStartTimedOutLocked(ProcessRecord app) {
5948 final int pid = app.pid;
5949 boolean gone = false;
5950 synchronized (mPidsSelfLocked) {
5951 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5952 if (knownApp != null && knownApp.thread == null) {
5953 mPidsSelfLocked.remove(pid);
5959 Slog.w(TAG, "Process " + app + " failed to attach");
5960 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5961 pid, app.uid, app.processName);
5962 removeProcessNameLocked(app.processName, app.uid);
5963 if (mHeavyWeightProcess == app) {
5964 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5965 mHeavyWeightProcess.userId, 0));
5966 mHeavyWeightProcess = null;
5968 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5970 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5972 // Take care of any launching providers waiting for this process.
5973 checkAppInLaunchingProvidersLocked(app, true);
5974 // Take care of any services that are waiting for the process.
5975 mServices.processStartTimedOutLocked(app);
5976 app.kill("start timeout", true);
5977 removeLruProcessLocked(app);
5978 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5979 Slog.w(TAG, "Unattached app died before backup, skipping");
5981 IBackupManager bm = IBackupManager.Stub.asInterface(
5982 ServiceManager.getService(Context.BACKUP_SERVICE));
5983 bm.agentDisconnected(app.info.packageName);
5984 } catch (RemoteException e) {
5985 // Can't happen; the backup manager is local
5988 if (isPendingBroadcastProcessLocked(pid)) {
5989 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5990 skipPendingBroadcastLocked(pid);
5993 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5997 private final boolean attachApplicationLocked(IApplicationThread thread,
6000 // Find the application record that is being attached... either via
6001 // the pid if we are running in multiple processes, or just pull the
6002 // next app record if we are emulating process with anonymous threads.
6004 if (pid != MY_PID && pid >= 0) {
6005 synchronized (mPidsSelfLocked) {
6006 app = mPidsSelfLocked.get(pid);
6013 Slog.w(TAG, "No pending application record for pid " + pid
6014 + " (IApplicationThread " + thread + "); dropping process");
6015 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6016 if (pid > 0 && pid != MY_PID) {
6017 Process.killProcessQuiet(pid);
6018 //TODO: killProcessGroup(app.info.uid, pid);
6021 thread.scheduleExit();
6022 } catch (Exception e) {
6023 // Ignore exceptions.
6029 // If this application record is still attached to a previous
6030 // process, clean it up now.
6031 if (app.thread != null) {
6032 handleAppDiedLocked(app, true, true);
6035 // Tell the process all about itself.
6037 if (DEBUG_ALL) Slog.v(
6038 TAG, "Binding process pid " + pid + " to record " + app);
6040 final String processName = app.processName;
6042 AppDeathRecipient adr = new AppDeathRecipient(
6044 thread.asBinder().linkToDeath(adr, 0);
6045 app.deathRecipient = adr;
6046 } catch (RemoteException e) {
6047 app.resetPackageList(mProcessStats);
6048 startProcessLocked(app, "link fail", processName);
6052 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6054 app.makeActive(thread, mProcessStats);
6055 app.curAdj = app.setAdj = -100;
6056 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6057 app.forcingToForeground = null;
6058 updateProcessForegroundLocked(app, false, false);
6059 app.hasShownUi = false;
6060 app.debugging = false;
6062 app.killedByAm = false;
6064 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6066 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6067 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6070 Slog.i(TAG, "Launching preboot mode app: " + app);
6073 if (DEBUG_ALL) Slog.v(
6074 TAG, "New app record " + app
6075 + " thread=" + thread.asBinder() + " pid=" + pid);
6077 int testMode = IApplicationThread.DEBUG_OFF;
6078 if (mDebugApp != null && mDebugApp.equals(processName)) {
6079 testMode = mWaitForDebugger
6080 ? IApplicationThread.DEBUG_WAIT
6081 : IApplicationThread.DEBUG_ON;
6082 app.debugging = true;
6083 if (mDebugTransient) {
6084 mDebugApp = mOrigDebugApp;
6085 mWaitForDebugger = mOrigWaitForDebugger;
6088 String profileFile = app.instrumentationProfileFile;
6089 ParcelFileDescriptor profileFd = null;
6090 int samplingInterval = 0;
6091 boolean profileAutoStop = false;
6092 if (mProfileApp != null && mProfileApp.equals(processName)) {
6094 profileFile = mProfileFile;
6095 profileFd = mProfileFd;
6096 samplingInterval = mSamplingInterval;
6097 profileAutoStop = mAutoStopProfiler;
6099 boolean enableOpenGlTrace = false;
6100 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6101 enableOpenGlTrace = true;
6102 mOpenGlTraceApp = null;
6105 // If the app is being launched for restore or full backup, set it up specially
6106 boolean isRestrictedBackupMode = false;
6107 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6108 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6109 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6110 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6113 ensurePackageDexOpt(app.instrumentationInfo != null
6114 ? app.instrumentationInfo.packageName
6115 : app.info.packageName);
6116 if (app.instrumentationClass != null) {
6117 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6119 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6120 + processName + " with config " + mConfiguration);
6121 ApplicationInfo appInfo = app.instrumentationInfo != null
6122 ? app.instrumentationInfo : app.info;
6123 app.compat = compatibilityInfoForPackageLocked(appInfo);
6124 if (profileFd != null) {
6125 profileFd = profileFd.dup();
6127 ProfilerInfo profilerInfo = profileFile == null ? null
6128 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6129 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6130 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6131 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6132 isRestrictedBackupMode || !normalMode, app.persistent,
6133 new Configuration(mConfiguration), app.compat,
6134 getCommonServicesLocked(app.isolated),
6135 mCoreSettingsObserver.getCoreSettingsLocked());
6136 updateLruProcessLocked(app, false, null);
6137 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6138 } catch (Exception e) {
6139 // todo: Yikes! What should we do? For now we will try to
6140 // start another process, but that could easily get us in
6141 // an infinite loop of restarting processes...
6142 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6144 app.resetPackageList(mProcessStats);
6145 app.unlinkDeathRecipient();
6146 startProcessLocked(app, "bind fail", processName);
6150 // Remove this record from the list of starting applications.
6151 mPersistentStartingProcesses.remove(app);
6152 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6153 "Attach application locked removing on hold: " + app);
6154 mProcessesOnHold.remove(app);
6156 boolean badApp = false;
6157 boolean didSomething = false;
6159 // See if the top visible activity is waiting to run in this process...
6162 if (mStackSupervisor.attachApplicationLocked(app)) {
6163 didSomething = true;
6165 } catch (Exception e) {
6166 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6171 // Find any services that should be running in this process...
6174 didSomething |= mServices.attachApplicationLocked(app, processName);
6175 } catch (Exception e) {
6176 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6181 // Check if a next-broadcast receiver is in this process...
6182 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6184 didSomething |= sendPendingBroadcastsLocked(app);
6185 } catch (Exception e) {
6186 // If the app died trying to launch the receiver we declare it 'bad'
6187 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6192 // Check whether the next backup agent is in this process...
6193 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6194 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6195 "New app is backup target, launching agent for " + app);
6196 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6198 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6199 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6200 mBackupTarget.backupMode);
6201 } catch (Exception e) {
6202 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6208 app.kill("error during init", true);
6209 handleAppDiedLocked(app, false, true);
6213 if (!didSomething) {
6214 updateOomAdjLocked();
6221 public final void attachApplication(IApplicationThread thread) {
6222 synchronized (this) {
6223 int callingPid = Binder.getCallingPid();
6224 final long origId = Binder.clearCallingIdentity();
6225 attachApplicationLocked(thread, callingPid);
6226 Binder.restoreCallingIdentity(origId);
6231 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6232 final long origId = Binder.clearCallingIdentity();
6233 synchronized (this) {
6234 ActivityStack stack = ActivityRecord.getStackLocked(token);
6235 if (stack != null) {
6237 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6238 if (stopProfiling) {
6239 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6242 } catch (IOException e) {
6244 clearProfilerLocked();
6249 Binder.restoreCallingIdentity(origId);
6252 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6253 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6254 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6257 void enableScreenAfterBoot() {
6258 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6259 SystemClock.uptimeMillis());
6260 mWindowManager.enableScreenAfterBoot();
6262 synchronized (this) {
6263 updateEventDispatchingLocked();
6268 public void showBootMessage(final CharSequence msg, final boolean always) {
6269 if (Binder.getCallingUid() != Process.myUid()) {
6270 // These days only the core system can call this, so apps can't get in
6271 // the way of what we show about running them.
6273 mWindowManager.showBootMessage(msg, always);
6277 public void keyguardWaitingForActivityDrawn() {
6278 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6279 final long token = Binder.clearCallingIdentity();
6281 synchronized (this) {
6282 if (DEBUG_LOCKSCREEN) logLockScreen("");
6283 mWindowManager.keyguardWaitingForActivityDrawn();
6284 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6285 mLockScreenShown = LOCK_SCREEN_LEAVING;
6286 updateSleepIfNeededLocked();
6290 Binder.restoreCallingIdentity(token);
6295 public void keyguardGoingAway(boolean disableWindowAnimations,
6296 boolean keyguardGoingToNotificationShade) {
6297 enforceNotIsolatedCaller("keyguardGoingAway");
6298 final long token = Binder.clearCallingIdentity();
6300 synchronized (this) {
6301 if (DEBUG_LOCKSCREEN) logLockScreen("");
6302 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6303 keyguardGoingToNotificationShade);
6304 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6305 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6306 updateSleepIfNeededLocked();
6310 Binder.restoreCallingIdentity(token);
6314 final void finishBooting() {
6315 synchronized (this) {
6316 if (!mBootAnimationComplete) {
6317 mCallFinishBooting = true;
6320 mCallFinishBooting = false;
6323 ArraySet<String> completedIsas = new ArraySet<String>();
6324 for (String abi : Build.SUPPORTED_ABIS) {
6325 Process.establishZygoteConnectionForAbi(abi);
6326 final String instructionSet = VMRuntime.getInstructionSet(abi);
6327 if (!completedIsas.contains(instructionSet)) {
6328 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6329 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6331 completedIsas.add(instructionSet);
6335 IntentFilter pkgFilter = new IntentFilter();
6336 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6337 pkgFilter.addDataScheme("package");
6338 mContext.registerReceiver(new BroadcastReceiver() {
6340 public void onReceive(Context context, Intent intent) {
6341 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6343 for (String pkg : pkgs) {
6344 synchronized (ActivityManagerService.this) {
6345 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6346 0, "query restart")) {
6347 setResultCode(Activity.RESULT_OK);
6356 IntentFilter dumpheapFilter = new IntentFilter();
6357 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6358 mContext.registerReceiver(new BroadcastReceiver() {
6360 public void onReceive(Context context, Intent intent) {
6361 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6362 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6364 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6369 // Let system services know.
6370 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6372 synchronized (this) {
6373 // Ensure that any processes we had put on hold are now started
6375 final int NP = mProcessesOnHold.size();
6377 ArrayList<ProcessRecord> procs =
6378 new ArrayList<ProcessRecord>(mProcessesOnHold);
6379 for (int ip=0; ip<NP; ip++) {
6380 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6382 startProcessLocked(procs.get(ip), "on-hold", null);
6386 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6387 // Start looking for apps that are abusing wake locks.
6388 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6389 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6390 // Tell anyone interested that we are done booting!
6391 SystemProperties.set("sys.boot_completed", "1");
6393 // And trigger dev.bootcomplete if we are not showing encryption progress
6394 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6395 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6396 SystemProperties.set("dev.bootcomplete", "1");
6398 for (int i=0; i<mStartedUsers.size(); i++) {
6399 UserState uss = mStartedUsers.valueAt(i);
6400 if (uss.mState == UserState.STATE_BOOTING) {
6401 uss.mState = UserState.STATE_RUNNING;
6402 final int userId = mStartedUsers.keyAt(i);
6403 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6404 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6405 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6406 broadcastIntentLocked(null, null, intent, null,
6407 new IIntentReceiver.Stub() {
6409 public void performReceive(Intent intent, int resultCode,
6410 String data, Bundle extras, boolean ordered,
6411 boolean sticky, int sendingUser) {
6412 synchronized (ActivityManagerService.this) {
6413 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6419 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6420 AppOpsManager.OP_NONE, null, true, false,
6421 MY_PID, Process.SYSTEM_UID, userId);
6424 scheduleStartProfilesLocked();
6430 public void bootAnimationComplete() {
6431 final boolean callFinishBooting;
6432 synchronized (this) {
6433 callFinishBooting = mCallFinishBooting;
6434 mBootAnimationComplete = true;
6436 if (callFinishBooting) {
6441 final void ensureBootCompleted() {
6443 boolean enableScreen;
6444 synchronized (this) {
6447 enableScreen = !mBooted;
6456 enableScreenAfterBoot();
6461 public final void activityResumed(IBinder token) {
6462 final long origId = Binder.clearCallingIdentity();
6463 synchronized(this) {
6464 ActivityStack stack = ActivityRecord.getStackLocked(token);
6465 if (stack != null) {
6466 ActivityRecord.activityResumedLocked(token);
6469 Binder.restoreCallingIdentity(origId);
6473 public final void activityPaused(IBinder token) {
6474 final long origId = Binder.clearCallingIdentity();
6475 synchronized(this) {
6476 ActivityStack stack = ActivityRecord.getStackLocked(token);
6477 if (stack != null) {
6478 stack.activityPausedLocked(token, false);
6481 Binder.restoreCallingIdentity(origId);
6485 public final void activityStopped(IBinder token, Bundle icicle,
6486 PersistableBundle persistentState, CharSequence description) {
6487 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6489 // Refuse possible leaked file descriptors
6490 if (icicle != null && icicle.hasFileDescriptors()) {
6491 throw new IllegalArgumentException("File descriptors passed in Bundle");
6494 final long origId = Binder.clearCallingIdentity();
6496 synchronized (this) {
6497 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6499 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6505 Binder.restoreCallingIdentity(origId);
6509 public final void activityDestroyed(IBinder token) {
6510 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6511 synchronized (this) {
6512 ActivityStack stack = ActivityRecord.getStackLocked(token);
6513 if (stack != null) {
6514 stack.activityDestroyedLocked(token, "activityDestroyed");
6520 public final void backgroundResourcesReleased(IBinder token) {
6521 final long origId = Binder.clearCallingIdentity();
6523 synchronized (this) {
6524 ActivityStack stack = ActivityRecord.getStackLocked(token);
6525 if (stack != null) {
6526 stack.backgroundResourcesReleased();
6530 Binder.restoreCallingIdentity(origId);
6535 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6536 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6540 public final void notifyEnterAnimationComplete(IBinder token) {
6541 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6545 public String getCallingPackage(IBinder token) {
6546 synchronized (this) {
6547 ActivityRecord r = getCallingRecordLocked(token);
6548 return r != null ? r.info.packageName : null;
6553 public ComponentName getCallingActivity(IBinder token) {
6554 synchronized (this) {
6555 ActivityRecord r = getCallingRecordLocked(token);
6556 return r != null ? r.intent.getComponent() : null;
6560 private ActivityRecord getCallingRecordLocked(IBinder token) {
6561 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6569 public ComponentName getActivityClassForToken(IBinder token) {
6570 synchronized(this) {
6571 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6575 return r.intent.getComponent();
6580 public String getPackageForToken(IBinder token) {
6581 synchronized(this) {
6582 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6586 return r.packageName;
6591 public boolean isRootVoiceInteraction(IBinder token) {
6592 synchronized(this) {
6593 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6597 return r.rootVoiceInteraction;
6602 public IIntentSender getIntentSender(int type,
6603 String packageName, IBinder token, String resultWho,
6604 int requestCode, Intent[] intents, String[] resolvedTypes,
6605 int flags, Bundle options, int userId) {
6606 enforceNotIsolatedCaller("getIntentSender");
6607 // Refuse possible leaked file descriptors
6608 if (intents != null) {
6609 if (intents.length < 1) {
6610 throw new IllegalArgumentException("Intents array length must be >= 1");
6612 for (int i=0; i<intents.length; i++) {
6613 Intent intent = intents[i];
6614 if (intent != null) {
6615 if (intent.hasFileDescriptors()) {
6616 throw new IllegalArgumentException("File descriptors passed in Intent");
6618 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6619 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6620 throw new IllegalArgumentException(
6621 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6623 intents[i] = new Intent(intent);
6626 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6627 throw new IllegalArgumentException(
6628 "Intent array length does not match resolvedTypes length");
6631 if (options != null) {
6632 if (options.hasFileDescriptors()) {
6633 throw new IllegalArgumentException("File descriptors passed in options");
6637 synchronized(this) {
6638 int callingUid = Binder.getCallingUid();
6639 int origUserId = userId;
6640 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6641 type == ActivityManager.INTENT_SENDER_BROADCAST,
6642 ALLOW_NON_FULL, "getIntentSender", null);
6643 if (origUserId == UserHandle.USER_CURRENT) {
6644 // We don't want to evaluate this until the pending intent is
6645 // actually executed. However, we do want to always do the
6646 // security checking for it above.
6647 userId = UserHandle.USER_CURRENT;
6650 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6651 int uid = AppGlobals.getPackageManager()
6652 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6653 if (!UserHandle.isSameApp(callingUid, uid)) {
6654 String msg = "Permission Denial: getIntentSender() from pid="
6655 + Binder.getCallingPid()
6656 + ", uid=" + Binder.getCallingUid()
6657 + ", (need uid=" + uid + ")"
6658 + " is not allowed to send as package " + packageName;
6660 throw new SecurityException(msg);
6664 return getIntentSenderLocked(type, packageName, callingUid, userId,
6665 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6667 } catch (RemoteException e) {
6668 throw new SecurityException(e);
6673 IIntentSender getIntentSenderLocked(int type, String packageName,
6674 int callingUid, int userId, IBinder token, String resultWho,
6675 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6677 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6678 ActivityRecord activity = null;
6679 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6680 activity = ActivityRecord.isInStackLocked(token);
6681 if (activity == null) {
6684 if (activity.finishing) {
6689 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6690 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6691 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6692 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6693 |PendingIntent.FLAG_UPDATE_CURRENT);
6695 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6696 type, packageName, activity, resultWho,
6697 requestCode, intents, resolvedTypes, flags, options, userId);
6698 WeakReference<PendingIntentRecord> ref;
6699 ref = mIntentSenderRecords.get(key);
6700 PendingIntentRecord rec = ref != null ? ref.get() : null;
6702 if (!cancelCurrent) {
6703 if (updateCurrent) {
6704 if (rec.key.requestIntent != null) {
6705 rec.key.requestIntent.replaceExtras(intents != null ?
6706 intents[intents.length - 1] : null);
6708 if (intents != null) {
6709 intents[intents.length-1] = rec.key.requestIntent;
6710 rec.key.allIntents = intents;
6711 rec.key.allResolvedTypes = resolvedTypes;
6713 rec.key.allIntents = null;
6714 rec.key.allResolvedTypes = null;
6719 rec.canceled = true;
6720 mIntentSenderRecords.remove(key);
6725 rec = new PendingIntentRecord(this, key, callingUid);
6726 mIntentSenderRecords.put(key, rec.ref);
6727 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6728 if (activity.pendingResults == null) {
6729 activity.pendingResults
6730 = new HashSet<WeakReference<PendingIntentRecord>>();
6732 activity.pendingResults.add(rec.ref);
6738 public void cancelIntentSender(IIntentSender sender) {
6739 if (!(sender instanceof PendingIntentRecord)) {
6742 synchronized(this) {
6743 PendingIntentRecord rec = (PendingIntentRecord)sender;
6745 int uid = AppGlobals.getPackageManager()
6746 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6747 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6748 String msg = "Permission Denial: cancelIntentSender() from pid="
6749 + Binder.getCallingPid()
6750 + ", uid=" + Binder.getCallingUid()
6751 + " is not allowed to cancel packges "
6752 + rec.key.packageName;
6754 throw new SecurityException(msg);
6756 } catch (RemoteException e) {
6757 throw new SecurityException(e);
6759 cancelIntentSenderLocked(rec, true);
6763 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6764 rec.canceled = true;
6765 mIntentSenderRecords.remove(rec.key);
6766 if (cleanActivity && rec.key.activity != null) {
6767 rec.key.activity.pendingResults.remove(rec.ref);
6772 public String getPackageForIntentSender(IIntentSender pendingResult) {
6773 if (!(pendingResult instanceof PendingIntentRecord)) {
6777 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6778 return res.key.packageName;
6779 } catch (ClassCastException e) {
6785 public int getUidForIntentSender(IIntentSender sender) {
6786 if (sender instanceof PendingIntentRecord) {
6788 PendingIntentRecord res = (PendingIntentRecord)sender;
6790 } catch (ClassCastException e) {
6797 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6798 if (!(pendingResult instanceof PendingIntentRecord)) {
6802 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6803 if (res.key.allIntents == null) {
6806 for (int i=0; i<res.key.allIntents.length; i++) {
6807 Intent intent = res.key.allIntents[i];
6808 if (intent.getPackage() != null && intent.getComponent() != null) {
6813 } catch (ClassCastException e) {
6819 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6820 if (!(pendingResult instanceof PendingIntentRecord)) {
6824 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6825 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6829 } catch (ClassCastException e) {
6835 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6836 if (!(pendingResult instanceof PendingIntentRecord)) {
6840 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6841 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6842 } catch (ClassCastException e) {
6848 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6849 if (!(pendingResult instanceof PendingIntentRecord)) {
6853 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6854 synchronized (this) {
6855 return getTagForIntentSenderLocked(res, prefix);
6857 } catch (ClassCastException e) {
6862 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6863 final Intent intent = res.key.requestIntent;
6864 if (intent != null) {
6865 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6866 || res.lastTagPrefix.equals(prefix))) {
6869 res.lastTagPrefix = prefix;
6870 final StringBuilder sb = new StringBuilder(128);
6871 if (prefix != null) {
6874 if (intent.getAction() != null) {
6875 sb.append(intent.getAction());
6876 } else if (intent.getComponent() != null) {
6877 intent.getComponent().appendShortString(sb);
6881 return res.lastTag = sb.toString();
6887 public void setProcessLimit(int max) {
6888 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6889 "setProcessLimit()");
6890 synchronized (this) {
6891 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6892 mProcessLimitOverride = max;
6898 public int getProcessLimit() {
6899 synchronized (this) {
6900 return mProcessLimitOverride;
6904 void foregroundTokenDied(ForegroundToken token) {
6905 synchronized (ActivityManagerService.this) {
6906 synchronized (mPidsSelfLocked) {
6908 = mForegroundProcesses.get(token.pid);
6912 mForegroundProcesses.remove(token.pid);
6913 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6917 pr.forcingToForeground = null;
6918 updateProcessForegroundLocked(pr, false, false);
6920 updateOomAdjLocked();
6925 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6926 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6927 "setProcessForeground()");
6928 synchronized(this) {
6929 boolean changed = false;
6931 synchronized (mPidsSelfLocked) {
6932 ProcessRecord pr = mPidsSelfLocked.get(pid);
6933 if (pr == null && isForeground) {
6934 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6937 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6938 if (oldToken != null) {
6939 oldToken.token.unlinkToDeath(oldToken, 0);
6940 mForegroundProcesses.remove(pid);
6942 pr.forcingToForeground = null;
6946 if (isForeground && token != null) {
6947 ForegroundToken newToken = new ForegroundToken() {
6949 public void binderDied() {
6950 foregroundTokenDied(this);
6954 newToken.token = token;
6956 token.linkToDeath(newToken, 0);
6957 mForegroundProcesses.put(pid, newToken);
6958 pr.forcingToForeground = token;
6960 } catch (RemoteException e) {
6961 // If the process died while doing this, we will later
6962 // do the cleanup with the process death link.
6968 updateOomAdjLocked();
6973 // =========================================================
6975 // =========================================================
6977 static class ProcessInfoService extends IProcessInfoService.Stub {
6978 final ActivityManagerService mActivityManagerService;
6979 ProcessInfoService(ActivityManagerService activityManagerService) {
6980 mActivityManagerService = activityManagerService;
6984 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6985 mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6990 * For each PID in the given input array, write the current process state
6991 * for that process into the output array, or -1 to indicate that no
6992 * process with the given PID exists.
6994 public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6996 throw new NullPointerException("pids");
6997 } else if (states == null) {
6998 throw new NullPointerException("states");
6999 } else if (pids.length != states.length) {
7000 throw new IllegalArgumentException("input and output arrays have different lengths!");
7003 synchronized (mPidsSelfLocked) {
7004 for (int i = 0; i < pids.length; i++) {
7005 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7006 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7012 // =========================================================
7014 // =========================================================
7016 static class PermissionController extends IPermissionController.Stub {
7017 ActivityManagerService mActivityManagerService;
7018 PermissionController(ActivityManagerService activityManagerService) {
7019 mActivityManagerService = activityManagerService;
7023 public boolean checkPermission(String permission, int pid, int uid) {
7024 return mActivityManagerService.checkPermission(permission, pid,
7025 uid) == PackageManager.PERMISSION_GRANTED;
7029 public String[] getPackagesForUid(int uid) {
7030 return mActivityManagerService.mContext.getPackageManager()
7031 .getPackagesForUid(uid);
7035 public boolean isRuntimePermission(String permission) {
7037 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7038 .getPermissionInfo(permission, 0);
7039 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7040 } catch (NameNotFoundException nnfe) {
7041 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7047 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7049 public int checkComponentPermission(String permission, int pid, int uid,
7050 int owningUid, boolean exported) {
7051 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7052 owningUid, exported);
7056 public Object getAMSLock() {
7057 return ActivityManagerService.this;
7062 * This can be called with or without the global lock held.
7064 int checkComponentPermission(String permission, int pid, int uid,
7065 int owningUid, boolean exported) {
7066 if (pid == MY_PID) {
7067 return PackageManager.PERMISSION_GRANTED;
7069 return ActivityManager.checkComponentPermission(permission, uid,
7070 owningUid, exported);
7074 * As the only public entry point for permissions checking, this method
7075 * can enforce the semantic that requesting a check on a null global
7076 * permission is automatically denied. (Internally a null permission
7077 * string is used when calling {@link #checkComponentPermission} in cases
7078 * when only uid-based security is needed.)
7080 * This can be called with or without the global lock held.
7083 public int checkPermission(String permission, int pid, int uid) {
7084 if (permission == null) {
7085 return PackageManager.PERMISSION_DENIED;
7087 return checkComponentPermission(permission, pid, uid, -1, true);
7091 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7092 if (permission == null) {
7093 return PackageManager.PERMISSION_DENIED;
7096 // We might be performing an operation on behalf of an indirect binder
7097 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7098 // client identity accordingly before proceeding.
7099 Identity tlsIdentity = sCallerIdentity.get();
7100 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7101 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7102 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7103 uid = tlsIdentity.uid;
7104 pid = tlsIdentity.pid;
7107 return checkComponentPermission(permission, pid, uid, -1, true);
7111 * Binder IPC calls go through the public entry point.
7112 * This can be called with or without the global lock held.
7114 int checkCallingPermission(String permission) {
7115 return checkPermission(permission,
7116 Binder.getCallingPid(),
7117 UserHandle.getAppId(Binder.getCallingUid()));
7121 * This can be called with or without the global lock held.
7123 void enforceCallingPermission(String permission, String func) {
7124 if (checkCallingPermission(permission)
7125 == PackageManager.PERMISSION_GRANTED) {
7129 String msg = "Permission Denial: " + func + " from pid="
7130 + Binder.getCallingPid()
7131 + ", uid=" + Binder.getCallingUid()
7132 + " requires " + permission;
7134 throw new SecurityException(msg);
7138 * Determine if UID is holding permissions required to access {@link Uri} in
7139 * the given {@link ProviderInfo}. Final permission checking is always done
7140 * in {@link ContentProvider}.
7142 private final boolean checkHoldingPermissionsLocked(
7143 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7144 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7145 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7146 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7147 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7148 != PERMISSION_GRANTED) {
7152 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7155 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7156 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7157 if (pi.applicationInfo.uid == uid) {
7159 } else if (!pi.exported) {
7163 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7164 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7166 // check if target holds top-level <provider> permissions
7167 if (!readMet && pi.readPermission != null && considerUidPermissions
7168 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7171 if (!writeMet && pi.writePermission != null && considerUidPermissions
7172 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7176 // track if unprotected read/write is allowed; any denied
7177 // <path-permission> below removes this ability
7178 boolean allowDefaultRead = pi.readPermission == null;
7179 boolean allowDefaultWrite = pi.writePermission == null;
7181 // check if target holds any <path-permission> that match uri
7182 final PathPermission[] pps = pi.pathPermissions;
7184 final String path = grantUri.uri.getPath();
7186 while (i > 0 && (!readMet || !writeMet)) {
7188 PathPermission pp = pps[i];
7189 if (pp.match(path)) {
7191 final String pprperm = pp.getReadPermission();
7192 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7193 "Checking read perm for " + pprperm + " for " + pp.getPath()
7194 + ": match=" + pp.match(path)
7195 + " check=" + pm.checkUidPermission(pprperm, uid));
7196 if (pprperm != null) {
7197 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7198 == PERMISSION_GRANTED) {
7201 allowDefaultRead = false;
7206 final String ppwperm = pp.getWritePermission();
7207 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7208 "Checking write perm " + ppwperm + " for " + pp.getPath()
7209 + ": match=" + pp.match(path)
7210 + " check=" + pm.checkUidPermission(ppwperm, uid));
7211 if (ppwperm != null) {
7212 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7213 == PERMISSION_GRANTED) {
7216 allowDefaultWrite = false;
7224 // grant unprotected <provider> read/write, if not blocked by
7225 // <path-permission> above
7226 if (allowDefaultRead) readMet = true;
7227 if (allowDefaultWrite) writeMet = true;
7229 } catch (RemoteException e) {
7233 return readMet && writeMet;
7236 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7237 ProviderInfo pi = null;
7238 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7243 pi = AppGlobals.getPackageManager().resolveContentProvider(
7244 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7245 } catch (RemoteException ex) {
7251 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7252 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7253 if (targetUris != null) {
7254 return targetUris.get(grantUri);
7259 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7260 String targetPkg, int targetUid, GrantUri grantUri) {
7261 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7262 if (targetUris == null) {
7263 targetUris = Maps.newArrayMap();
7264 mGrantedUriPermissions.put(targetUid, targetUris);
7267 UriPermission perm = targetUris.get(grantUri);
7269 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7270 targetUris.put(grantUri, perm);
7276 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7277 final int modeFlags) {
7278 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7279 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7280 : UriPermission.STRENGTH_OWNED;
7282 // Root gets to do everything.
7287 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7288 if (perms == null) return false;
7290 // First look for exact match
7291 final UriPermission exactPerm = perms.get(grantUri);
7292 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7296 // No exact match, look for prefixes
7297 final int N = perms.size();
7298 for (int i = 0; i < N; i++) {
7299 final UriPermission perm = perms.valueAt(i);
7300 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7301 && perm.getStrength(modeFlags) >= minStrength) {
7310 * @param uri This uri must NOT contain an embedded userId.
7311 * @param userId The userId in which the uri is to be resolved.
7314 public int checkUriPermission(Uri uri, int pid, int uid,
7315 final int modeFlags, int userId, IBinder callerToken) {
7316 enforceNotIsolatedCaller("checkUriPermission");
7318 // Another redirected-binder-call permissions check as in
7319 // {@link checkPermissionWithToken}.
7320 Identity tlsIdentity = sCallerIdentity.get();
7321 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7322 uid = tlsIdentity.uid;
7323 pid = tlsIdentity.pid;
7326 // Our own process gets to do everything.
7327 if (pid == MY_PID) {
7328 return PackageManager.PERMISSION_GRANTED;
7330 synchronized (this) {
7331 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7332 ? PackageManager.PERMISSION_GRANTED
7333 : PackageManager.PERMISSION_DENIED;
7338 * Check if the targetPkg can be granted permission to access uri by
7339 * the callingUid using the given modeFlags. Throws a security exception
7340 * if callingUid is not allowed to do this. Returns the uid of the target
7341 * if the URI permission grant should be performed; returns -1 if it is not
7342 * needed (for example targetPkg already has permission to access the URI).
7343 * If you already know the uid of the target, you can supply it in
7344 * lastTargetUid else set that to -1.
7346 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7347 final int modeFlags, int lastTargetUid) {
7348 if (!Intent.isAccessUriMode(modeFlags)) {
7352 if (targetPkg != null) {
7353 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7354 "Checking grant " + targetPkg + " permission to " + grantUri);
7357 final IPackageManager pm = AppGlobals.getPackageManager();
7359 // If this is not a content: uri, we can't do anything with it.
7360 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7361 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7362 "Can't grant URI permission for non-content URI: " + grantUri);
7366 final String authority = grantUri.uri.getAuthority();
7367 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7369 Slog.w(TAG, "No content provider found for permission check: " +
7370 grantUri.uri.toSafeString());
7374 int targetUid = lastTargetUid;
7375 if (targetUid < 0 && targetPkg != null) {
7377 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7378 if (targetUid < 0) {
7379 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7380 "Can't grant URI permission no uid for: " + targetPkg);
7383 } catch (RemoteException ex) {
7388 if (targetUid >= 0) {
7389 // First... does the target actually need this permission?
7390 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7391 // No need to grant the target this permission.
7392 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7393 "Target " + targetPkg + " already has full permission to " + grantUri);
7397 // First... there is no target package, so can anyone access it?
7398 boolean allowed = pi.exported;
7399 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7400 if (pi.readPermission != null) {
7404 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7405 if (pi.writePermission != null) {
7414 /* There is a special cross user grant if:
7415 * - The target is on another user.
7416 * - Apps on the current user can access the uri without any uid permissions.
7417 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7418 * grant uri permissions.
7420 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7421 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7422 modeFlags, false /*without considering the uid permissions*/);
7424 // Second... is the provider allowing granting of URI permissions?
7425 if (!specialCrossUserGrant) {
7426 if (!pi.grantUriPermissions) {
7427 throw new SecurityException("Provider " + pi.packageName
7429 + " does not allow granting of Uri permissions (uri "
7432 if (pi.uriPermissionPatterns != null) {
7433 final int N = pi.uriPermissionPatterns.length;
7434 boolean allowed = false;
7435 for (int i=0; i<N; i++) {
7436 if (pi.uriPermissionPatterns[i] != null
7437 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7443 throw new SecurityException("Provider " + pi.packageName
7445 + " does not allow granting of permission to path of Uri "
7451 // Third... does the caller itself have permission to access
7453 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7454 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7455 // Require they hold a strong enough Uri permission
7456 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7457 throw new SecurityException("Uid " + callingUid
7458 + " does not have permission to uri " + grantUri);
7466 * @param uri This uri must NOT contain an embedded userId.
7467 * @param userId The userId in which the uri is to be resolved.
7470 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7471 final int modeFlags, int userId) {
7472 enforceNotIsolatedCaller("checkGrantUriPermission");
7473 synchronized(this) {
7474 return checkGrantUriPermissionLocked(callingUid, targetPkg,
7475 new GrantUri(userId, uri, false), modeFlags, -1);
7479 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7480 final int modeFlags, UriPermissionOwner owner) {
7481 if (!Intent.isAccessUriMode(modeFlags)) {
7485 // So here we are: the caller has the assumed permission
7486 // to the uri, and the target doesn't. Let's now give this to
7489 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7490 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7492 final String authority = grantUri.uri.getAuthority();
7493 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7495 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7499 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7500 grantUri.prefix = true;
7502 final UriPermission perm = findOrCreateUriPermissionLocked(
7503 pi.packageName, targetPkg, targetUid, grantUri);
7504 perm.grantModes(modeFlags, owner);
7507 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7508 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7509 if (targetPkg == null) {
7510 throw new NullPointerException("targetPkg");
7513 final IPackageManager pm = AppGlobals.getPackageManager();
7515 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7516 } catch (RemoteException ex) {
7520 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7522 if (targetUid < 0) {
7526 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7530 static class NeededUriGrants extends ArrayList<GrantUri> {
7531 final String targetPkg;
7532 final int targetUid;
7535 NeededUriGrants(String targetPkg, int targetUid, int flags) {
7536 this.targetPkg = targetPkg;
7537 this.targetUid = targetUid;
7543 * Like checkGrantUriPermissionLocked, but takes an Intent.
7545 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7546 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7547 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7548 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7549 + " clip=" + (intent != null ? intent.getClipData() : null)
7550 + " from " + intent + "; flags=0x"
7551 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7553 if (targetPkg == null) {
7554 throw new NullPointerException("targetPkg");
7557 if (intent == null) {
7560 Uri data = intent.getData();
7561 ClipData clip = intent.getClipData();
7562 if (data == null && clip == null) {
7565 // Default userId for uris in the intent (if they don't specify it themselves)
7566 int contentUserHint = intent.getContentUserHint();
7567 if (contentUserHint == UserHandle.USER_CURRENT) {
7568 contentUserHint = UserHandle.getUserId(callingUid);
7570 final IPackageManager pm = AppGlobals.getPackageManager();
7572 if (needed != null) {
7573 targetUid = needed.targetUid;
7576 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7577 } catch (RemoteException ex) {
7580 if (targetUid < 0) {
7581 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7582 "Can't grant URI permission no uid for: " + targetPkg
7583 + " on user " + targetUserId);
7588 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7589 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7591 if (targetUid > 0) {
7592 if (needed == null) {
7593 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7595 needed.add(grantUri);
7599 for (int i=0; i<clip.getItemCount(); i++) {
7600 Uri uri = clip.getItemAt(i).getUri();
7602 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7603 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7605 if (targetUid > 0) {
7606 if (needed == null) {
7607 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7609 needed.add(grantUri);
7612 Intent clipIntent = clip.getItemAt(i).getIntent();
7613 if (clipIntent != null) {
7614 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7615 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7616 if (newNeeded != null) {
7628 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7630 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7631 UriPermissionOwner owner) {
7632 if (needed != null) {
7633 for (int i=0; i<needed.size(); i++) {
7634 GrantUri grantUri = needed.get(i);
7635 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7636 grantUri, needed.flags, owner);
7641 void grantUriPermissionFromIntentLocked(int callingUid,
7642 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7643 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7644 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7645 if (needed == null) {
7649 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7653 * @param uri This uri must NOT contain an embedded userId.
7654 * @param userId The userId in which the uri is to be resolved.
7657 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7658 final int modeFlags, int userId) {
7659 enforceNotIsolatedCaller("grantUriPermission");
7660 GrantUri grantUri = new GrantUri(userId, uri, false);
7661 synchronized(this) {
7662 final ProcessRecord r = getRecordForAppLocked(caller);
7664 throw new SecurityException("Unable to find app for caller "
7666 + " when granting permission to uri " + grantUri);
7668 if (targetPkg == null) {
7669 throw new IllegalArgumentException("null target");
7671 if (grantUri == null) {
7672 throw new IllegalArgumentException("null uri");
7675 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7676 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7677 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7678 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7680 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7681 UserHandle.getUserId(r.uid));
7685 void removeUriPermissionIfNeededLocked(UriPermission perm) {
7686 if (perm.modeFlags == 0) {
7687 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7689 if (perms != null) {
7690 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7691 "Removing " + perm.targetUid + " permission to " + perm.uri);
7693 perms.remove(perm.uri);
7694 if (perms.isEmpty()) {
7695 mGrantedUriPermissions.remove(perm.targetUid);
7701 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7702 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7703 "Revoking all granted permissions to " + grantUri);
7705 final IPackageManager pm = AppGlobals.getPackageManager();
7706 final String authority = grantUri.uri.getAuthority();
7707 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7709 Slog.w(TAG, "No content provider found for permission revoke: "
7710 + grantUri.toSafeString());
7714 // Does the caller have this permission on the URI?
7715 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7716 // If they don't have direct access to the URI, then revoke any
7717 // ownerless URI permissions that have been granted to them.
7718 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7719 if (perms != null) {
7720 boolean persistChanged = false;
7721 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7722 final UriPermission perm = it.next();
7723 if (perm.uri.sourceUserId == grantUri.sourceUserId
7724 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7725 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7726 "Revoking non-owned " + perm.targetUid
7727 + " permission to " + perm.uri);
7728 persistChanged |= perm.revokeModes(
7729 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7730 if (perm.modeFlags == 0) {
7735 if (perms.isEmpty()) {
7736 mGrantedUriPermissions.remove(callingUid);
7738 if (persistChanged) {
7739 schedulePersistUriGrants();
7745 boolean persistChanged = false;
7747 // Go through all of the permissions and remove any that match.
7748 int N = mGrantedUriPermissions.size();
7749 for (int i = 0; i < N; i++) {
7750 final int targetUid = mGrantedUriPermissions.keyAt(i);
7751 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7753 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7754 final UriPermission perm = it.next();
7755 if (perm.uri.sourceUserId == grantUri.sourceUserId
7756 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7757 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7758 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7759 persistChanged |= perm.revokeModes(
7760 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7761 if (perm.modeFlags == 0) {
7767 if (perms.isEmpty()) {
7768 mGrantedUriPermissions.remove(targetUid);
7774 if (persistChanged) {
7775 schedulePersistUriGrants();
7780 * @param uri This uri must NOT contain an embedded userId.
7781 * @param userId The userId in which the uri is to be resolved.
7784 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7786 enforceNotIsolatedCaller("revokeUriPermission");
7787 synchronized(this) {
7788 final ProcessRecord r = getRecordForAppLocked(caller);
7790 throw new SecurityException("Unable to find app for caller "
7792 + " when revoking permission to uri " + uri);
7795 Slog.w(TAG, "revokeUriPermission: null uri");
7799 if (!Intent.isAccessUriMode(modeFlags)) {
7803 final String authority = uri.getAuthority();
7804 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7806 Slog.w(TAG, "No content provider found for permission revoke: "
7807 + uri.toSafeString());
7811 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7816 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7819 * @param packageName Package name to match, or {@code null} to apply to all
7821 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7823 * @param persistable If persistable grants should be removed.
7825 private void removeUriPermissionsForPackageLocked(
7826 String packageName, int userHandle, boolean persistable) {
7827 if (userHandle == UserHandle.USER_ALL && packageName == null) {
7828 throw new IllegalArgumentException("Must narrow by either package or user");
7831 boolean persistChanged = false;
7833 int N = mGrantedUriPermissions.size();
7834 for (int i = 0; i < N; i++) {
7835 final int targetUid = mGrantedUriPermissions.keyAt(i);
7836 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7838 // Only inspect grants matching user
7839 if (userHandle == UserHandle.USER_ALL
7840 || userHandle == UserHandle.getUserId(targetUid)) {
7841 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7842 final UriPermission perm = it.next();
7844 // Only inspect grants matching package
7845 if (packageName == null || perm.sourcePkg.equals(packageName)
7846 || perm.targetPkg.equals(packageName)) {
7847 persistChanged |= perm.revokeModes(persistable
7848 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7850 // Only remove when no modes remain; any persisted grants
7851 // will keep this alive.
7852 if (perm.modeFlags == 0) {
7858 if (perms.isEmpty()) {
7859 mGrantedUriPermissions.remove(targetUid);
7866 if (persistChanged) {
7867 schedulePersistUriGrants();
7872 public IBinder newUriPermissionOwner(String name) {
7873 enforceNotIsolatedCaller("newUriPermissionOwner");
7874 synchronized(this) {
7875 UriPermissionOwner owner = new UriPermissionOwner(this, name);
7876 return owner.getExternalTokenLocked();
7881 * @param uri This uri must NOT contain an embedded userId.
7882 * @param sourceUserId The userId in which the uri is to be resolved.
7883 * @param targetUserId The userId of the app that receives the grant.
7886 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7887 final int modeFlags, int sourceUserId, int targetUserId) {
7888 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7889 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7890 synchronized(this) {
7891 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7892 if (owner == null) {
7893 throw new IllegalArgumentException("Unknown owner: " + token);
7895 if (fromUid != Binder.getCallingUid()) {
7896 if (Binder.getCallingUid() != Process.myUid()) {
7897 // Only system code can grant URI permissions on behalf
7899 throw new SecurityException("nice try");
7902 if (targetPkg == null) {
7903 throw new IllegalArgumentException("null target");
7906 throw new IllegalArgumentException("null uri");
7909 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7910 modeFlags, owner, targetUserId);
7915 * @param uri This uri must NOT contain an embedded userId.
7916 * @param userId The userId in which the uri is to be resolved.
7919 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7920 synchronized(this) {
7921 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7922 if (owner == null) {
7923 throw new IllegalArgumentException("Unknown owner: " + token);
7927 owner.removeUriPermissionsLocked(mode);
7929 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7934 private void schedulePersistUriGrants() {
7935 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7936 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7937 10 * DateUtils.SECOND_IN_MILLIS);
7941 private void writeGrantedUriPermissions() {
7942 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7944 // Snapshot permissions so we can persist without lock
7945 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7946 synchronized (this) {
7947 final int size = mGrantedUriPermissions.size();
7948 for (int i = 0; i < size; i++) {
7949 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7950 for (UriPermission perm : perms.values()) {
7951 if (perm.persistedModeFlags != 0) {
7952 persist.add(perm.snapshot());
7958 FileOutputStream fos = null;
7960 fos = mGrantFile.startWrite();
7962 XmlSerializer out = new FastXmlSerializer();
7963 out.setOutput(fos, StandardCharsets.UTF_8.name());
7964 out.startDocument(null, true);
7965 out.startTag(null, TAG_URI_GRANTS);
7966 for (UriPermission.Snapshot perm : persist) {
7967 out.startTag(null, TAG_URI_GRANT);
7968 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7969 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7970 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7971 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7972 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7973 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7974 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7975 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7976 out.endTag(null, TAG_URI_GRANT);
7978 out.endTag(null, TAG_URI_GRANTS);
7981 mGrantFile.finishWrite(fos);
7982 } catch (IOException e) {
7984 mGrantFile.failWrite(fos);
7989 private void readGrantedUriPermissionsLocked() {
7990 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
7992 final long now = System.currentTimeMillis();
7994 FileInputStream fis = null;
7996 fis = mGrantFile.openRead();
7997 final XmlPullParser in = Xml.newPullParser();
7998 in.setInput(fis, StandardCharsets.UTF_8.name());
8001 while ((type = in.next()) != END_DOCUMENT) {
8002 final String tag = in.getName();
8003 if (type == START_TAG) {
8004 if (TAG_URI_GRANT.equals(tag)) {
8005 final int sourceUserId;
8006 final int targetUserId;
8007 final int userHandle = readIntAttribute(in,
8008 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8009 if (userHandle != UserHandle.USER_NULL) {
8010 // For backwards compatibility.
8011 sourceUserId = userHandle;
8012 targetUserId = userHandle;
8014 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8015 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8017 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8018 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8019 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8020 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8021 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8022 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8024 // Sanity check that provider still belongs to source package
8025 final ProviderInfo pi = getProviderInfoLocked(
8026 uri.getAuthority(), sourceUserId);
8027 if (pi != null && sourcePkg.equals(pi.packageName)) {
8030 targetUid = AppGlobals.getPackageManager()
8031 .getPackageUid(targetPkg, targetUserId);
8032 } catch (RemoteException e) {
8034 if (targetUid != -1) {
8035 final UriPermission perm = findOrCreateUriPermissionLocked(
8036 sourcePkg, targetPkg, targetUid,
8037 new GrantUri(sourceUserId, uri, prefix));
8038 perm.initPersistedModes(modeFlags, createdTime);
8041 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8042 + " but instead found " + pi);
8047 } catch (FileNotFoundException e) {
8048 // Missing grants is okay
8049 } catch (IOException e) {
8050 Slog.wtf(TAG, "Failed reading Uri grants", e);
8051 } catch (XmlPullParserException e) {
8052 Slog.wtf(TAG, "Failed reading Uri grants", e);
8054 IoUtils.closeQuietly(fis);
8059 * @param uri This uri must NOT contain an embedded userId.
8060 * @param userId The userId in which the uri is to be resolved.
8063 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8064 enforceNotIsolatedCaller("takePersistableUriPermission");
8066 Preconditions.checkFlagsArgument(modeFlags,
8067 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8069 synchronized (this) {
8070 final int callingUid = Binder.getCallingUid();
8071 boolean persistChanged = false;
8072 GrantUri grantUri = new GrantUri(userId, uri, false);
8074 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8075 new GrantUri(userId, uri, false));
8076 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8077 new GrantUri(userId, uri, true));
8079 final boolean exactValid = (exactPerm != null)
8080 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8081 final boolean prefixValid = (prefixPerm != null)
8082 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8084 if (!(exactValid || prefixValid)) {
8085 throw new SecurityException("No persistable permission grants found for UID "
8086 + callingUid + " and Uri " + grantUri.toSafeString());
8090 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8093 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8096 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8098 if (persistChanged) {
8099 schedulePersistUriGrants();
8105 * @param uri This uri must NOT contain an embedded userId.
8106 * @param userId The userId in which the uri is to be resolved.
8109 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8110 enforceNotIsolatedCaller("releasePersistableUriPermission");
8112 Preconditions.checkFlagsArgument(modeFlags,
8113 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8115 synchronized (this) {
8116 final int callingUid = Binder.getCallingUid();
8117 boolean persistChanged = false;
8119 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8120 new GrantUri(userId, uri, false));
8121 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8122 new GrantUri(userId, uri, true));
8123 if (exactPerm == null && prefixPerm == null) {
8124 throw new SecurityException("No permission grants found for UID " + callingUid
8125 + " and Uri " + uri.toSafeString());
8128 if (exactPerm != null) {
8129 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8130 removeUriPermissionIfNeededLocked(exactPerm);
8132 if (prefixPerm != null) {
8133 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8134 removeUriPermissionIfNeededLocked(prefixPerm);
8137 if (persistChanged) {
8138 schedulePersistUriGrants();
8144 * Prune any older {@link UriPermission} for the given UID until outstanding
8145 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8147 * @return if any mutations occured that require persisting.
8149 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8150 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8151 if (perms == null) return false;
8152 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8154 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8155 for (UriPermission perm : perms.values()) {
8156 if (perm.persistedModeFlags != 0) {
8157 persisted.add(perm);
8161 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8162 if (trimCount <= 0) return false;
8164 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8165 for (int i = 0; i < trimCount; i++) {
8166 final UriPermission perm = persisted.get(i);
8168 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8169 "Trimming grant created at " + perm.persistedCreateTime);
8171 perm.releasePersistableModes(~0);
8172 removeUriPermissionIfNeededLocked(perm);
8179 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8180 String packageName, boolean incoming) {
8181 enforceNotIsolatedCaller("getPersistedUriPermissions");
8182 Preconditions.checkNotNull(packageName, "packageName");
8184 final int callingUid = Binder.getCallingUid();
8185 final IPackageManager pm = AppGlobals.getPackageManager();
8187 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8188 if (packageUid != callingUid) {
8189 throw new SecurityException(
8190 "Package " + packageName + " does not belong to calling UID " + callingUid);
8192 } catch (RemoteException e) {
8193 throw new SecurityException("Failed to verify package name ownership");
8196 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8197 synchronized (this) {
8199 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8201 if (perms == null) {
8202 Slog.w(TAG, "No permission grants found for " + packageName);
8204 for (UriPermission perm : perms.values()) {
8205 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8206 result.add(perm.buildPersistedPublicApiObject());
8211 final int size = mGrantedUriPermissions.size();
8212 for (int i = 0; i < size; i++) {
8213 final ArrayMap<GrantUri, UriPermission> perms =
8214 mGrantedUriPermissions.valueAt(i);
8215 for (UriPermission perm : perms.values()) {
8216 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8217 result.add(perm.buildPersistedPublicApiObject());
8223 return new ParceledListSlice<android.content.UriPermission>(result);
8227 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8228 synchronized (this) {
8230 who != null ? getRecordForAppLocked(who) : null;
8231 if (app == null) return;
8233 Message msg = Message.obtain();
8234 msg.what = WAIT_FOR_DEBUGGER_MSG;
8236 msg.arg1 = waiting ? 1 : 0;
8237 mUiHandler.sendMessage(msg);
8242 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8243 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8244 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8245 outInfo.availMem = Process.getFreeMemory();
8246 outInfo.totalMem = Process.getTotalMemory();
8247 outInfo.threshold = homeAppMem;
8248 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8249 outInfo.hiddenAppThreshold = cachedAppMem;
8250 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8251 ProcessList.SERVICE_ADJ);
8252 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8253 ProcessList.VISIBLE_APP_ADJ);
8254 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8255 ProcessList.FOREGROUND_APP_ADJ);
8258 // =========================================================
8260 // =========================================================
8263 public List<IAppTask> getAppTasks(String callingPackage) {
8264 int callingUid = Binder.getCallingUid();
8265 long ident = Binder.clearCallingIdentity();
8267 synchronized(this) {
8268 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8270 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8272 final int N = mRecentTasks.size();
8273 for (int i = 0; i < N; i++) {
8274 TaskRecord tr = mRecentTasks.get(i);
8275 // Skip tasks that do not match the caller. We don't need to verify
8276 // callingPackage, because we are also limiting to callingUid and know
8277 // that will limit to the correct security sandbox.
8278 if (tr.effectiveUid != callingUid) {
8281 Intent intent = tr.getBaseIntent();
8282 if (intent == null ||
8283 !callingPackage.equals(intent.getComponent().getPackageName())) {
8286 ActivityManager.RecentTaskInfo taskInfo =
8287 createRecentTaskInfoFromTaskRecord(tr);
8288 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8292 Binder.restoreCallingIdentity(ident);
8299 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8300 final int callingUid = Binder.getCallingUid();
8301 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8303 synchronized(this) {
8304 if (DEBUG_ALL) Slog.v(
8305 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8307 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8310 // TODO: Improve with MRU list from all ActivityStacks.
8311 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8318 * Creates a new RecentTaskInfo from a TaskRecord.
8320 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8321 // Update the task description to reflect any changes in the task stack
8322 tr.updateTaskDescription();
8324 // Compose the recent task info
8325 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8326 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8327 rti.persistentId = tr.taskId;
8328 rti.baseIntent = new Intent(tr.getBaseIntent());
8329 rti.origActivity = tr.origActivity;
8330 rti.description = tr.lastDescription;
8331 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8332 rti.userId = tr.userId;
8333 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8334 rti.firstActiveTime = tr.firstActiveTime;
8335 rti.lastActiveTime = tr.lastActiveTime;
8336 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8337 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8338 rti.numActivities = 0;
8340 ActivityRecord base = null;
8341 ActivityRecord top = null;
8344 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8345 tmp = tr.mActivities.get(i);
8346 if (tmp.finishing) {
8350 if (top == null || (top.state == ActivityState.INITIALIZING)) {
8353 rti.numActivities++;
8356 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8357 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8362 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8363 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8364 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8366 if (checkPermission(android.Manifest.permission.GET_TASKS,
8367 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8368 // Temporary compatibility: some existing apps on the system image may
8369 // still be requesting the old permission and not switched to the new
8370 // one; if so, we'll still allow them full access. This means we need
8371 // to see if they are holding the old permission and are a system app.
8373 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8375 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8376 + " is using old GET_TASKS but privileged; allowing");
8378 } catch (RemoteException e) {
8383 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8384 + " does not hold REAL_GET_TASKS; limiting output");
8390 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8391 final int callingUid = Binder.getCallingUid();
8392 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8393 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8395 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8396 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8397 synchronized (this) {
8398 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8400 final boolean detailed = checkCallingPermission(
8401 android.Manifest.permission.GET_DETAILED_TASKS)
8402 == PackageManager.PERMISSION_GRANTED;
8404 final int recentsCount = mRecentTasks.size();
8405 ArrayList<ActivityManager.RecentTaskInfo> res =
8406 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8408 final Set<Integer> includedUsers;
8409 if (includeProfiles) {
8410 includedUsers = getProfileIdsLocked(userId);
8412 includedUsers = new HashSet<>();
8414 includedUsers.add(Integer.valueOf(userId));
8416 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8417 TaskRecord tr = mRecentTasks.get(i);
8418 // Only add calling user or related users recent tasks
8419 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8420 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8424 // Return the entry if desired by the caller. We always return
8425 // the first entry, because callers always expect this to be the
8426 // foreground app. We may filter others if the caller has
8427 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8428 // we should exclude the entry.
8432 || (tr.intent == null)
8433 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8436 // If the caller doesn't have the GET_TASKS permission, then only
8437 // allow them to see a small subset of tasks -- their own and home.
8438 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8439 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8443 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8444 if (tr.stack != null && tr.stack.isHomeStack()) {
8445 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8446 "Skipping, home stack task: " + tr);
8450 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8451 // Don't include auto remove tasks that are finished or finishing.
8452 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8453 "Skipping, auto-remove without activity: " + tr);
8456 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8457 && !tr.isAvailable) {
8458 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8459 "Skipping, unavail real act: " + tr);
8463 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8465 rti.baseIntent.replaceExtras((Bundle)null);
8477 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8478 synchronized (this) {
8479 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8480 "getTaskThumbnail()");
8481 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8483 return tr.getTaskThumbnailLocked();
8490 public int addAppTask(IBinder activityToken, Intent intent,
8491 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8492 final int callingUid = Binder.getCallingUid();
8493 final long callingIdent = Binder.clearCallingIdentity();
8496 synchronized (this) {
8497 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8499 throw new IllegalArgumentException("Activity does not exist; token="
8502 ComponentName comp = intent.getComponent();
8504 throw new IllegalArgumentException("Intent " + intent
8505 + " must specify explicit component");
8507 if (thumbnail.getWidth() != mThumbnailWidth
8508 || thumbnail.getHeight() != mThumbnailHeight) {
8509 throw new IllegalArgumentException("Bad thumbnail size: got "
8510 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8511 + mThumbnailWidth + "x" + mThumbnailHeight);
8513 if (intent.getSelector() != null) {
8514 intent.setSelector(null);
8516 if (intent.getSourceBounds() != null) {
8517 intent.setSourceBounds(null);
8519 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8520 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8521 // The caller has added this as an auto-remove task... that makes no
8522 // sense, so turn off auto-remove.
8523 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8525 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8526 // Must be a new task.
8527 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8529 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8530 mLastAddedTaskActivity = null;
8532 ActivityInfo ainfo = mLastAddedTaskActivity;
8533 if (ainfo == null) {
8534 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8535 comp, 0, UserHandle.getUserId(callingUid));
8536 if (ainfo.applicationInfo.uid != callingUid) {
8537 throw new SecurityException(
8538 "Can't add task for another application: target uid="
8539 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8543 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8544 intent, description);
8546 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8548 // If this would have caused a trim, then we'll abort because that
8549 // means it would be added at the end of the list but then just removed.
8550 return INVALID_TASK_ID;
8553 final int N = mRecentTasks.size();
8554 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8555 final TaskRecord tr = mRecentTasks.remove(N - 1);
8556 tr.removedFromRecents();
8559 task.inRecents = true;
8560 mRecentTasks.add(task);
8561 r.task.stack.addTask(task, false, false);
8563 task.setLastThumbnail(thumbnail);
8564 task.freeLastThumbnail();
8569 Binder.restoreCallingIdentity(callingIdent);
8574 public Point getAppTaskThumbnailSize() {
8575 synchronized (this) {
8576 return new Point(mThumbnailWidth, mThumbnailHeight);
8581 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8582 synchronized (this) {
8583 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8585 r.setTaskDescription(td);
8586 r.task.updateTaskDescription();
8592 public void setTaskResizeable(int taskId, boolean resizeable) {
8593 synchronized (this) {
8594 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8596 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8599 if (task.mResizeable != resizeable) {
8600 task.mResizeable = resizeable;
8601 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8602 mStackSupervisor.resumeTopActivitiesLocked();
8608 public void resizeTask(int taskId, Rect bounds) {
8609 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8611 long ident = Binder.clearCallingIdentity();
8613 synchronized (this) {
8614 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8616 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8619 mStackSupervisor.resizeTaskLocked(task, bounds);
8622 Binder.restoreCallingIdentity(ident);
8627 public Bitmap getTaskDescriptionIcon(String filename) {
8628 if (!FileUtils.isValidExtFilename(filename)
8629 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8630 throw new IllegalArgumentException("Bad filename: " + filename);
8632 return mTaskPersister.getTaskDescriptionIcon(filename);
8636 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8637 throws RemoteException {
8638 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8639 opts.getCustomInPlaceResId() == 0) {
8640 throw new IllegalArgumentException("Expected in-place ActivityOption " +
8641 "with valid animation");
8643 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8644 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8645 opts.getCustomInPlaceResId());
8646 mWindowManager.executeAppTransition();
8649 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8650 mRecentTasks.remove(tr);
8651 tr.removedFromRecents();
8652 ComponentName component = tr.getBaseIntent().getComponent();
8653 if (component == null) {
8654 Slog.w(TAG, "No component for base intent of task: " + tr);
8658 // Find any running services associated with this app and stop if needed.
8659 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8665 // Determine if the process(es) for this task should be killed.
8666 final String pkg = component.getPackageName();
8667 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8668 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8669 for (int i = 0; i < pmap.size(); i++) {
8671 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8672 for (int j = 0; j < uids.size(); j++) {
8673 ProcessRecord proc = uids.valueAt(j);
8674 if (proc.userId != tr.userId) {
8675 // Don't kill process for a different user.
8678 if (proc == mHomeProcess) {
8679 // Don't kill the home process along with tasks from the same package.
8682 if (!proc.pkgList.containsKey(pkg)) {
8683 // Don't kill process that is not associated with this task.
8687 for (int k = 0; k < proc.activities.size(); k++) {
8688 TaskRecord otherTask = proc.activities.get(k).task;
8689 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8690 // Don't kill process(es) that has an activity in a different task that is
8696 if (proc.foregroundServices) {
8697 // Don't kill process(es) with foreground service.
8701 // Add process to kill list.
8702 procsToKill.add(proc);
8706 // Kill the running processes.
8707 for (int i = 0; i < procsToKill.size(); i++) {
8708 ProcessRecord pr = procsToKill.get(i);
8709 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8710 && pr.curReceiver == null) {
8711 pr.kill("remove task", true);
8713 // We delay killing processes that are not in the background or running a receiver.
8714 pr.waitingToKill = "remove task";
8719 private void removeTasksByPackageNameLocked(String packageName, int userId) {
8720 // Remove all tasks with activities in the specified package from the list of recent tasks
8721 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8722 TaskRecord tr = mRecentTasks.get(i);
8723 if (tr.userId != userId) continue;
8725 ComponentName cn = tr.intent.getComponent();
8726 if (cn != null && cn.getPackageName().equals(packageName)) {
8727 // If the package name matches, remove the task.
8728 removeTaskByIdLocked(tr.taskId, true);
8733 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8736 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8737 TaskRecord tr = mRecentTasks.get(i);
8738 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8742 ComponentName cn = tr.intent.getComponent();
8743 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8744 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8745 if (sameComponent) {
8746 removeTaskByIdLocked(tr.taskId, false);
8752 * Removes the task with the specified task id.
8754 * @param taskId Identifier of the task to be removed.
8755 * @param killProcess Kill any process associated with the task if possible.
8756 * @return Returns true if the given task was found and removed.
8758 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8759 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8761 tr.removeTaskActivitiesLocked();
8762 cleanUpRemovedTaskLocked(tr, killProcess);
8763 if (tr.isPersistable) {
8764 notifyTaskPersisterLocked(null, true);
8768 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8773 public boolean removeTask(int taskId) {
8774 synchronized (this) {
8775 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8777 long ident = Binder.clearCallingIdentity();
8779 return removeTaskByIdLocked(taskId, true);
8781 Binder.restoreCallingIdentity(ident);
8787 * TODO: Add mController hook
8790 public void moveTaskToFront(int taskId, int flags, Bundle options) {
8791 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8793 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8794 synchronized(this) {
8795 moveTaskToFrontLocked(taskId, flags, options);
8799 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8800 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8801 Binder.getCallingUid(), -1, -1, "Task to front")) {
8802 ActivityOptions.abort(options);
8805 final long origId = Binder.clearCallingIdentity();
8807 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8809 Slog.d(TAG, "Could not find task for id: "+ taskId);
8812 if (mStackSupervisor.isLockTaskModeViolation(task)) {
8813 mStackSupervisor.showLockTaskToast();
8814 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8817 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8818 if (prev != null && prev.isRecentsActivity()) {
8819 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8821 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8823 Binder.restoreCallingIdentity(origId);
8825 ActivityOptions.abort(options);
8829 * Moves an activity, and all of the other activities within the same task, to the bottom
8830 * of the history stack. The activity's order within the task is unchanged.
8832 * @param token A reference to the activity we wish to move
8833 * @param nonRoot If false then this only works if the activity is the root
8834 * of a task; if true it will work for any activity in a task.
8835 * @return Returns true if the move completed, false if not.
8838 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8839 enforceNotIsolatedCaller("moveActivityTaskToBack");
8840 synchronized(this) {
8841 final long origId = Binder.clearCallingIdentity();
8843 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8844 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8846 if (mStackSupervisor.isLockedTask(task)) {
8847 mStackSupervisor.showLockTaskToast();
8850 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8853 Binder.restoreCallingIdentity(origId);
8860 public void moveTaskBackwards(int task) {
8861 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8862 "moveTaskBackwards()");
8864 synchronized(this) {
8865 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8866 Binder.getCallingUid(), -1, -1, "Task backwards")) {
8869 final long origId = Binder.clearCallingIdentity();
8870 moveTaskBackwardsLocked(task);
8871 Binder.restoreCallingIdentity(origId);
8875 private final void moveTaskBackwardsLocked(int task) {
8876 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8880 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8881 IActivityContainerCallback callback) throws RemoteException {
8882 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8883 "createActivityContainer()");
8884 synchronized (this) {
8885 if (parentActivityToken == null) {
8886 throw new IllegalArgumentException("parent token must not be null");
8888 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8892 if (callback == null) {
8893 throw new IllegalArgumentException("callback must not be null");
8895 return mStackSupervisor.createVirtualActivityContainer(r, callback);
8900 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8901 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8902 "deleteActivityContainer()");
8903 synchronized (this) {
8904 mStackSupervisor.deleteActivityContainer(container);
8909 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8910 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8911 "createStackOnDisplay()");
8912 synchronized (this) {
8913 final int stackId = mStackSupervisor.getNextStackId();
8914 final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8915 if (stack == null) {
8918 return stack.mActivityContainer;
8923 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8924 synchronized (this) {
8925 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8926 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8927 return stack.mActivityContainer.getDisplayId();
8929 return Display.DEFAULT_DISPLAY;
8934 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8935 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8936 "moveTaskToStack()");
8937 if (stackId == HOME_STACK_ID) {
8938 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8939 new RuntimeException("here").fillInStackTrace());
8941 synchronized (this) {
8942 long ident = Binder.clearCallingIdentity();
8944 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8945 + " to stackId=" + stackId + " toTop=" + toTop);
8946 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8948 Binder.restoreCallingIdentity(ident);
8954 public void resizeStack(int stackId, Rect bounds) {
8955 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8957 long ident = Binder.clearCallingIdentity();
8959 synchronized (this) {
8960 mStackSupervisor.resizeStackLocked(stackId, bounds);
8963 Binder.restoreCallingIdentity(ident);
8968 public List<StackInfo> getAllStackInfos() {
8969 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8970 "getAllStackInfos()");
8971 long ident = Binder.clearCallingIdentity();
8973 synchronized (this) {
8974 return mStackSupervisor.getAllStackInfosLocked();
8977 Binder.restoreCallingIdentity(ident);
8982 public StackInfo getStackInfo(int stackId) {
8983 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8985 long ident = Binder.clearCallingIdentity();
8987 synchronized (this) {
8988 return mStackSupervisor.getStackInfoLocked(stackId);
8991 Binder.restoreCallingIdentity(ident);
8996 public boolean isInHomeStack(int taskId) {
8997 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8999 long ident = Binder.clearCallingIdentity();
9001 synchronized (this) {
9002 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
9003 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9006 Binder.restoreCallingIdentity(ident);
9011 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9012 synchronized(this) {
9013 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9018 public void updateDeviceOwner(String packageName) {
9019 final int callingUid = Binder.getCallingUid();
9020 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9021 throw new SecurityException("updateDeviceOwner called from non-system process");
9023 synchronized (this) {
9024 mDeviceOwnerName = packageName;
9029 public void updateLockTaskPackages(int userId, String[] packages) {
9030 final int callingUid = Binder.getCallingUid();
9031 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9032 throw new SecurityException("updateLockTaskPackage called from non-system process");
9034 synchronized (this) {
9035 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9036 Arrays.toString(packages));
9037 mLockTaskPackages.put(userId, packages);
9038 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9043 void startLockTaskModeLocked(TaskRecord task) {
9044 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9045 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9049 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9050 // is initiated by system after the pinning request was shown and locked mode is initiated
9051 // by an authorized app directly
9052 final int callingUid = Binder.getCallingUid();
9053 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9054 long ident = Binder.clearCallingIdentity();
9056 final ActivityStack stack = mStackSupervisor.getFocusedStack();
9057 if (!isSystemInitiated) {
9058 task.mLockTaskUid = callingUid;
9059 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9060 // startLockTask() called by app and task mode is lockTaskModeDefault.
9061 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9062 StatusBarManagerInternal statusBarManager =
9063 LocalServices.getService(StatusBarManagerInternal.class);
9064 if (statusBarManager != null) {
9065 statusBarManager.showScreenPinningRequest();
9070 if (stack == null || task != stack.topTask()) {
9071 throw new IllegalArgumentException("Invalid task, not in foreground");
9074 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9076 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9077 ActivityManager.LOCK_TASK_MODE_PINNED :
9078 ActivityManager.LOCK_TASK_MODE_LOCKED,
9079 "startLockTask", true);
9081 Binder.restoreCallingIdentity(ident);
9086 public void startLockTaskMode(int taskId) {
9087 synchronized (this) {
9088 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9090 startLockTaskModeLocked(task);
9096 public void startLockTaskMode(IBinder token) {
9097 synchronized (this) {
9098 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9102 final TaskRecord task = r.task;
9104 startLockTaskModeLocked(task);
9110 public void startLockTaskModeOnCurrent() throws RemoteException {
9111 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9112 "startLockTaskModeOnCurrent");
9113 long ident = Binder.clearCallingIdentity();
9115 synchronized (this) {
9116 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9118 startLockTaskModeLocked(r.task);
9122 Binder.restoreCallingIdentity(ident);
9127 public void stopLockTaskMode() {
9128 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9129 if (lockTask == null) {
9130 // Our work here is done.
9134 final int callingUid = Binder.getCallingUid();
9135 final int lockTaskUid = lockTask.mLockTaskUid;
9136 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9137 // It is possible lockTaskMode was started by the system process because
9138 // android:lockTaskMode is set to a locking value in the application manifest instead of
9139 // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9140 // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9141 if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9142 callingUid != lockTaskUid
9143 && (lockTaskUid != 0
9144 || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9145 throw new SecurityException("Invalid uid, expected " + lockTaskUid
9146 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9149 long ident = Binder.clearCallingIdentity();
9151 Log.d(TAG, "stopLockTaskMode");
9153 synchronized (this) {
9154 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9155 "stopLockTask", true);
9158 Binder.restoreCallingIdentity(ident);
9163 public void stopLockTaskModeOnCurrent() throws RemoteException {
9164 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9165 "stopLockTaskModeOnCurrent");
9166 long ident = Binder.clearCallingIdentity();
9170 Binder.restoreCallingIdentity(ident);
9175 public boolean isInLockTaskMode() {
9176 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9180 public int getLockTaskModeState() {
9181 synchronized (this) {
9182 return mStackSupervisor.getLockTaskModeState();
9187 public void showLockTaskEscapeMessage(IBinder token) {
9188 synchronized (this) {
9189 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9193 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9197 // =========================================================
9198 // CONTENT PROVIDERS
9199 // =========================================================
9201 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9202 List<ProviderInfo> providers = null;
9204 ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9205 queryContentProviders(app.processName, app.uid,
9206 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9207 providers = slice != null ? slice.getList() : null;
9208 } catch (RemoteException ex) {
9210 if (DEBUG_MU) Slog.v(TAG_MU,
9211 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9212 int userId = app.userId;
9213 if (providers != null) {
9214 int N = providers.size();
9215 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9216 for (int i=0; i<N; i++) {
9218 (ProviderInfo)providers.get(i);
9219 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9220 cpi.name, cpi.flags);
9221 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9222 // This is a singleton provider, but a user besides the
9223 // default user is asking to initialize a process it runs
9224 // in... well, no, it doesn't actually run in this process,
9225 // it runs in the process of the default user. Get rid of it.
9226 providers.remove(i);
9232 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9233 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9235 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9236 mProviderMap.putProviderByClass(comp, cpr);
9238 if (DEBUG_MU) Slog.v(TAG_MU,
9239 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9240 app.pubProviders.put(cpi.name, cpr);
9241 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9242 // Don't add this if it is a platform component that is marked
9243 // to run in multiple processes, because this is actually
9244 // part of the framework so doesn't make sense to track as a
9245 // separate apk in the process.
9246 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9249 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9256 * Check if {@link ProcessRecord} has a possible chance at accessing the
9257 * given {@link ProviderInfo}. Final permission checking is always done
9258 * in {@link ContentProvider}.
9260 private final String checkContentProviderPermissionLocked(
9261 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9262 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9263 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9264 boolean checkedGrants = false;
9266 // Looking for cross-user grants before enforcing the typical cross-users permissions
9267 int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9268 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9269 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9272 checkedGrants = true;
9274 userId = handleIncomingUser(callingPid, callingUid, userId,
9275 false, ALLOW_NON_FULL,
9276 "checkContentProviderPermissionLocked " + cpi.authority, null);
9277 if (userId != tmpTargetUserId) {
9278 // When we actually went to determine the final targer user ID, this ended
9279 // up different than our initial check for the authority. This is because
9280 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9281 // SELF. So we need to re-check the grants again.
9282 checkedGrants = false;
9285 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9286 cpi.applicationInfo.uid, cpi.exported)
9287 == PackageManager.PERMISSION_GRANTED) {
9290 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9291 cpi.applicationInfo.uid, cpi.exported)
9292 == PackageManager.PERMISSION_GRANTED) {
9296 PathPermission[] pps = cpi.pathPermissions;
9301 PathPermission pp = pps[i];
9302 String pprperm = pp.getReadPermission();
9303 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9304 cpi.applicationInfo.uid, cpi.exported)
9305 == PackageManager.PERMISSION_GRANTED) {
9308 String ppwperm = pp.getWritePermission();
9309 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9310 cpi.applicationInfo.uid, cpi.exported)
9311 == PackageManager.PERMISSION_GRANTED) {
9316 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9321 if (!cpi.exported) {
9322 msg = "Permission Denial: opening provider " + cpi.name
9323 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9324 + ", uid=" + callingUid + ") that is not exported from uid "
9325 + cpi.applicationInfo.uid;
9327 msg = "Permission Denial: opening provider " + cpi.name
9328 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9329 + ", uid=" + callingUid + ") requires "
9330 + cpi.readPermission + " or " + cpi.writePermission;
9337 * Returns if the ContentProvider has granted a uri to callingUid
9339 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9340 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9341 if (perms != null) {
9342 for (int i=perms.size()-1; i>=0; i--) {
9343 GrantUri grantUri = perms.keyAt(i);
9344 if (grantUri.sourceUserId == userId || !checkUser) {
9345 if (matchesProvider(grantUri.uri, cpi)) {
9355 * Returns true if the uri authority is one of the authorities specified in the provider.
9357 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9358 String uriAuth = uri.getAuthority();
9359 String cpiAuth = cpi.authority;
9360 if (cpiAuth.indexOf(';') == -1) {
9361 return cpiAuth.equals(uriAuth);
9363 String[] cpiAuths = cpiAuth.split(";");
9364 int length = cpiAuths.length;
9365 for (int i = 0; i < length; i++) {
9366 if (cpiAuths[i].equals(uriAuth)) return true;
9371 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9372 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9374 for (int i=0; i<r.conProviders.size(); i++) {
9375 ContentProviderConnection conn = r.conProviders.get(i);
9376 if (conn.provider == cpr) {
9377 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9378 "Adding provider requested by "
9379 + r.processName + " from process "
9380 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9381 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9384 conn.numStableIncs++;
9386 conn.unstableCount++;
9387 conn.numUnstableIncs++;
9392 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9394 conn.stableCount = 1;
9395 conn.numStableIncs = 1;
9397 conn.unstableCount = 1;
9398 conn.numUnstableIncs = 1;
9400 cpr.connections.add(conn);
9401 r.conProviders.add(conn);
9402 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9405 cpr.addExternalProcessHandleLocked(externalProcessToken);
9409 boolean decProviderCountLocked(ContentProviderConnection conn,
9410 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9412 cpr = conn.provider;
9413 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9414 "Removing provider requested by "
9415 + conn.client.processName + " from process "
9416 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9417 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9421 conn.unstableCount--;
9423 if (conn.stableCount == 0 && conn.unstableCount == 0) {
9424 cpr.connections.remove(conn);
9425 conn.client.conProviders.remove(conn);
9426 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9431 cpr.removeExternalProcessHandleLocked(externalProcessToken);
9435 private void checkTime(long startTime, String where) {
9436 long now = SystemClock.elapsedRealtime();
9437 if ((now-startTime) > 1000) {
9438 // If we are taking more than a second, log about it.
9439 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9443 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9444 String name, IBinder token, boolean stable, int userId) {
9445 ContentProviderRecord cpr;
9446 ContentProviderConnection conn = null;
9447 ProviderInfo cpi = null;
9449 synchronized(this) {
9450 long startTime = SystemClock.elapsedRealtime();
9452 ProcessRecord r = null;
9453 if (caller != null) {
9454 r = getRecordForAppLocked(caller);
9456 throw new SecurityException(
9457 "Unable to find app for caller " + caller
9458 + " (pid=" + Binder.getCallingPid()
9459 + ") when getting content provider " + name);
9463 boolean checkCrossUser = true;
9465 checkTime(startTime, "getContentProviderImpl: getProviderByName");
9467 // First check if this content provider has been published...
9468 cpr = mProviderMap.getProviderByName(name, userId);
9469 // If that didn't work, check if it exists for user 0 and then
9470 // verify that it's a singleton provider before using it.
9471 if (cpr == null && userId != UserHandle.USER_OWNER) {
9472 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9475 if (isSingleton(cpi.processName, cpi.applicationInfo,
9476 cpi.name, cpi.flags)
9477 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9478 userId = UserHandle.USER_OWNER;
9479 checkCrossUser = false;
9487 boolean providerRunning = cpr != null;
9488 if (providerRunning) {
9491 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9492 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9494 throw new SecurityException(msg);
9496 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9498 if (r != null && cpr.canRunHere(r)) {
9499 // This provider has been published or is in the process
9500 // of being published... but it is also allowed to run
9501 // in the caller's process, so don't make a connection
9502 // and just let the caller instantiate its own instance.
9503 ContentProviderHolder holder = cpr.newHolder(null);
9504 // don't give caller the provider object, it needs
9506 holder.provider = null;
9510 final long origId = Binder.clearCallingIdentity();
9512 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9514 // In this case the provider instance already exists, so we can
9515 // return it right away.
9516 conn = incProviderCountLocked(r, cpr, token, stable);
9517 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9518 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9519 // If this is a perceptible app accessing the provider,
9520 // make sure to count it as being accessed and thus
9521 // back up on the LRU list. This is good because
9522 // content providers are often expensive to start.
9523 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9524 updateLruProcessLocked(cpr.proc, false, null);
9525 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9529 if (cpr.proc != null) {
9531 if (cpr.name.flattenToShortString().equals(
9532 "com.android.providers.calendar/.CalendarProvider2")) {
9533 Slog.v(TAG, "****************** KILLING "
9534 + cpr.name.flattenToShortString());
9535 Process.killProcess(cpr.proc.pid);
9538 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9539 boolean success = updateOomAdjLocked(cpr.proc);
9540 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9541 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9542 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9543 // NOTE: there is still a race here where a signal could be
9544 // pending on the process even though we managed to update its
9545 // adj level. Not sure what to do about this, but at least
9546 // the race is now smaller.
9548 // Uh oh... it looks like the provider's process
9549 // has been killed on us. We need to wait for a new
9550 // process to be started, and make sure its death
9551 // doesn't kill our process.
9552 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9553 + " is crashing; detaching " + r);
9554 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9555 checkTime(startTime, "getContentProviderImpl: before appDied");
9556 appDiedLocked(cpr.proc);
9557 checkTime(startTime, "getContentProviderImpl: after appDied");
9559 // This wasn't the last ref our process had on
9560 // the provider... we have now been killed, bail.
9563 providerRunning = false;
9568 Binder.restoreCallingIdentity(origId);
9572 if (!providerRunning) {
9574 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9575 cpi = AppGlobals.getPackageManager().
9576 resolveContentProvider(name,
9577 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9578 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9579 } catch (RemoteException ex) {
9584 // If the provider is a singleton AND
9585 // (it's a call within the same user || the provider is a
9587 // Then allow connecting to the singleton provider
9588 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9589 cpi.name, cpi.flags)
9590 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9592 userId = UserHandle.USER_OWNER;
9594 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9595 checkTime(startTime, "getContentProviderImpl: got app info for user");
9598 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9599 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9601 throw new SecurityException(msg);
9603 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9605 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9606 && !cpi.processName.equals("system")) {
9607 // If this content provider does not run in the system
9608 // process, and the system is not yet ready to run other
9609 // processes, then fail fast instead of hanging.
9610 throw new IllegalArgumentException(
9611 "Attempt to launch content provider before system ready");
9614 // Make sure that the user who owns this provider is running. If not,
9615 // we don't want to allow it to run.
9616 if (!isUserRunningLocked(userId, false)) {
9617 Slog.w(TAG, "Unable to launch app "
9618 + cpi.applicationInfo.packageName + "/"
9619 + cpi.applicationInfo.uid + " for provider "
9620 + name + ": user " + userId + " is stopped");
9624 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9625 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9626 cpr = mProviderMap.getProviderByClass(comp, userId);
9627 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9628 final boolean firstClass = cpr == null;
9630 final long ident = Binder.clearCallingIdentity();
9632 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9633 ApplicationInfo ai =
9634 AppGlobals.getPackageManager().
9636 cpi.applicationInfo.packageName,
9637 STOCK_PM_FLAGS, userId);
9638 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9640 Slog.w(TAG, "No package info for content provider "
9644 ai = getAppInfoForUser(ai, userId);
9645 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9646 } catch (RemoteException ex) {
9647 // pm is in same process, this will never happen.
9649 Binder.restoreCallingIdentity(ident);
9653 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9655 if (r != null && cpr.canRunHere(r)) {
9656 // If this is a multiprocess provider, then just return its
9657 // info and allow the caller to instantiate it. Only do
9658 // this if the provider is the same user as the caller's
9659 // process, or can run as root (so can be in any process).
9660 return cpr.newHolder(null);
9663 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9664 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9665 + cpr.info.name + " callers=" + Debug.getCallers(6));
9667 // This is single process, and our app is now connecting to it.
9668 // See if we are already in the process of launching this
9670 final int N = mLaunchingProviders.size();
9672 for (i = 0; i < N; i++) {
9673 if (mLaunchingProviders.get(i) == cpr) {
9678 // If the provider is not already being launched, then get it
9681 final long origId = Binder.clearCallingIdentity();
9684 // Content provider is now in use, its package can't be stopped.
9686 checkTime(startTime, "getContentProviderImpl: before set stopped state");
9687 AppGlobals.getPackageManager().setPackageStoppedState(
9688 cpr.appInfo.packageName, false, userId);
9689 checkTime(startTime, "getContentProviderImpl: after set stopped state");
9690 } catch (RemoteException e) {
9691 } catch (IllegalArgumentException e) {
9692 Slog.w(TAG, "Failed trying to unstop package "
9693 + cpr.appInfo.packageName + ": " + e);
9696 // Use existing process if already started
9697 checkTime(startTime, "getContentProviderImpl: looking for process record");
9698 ProcessRecord proc = getProcessRecordLocked(
9699 cpi.processName, cpr.appInfo.uid, false);
9700 if (proc != null && proc.thread != null) {
9701 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9702 "Installing in existing process " + proc);
9703 if (!proc.pubProviders.containsKey(cpi.name)) {
9704 checkTime(startTime, "getContentProviderImpl: scheduling install");
9705 proc.pubProviders.put(cpi.name, cpr);
9707 proc.thread.scheduleInstallProvider(cpi);
9708 } catch (RemoteException e) {
9712 checkTime(startTime, "getContentProviderImpl: before start process");
9713 proc = startProcessLocked(cpi.processName,
9714 cpr.appInfo, false, 0, "content provider",
9715 new ComponentName(cpi.applicationInfo.packageName,
9716 cpi.name), false, false, false);
9717 checkTime(startTime, "getContentProviderImpl: after start process");
9719 Slog.w(TAG, "Unable to launch app "
9720 + cpi.applicationInfo.packageName + "/"
9721 + cpi.applicationInfo.uid + " for provider "
9722 + name + ": process is bad");
9726 cpr.launchingApp = proc;
9727 mLaunchingProviders.add(cpr);
9729 Binder.restoreCallingIdentity(origId);
9733 checkTime(startTime, "getContentProviderImpl: updating data structures");
9735 // Make sure the provider is published (the same provider class
9736 // may be published under multiple names).
9738 mProviderMap.putProviderByClass(comp, cpr);
9741 mProviderMap.putProviderByName(name, cpr);
9742 conn = incProviderCountLocked(r, cpr, token, stable);
9744 conn.waiting = true;
9747 checkTime(startTime, "getContentProviderImpl: done!");
9750 // Wait for the provider to be published...
9751 synchronized (cpr) {
9752 while (cpr.provider == null) {
9753 if (cpr.launchingApp == null) {
9754 Slog.w(TAG, "Unable to launch app "
9755 + cpi.applicationInfo.packageName + "/"
9756 + cpi.applicationInfo.uid + " for provider "
9757 + name + ": launching app became null");
9758 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9759 UserHandle.getUserId(cpi.applicationInfo.uid),
9760 cpi.applicationInfo.packageName,
9761 cpi.applicationInfo.uid, name);
9765 if (DEBUG_MU) Slog.v(TAG_MU,
9766 "Waiting to start provider " + cpr
9767 + " launchingApp=" + cpr.launchingApp);
9769 conn.waiting = true;
9772 } catch (InterruptedException ex) {
9775 conn.waiting = false;
9780 return cpr != null ? cpr.newHolder(conn) : null;
9784 public final ContentProviderHolder getContentProvider(
9785 IApplicationThread caller, String name, int userId, boolean stable) {
9786 enforceNotIsolatedCaller("getContentProvider");
9787 if (caller == null) {
9788 String msg = "null IApplicationThread when getting content provider "
9791 throw new SecurityException(msg);
9793 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9794 // with cross-user grant.
9795 return getContentProviderImpl(caller, name, null, stable, userId);
9798 public ContentProviderHolder getContentProviderExternal(
9799 String name, int userId, IBinder token) {
9800 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9801 "Do not have permission in call getContentProviderExternal()");
9802 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9803 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9804 return getContentProviderExternalUnchecked(name, token, userId);
9807 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9808 IBinder token, int userId) {
9809 return getContentProviderImpl(null, name, token, true, userId);
9813 * Drop a content provider from a ProcessRecord's bookkeeping
9815 public void removeContentProvider(IBinder connection, boolean stable) {
9816 enforceNotIsolatedCaller("removeContentProvider");
9817 long ident = Binder.clearCallingIdentity();
9819 synchronized (this) {
9820 ContentProviderConnection conn;
9822 conn = (ContentProviderConnection)connection;
9823 } catch (ClassCastException e) {
9824 String msg ="removeContentProvider: " + connection
9825 + " not a ContentProviderConnection";
9827 throw new IllegalArgumentException(msg);
9830 throw new NullPointerException("connection is null");
9832 if (decProviderCountLocked(conn, null, null, stable)) {
9833 updateOomAdjLocked();
9837 Binder.restoreCallingIdentity(ident);
9841 public void removeContentProviderExternal(String name, IBinder token) {
9842 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9843 "Do not have permission in call removeContentProviderExternal()");
9844 int userId = UserHandle.getCallingUserId();
9845 long ident = Binder.clearCallingIdentity();
9847 removeContentProviderExternalUnchecked(name, token, userId);
9849 Binder.restoreCallingIdentity(ident);
9853 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9854 synchronized (this) {
9855 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9857 //remove from mProvidersByClass
9858 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9862 //update content provider record entry info
9863 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9864 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9865 if (localCpr.hasExternalProcessHandles()) {
9866 if (localCpr.removeExternalProcessHandleLocked(token)) {
9867 updateOomAdjLocked();
9869 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9870 + " with no external reference for token: "
9874 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9875 + " with no external references.");
9880 public final void publishContentProviders(IApplicationThread caller,
9881 List<ContentProviderHolder> providers) {
9882 if (providers == null) {
9886 enforceNotIsolatedCaller("publishContentProviders");
9887 synchronized (this) {
9888 final ProcessRecord r = getRecordForAppLocked(caller);
9889 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9891 throw new SecurityException(
9892 "Unable to find app for caller " + caller
9893 + " (pid=" + Binder.getCallingPid()
9894 + ") when publishing content providers");
9897 final long origId = Binder.clearCallingIdentity();
9899 final int N = providers.size();
9900 for (int i=0; i<N; i++) {
9901 ContentProviderHolder src = providers.get(i);
9902 if (src == null || src.info == null || src.provider == null) {
9905 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9906 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9908 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9909 mProviderMap.putProviderByClass(comp, dst);
9910 String names[] = dst.info.authority.split(";");
9911 for (int j = 0; j < names.length; j++) {
9912 mProviderMap.putProviderByName(names[j], dst);
9915 int NL = mLaunchingProviders.size();
9917 for (j=0; j<NL; j++) {
9918 if (mLaunchingProviders.get(j) == dst) {
9919 mLaunchingProviders.remove(j);
9924 synchronized (dst) {
9925 dst.provider = src.provider;
9929 updateOomAdjLocked(r);
9930 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9931 src.info.authority);
9935 Binder.restoreCallingIdentity(origId);
9939 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9940 ContentProviderConnection conn;
9942 conn = (ContentProviderConnection)connection;
9943 } catch (ClassCastException e) {
9944 String msg ="refContentProvider: " + connection
9945 + " not a ContentProviderConnection";
9947 throw new IllegalArgumentException(msg);
9950 throw new NullPointerException("connection is null");
9953 synchronized (this) {
9955 conn.numStableIncs += stable;
9957 stable = conn.stableCount + stable;
9959 throw new IllegalStateException("stableCount < 0: " + stable);
9963 conn.numUnstableIncs += unstable;
9965 unstable = conn.unstableCount + unstable;
9967 throw new IllegalStateException("unstableCount < 0: " + unstable);
9970 if ((stable+unstable) <= 0) {
9971 throw new IllegalStateException("ref counts can't go to zero here: stable="
9972 + stable + " unstable=" + unstable);
9974 conn.stableCount = stable;
9975 conn.unstableCount = unstable;
9980 public void unstableProviderDied(IBinder connection) {
9981 ContentProviderConnection conn;
9983 conn = (ContentProviderConnection)connection;
9984 } catch (ClassCastException e) {
9985 String msg ="refContentProvider: " + connection
9986 + " not a ContentProviderConnection";
9988 throw new IllegalArgumentException(msg);
9991 throw new NullPointerException("connection is null");
9994 // Safely retrieve the content provider associated with the connection.
9995 IContentProvider provider;
9996 synchronized (this) {
9997 provider = conn.provider.provider;
10000 if (provider == null) {
10001 // Um, yeah, we're way ahead of you.
10005 // Make sure the caller is being honest with us.
10006 if (provider.asBinder().pingBinder()) {
10007 // Er, no, still looks good to us.
10008 synchronized (this) {
10009 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10010 + " says " + conn + " died, but we don't agree");
10015 // Well look at that! It's dead!
10016 synchronized (this) {
10017 if (conn.provider.provider != provider) {
10018 // But something changed... good enough.
10022 ProcessRecord proc = conn.provider.proc;
10023 if (proc == null || proc.thread == null) {
10024 // Seems like the process is already cleaned up.
10028 // As far as we're concerned, this is just like receiving a
10029 // death notification... just a bit prematurely.
10030 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10031 + ") early provider death");
10032 final long ident = Binder.clearCallingIdentity();
10034 appDiedLocked(proc);
10036 Binder.restoreCallingIdentity(ident);
10042 public void appNotRespondingViaProvider(IBinder connection) {
10043 enforceCallingPermission(
10044 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10046 final ContentProviderConnection conn = (ContentProviderConnection) connection;
10047 if (conn == null) {
10048 Slog.w(TAG, "ContentProviderConnection is null");
10052 final ProcessRecord host = conn.provider.proc;
10053 if (host == null) {
10054 Slog.w(TAG, "Failed to find hosting ProcessRecord");
10058 final long token = Binder.clearCallingIdentity();
10060 appNotResponding(host, null, null, false, "ContentProvider not responding");
10062 Binder.restoreCallingIdentity(token);
10066 public final void installSystemProviders() {
10067 List<ProviderInfo> providers;
10068 synchronized (this) {
10069 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10070 providers = generateApplicationProvidersLocked(app);
10071 if (providers != null) {
10072 for (int i=providers.size()-1; i>=0; i--) {
10073 ProviderInfo pi = (ProviderInfo)providers.get(i);
10074 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10075 Slog.w(TAG, "Not installing system proc provider " + pi.name
10076 + ": not system .apk");
10077 providers.remove(i);
10082 if (providers != null) {
10083 mSystemThread.installSystemProviders(providers);
10086 mCoreSettingsObserver = new CoreSettingsObserver(this);
10088 //mUsageStatsService.monitorPackages();
10092 * Allows apps to retrieve the MIME type of a URI.
10093 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10094 * users, then it does not need permission to access the ContentProvider.
10095 * Either, it needs cross-user uri grants.
10097 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10099 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10100 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10102 public String getProviderMimeType(Uri uri, int userId) {
10103 enforceNotIsolatedCaller("getProviderMimeType");
10104 final String name = uri.getAuthority();
10105 int callingUid = Binder.getCallingUid();
10106 int callingPid = Binder.getCallingPid();
10108 boolean clearedIdentity = false;
10109 userId = unsafeConvertIncomingUser(userId);
10110 if (canClearIdentity(callingPid, callingUid, userId)) {
10111 clearedIdentity = true;
10112 ident = Binder.clearCallingIdentity();
10114 ContentProviderHolder holder = null;
10116 holder = getContentProviderExternalUnchecked(name, null, userId);
10117 if (holder != null) {
10118 return holder.provider.getType(uri);
10120 } catch (RemoteException e) {
10121 Log.w(TAG, "Content provider dead retrieving " + uri, e);
10124 // We need to clear the identity to call removeContentProviderExternalUnchecked
10125 if (!clearedIdentity) {
10126 ident = Binder.clearCallingIdentity();
10129 if (holder != null) {
10130 removeContentProviderExternalUnchecked(name, null, userId);
10133 Binder.restoreCallingIdentity(ident);
10140 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10141 if (UserHandle.getUserId(callingUid) == userId) {
10144 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10145 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10146 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10147 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10153 // =========================================================
10154 // GLOBAL MANAGEMENT
10155 // =========================================================
10157 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10158 boolean isolated, int isolatedUid) {
10159 String proc = customProcess != null ? customProcess : info.processName;
10160 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10161 final int userId = UserHandle.getUserId(info.uid);
10162 int uid = info.uid;
10164 if (isolatedUid == 0) {
10165 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10167 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10168 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10169 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10171 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10172 mNextIsolatedProcessUid++;
10173 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10174 // No process for this uid, use it.
10178 if (stepsLeft <= 0) {
10183 // Special case for startIsolatedProcess (internal only), where
10184 // the uid of the isolated process is specified by the caller.
10188 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10189 if (!mBooted && !mBooting
10190 && userId == UserHandle.USER_OWNER
10191 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10192 r.persistent = true;
10194 addProcessNameLocked(r);
10198 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10199 String abiOverride) {
10202 app = getProcessRecordLocked(info.processName, info.uid, true);
10208 app = newProcessRecordLocked(info, null, isolated, 0);
10209 updateLruProcessLocked(app, false, null);
10210 updateOomAdjLocked();
10213 // This package really, really can not be stopped.
10215 AppGlobals.getPackageManager().setPackageStoppedState(
10216 info.packageName, false, UserHandle.getUserId(app.uid));
10217 } catch (RemoteException e) {
10218 } catch (IllegalArgumentException e) {
10219 Slog.w(TAG, "Failed trying to unstop package "
10220 + info.packageName + ": " + e);
10223 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10224 app.persistent = true;
10225 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10227 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10228 mPersistentStartingProcesses.add(app);
10229 startProcessLocked(app, "added application", app.processName, abiOverride,
10230 null /* entryPoint */, null /* entryPointArgs */);
10236 public void unhandledBack() {
10237 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10238 "unhandledBack()");
10240 synchronized(this) {
10241 final long origId = Binder.clearCallingIdentity();
10243 getFocusedStack().unhandledBackLocked();
10245 Binder.restoreCallingIdentity(origId);
10250 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10251 enforceNotIsolatedCaller("openContentUri");
10252 final int userId = UserHandle.getCallingUserId();
10253 String name = uri.getAuthority();
10254 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10255 ParcelFileDescriptor pfd = null;
10257 // We record the binder invoker's uid in thread-local storage before
10258 // going to the content provider to open the file. Later, in the code
10259 // that handles all permissions checks, we look for this uid and use
10260 // that rather than the Activity Manager's own uid. The effect is that
10261 // we do the check against the caller's permissions even though it looks
10262 // to the content provider like the Activity Manager itself is making
10264 Binder token = new Binder();
10265 sCallerIdentity.set(new Identity(
10266 token, Binder.getCallingPid(), Binder.getCallingUid()));
10268 pfd = cph.provider.openFile(null, uri, "r", null, token);
10269 } catch (FileNotFoundException e) {
10270 // do nothing; pfd will be returned null
10272 // Ensure that whatever happens, we clean up the identity state
10273 sCallerIdentity.remove();
10274 // Ensure we're done with the provider.
10275 removeContentProviderExternalUnchecked(name, null, userId);
10278 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10283 // Actually is sleeping or shutting down or whatever else in the future
10284 // is an inactive state.
10285 public boolean isSleepingOrShuttingDown() {
10286 return isSleeping() || mShuttingDown;
10289 public boolean isSleeping() {
10293 void onWakefulnessChanged(int wakefulness) {
10294 synchronized(this) {
10295 mWakefulness = wakefulness;
10296 updateSleepIfNeededLocked();
10300 void finishRunningVoiceLocked() {
10301 if (mRunningVoice != null) {
10302 mRunningVoice = null;
10303 mVoiceWakeLock.release();
10304 updateSleepIfNeededLocked();
10308 void startTimeTrackingFocusedActivityLocked() {
10309 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10310 mCurAppTimeTracker.start(mFocusedActivity.packageName);
10314 void updateSleepIfNeededLocked() {
10315 if (mSleeping && !shouldSleepLocked()) {
10317 startTimeTrackingFocusedActivityLocked();
10318 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10319 mStackSupervisor.comeOutOfSleepIfNeededLocked();
10320 updateOomAdjLocked();
10321 } else if (!mSleeping && shouldSleepLocked()) {
10323 if (mCurAppTimeTracker != null) {
10324 mCurAppTimeTracker.stop();
10326 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10327 mStackSupervisor.goingToSleepLocked();
10328 updateOomAdjLocked();
10330 // Initialize the wake times of all processes.
10331 checkExcessivePowerUsageLocked(false);
10332 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10333 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10334 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10338 private boolean shouldSleepLocked() {
10339 // Resume applications while running a voice interactor.
10340 if (mRunningVoice != null) {
10344 // TODO: Transform the lock screen state into a sleep token instead.
10345 switch (mWakefulness) {
10346 case PowerManagerInternal.WAKEFULNESS_AWAKE:
10347 case PowerManagerInternal.WAKEFULNESS_DREAMING:
10348 case PowerManagerInternal.WAKEFULNESS_DOZING:
10349 // Pause applications whenever the lock screen is shown or any sleep
10350 // tokens have been acquired.
10351 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10352 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10354 // If we're asleep then pause applications unconditionally.
10359 /** Pokes the task persister. */
10360 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10361 if (task != null && task.stack != null && task.stack.isHomeStack()) {
10362 // Never persist the home stack.
10365 mTaskPersister.wakeup(task, flush);
10368 /** Notifies all listeners when the task stack has changed. */
10369 void notifyTaskStackChangedLocked() {
10370 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10371 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10372 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10376 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10377 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10381 public boolean shutdown(int timeout) {
10382 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10383 != PackageManager.PERMISSION_GRANTED) {
10384 throw new SecurityException("Requires permission "
10385 + android.Manifest.permission.SHUTDOWN);
10388 boolean timedout = false;
10390 synchronized(this) {
10391 mShuttingDown = true;
10392 updateEventDispatchingLocked();
10393 timedout = mStackSupervisor.shutdownLocked(timeout);
10396 mAppOpsService.shutdown();
10397 if (mUsageStatsService != null) {
10398 mUsageStatsService.prepareShutdown();
10400 mBatteryStatsService.shutdown();
10401 synchronized (this) {
10402 mProcessStats.shutdownLocked();
10403 notifyTaskPersisterLocked(null, true);
10409 public final void activitySlept(IBinder token) {
10410 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10412 final long origId = Binder.clearCallingIdentity();
10414 synchronized (this) {
10415 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10417 mStackSupervisor.activitySleptLocked(r);
10421 Binder.restoreCallingIdentity(origId);
10424 private String lockScreenShownToString() {
10425 switch (mLockScreenShown) {
10426 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10427 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10428 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10429 default: return "Unknown=" + mLockScreenShown;
10433 void logLockScreen(String msg) {
10434 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10435 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10436 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10437 + " mSleeping=" + mSleeping);
10440 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10441 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10442 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10443 boolean wasRunningVoice = mRunningVoice != null;
10444 mRunningVoice = session;
10445 if (!wasRunningVoice) {
10446 mVoiceWakeLock.acquire();
10447 updateSleepIfNeededLocked();
10452 private void updateEventDispatchingLocked() {
10453 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10456 public void setLockScreenShown(boolean shown) {
10457 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10458 != PackageManager.PERMISSION_GRANTED) {
10459 throw new SecurityException("Requires permission "
10460 + android.Manifest.permission.DEVICE_POWER);
10463 synchronized(this) {
10464 long ident = Binder.clearCallingIdentity();
10466 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10467 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10468 updateSleepIfNeededLocked();
10470 Binder.restoreCallingIdentity(ident);
10476 public void stopAppSwitches() {
10477 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10478 != PackageManager.PERMISSION_GRANTED) {
10479 throw new SecurityException("Requires permission "
10480 + android.Manifest.permission.STOP_APP_SWITCHES);
10483 synchronized(this) {
10484 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10485 + APP_SWITCH_DELAY_TIME;
10486 mDidAppSwitch = false;
10487 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10488 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10489 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10493 public void resumeAppSwitches() {
10494 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10495 != PackageManager.PERMISSION_GRANTED) {
10496 throw new SecurityException("Requires permission "
10497 + android.Manifest.permission.STOP_APP_SWITCHES);
10500 synchronized(this) {
10501 // Note that we don't execute any pending app switches... we will
10502 // let those wait until either the timeout, or the next start
10503 // activity request.
10504 mAppSwitchesAllowedTime = 0;
10508 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10509 int callingPid, int callingUid, String name) {
10510 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10514 int perm = checkComponentPermission(
10515 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10516 sourceUid, -1, true);
10517 if (perm == PackageManager.PERMISSION_GRANTED) {
10521 // If the actual IPC caller is different from the logical source, then
10522 // also see if they are allowed to control app switches.
10523 if (callingUid != -1 && callingUid != sourceUid) {
10524 perm = checkComponentPermission(
10525 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10526 callingUid, -1, true);
10527 if (perm == PackageManager.PERMISSION_GRANTED) {
10532 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10536 public void setDebugApp(String packageName, boolean waitForDebugger,
10537 boolean persistent) {
10538 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10541 long ident = Binder.clearCallingIdentity();
10543 // Note that this is not really thread safe if there are multiple
10544 // callers into it at the same time, but that's not a situation we
10547 final ContentResolver resolver = mContext.getContentResolver();
10548 Settings.Global.putString(
10549 resolver, Settings.Global.DEBUG_APP,
10551 Settings.Global.putInt(
10552 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10553 waitForDebugger ? 1 : 0);
10556 synchronized (this) {
10558 mOrigDebugApp = mDebugApp;
10559 mOrigWaitForDebugger = mWaitForDebugger;
10561 mDebugApp = packageName;
10562 mWaitForDebugger = waitForDebugger;
10563 mDebugTransient = !persistent;
10564 if (packageName != null) {
10565 forceStopPackageLocked(packageName, -1, false, false, true, true,
10566 false, UserHandle.USER_ALL, "set debug app");
10570 Binder.restoreCallingIdentity(ident);
10574 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10575 synchronized (this) {
10576 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10577 if (!isDebuggable) {
10578 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10579 throw new SecurityException("Process not debuggable: " + app.packageName);
10583 mOpenGlTraceApp = processName;
10587 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10588 synchronized (this) {
10589 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10590 if (!isDebuggable) {
10591 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10592 throw new SecurityException("Process not debuggable: " + app.packageName);
10595 mProfileApp = processName;
10596 mProfileFile = profilerInfo.profileFile;
10597 if (mProfileFd != null) {
10599 mProfileFd.close();
10600 } catch (IOException e) {
10604 mProfileFd = profilerInfo.profileFd;
10605 mSamplingInterval = profilerInfo.samplingInterval;
10606 mAutoStopProfiler = profilerInfo.autoStopProfiler;
10612 public void setAlwaysFinish(boolean enabled) {
10613 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10614 "setAlwaysFinish()");
10616 Settings.Global.putInt(
10617 mContext.getContentResolver(),
10618 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10620 synchronized (this) {
10621 mAlwaysFinishActivities = enabled;
10626 public void setActivityController(IActivityController controller) {
10627 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10628 "setActivityController()");
10629 synchronized (this) {
10630 mController = controller;
10631 Watchdog.getInstance().setActivityController(controller);
10636 public void setUserIsMonkey(boolean userIsMonkey) {
10637 synchronized (this) {
10638 synchronized (mPidsSelfLocked) {
10639 final int callingPid = Binder.getCallingPid();
10640 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10641 if (precessRecord == null) {
10642 throw new SecurityException("Unknown process: " + callingPid);
10644 if (precessRecord.instrumentationUiAutomationConnection == null) {
10645 throw new SecurityException("Only an instrumentation process "
10646 + "with a UiAutomation can call setUserIsMonkey");
10649 mUserIsMonkey = userIsMonkey;
10654 public boolean isUserAMonkey() {
10655 synchronized (this) {
10656 // If there is a controller also implies the user is a monkey.
10657 return (mUserIsMonkey || mController != null);
10661 public void requestBugReport() {
10662 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10663 SystemProperties.set("ctl.start", "bugreport");
10666 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10667 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10670 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10671 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10672 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10674 return KEY_DISPATCHING_TIMEOUT;
10678 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10679 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10680 != PackageManager.PERMISSION_GRANTED) {
10681 throw new SecurityException("Requires permission "
10682 + android.Manifest.permission.FILTER_EVENTS);
10684 ProcessRecord proc;
10686 synchronized (this) {
10687 synchronized (mPidsSelfLocked) {
10688 proc = mPidsSelfLocked.get(pid);
10690 timeout = getInputDispatchingTimeoutLocked(proc);
10693 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10701 * Handle input dispatching timeouts.
10702 * Returns whether input dispatching should be aborted or not.
10704 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10705 final ActivityRecord activity, final ActivityRecord parent,
10706 final boolean aboveSystem, String reason) {
10707 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10708 != PackageManager.PERMISSION_GRANTED) {
10709 throw new SecurityException("Requires permission "
10710 + android.Manifest.permission.FILTER_EVENTS);
10713 final String annotation;
10714 if (reason == null) {
10715 annotation = "Input dispatching timed out";
10717 annotation = "Input dispatching timed out (" + reason + ")";
10720 if (proc != null) {
10721 synchronized (this) {
10722 if (proc.debugging) {
10727 // Give more time since we were dexopting.
10728 mDidDexOpt = false;
10732 if (proc.instrumentationClass != null) {
10733 Bundle info = new Bundle();
10734 info.putString("shortMsg", "keyDispatchingTimedOut");
10735 info.putString("longMsg", annotation);
10736 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10740 mHandler.post(new Runnable() {
10742 public void run() {
10743 appNotResponding(proc, activity, parent, aboveSystem, annotation);
10752 public Bundle getAssistContextExtras(int requestType) {
10753 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10754 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10758 synchronized (pae) {
10759 while (!pae.haveResult) {
10762 } catch (InterruptedException e) {
10766 synchronized (this) {
10767 buildAssistBundleLocked(pae, pae.result);
10768 mPendingAssistExtras.remove(pae);
10769 mUiHandler.removeCallbacks(pae);
10775 public boolean isAssistDataAllowedOnCurrentActivity() {
10776 int userId = mCurrentUserId;
10777 synchronized (this) {
10778 ActivityRecord activity = getFocusedStack().topActivity();
10779 if (activity == null) {
10782 userId = activity.userId;
10784 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10785 Context.DEVICE_POLICY_SERVICE);
10786 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10790 public boolean showAssistFromActivity(IBinder token, Bundle args) {
10791 long ident = Binder.clearCallingIdentity();
10793 synchronized (this) {
10794 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10795 ActivityRecord top = getFocusedStack().topActivity();
10796 if (top != caller) {
10797 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10798 + " is not current top " + top);
10801 if (!top.nowVisible) {
10802 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10803 + " is not visible");
10807 AssistUtils utils = new AssistUtils(mContext);
10808 return utils.showSessionForActiveService(args,
10809 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10811 Binder.restoreCallingIdentity(ident);
10816 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10817 IBinder activityToken) {
10818 return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10819 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10822 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10823 IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10825 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10826 "enqueueAssistContext()");
10827 synchronized (this) {
10828 ActivityRecord activity = getFocusedStack().topActivity();
10829 if (activity == null) {
10830 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10833 if (activity.app == null || activity.app.thread == null) {
10834 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10837 if (activityToken != null) {
10838 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10839 if (activity != caller) {
10840 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10841 + " is not current top " + activity);
10845 PendingAssistExtras pae;
10846 Bundle extras = new Bundle();
10847 if (args != null) {
10848 extras.putAll(args);
10850 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10851 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10852 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10854 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10856 mPendingAssistExtras.add(pae);
10857 mUiHandler.postDelayed(pae, timeout);
10858 } catch (RemoteException e) {
10859 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10866 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10867 IResultReceiver receiver;
10868 synchronized (this) {
10869 mPendingAssistExtras.remove(pae);
10870 receiver = pae.receiver;
10872 if (receiver != null) {
10873 // Caller wants result sent back to them.
10875 pae.receiver.send(0, null);
10876 } catch (RemoteException e) {
10881 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10882 if (result != null) {
10883 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10885 if (pae.hint != null) {
10886 pae.extras.putBoolean(pae.hint, true);
10890 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10891 AssistContent content, Uri referrer) {
10892 PendingAssistExtras pae = (PendingAssistExtras)token;
10893 synchronized (pae) {
10894 pae.result = extras;
10895 pae.structure = structure;
10896 pae.content = content;
10897 if (referrer != null) {
10898 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10900 pae.haveResult = true;
10902 if (pae.intent == null && pae.receiver == null) {
10903 // Caller is just waiting for the result.
10908 // We are now ready to launch the assist activity.
10909 IResultReceiver sendReceiver = null;
10910 Bundle sendBundle = null;
10911 synchronized (this) {
10912 buildAssistBundleLocked(pae, extras);
10913 boolean exists = mPendingAssistExtras.remove(pae);
10914 mUiHandler.removeCallbacks(pae);
10919 if ((sendReceiver=pae.receiver) != null) {
10920 // Caller wants result sent back to them.
10921 sendBundle = new Bundle();
10922 sendBundle.putBundle("data", pae.extras);
10923 sendBundle.putParcelable("structure", pae.structure);
10924 sendBundle.putParcelable("content", pae.content);
10927 if (sendReceiver != null) {
10929 sendReceiver.send(0, sendBundle);
10930 } catch (RemoteException e) {
10935 long ident = Binder.clearCallingIdentity();
10937 pae.intent.replaceExtras(pae.extras);
10938 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10939 | Intent.FLAG_ACTIVITY_SINGLE_TOP
10940 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10941 closeSystemDialogs("assist");
10943 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10944 } catch (ActivityNotFoundException e) {
10945 Slog.w(TAG, "No activity to handle assist action.", e);
10948 Binder.restoreCallingIdentity(ident);
10952 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10954 return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10955 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10958 public void registerProcessObserver(IProcessObserver observer) {
10959 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10960 "registerProcessObserver()");
10961 synchronized (this) {
10962 mProcessObservers.register(observer);
10967 public void unregisterProcessObserver(IProcessObserver observer) {
10968 synchronized (this) {
10969 mProcessObservers.unregister(observer);
10973 public void registerUidObserver(IUidObserver observer) {
10974 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10975 "registerUidObserver()");
10976 synchronized (this) {
10977 mUidObservers.register(observer);
10982 public void unregisterUidObserver(IUidObserver observer) {
10983 synchronized (this) {
10984 mUidObservers.unregister(observer);
10989 public boolean convertFromTranslucent(IBinder token) {
10990 final long origId = Binder.clearCallingIdentity();
10992 synchronized (this) {
10993 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10997 final boolean translucentChanged = r.changeWindowTranslucency(true);
10998 if (translucentChanged) {
10999 r.task.stack.releaseBackgroundResources(r);
11000 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11002 mWindowManager.setAppFullscreen(token, true);
11003 return translucentChanged;
11006 Binder.restoreCallingIdentity(origId);
11011 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11012 final long origId = Binder.clearCallingIdentity();
11014 synchronized (this) {
11015 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11019 int index = r.task.mActivities.lastIndexOf(r);
11021 ActivityRecord under = r.task.mActivities.get(index - 1);
11022 under.returningOptions = options;
11024 final boolean translucentChanged = r.changeWindowTranslucency(false);
11025 if (translucentChanged) {
11026 r.task.stack.convertActivityToTranslucent(r);
11028 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11029 mWindowManager.setAppFullscreen(token, false);
11030 return translucentChanged;
11033 Binder.restoreCallingIdentity(origId);
11038 public boolean requestVisibleBehind(IBinder token, boolean visible) {
11039 final long origId = Binder.clearCallingIdentity();
11041 synchronized (this) {
11042 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11044 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11049 Binder.restoreCallingIdentity(origId);
11054 public boolean isBackgroundVisibleBehind(IBinder token) {
11055 final long origId = Binder.clearCallingIdentity();
11057 synchronized (this) {
11058 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11059 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11060 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11061 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11065 Binder.restoreCallingIdentity(origId);
11070 public ActivityOptions getActivityOptions(IBinder token) {
11071 final long origId = Binder.clearCallingIdentity();
11073 synchronized (this) {
11074 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11076 final ActivityOptions activityOptions = r.pendingOptions;
11077 r.pendingOptions = null;
11078 return activityOptions;
11083 Binder.restoreCallingIdentity(origId);
11088 public void setImmersive(IBinder token, boolean immersive) {
11089 synchronized(this) {
11090 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11092 throw new IllegalArgumentException();
11094 r.immersive = immersive;
11096 // update associated state if we're frontmost
11097 if (r == mFocusedActivity) {
11098 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11099 applyUpdateLockStateLocked(r);
11105 public boolean isImmersive(IBinder token) {
11106 synchronized (this) {
11107 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11109 throw new IllegalArgumentException();
11111 return r.immersive;
11115 public boolean isTopActivityImmersive() {
11116 enforceNotIsolatedCaller("startActivity");
11117 synchronized (this) {
11118 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11119 return (r != null) ? r.immersive : false;
11124 public boolean isTopOfTask(IBinder token) {
11125 synchronized (this) {
11126 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11128 throw new IllegalArgumentException();
11130 return r.task.getTopActivity() == r;
11134 public final void enterSafeMode() {
11135 synchronized(this) {
11136 // It only makes sense to do this before the system is ready
11137 // and started launching other packages.
11138 if (!mSystemReady) {
11140 AppGlobals.getPackageManager().enterSafeMode();
11141 } catch (RemoteException e) {
11149 public final void showSafeModeOverlay() {
11150 View v = LayoutInflater.from(mContext).inflate(
11151 com.android.internal.R.layout.safe_mode, null);
11152 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11153 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11154 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11155 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11156 lp.gravity = Gravity.BOTTOM | Gravity.START;
11157 lp.format = v.getBackground().getOpacity();
11158 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11159 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11160 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11161 ((WindowManager)mContext.getSystemService(
11162 Context.WINDOW_SERVICE)).addView(v, lp);
11165 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11166 if (!(sender instanceof PendingIntentRecord)) {
11169 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11170 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11171 synchronized (stats) {
11172 if (mBatteryStatsService.isOnBattery()) {
11173 mBatteryStatsService.enforceCallingPermission();
11174 int MY_UID = Binder.getCallingUid();
11175 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11176 BatteryStatsImpl.Uid.Pkg pkg =
11177 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11178 sourcePkg != null ? sourcePkg : rec.key.packageName);
11179 pkg.noteWakeupAlarmLocked(tag);
11184 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11185 if (!(sender instanceof PendingIntentRecord)) {
11188 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11189 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11190 synchronized (stats) {
11191 mBatteryStatsService.enforceCallingPermission();
11192 int MY_UID = Binder.getCallingUid();
11193 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11194 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11198 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11199 if (!(sender instanceof PendingIntentRecord)) {
11202 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11203 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11204 synchronized (stats) {
11205 mBatteryStatsService.enforceCallingPermission();
11206 int MY_UID = Binder.getCallingUid();
11207 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11208 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11212 public boolean killPids(int[] pids, String pReason, boolean secure) {
11213 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11214 throw new SecurityException("killPids only available to the system");
11216 String reason = (pReason == null) ? "Unknown" : pReason;
11217 // XXX Note: don't acquire main activity lock here, because the window
11218 // manager calls in with its locks held.
11220 boolean killed = false;
11221 synchronized (mPidsSelfLocked) {
11222 int[] types = new int[pids.length];
11224 for (int i=0; i<pids.length; i++) {
11225 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11226 if (proc != null) {
11227 int type = proc.setAdj;
11229 if (type > worstType) {
11235 // If the worst oom_adj is somewhere in the cached proc LRU range,
11236 // then constrain it so we will kill all cached procs.
11237 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11238 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11239 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11242 // If this is not a secure call, don't let it kill processes that
11244 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11245 worstType = ProcessList.SERVICE_ADJ;
11248 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11249 for (int i=0; i<pids.length; i++) {
11250 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11251 if (proc == null) {
11254 int adj = proc.setAdj;
11255 if (adj >= worstType && !proc.killedByAm) {
11256 proc.kill(reason, true);
11265 public void killUid(int appId, int userId, String reason) {
11266 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11267 synchronized (this) {
11268 final long identity = Binder.clearCallingIdentity();
11270 killPackageProcessesLocked(null, appId, userId,
11271 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11272 reason != null ? reason : "kill uid");
11274 Binder.restoreCallingIdentity(identity);
11280 public boolean killProcessesBelowForeground(String reason) {
11281 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11282 throw new SecurityException("killProcessesBelowForeground() only available to system");
11285 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11288 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11289 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11290 throw new SecurityException("killProcessesBelowAdj() only available to system");
11293 boolean killed = false;
11294 synchronized (mPidsSelfLocked) {
11295 final int size = mPidsSelfLocked.size();
11296 for (int i = 0; i < size; i++) {
11297 final int pid = mPidsSelfLocked.keyAt(i);
11298 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11299 if (proc == null) continue;
11301 final int adj = proc.setAdj;
11302 if (adj > belowAdj && !proc.killedByAm) {
11303 proc.kill(reason, true);
11312 public void hang(final IBinder who, boolean allowRestart) {
11313 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11314 != PackageManager.PERMISSION_GRANTED) {
11315 throw new SecurityException("Requires permission "
11316 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11319 final IBinder.DeathRecipient death = new DeathRecipient() {
11321 public void binderDied() {
11322 synchronized (this) {
11329 who.linkToDeath(death, 0);
11330 } catch (RemoteException e) {
11331 Slog.w(TAG, "hang: given caller IBinder is already dead.");
11335 synchronized (this) {
11336 Watchdog.getInstance().setAllowRestart(allowRestart);
11337 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11338 synchronized (death) {
11339 while (who.isBinderAlive()) {
11342 } catch (InterruptedException e) {
11346 Watchdog.getInstance().setAllowRestart(true);
11351 public void restart() {
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 Log.i(TAG, "Sending shutdown broadcast...");
11360 BroadcastReceiver br = new BroadcastReceiver() {
11361 @Override public void onReceive(Context context, Intent intent) {
11362 // Now the broadcast is done, finish up the low-level shutdown.
11363 Log.i(TAG, "Shutting down activity manager...");
11365 Log.i(TAG, "Shutdown complete, restarting!");
11366 Process.killProcess(Process.myPid());
11371 // First send the high-level shut down broadcast.
11372 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11373 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11374 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11375 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11376 mContext.sendOrderedBroadcastAsUser(intent,
11377 UserHandle.ALL, null, br, mHandler, 0, null, null);
11379 br.onReceive(mContext, intent);
11382 private long getLowRamTimeSinceIdle(long now) {
11383 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11387 public void performIdleMaintenance() {
11388 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11389 != PackageManager.PERMISSION_GRANTED) {
11390 throw new SecurityException("Requires permission "
11391 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11394 synchronized (this) {
11395 final long now = SystemClock.uptimeMillis();
11396 final long timeSinceLastIdle = now - mLastIdleTime;
11397 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11398 mLastIdleTime = now;
11399 mLowRamTimeSinceLastIdle = 0;
11400 if (mLowRamStartTime != 0) {
11401 mLowRamStartTime = now;
11404 StringBuilder sb = new StringBuilder(128);
11405 sb.append("Idle maintenance over ");
11406 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11407 sb.append(" low RAM for ");
11408 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11409 Slog.i(TAG, sb.toString());
11411 // If at least 1/3 of our time since the last idle period has been spent
11412 // with RAM low, then we want to kill processes.
11413 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11415 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11416 ProcessRecord proc = mLruProcesses.get(i);
11417 if (proc.notCachedSinceIdle) {
11418 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11419 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11420 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11421 if (doKilling && proc.initialIdlePss != 0
11422 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11423 sb = new StringBuilder(128);
11425 sb.append(proc.processName);
11426 sb.append(" in idle maint: pss=");
11427 sb.append(proc.lastPss);
11428 sb.append(", initialPss=");
11429 sb.append(proc.initialIdlePss);
11430 sb.append(", period=");
11431 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11432 sb.append(", lowRamPeriod=");
11433 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11434 Slog.wtfQuiet(TAG, sb.toString());
11435 proc.kill("idle maint (pss " + proc.lastPss
11436 + " from " + proc.initialIdlePss + ")", true);
11439 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11440 proc.notCachedSinceIdle = true;
11441 proc.initialIdlePss = 0;
11442 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11443 mTestPssMode, isSleeping(), now);
11447 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11448 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11452 private void retrieveSettings() {
11453 final ContentResolver resolver = mContext.getContentResolver();
11454 String debugApp = Settings.Global.getString(
11455 resolver, Settings.Global.DEBUG_APP);
11456 boolean waitForDebugger = Settings.Global.getInt(
11457 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11458 boolean alwaysFinishActivities = Settings.Global.getInt(
11459 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11460 boolean forceRtl = Settings.Global.getInt(
11461 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11462 // Transfer any global setting for forcing RTL layout, into a System Property
11463 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11465 Configuration configuration = new Configuration();
11466 Settings.System.getConfiguration(resolver, configuration);
11468 // This will take care of setting the correct layout direction flags
11469 configuration.setLayoutDirection(configuration.locale);
11472 synchronized (this) {
11473 mDebugApp = mOrigDebugApp = debugApp;
11474 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11475 mAlwaysFinishActivities = alwaysFinishActivities;
11476 // This happens before any activities are started, so we can
11477 // change mConfiguration in-place.
11478 updateConfigurationLocked(configuration, null, false, true);
11479 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11480 "Initial config: " + mConfiguration);
11484 /** Loads resources after the current configuration has been set. */
11485 private void loadResourcesOnSystemReady() {
11486 final Resources res = mContext.getResources();
11487 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11488 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11489 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11492 public boolean testIsSystemReady() {
11493 // no need to synchronize(this) just to read & return the value
11494 return mSystemReady;
11497 private static File getCalledPreBootReceiversFile() {
11498 File dataDir = Environment.getDataDirectory();
11499 File systemDir = new File(dataDir, "system");
11500 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11504 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11505 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11506 File file = getCalledPreBootReceiversFile();
11507 FileInputStream fis = null;
11509 fis = new FileInputStream(file);
11510 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11511 int fvers = dis.readInt();
11512 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11513 String vers = dis.readUTF();
11514 String codename = dis.readUTF();
11515 String build = dis.readUTF();
11516 if (android.os.Build.VERSION.RELEASE.equals(vers)
11517 && android.os.Build.VERSION.CODENAME.equals(codename)
11518 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11519 int num = dis.readInt();
11522 String pkg = dis.readUTF();
11523 String cls = dis.readUTF();
11524 lastDoneReceivers.add(new ComponentName(pkg, cls));
11528 } catch (FileNotFoundException e) {
11529 } catch (IOException e) {
11530 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11535 } catch (IOException e) {
11539 return lastDoneReceivers;
11542 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11543 File file = getCalledPreBootReceiversFile();
11544 FileOutputStream fos = null;
11545 DataOutputStream dos = null;
11547 fos = new FileOutputStream(file);
11548 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11549 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11550 dos.writeUTF(android.os.Build.VERSION.RELEASE);
11551 dos.writeUTF(android.os.Build.VERSION.CODENAME);
11552 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11553 dos.writeInt(list.size());
11554 for (int i=0; i<list.size(); i++) {
11555 dos.writeUTF(list.get(i).getPackageName());
11556 dos.writeUTF(list.get(i).getClassName());
11558 } catch (IOException e) {
11559 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11562 FileUtils.sync(fos);
11566 } catch (IOException e) {
11567 // TODO Auto-generated catch block
11568 e.printStackTrace();
11574 final class PreBootContinuation extends IIntentReceiver.Stub {
11575 final Intent intent;
11576 final Runnable onFinishCallback;
11577 final ArrayList<ComponentName> doneReceivers;
11578 final List<ResolveInfo> ris;
11584 PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11585 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11587 onFinishCallback = _onFinishCallback;
11588 doneReceivers = _doneReceivers;
11594 if (lastRi != curRi) {
11595 ActivityInfo ai = ris.get(curRi).activityInfo;
11596 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11597 intent.setComponent(comp);
11598 doneReceivers.add(comp);
11600 CharSequence label = ai.loadLabel(mContext.getPackageManager());
11601 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11603 Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11604 + " for user " + users[curUser]);
11605 EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11606 broadcastIntentLocked(null, null, intent, null, this,
11607 0, null, null, null, AppOpsManager.OP_NONE,
11608 null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11611 public void performReceive(Intent intent, int resultCode,
11612 String data, Bundle extras, boolean ordered,
11613 boolean sticky, int sendingUser) {
11615 if (curUser >= users.length) {
11618 if (curRi >= ris.size()) {
11619 // All done sending broadcasts!
11620 if (onFinishCallback != null) {
11621 // The raw IIntentReceiver interface is called
11622 // with the AM lock held, so redispatch to
11623 // execute our code without the lock.
11624 mHandler.post(onFinishCallback);
11633 private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11634 ArrayList<ComponentName> doneReceivers, int userId) {
11635 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11636 List<ResolveInfo> ris = null;
11638 ris = AppGlobals.getPackageManager().queryIntentReceivers(
11639 intent, null, 0, userId);
11640 } catch (RemoteException e) {
11645 for (int i=ris.size()-1; i>=0; i--) {
11646 if ((ris.get(i).activityInfo.applicationInfo.flags
11647 &ApplicationInfo.FLAG_SYSTEM) == 0) {
11651 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11653 // For User 0, load the version number. When delivering to a new user, deliver
11654 // to all receivers.
11655 if (userId == UserHandle.USER_OWNER) {
11656 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11657 for (int i=0; i<ris.size(); i++) {
11658 ActivityInfo ai = ris.get(i).activityInfo;
11659 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11660 if (lastDoneReceivers.contains(comp)) {
11661 // We already did the pre boot receiver for this app with the current
11662 // platform version, so don't do it again...
11665 // ...however, do keep it as one that has been done, so we don't
11666 // forget about it when rewriting the file of last done receivers.
11667 doneReceivers.add(comp);
11672 if (ris.size() <= 0) {
11676 // If primary user, send broadcast to all available users, else just to userId
11677 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11678 : new int[] { userId };
11679 if (users.length <= 0) {
11683 PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11689 public void systemReady(final Runnable goingCallback) {
11690 synchronized(this) {
11691 if (mSystemReady) {
11692 // If we're done calling all the receivers, run the next "boot phase" passed in
11693 // by the SystemServer
11694 if (goingCallback != null) {
11695 goingCallback.run();
11700 mLocalDeviceIdleController
11701 = LocalServices.getService(DeviceIdleController.LocalService.class);
11703 // Make sure we have the current profile info, since it is needed for
11704 // security checks.
11705 updateCurrentProfileIdsLocked();
11707 mRecentTasks.clear();
11708 mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11709 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11710 mTaskPersister.startPersisting();
11712 // Check to see if there are any update receivers to run.
11714 if (mWaitingUpdate) {
11717 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11718 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11719 public void run() {
11720 synchronized (ActivityManagerService.this) {
11723 showBootMessage(mContext.getText(
11724 R.string.android_upgrading_complete),
11726 writeLastDonePreBootReceivers(doneReceivers);
11727 systemReady(goingCallback);
11729 }, doneReceivers, UserHandle.USER_OWNER);
11731 if (mWaitingUpdate) {
11737 mAppOpsService.systemReady();
11738 mSystemReady = true;
11741 ArrayList<ProcessRecord> procsToKill = null;
11742 synchronized(mPidsSelfLocked) {
11743 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11744 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11745 if (!isAllowedWhileBooting(proc.info)){
11746 if (procsToKill == null) {
11747 procsToKill = new ArrayList<ProcessRecord>();
11749 procsToKill.add(proc);
11754 synchronized(this) {
11755 if (procsToKill != null) {
11756 for (int i=procsToKill.size()-1; i>=0; i--) {
11757 ProcessRecord proc = procsToKill.get(i);
11758 Slog.i(TAG, "Removing system update proc: " + proc);
11759 removeProcessLocked(proc, true, false, "system update done");
11763 // Now that we have cleaned up any update processes, we
11764 // are ready to start launching real processes and know that
11765 // we won't trample on them any more.
11766 mProcessesReady = true;
11769 Slog.i(TAG, "System now ready");
11770 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11771 SystemClock.uptimeMillis());
11773 synchronized(this) {
11774 // Make sure we have no pre-ready processes sitting around.
11776 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11777 ResolveInfo ri = mContext.getPackageManager()
11778 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11780 CharSequence errorMsg = null;
11782 ActivityInfo ai = ri.activityInfo;
11783 ApplicationInfo app = ai.applicationInfo;
11784 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11785 mTopAction = Intent.ACTION_FACTORY_TEST;
11787 mTopComponent = new ComponentName(app.packageName,
11790 errorMsg = mContext.getResources().getText(
11791 com.android.internal.R.string.factorytest_not_system);
11794 errorMsg = mContext.getResources().getText(
11795 com.android.internal.R.string.factorytest_no_action);
11797 if (errorMsg != null) {
11800 mTopComponent = null;
11801 Message msg = Message.obtain();
11802 msg.what = SHOW_FACTORY_ERROR_MSG;
11803 msg.getData().putCharSequence("msg", errorMsg);
11804 mUiHandler.sendMessage(msg);
11809 retrieveSettings();
11810 loadResourcesOnSystemReady();
11812 synchronized (this) {
11813 readGrantedUriPermissionsLocked();
11816 if (goingCallback != null) goingCallback.run();
11818 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11819 Integer.toString(mCurrentUserId), mCurrentUserId);
11820 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11821 Integer.toString(mCurrentUserId), mCurrentUserId);
11822 mSystemServiceManager.startUser(mCurrentUserId);
11824 synchronized (this) {
11825 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11827 List apps = AppGlobals.getPackageManager().
11828 getPersistentApplications(STOCK_PM_FLAGS);
11829 if (apps != null) {
11830 int N = apps.size();
11832 for (i=0; i<N; i++) {
11833 ApplicationInfo info
11834 = (ApplicationInfo)apps.get(i);
11835 if (info != null &&
11836 !info.packageName.equals("android")) {
11837 addAppLocked(info, false, null /* ABI override */);
11841 } catch (RemoteException ex) {
11842 // pm is in same process, this will never happen.
11846 // Start up initial activity.
11848 startHomeActivityLocked(mCurrentUserId, "systemReady");
11851 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11852 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11853 + " data partition or your device will be unstable.");
11854 mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11856 } catch (RemoteException e) {
11859 if (!Build.isBuildConsistent()) {
11860 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11861 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11864 long ident = Binder.clearCallingIdentity();
11866 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11867 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11868 | Intent.FLAG_RECEIVER_FOREGROUND);
11869 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11870 broadcastIntentLocked(null, null, intent,
11871 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11872 null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11873 intent = new Intent(Intent.ACTION_USER_STARTING);
11874 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11875 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11876 broadcastIntentLocked(null, null, intent,
11877 null, new IIntentReceiver.Stub() {
11879 public void performReceive(Intent intent, int resultCode, String data,
11880 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11881 throws RemoteException {
11884 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11885 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11886 } catch (Throwable t) {
11887 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11889 Binder.restoreCallingIdentity(ident);
11891 mStackSupervisor.resumeTopActivitiesLocked();
11892 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11896 private boolean makeAppCrashingLocked(ProcessRecord app,
11897 String shortMsg, String longMsg, String stackTrace) {
11898 app.crashing = true;
11899 app.crashingReport = generateProcessError(app,
11900 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11901 startAppProblemLocked(app);
11902 app.stopFreezingAllLocked();
11903 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11906 private void makeAppNotRespondingLocked(ProcessRecord app,
11907 String activity, String shortMsg, String longMsg) {
11908 app.notResponding = true;
11909 app.notRespondingReport = generateProcessError(app,
11910 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11911 activity, shortMsg, longMsg, null);
11912 startAppProblemLocked(app);
11913 app.stopFreezingAllLocked();
11917 * Generate a process error record, suitable for attachment to a ProcessRecord.
11919 * @param app The ProcessRecord in which the error occurred.
11920 * @param condition Crashing, Application Not Responding, etc. Values are defined in
11921 * ActivityManager.AppErrorStateInfo
11922 * @param activity The activity associated with the crash, if known.
11923 * @param shortMsg Short message describing the crash.
11924 * @param longMsg Long message describing the crash.
11925 * @param stackTrace Full crash stack trace, may be null.
11927 * @return Returns a fully-formed AppErrorStateInfo record.
11929 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11930 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11931 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11933 report.condition = condition;
11934 report.processName = app.processName;
11935 report.pid = app.pid;
11936 report.uid = app.info.uid;
11937 report.tag = activity;
11938 report.shortMsg = shortMsg;
11939 report.longMsg = longMsg;
11940 report.stackTrace = stackTrace;
11945 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11946 synchronized (this) {
11947 app.crashing = false;
11948 app.crashingReport = null;
11949 app.notResponding = false;
11950 app.notRespondingReport = null;
11951 if (app.anrDialog == fromDialog) {
11952 app.anrDialog = null;
11954 if (app.waitDialog == fromDialog) {
11955 app.waitDialog = null;
11957 if (app.pid > 0 && app.pid != MY_PID) {
11958 handleAppCrashLocked(app, "user-terminated" /*reason*/,
11959 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11960 app.kill("user request after error", true);
11965 private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11966 String shortMsg, String longMsg, String stackTrace) {
11967 long now = SystemClock.uptimeMillis();
11970 if (!app.isolated) {
11971 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11975 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11976 // This process loses!
11977 Slog.w(TAG, "Process " + app.info.processName
11978 + " has crashed too many times: killing!");
11979 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11980 app.userId, app.info.processName, app.uid);
11981 mStackSupervisor.handleAppCrashLocked(app);
11982 if (!app.persistent) {
11983 // We don't want to start this process again until the user
11984 // explicitly does so... but for persistent process, we really
11985 // need to keep it running. If a persistent process is actually
11986 // repeatedly crashing, then badness for everyone.
11987 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11988 app.info.processName);
11989 if (!app.isolated) {
11990 // XXX We don't have a way to mark isolated processes
11991 // as bad, since they don't have a peristent identity.
11992 mBadProcesses.put(app.info.processName, app.uid,
11993 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11994 mProcessCrashTimes.remove(app.info.processName, app.uid);
11997 app.removed = true;
11998 // Don't let services in this process be restarted and potentially
11999 // annoy the user repeatedly. Unless it is persistent, since those
12000 // processes run critical code.
12001 removeProcessLocked(app, false, false, "crash");
12002 mStackSupervisor.resumeTopActivitiesLocked();
12005 mStackSupervisor.resumeTopActivitiesLocked();
12007 mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12010 // Bump up the crash count of any services currently running in the proc.
12011 for (int i=app.services.size()-1; i>=0; i--) {
12012 // Any services running in the application need to be placed
12013 // back in the pending list.
12014 ServiceRecord sr = app.services.valueAt(i);
12018 // If the crashing process is what we consider to be the "home process" and it has been
12019 // replaced by a third-party app, clear the package preferred activities from packages
12020 // with a home activity running in the process to prevent a repeatedly crashing app
12021 // from blocking the user to manually clear the list.
12022 final ArrayList<ActivityRecord> activities = app.activities;
12023 if (app == mHomeProcess && activities.size() > 0
12024 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12025 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12026 final ActivityRecord r = activities.get(activityNdx);
12027 if (r.isHomeActivity()) {
12028 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12030 ActivityThread.getPackageManager()
12031 .clearPackagePreferredActivities(r.packageName);
12032 } catch (RemoteException c) {
12033 // pm is in same process, this will never happen.
12039 if (!app.isolated) {
12040 // XXX Can't keep track of crash times for isolated processes,
12041 // because they don't have a perisistent identity.
12042 mProcessCrashTimes.put(app.info.processName, app.uid, now);
12045 if (app.crashHandler != null) mHandler.post(app.crashHandler);
12049 void startAppProblemLocked(ProcessRecord app) {
12050 // If this app is not running under the current user, then we
12051 // can't give it a report button because that would require
12052 // launching the report UI under a different user.
12053 app.errorReportReceiver = null;
12055 for (int userId : mCurrentProfileIds) {
12056 if (app.userId == userId) {
12057 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12058 mContext, app.info.packageName, app.info.flags);
12061 skipCurrentReceiverLocked(app);
12064 void skipCurrentReceiverLocked(ProcessRecord app) {
12065 for (BroadcastQueue queue : mBroadcastQueues) {
12066 queue.skipCurrentReceiverLocked(app);
12071 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12072 * The application process will exit immediately after this call returns.
12073 * @param app object of the crashing app, null for the system server
12074 * @param crashInfo describing the exception
12076 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12077 ProcessRecord r = findAppProcess(app, "Crash");
12078 final String processName = app == null ? "system_server"
12079 : (r == null ? "unknown" : r.processName);
12081 handleApplicationCrashInner("crash", r, processName, crashInfo);
12084 /* Native crash reporting uses this inner version because it needs to be somewhat
12085 * decoupled from the AM-managed cleanup lifecycle
12087 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12088 ApplicationErrorReport.CrashInfo crashInfo) {
12089 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12090 UserHandle.getUserId(Binder.getCallingUid()), processName,
12091 r == null ? -1 : r.info.flags,
12092 crashInfo.exceptionClassName,
12093 crashInfo.exceptionMessage,
12094 crashInfo.throwFileName,
12095 crashInfo.throwLineNumber);
12097 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12099 crashApplication(r, crashInfo);
12102 public void handleApplicationStrictModeViolation(
12105 StrictMode.ViolationInfo info) {
12106 ProcessRecord r = findAppProcess(app, "StrictMode");
12111 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12112 Integer stackFingerprint = info.hashCode();
12113 boolean logIt = true;
12114 synchronized (mAlreadyLoggedViolatedStacks) {
12115 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12117 // TODO: sub-sample into EventLog for these, with
12118 // the info.durationMillis? Then we'd get
12119 // the relative pain numbers, without logging all
12120 // the stack traces repeatedly. We'd want to do
12121 // likewise in the client code, which also does
12122 // dup suppression, before the Binder call.
12124 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12125 mAlreadyLoggedViolatedStacks.clear();
12127 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12131 logStrictModeViolationToDropBox(r, info);
12135 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12136 AppErrorResult result = new AppErrorResult();
12137 synchronized (this) {
12138 final long origId = Binder.clearCallingIdentity();
12140 Message msg = Message.obtain();
12141 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12142 HashMap<String, Object> data = new HashMap<String, Object>();
12143 data.put("result", result);
12144 data.put("app", r);
12145 data.put("violationMask", violationMask);
12146 data.put("info", info);
12148 mUiHandler.sendMessage(msg);
12150 Binder.restoreCallingIdentity(origId);
12152 int res = result.get();
12153 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12157 // Depending on the policy in effect, there could be a bunch of
12158 // these in quick succession so we try to batch these together to
12159 // minimize disk writes, number of dropbox entries, and maximize
12160 // compression, by having more fewer, larger records.
12161 private void logStrictModeViolationToDropBox(
12162 ProcessRecord process,
12163 StrictMode.ViolationInfo info) {
12164 if (info == null) {
12167 final boolean isSystemApp = process == null ||
12168 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12169 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12170 final String processName = process == null ? "unknown" : process.processName;
12171 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12172 final DropBoxManager dbox = (DropBoxManager)
12173 mContext.getSystemService(Context.DROPBOX_SERVICE);
12175 // Exit early if the dropbox isn't configured to accept this report type.
12176 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12178 boolean bufferWasEmpty;
12179 boolean needsFlush;
12180 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12181 synchronized (sb) {
12182 bufferWasEmpty = sb.length() == 0;
12183 appendDropBoxProcessHeaders(process, processName, sb);
12184 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12185 sb.append("System-App: ").append(isSystemApp).append("\n");
12186 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12187 if (info.violationNumThisLoop != 0) {
12188 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12190 if (info.numAnimationsRunning != 0) {
12191 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12193 if (info.broadcastIntentAction != null) {
12194 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12196 if (info.durationMillis != -1) {
12197 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12199 if (info.numInstances != -1) {
12200 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12202 if (info.tags != null) {
12203 for (String tag : info.tags) {
12204 sb.append("Span-Tag: ").append(tag).append("\n");
12208 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12209 sb.append(info.crashInfo.stackTrace);
12212 if (info.message != null) {
12213 sb.append(info.message);
12217 // Only buffer up to ~64k. Various logging bits truncate
12219 needsFlush = (sb.length() > 64 * 1024);
12222 // Flush immediately if the buffer's grown too large, or this
12223 // is a non-system app. Non-system apps are isolated with a
12224 // different tag & policy and not batched.
12226 // Batching is useful during internal testing with
12227 // StrictMode settings turned up high. Without batching,
12228 // thousands of separate files could be created on boot.
12229 if (!isSystemApp || needsFlush) {
12230 new Thread("Error dump: " + dropboxTag) {
12232 public void run() {
12234 synchronized (sb) {
12235 report = sb.toString();
12236 sb.delete(0, sb.length());
12239 if (report.length() != 0) {
12240 dbox.addText(dropboxTag, report);
12247 // System app batching:
12248 if (!bufferWasEmpty) {
12249 // An existing dropbox-writing thread is outstanding, so
12250 // we don't need to start it up. The existing thread will
12251 // catch the buffer appends we just did.
12255 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12256 // (After this point, we shouldn't access AMS internal data structures.)
12257 new Thread("Error dump: " + dropboxTag) {
12259 public void run() {
12260 // 5 second sleep to let stacks arrive and be batched together
12262 Thread.sleep(5000); // 5 seconds
12263 } catch (InterruptedException e) {}
12265 String errorReport;
12266 synchronized (mStrictModeBuffer) {
12267 errorReport = mStrictModeBuffer.toString();
12268 if (errorReport.length() == 0) {
12271 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12272 mStrictModeBuffer.trimToSize();
12274 dbox.addText(dropboxTag, errorReport);
12280 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12281 * @param app object of the crashing app, null for the system server
12282 * @param tag reported by the caller
12283 * @param system whether this wtf is coming from the system
12284 * @param crashInfo describing the context of the error
12285 * @return true if the process should exit immediately (WTF is fatal)
12287 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12288 final ApplicationErrorReport.CrashInfo crashInfo) {
12289 final int callingUid = Binder.getCallingUid();
12290 final int callingPid = Binder.getCallingPid();
12293 // If this is coming from the system, we could very well have low-level
12294 // system locks held, so we want to do this all asynchronously. And we
12295 // never want this to become fatal, so there is that too.
12296 mHandler.post(new Runnable() {
12297 @Override public void run() {
12298 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12304 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12307 if (r != null && r.pid != Process.myPid() &&
12308 Settings.Global.getInt(mContext.getContentResolver(),
12309 Settings.Global.WTF_IS_FATAL, 0) != 0) {
12310 crashApplication(r, crashInfo);
12317 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12318 final ApplicationErrorReport.CrashInfo crashInfo) {
12319 final ProcessRecord r = findAppProcess(app, "WTF");
12320 final String processName = app == null ? "system_server"
12321 : (r == null ? "unknown" : r.processName);
12323 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12324 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12326 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12332 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12333 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12335 private ProcessRecord findAppProcess(IBinder app, String reason) {
12340 synchronized (this) {
12341 final int NP = mProcessNames.getMap().size();
12342 for (int ip=0; ip<NP; ip++) {
12343 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12344 final int NA = apps.size();
12345 for (int ia=0; ia<NA; ia++) {
12346 ProcessRecord p = apps.valueAt(ia);
12347 if (p.thread != null && p.thread.asBinder() == app) {
12353 Slog.w(TAG, "Can't find mystery application for " + reason
12354 + " from pid=" + Binder.getCallingPid()
12355 + " uid=" + Binder.getCallingUid() + ": " + app);
12361 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12362 * to append various headers to the dropbox log text.
12364 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12365 StringBuilder sb) {
12366 // Watchdog thread ends up invoking this function (with
12367 // a null ProcessRecord) to add the stack file to dropbox.
12368 // Do not acquire a lock on this (am) in such cases, as it
12369 // could cause a potential deadlock, if and when watchdog
12370 // is invoked due to unavailability of lock on am and it
12371 // would prevent watchdog from killing system_server.
12372 if (process == null) {
12373 sb.append("Process: ").append(processName).append("\n");
12376 // Note: ProcessRecord 'process' is guarded by the service
12377 // instance. (notably process.pkgList, which could otherwise change
12378 // concurrently during execution of this method)
12379 synchronized (this) {
12380 sb.append("Process: ").append(processName).append("\n");
12381 int flags = process.info.flags;
12382 IPackageManager pm = AppGlobals.getPackageManager();
12383 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12384 for (int ip=0; ip<process.pkgList.size(); ip++) {
12385 String pkg = process.pkgList.keyAt(ip);
12386 sb.append("Package: ").append(pkg);
12388 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12390 sb.append(" v").append(pi.versionCode);
12391 if (pi.versionName != null) {
12392 sb.append(" (").append(pi.versionName).append(")");
12395 } catch (RemoteException e) {
12396 Slog.e(TAG, "Error getting package info: " + pkg, e);
12403 private static String processClass(ProcessRecord process) {
12404 if (process == null || process.pid == MY_PID) {
12405 return "system_server";
12406 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12407 return "system_app";
12414 * Write a description of an error (crash, WTF, ANR) to the drop box.
12415 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12416 * @param process which caused the error, null means the system server
12417 * @param activity which triggered the error, null if unknown
12418 * @param parent activity related to the error, null if unknown
12419 * @param subject line related to the error, null if absent
12420 * @param report in long form describing the error, null if absent
12421 * @param logFile to include in the report, null if none
12422 * @param crashInfo giving an application stack trace, null if absent
12424 public void addErrorToDropBox(String eventType,
12425 ProcessRecord process, String processName, ActivityRecord activity,
12426 ActivityRecord parent, String subject,
12427 final String report, final File logFile,
12428 final ApplicationErrorReport.CrashInfo crashInfo) {
12429 // NOTE -- this must never acquire the ActivityManagerService lock,
12430 // otherwise the watchdog may be prevented from resetting the system.
12432 final String dropboxTag = processClass(process) + "_" + eventType;
12433 final DropBoxManager dbox = (DropBoxManager)
12434 mContext.getSystemService(Context.DROPBOX_SERVICE);
12436 // Exit early if the dropbox isn't configured to accept this report type.
12437 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12439 final StringBuilder sb = new StringBuilder(1024);
12440 appendDropBoxProcessHeaders(process, processName, sb);
12441 if (activity != null) {
12442 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12444 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12445 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12447 if (parent != null && parent != activity) {
12448 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12450 if (subject != null) {
12451 sb.append("Subject: ").append(subject).append("\n");
12453 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12454 if (Debug.isDebuggerConnected()) {
12455 sb.append("Debugger: Connected\n");
12459 // Do the rest in a worker thread to avoid blocking the caller on I/O
12460 // (After this point, we shouldn't access AMS internal data structures.)
12461 Thread worker = new Thread("Error dump: " + dropboxTag) {
12463 public void run() {
12464 if (report != null) {
12467 if (logFile != null) {
12469 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12470 "\n\n[[TRUNCATED]]"));
12471 } catch (IOException e) {
12472 Slog.e(TAG, "Error reading " + logFile, e);
12475 if (crashInfo != null && crashInfo.stackTrace != null) {
12476 sb.append(crashInfo.stackTrace);
12479 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12480 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12484 // Merge several logcat streams, and take the last N lines
12485 InputStreamReader input = null;
12487 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12488 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12490 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12492 try { logcat.getOutputStream().close(); } catch (IOException e) {}
12493 try { logcat.getErrorStream().close(); } catch (IOException e) {}
12494 input = new InputStreamReader(logcat.getInputStream());
12497 char[] buf = new char[8192];
12498 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12499 } catch (IOException e) {
12500 Slog.e(TAG, "Error running logcat", e);
12502 if (input != null) try { input.close(); } catch (IOException e) {}
12506 dbox.addText(dropboxTag, sb.toString());
12510 if (process == null) {
12511 // If process is null, we are being called from some internal code
12512 // and may be about to die -- run this synchronously.
12520 * Bring up the "unexpected error" dialog box for a crashing app.
12521 * Deal with edge cases (intercepts from instrumented applications,
12522 * ActivityController, error intent receivers, that sort of thing).
12523 * @param r the application crashing
12524 * @param crashInfo describing the failure
12526 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12527 long timeMillis = System.currentTimeMillis();
12528 String shortMsg = crashInfo.exceptionClassName;
12529 String longMsg = crashInfo.exceptionMessage;
12530 String stackTrace = crashInfo.stackTrace;
12531 if (shortMsg != null && longMsg != null) {
12532 longMsg = shortMsg + ": " + longMsg;
12533 } else if (shortMsg != null) {
12534 longMsg = shortMsg;
12537 AppErrorResult result = new AppErrorResult();
12538 synchronized (this) {
12539 if (mController != null) {
12541 String name = r != null ? r.processName : null;
12542 int pid = r != null ? r.pid : Binder.getCallingPid();
12543 int uid = r != null ? r.info.uid : Binder.getCallingUid();
12544 if (!mController.appCrashed(name, pid,
12545 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12546 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12547 && "Native crash".equals(crashInfo.exceptionClassName)) {
12548 Slog.w(TAG, "Skip killing native crashed app " + name
12549 + "(" + pid + ") during testing");
12551 Slog.w(TAG, "Force-killing crashed app " + name
12552 + " at watcher's request");
12554 r.kill("crash", true);
12557 Process.killProcess(pid);
12558 killProcessGroup(uid, pid);
12563 } catch (RemoteException e) {
12564 mController = null;
12565 Watchdog.getInstance().setActivityController(null);
12569 final long origId = Binder.clearCallingIdentity();
12571 // If this process is running instrumentation, finish it.
12572 if (r != null && r.instrumentationClass != null) {
12573 Slog.w(TAG, "Error in app " + r.processName
12574 + " running instrumentation " + r.instrumentationClass + ":");
12575 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
12576 if (longMsg != null) Slog.w(TAG, " " + longMsg);
12577 Bundle info = new Bundle();
12578 info.putString("shortMsg", shortMsg);
12579 info.putString("longMsg", longMsg);
12580 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12581 Binder.restoreCallingIdentity(origId);
12585 // Log crash in battery stats.
12587 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12590 // If we can't identify the process or it's already exceeded its crash quota,
12591 // quit right away without showing a crash dialog.
12592 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12593 Binder.restoreCallingIdentity(origId);
12597 Message msg = Message.obtain();
12598 msg.what = SHOW_ERROR_MSG;
12599 HashMap data = new HashMap();
12600 data.put("result", result);
12601 data.put("app", r);
12603 mUiHandler.sendMessage(msg);
12605 Binder.restoreCallingIdentity(origId);
12608 int res = result.get();
12610 Intent appErrorIntent = null;
12611 synchronized (this) {
12612 if (r != null && !r.isolated) {
12613 // XXX Can't keep track of crash time for isolated processes,
12614 // since they don't have a persistent identity.
12615 mProcessCrashTimes.put(r.info.processName, r.uid,
12616 SystemClock.uptimeMillis());
12618 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12619 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12623 if (appErrorIntent != null) {
12625 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12626 } catch (ActivityNotFoundException e) {
12627 Slog.w(TAG, "bug report receiver dissappeared", e);
12632 Intent createAppErrorIntentLocked(ProcessRecord r,
12633 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12634 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12635 if (report == null) {
12638 Intent result = new Intent(Intent.ACTION_APP_ERROR);
12639 result.setComponent(r.errorReportReceiver);
12640 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12641 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12645 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12646 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12647 if (r.errorReportReceiver == null) {
12651 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12655 ApplicationErrorReport report = new ApplicationErrorReport();
12656 report.packageName = r.info.packageName;
12657 report.installerPackageName = r.errorReportReceiver.getPackageName();
12658 report.processName = r.processName;
12659 report.time = timeMillis;
12660 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12662 if (r.crashing || r.forceCrashReport) {
12663 report.type = ApplicationErrorReport.TYPE_CRASH;
12664 report.crashInfo = crashInfo;
12665 } else if (r.notResponding) {
12666 report.type = ApplicationErrorReport.TYPE_ANR;
12667 report.anrInfo = new ApplicationErrorReport.AnrInfo();
12669 report.anrInfo.activity = r.notRespondingReport.tag;
12670 report.anrInfo.cause = r.notRespondingReport.shortMsg;
12671 report.anrInfo.info = r.notRespondingReport.longMsg;
12677 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12678 enforceNotIsolatedCaller("getProcessesInErrorState");
12679 // assume our apps are happy - lazy create the list
12680 List<ActivityManager.ProcessErrorStateInfo> errList = null;
12682 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12683 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12684 int userId = UserHandle.getUserId(Binder.getCallingUid());
12686 synchronized (this) {
12688 // iterate across all processes
12689 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12690 ProcessRecord app = mLruProcesses.get(i);
12691 if (!allUsers && app.userId != userId) {
12694 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12695 // This one's in trouble, so we'll generate a report for it
12696 // crashes are higher priority (in case there's a crash *and* an anr)
12697 ActivityManager.ProcessErrorStateInfo report = null;
12698 if (app.crashing) {
12699 report = app.crashingReport;
12700 } else if (app.notResponding) {
12701 report = app.notRespondingReport;
12704 if (report != null) {
12705 if (errList == null) {
12706 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12708 errList.add(report);
12710 Slog.w(TAG, "Missing app error report, app = " + app.processName +
12711 " crashing = " + app.crashing +
12712 " notResponding = " + app.notResponding);
12721 static int procStateToImportance(int procState, int memAdj,
12722 ActivityManager.RunningAppProcessInfo currApp) {
12723 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12724 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12725 currApp.lru = memAdj;
12732 private void fillInProcMemInfo(ProcessRecord app,
12733 ActivityManager.RunningAppProcessInfo outInfo) {
12734 outInfo.pid = app.pid;
12735 outInfo.uid = app.info.uid;
12736 if (mHeavyWeightProcess == app) {
12737 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12739 if (app.persistent) {
12740 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12742 if (app.activities.size() > 0) {
12743 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12745 outInfo.lastTrimLevel = app.trimMemoryLevel;
12746 int adj = app.curAdj;
12747 int procState = app.curProcState;
12748 outInfo.importance = procStateToImportance(procState, adj, outInfo);
12749 outInfo.importanceReasonCode = app.adjTypeCode;
12750 outInfo.processState = app.curProcState;
12753 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12754 enforceNotIsolatedCaller("getRunningAppProcesses");
12756 final int callingUid = Binder.getCallingUid();
12758 // Lazy instantiation of list
12759 List<ActivityManager.RunningAppProcessInfo> runList = null;
12760 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12761 callingUid) == PackageManager.PERMISSION_GRANTED;
12762 final int userId = UserHandle.getUserId(callingUid);
12763 final boolean allUids = isGetTasksAllowed(
12764 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12766 synchronized (this) {
12767 // Iterate across all processes
12768 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12769 ProcessRecord app = mLruProcesses.get(i);
12770 if ((!allUsers && app.userId != userId)
12771 || (!allUids && app.uid != callingUid)) {
12774 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12775 // Generate process state info for running application
12776 ActivityManager.RunningAppProcessInfo currApp =
12777 new ActivityManager.RunningAppProcessInfo(app.processName,
12778 app.pid, app.getPackageList());
12779 fillInProcMemInfo(app, currApp);
12780 if (app.adjSource instanceof ProcessRecord) {
12781 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12782 currApp.importanceReasonImportance =
12783 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12784 app.adjSourceProcState);
12785 } else if (app.adjSource instanceof ActivityRecord) {
12786 ActivityRecord r = (ActivityRecord)app.adjSource;
12787 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12789 if (app.adjTarget instanceof ComponentName) {
12790 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12792 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12793 // + " lru=" + currApp.lru);
12794 if (runList == null) {
12795 runList = new ArrayList<>();
12797 runList.add(currApp);
12804 public List<ApplicationInfo> getRunningExternalApplications() {
12805 enforceNotIsolatedCaller("getRunningExternalApplications");
12806 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12807 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12808 if (runningApps != null && runningApps.size() > 0) {
12809 Set<String> extList = new HashSet<String>();
12810 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12811 if (app.pkgList != null) {
12812 for (String pkg : app.pkgList) {
12817 IPackageManager pm = AppGlobals.getPackageManager();
12818 for (String pkg : extList) {
12820 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12821 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12824 } catch (RemoteException e) {
12832 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12833 enforceNotIsolatedCaller("getMyMemoryState");
12834 synchronized (this) {
12835 ProcessRecord proc;
12836 synchronized (mPidsSelfLocked) {
12837 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12839 fillInProcMemInfo(proc, outInfo);
12844 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12845 if (checkCallingPermission(android.Manifest.permission.DUMP)
12846 != PackageManager.PERMISSION_GRANTED) {
12847 pw.println("Permission Denial: can't dump ActivityManager from from pid="
12848 + Binder.getCallingPid()
12849 + ", uid=" + Binder.getCallingUid()
12850 + " without permission "
12851 + android.Manifest.permission.DUMP);
12855 boolean dumpAll = false;
12856 boolean dumpClient = false;
12857 String dumpPackage = null;
12860 while (opti < args.length) {
12861 String opt = args[opti];
12862 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12866 if ("-a".equals(opt)) {
12868 } else if ("-c".equals(opt)) {
12870 } else if ("-p".equals(opt)) {
12871 if (opti < args.length) {
12872 dumpPackage = args[opti];
12875 pw.println("Error: -p option requires package argument");
12879 } else if ("-h".equals(opt)) {
12880 pw.println("Activity manager dump options:");
12881 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ...");
12882 pw.println(" cmd may be one of:");
12883 pw.println(" a[ctivities]: activity stack state");
12884 pw.println(" r[recents]: recent activities state");
12885 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12886 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
12887 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
12888 pw.println(" o[om]: out of memory management");
12889 pw.println(" perm[issions]: URI permission grant state");
12890 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
12891 pw.println(" provider [COMP_SPEC]: provider client-side state");
12892 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
12893 pw.println(" as[sociations]: tracked app associations");
12894 pw.println(" service [COMP_SPEC]: service client-side state");
12895 pw.println(" package [PACKAGE_NAME]: all state related to given package");
12896 pw.println(" all: dump all activities");
12897 pw.println(" top: dump the top activity");
12898 pw.println(" write: write all pending state to storage");
12899 pw.println(" track-associations: enable association tracking");
12900 pw.println(" untrack-associations: disable and clear association tracking");
12901 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
12902 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
12903 pw.println(" a partial substring in a component name, a");
12904 pw.println(" hex object identifier.");
12905 pw.println(" -a: include all available server state.");
12906 pw.println(" -c: include client state.");
12907 pw.println(" -p: limit output to given package.");
12910 pw.println("Unknown argument: " + opt + "; use -h for help");
12914 long origId = Binder.clearCallingIdentity();
12915 boolean more = false;
12916 // Is the caller requesting to dump a particular piece of data?
12917 if (opti < args.length) {
12918 String cmd = args[opti];
12920 if ("activities".equals(cmd) || "a".equals(cmd)) {
12921 synchronized (this) {
12922 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12924 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12925 synchronized (this) {
12926 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12928 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12931 if (opti >= args.length) {
12933 newArgs = EMPTY_STRING_ARRAY;
12935 dumpPackage = args[opti];
12937 newArgs = new String[args.length - opti];
12938 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12939 args.length - opti);
12941 synchronized (this) {
12942 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12944 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12947 if (opti >= args.length) {
12949 newArgs = EMPTY_STRING_ARRAY;
12951 dumpPackage = args[opti];
12953 newArgs = new String[args.length - opti];
12954 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12955 args.length - opti);
12957 synchronized (this) {
12958 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12960 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12963 if (opti >= args.length) {
12965 newArgs = EMPTY_STRING_ARRAY;
12967 dumpPackage = args[opti];
12969 newArgs = new String[args.length - opti];
12970 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12971 args.length - opti);
12973 synchronized (this) {
12974 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12976 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12977 synchronized (this) {
12978 dumpOomLocked(fd, pw, args, opti, true);
12980 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
12981 synchronized (this) {
12982 dumpPermissionsLocked(fd, pw, args, opti, true, null);
12984 } else if ("provider".equals(cmd)) {
12987 if (opti >= args.length) {
12989 newArgs = EMPTY_STRING_ARRAY;
12993 newArgs = new String[args.length - opti];
12994 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12996 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12997 pw.println("No providers match: " + name);
12998 pw.println("Use -h for help.");
13000 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13001 synchronized (this) {
13002 dumpProvidersLocked(fd, pw, args, opti, true, null);
13004 } else if ("service".equals(cmd)) {
13007 if (opti >= args.length) {
13009 newArgs = EMPTY_STRING_ARRAY;
13013 newArgs = new String[args.length - opti];
13014 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13015 args.length - opti);
13017 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13018 pw.println("No services match: " + name);
13019 pw.println("Use -h for help.");
13021 } else if ("package".equals(cmd)) {
13023 if (opti >= args.length) {
13024 pw.println("package: no package name specified");
13025 pw.println("Use -h for help.");
13027 dumpPackage = args[opti];
13029 newArgs = new String[args.length - opti];
13030 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13031 args.length - opti);
13036 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13037 synchronized (this) {
13038 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13040 } else if ("services".equals(cmd) || "s".equals(cmd)) {
13041 synchronized (this) {
13042 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13044 } else if ("write".equals(cmd)) {
13045 mTaskPersister.flush();
13046 pw.println("All tasks persisted.");
13048 } else if ("track-associations".equals(cmd)) {
13049 synchronized (this) {
13050 if (!mTrackingAssociations) {
13051 mTrackingAssociations = true;
13052 pw.println("Association tracking started.");
13054 pw.println("Association tracking already enabled.");
13058 } else if ("untrack-associations".equals(cmd)) {
13059 synchronized (this) {
13060 if (mTrackingAssociations) {
13061 mTrackingAssociations = false;
13062 mAssociations.clear();
13063 pw.println("Association tracking stopped.");
13065 pw.println("Association tracking not running.");
13070 // Dumping a single activity?
13071 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13072 pw.println("Bad activity command, or no activities match: " + cmd);
13073 pw.println("Use -h for help.");
13077 Binder.restoreCallingIdentity(origId);
13082 // No piece of data specified, dump everything.
13083 synchronized (this) {
13084 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13087 pw.println("-------------------------------------------------------------------------------");
13089 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13092 pw.println("-------------------------------------------------------------------------------");
13094 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13097 pw.println("-------------------------------------------------------------------------------");
13099 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13102 pw.println("-------------------------------------------------------------------------------");
13104 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13107 pw.println("-------------------------------------------------------------------------------");
13109 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13112 pw.println("-------------------------------------------------------------------------------");
13114 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13115 if (mAssociations.size() > 0) {
13118 pw.println("-------------------------------------------------------------------------------");
13120 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13124 pw.println("-------------------------------------------------------------------------------");
13126 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13128 Binder.restoreCallingIdentity(origId);
13131 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13132 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13133 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13135 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13137 boolean needSep = printedAnything;
13139 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13140 dumpPackage, needSep, " mFocusedActivity: ");
13142 printedAnything = true;
13146 if (dumpPackage == null) {
13151 printedAnything = true;
13152 mStackSupervisor.dump(pw, " ");
13155 if (!printedAnything) {
13156 pw.println(" (nothing)");
13160 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13161 int opti, boolean dumpAll, String dumpPackage) {
13162 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13164 boolean printedAnything = false;
13166 if (mRecentTasks != null && mRecentTasks.size() > 0) {
13167 boolean printedHeader = false;
13169 final int N = mRecentTasks.size();
13170 for (int i=0; i<N; i++) {
13171 TaskRecord tr = mRecentTasks.get(i);
13172 if (dumpPackage != null) {
13173 if (tr.realActivity == null ||
13174 !dumpPackage.equals(tr.realActivity)) {
13178 if (!printedHeader) {
13179 pw.println(" Recent tasks:");
13180 printedHeader = true;
13181 printedAnything = true;
13183 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
13186 mRecentTasks.get(i).dump(pw, " ");
13191 if (!printedAnything) {
13192 pw.println(" (nothing)");
13196 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13197 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13198 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13201 if (dumpPackage != null) {
13202 IPackageManager pm = AppGlobals.getPackageManager();
13204 dumpUid = pm.getPackageUid(dumpPackage, 0);
13205 } catch (RemoteException e) {
13209 boolean printedAnything = false;
13211 final long now = SystemClock.uptimeMillis();
13213 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13214 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13215 = mAssociations.valueAt(i1);
13216 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13217 SparseArray<ArrayMap<String, Association>> sourceUids
13218 = targetComponents.valueAt(i2);
13219 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13220 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13221 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13222 Association ass = sourceProcesses.valueAt(i4);
13223 if (dumpPackage != null) {
13224 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13225 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13229 printedAnything = true;
13231 pw.print(ass.mTargetProcess);
13233 UserHandle.formatUid(pw, ass.mTargetUid);
13235 pw.print(ass.mSourceProcess);
13237 UserHandle.formatUid(pw, ass.mSourceUid);
13240 pw.print(ass.mTargetComponent.flattenToShortString());
13243 long dur = ass.mTime;
13244 if (ass.mNesting > 0) {
13245 dur += now - ass.mStartTime;
13247 TimeUtils.formatDuration(dur, pw);
13249 pw.print(ass.mCount);
13250 pw.println(" times)");
13251 if (ass.mNesting > 0) {
13253 pw.print(" Currently active: ");
13254 TimeUtils.formatDuration(now - ass.mStartTime, pw);
13263 if (!printedAnything) {
13264 pw.println(" (nothing)");
13268 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13269 int opti, boolean dumpAll, String dumpPackage) {
13270 boolean needSep = false;
13271 boolean printedAnything = false;
13274 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13277 final int NP = mProcessNames.getMap().size();
13278 for (int ip=0; ip<NP; ip++) {
13279 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13280 final int NA = procs.size();
13281 for (int ia=0; ia<NA; ia++) {
13282 ProcessRecord r = procs.valueAt(ia);
13283 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13287 pw.println(" All known processes:");
13289 printedAnything = true;
13291 pw.print(r.persistent ? " *PERS*" : " *APP*");
13292 pw.print(" UID "); pw.print(procs.keyAt(ia));
13293 pw.print(" "); pw.println(r);
13295 if (r.persistent) {
13302 if (mIsolatedProcesses.size() > 0) {
13303 boolean printed = false;
13304 for (int i=0; i<mIsolatedProcesses.size(); i++) {
13305 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13306 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13313 pw.println(" Isolated process list (sorted by uid):");
13314 printedAnything = true;
13318 pw.println(String.format("%sIsolated #%2d: %s",
13319 " ", i, r.toString()));
13323 if (mActiveUids.size() > 0) {
13327 pw.println(" UID states:");
13328 for (int i=0; i<mActiveUids.size(); i++) {
13329 UidRecord uidRec = mActiveUids.valueAt(i);
13330 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
13331 pw.print(": "); pw.println(uidRec);
13334 printedAnything = true;
13337 if (mLruProcesses.size() > 0) {
13341 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13342 pw.print(" total, non-act at ");
13343 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13344 pw.print(", non-svc at ");
13345 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13347 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
13349 printedAnything = true;
13352 if (dumpAll || dumpPackage != null) {
13353 synchronized (mPidsSelfLocked) {
13354 boolean printed = false;
13355 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13356 ProcessRecord r = mPidsSelfLocked.valueAt(i);
13357 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13361 if (needSep) pw.println();
13363 pw.println(" PID mappings:");
13365 printedAnything = true;
13367 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13368 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13373 if (mForegroundProcesses.size() > 0) {
13374 synchronized (mPidsSelfLocked) {
13375 boolean printed = false;
13376 for (int i=0; i<mForegroundProcesses.size(); i++) {
13377 ProcessRecord r = mPidsSelfLocked.get(
13378 mForegroundProcesses.valueAt(i).pid);
13379 if (dumpPackage != null && (r == null
13380 || !r.pkgList.containsKey(dumpPackage))) {
13384 if (needSep) pw.println();
13386 pw.println(" Foreground Processes:");
13388 printedAnything = true;
13390 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
13391 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13396 if (mPersistentStartingProcesses.size() > 0) {
13397 if (needSep) pw.println();
13399 printedAnything = true;
13400 pw.println(" Persisent processes that are starting:");
13401 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
13402 "Starting Norm", "Restarting PERS", dumpPackage);
13405 if (mRemovedProcesses.size() > 0) {
13406 if (needSep) pw.println();
13408 printedAnything = true;
13409 pw.println(" Processes that are being removed:");
13410 dumpProcessList(pw, this, mRemovedProcesses, " ",
13411 "Removed Norm", "Removed PERS", dumpPackage);
13414 if (mProcessesOnHold.size() > 0) {
13415 if (needSep) pw.println();
13417 printedAnything = true;
13418 pw.println(" Processes that are on old until the system is ready:");
13419 dumpProcessList(pw, this, mProcessesOnHold, " ",
13420 "OnHold Norm", "OnHold PERS", dumpPackage);
13423 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13425 if (mProcessCrashTimes.getMap().size() > 0) {
13426 boolean printed = false;
13427 long now = SystemClock.uptimeMillis();
13428 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13429 final int NP = pmap.size();
13430 for (int ip=0; ip<NP; ip++) {
13431 String pname = pmap.keyAt(ip);
13432 SparseArray<Long> uids = pmap.valueAt(ip);
13433 final int N = uids.size();
13434 for (int i=0; i<N; i++) {
13435 int puid = uids.keyAt(i);
13436 ProcessRecord r = mProcessNames.get(pname, puid);
13437 if (dumpPackage != null && (r == null
13438 || !r.pkgList.containsKey(dumpPackage))) {
13442 if (needSep) pw.println();
13444 pw.println(" Time since processes crashed:");
13446 printedAnything = true;
13448 pw.print(" Process "); pw.print(pname);
13449 pw.print(" uid "); pw.print(puid);
13450 pw.print(": last crashed ");
13451 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13452 pw.println(" ago");
13457 if (mBadProcesses.getMap().size() > 0) {
13458 boolean printed = false;
13459 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13460 final int NP = pmap.size();
13461 for (int ip=0; ip<NP; ip++) {
13462 String pname = pmap.keyAt(ip);
13463 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13464 final int N = uids.size();
13465 for (int i=0; i<N; i++) {
13466 int puid = uids.keyAt(i);
13467 ProcessRecord r = mProcessNames.get(pname, puid);
13468 if (dumpPackage != null && (r == null
13469 || !r.pkgList.containsKey(dumpPackage))) {
13473 if (needSep) pw.println();
13475 pw.println(" Bad processes:");
13476 printedAnything = true;
13478 BadProcessInfo info = uids.valueAt(i);
13479 pw.print(" Bad process "); pw.print(pname);
13480 pw.print(" uid "); pw.print(puid);
13481 pw.print(": crashed at time "); pw.println(info.time);
13482 if (info.shortMsg != null) {
13483 pw.print(" Short msg: "); pw.println(info.shortMsg);
13485 if (info.longMsg != null) {
13486 pw.print(" Long msg: "); pw.println(info.longMsg);
13488 if (info.stack != null) {
13489 pw.println(" Stack:");
13491 for (int pos=0; pos<info.stack.length(); pos++) {
13492 if (info.stack.charAt(pos) == '\n') {
13494 pw.write(info.stack, lastPos, pos-lastPos);
13499 if (lastPos < info.stack.length()) {
13501 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13509 if (dumpPackage == null) {
13512 pw.println(" mStartedUsers:");
13513 for (int i=0; i<mStartedUsers.size(); i++) {
13514 UserState uss = mStartedUsers.valueAt(i);
13515 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
13516 pw.print(": "); uss.dump("", pw);
13518 pw.print(" mStartedUserArray: [");
13519 for (int i=0; i<mStartedUserArray.length; i++) {
13520 if (i > 0) pw.print(", ");
13521 pw.print(mStartedUserArray[i]);
13524 pw.print(" mUserLru: [");
13525 for (int i=0; i<mUserLru.size(); i++) {
13526 if (i > 0) pw.print(", ");
13527 pw.print(mUserLru.get(i));
13531 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13533 synchronized (mUserProfileGroupIdsSelfLocked) {
13534 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13535 pw.println(" mUserProfileGroupIds:");
13536 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13537 pw.print(" User #");
13538 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13539 pw.print(" -> profile #");
13540 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13545 if (mHomeProcess != null && (dumpPackage == null
13546 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13551 pw.println(" mHomeProcess: " + mHomeProcess);
13553 if (mPreviousProcess != null && (dumpPackage == null
13554 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13559 pw.println(" mPreviousProcess: " + mPreviousProcess);
13562 StringBuilder sb = new StringBuilder(128);
13563 sb.append(" mPreviousProcessVisibleTime: ");
13564 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13567 if (mHeavyWeightProcess != null && (dumpPackage == null
13568 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13573 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13575 if (dumpPackage == null) {
13576 pw.println(" mConfiguration: " + mConfiguration);
13579 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13580 if (mCompatModePackages.getPackages().size() > 0) {
13581 boolean printed = false;
13582 for (Map.Entry<String, Integer> entry
13583 : mCompatModePackages.getPackages().entrySet()) {
13584 String pkg = entry.getKey();
13585 int mode = entry.getValue();
13586 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13590 pw.println(" mScreenCompatPackages:");
13593 pw.print(" "); pw.print(pkg); pw.print(": ");
13594 pw.print(mode); pw.println();
13598 if (dumpPackage == null) {
13599 pw.println(" mWakefulness="
13600 + PowerManagerInternal.wakefulnessToString(mWakefulness));
13601 pw.println(" mSleepTokens=" + mSleepTokens);
13602 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
13603 + lockScreenShownToString());
13604 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13605 if (mRunningVoice != null) {
13606 pw.println(" mRunningVoice=" + mRunningVoice);
13607 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
13610 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13611 || mOrigWaitForDebugger) {
13612 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13613 || dumpPackage.equals(mOrigDebugApp)) {
13618 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13619 + " mDebugTransient=" + mDebugTransient
13620 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13623 if (mCurAppTimeTracker != null) {
13624 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
13626 if (mMemWatchProcesses.getMap().size() > 0) {
13627 pw.println(" Mem watch processes:");
13628 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13629 = mMemWatchProcesses.getMap();
13630 for (int i=0; i<procs.size(); i++) {
13631 final String proc = procs.keyAt(i);
13632 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13633 for (int j=0; j<uids.size(); j++) {
13638 StringBuilder sb = new StringBuilder();
13639 sb.append(" ").append(proc).append('/');
13640 UserHandle.formatUid(sb, uids.keyAt(j));
13641 Pair<Long, String> val = uids.valueAt(j);
13642 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13643 if (val.second != null) {
13644 sb.append(", report to ").append(val.second);
13646 pw.println(sb.toString());
13649 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13650 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13651 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13652 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13654 if (mOpenGlTraceApp != null) {
13655 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13660 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
13663 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13664 || mProfileFd != null) {
13665 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13670 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13671 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13672 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13673 + mAutoStopProfiler);
13674 pw.println(" mProfileType=" + mProfileType);
13677 if (dumpPackage == null) {
13678 if (mAlwaysFinishActivities || mController != null) {
13679 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
13680 + " mController=" + mController);
13683 pw.println(" Total persistent processes: " + numPers);
13684 pw.println(" mProcessesReady=" + mProcessesReady
13685 + " mSystemReady=" + mSystemReady
13686 + " mBooted=" + mBooted
13687 + " mFactoryTest=" + mFactoryTest);
13688 pw.println(" mBooting=" + mBooting
13689 + " mCallFinishBooting=" + mCallFinishBooting
13690 + " mBootAnimationComplete=" + mBootAnimationComplete);
13691 pw.print(" mLastPowerCheckRealtime=");
13692 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13694 pw.print(" mLastPowerCheckUptime=");
13695 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13697 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13698 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13699 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13700 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
13701 + " (" + mLruProcesses.size() + " total)"
13702 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13703 + " mNumServiceProcs=" + mNumServiceProcs
13704 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13705 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
13706 + " mLastMemoryLevel" + mLastMemoryLevel
13707 + " mLastNumProcesses" + mLastNumProcesses);
13708 long now = SystemClock.uptimeMillis();
13709 pw.print(" mLastIdleTime=");
13710 TimeUtils.formatDuration(now, mLastIdleTime, pw);
13711 pw.print(" mLowRamSinceLastIdle=");
13712 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13717 if (!printedAnything) {
13718 pw.println(" (nothing)");
13722 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13723 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13724 if (mProcessesToGc.size() > 0) {
13725 boolean printed = false;
13726 long now = SystemClock.uptimeMillis();
13727 for (int i=0; i<mProcessesToGc.size(); i++) {
13728 ProcessRecord proc = mProcessesToGc.get(i);
13729 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13733 if (needSep) pw.println();
13735 pw.println(" Processes that are waiting to GC:");
13738 pw.print(" Process "); pw.println(proc);
13739 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
13740 pw.print(", last gced=");
13741 pw.print(now-proc.lastRequestedGc);
13742 pw.print(" ms ago, last lowMem=");
13743 pw.print(now-proc.lastLowMemory);
13744 pw.println(" ms ago");
13751 void printOomLevel(PrintWriter pw, String name, int adj) {
13755 if (adj < 10) pw.print(' ');
13757 if (adj > -10) pw.print(' ');
13763 pw.print(mProcessList.getMemLevel(adj)/1024);
13764 pw.println(" kB)");
13767 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13768 int opti, boolean dumpAll) {
13769 boolean needSep = false;
13771 if (mLruProcesses.size() > 0) {
13772 if (needSep) pw.println();
13774 pw.println(" OOM levels:");
13775 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13776 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13777 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13778 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13779 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13780 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13781 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13782 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13783 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13784 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13785 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13786 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13787 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13788 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13790 if (needSep) pw.println();
13791 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
13792 pw.print(" total, non-act at ");
13793 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13794 pw.print(", non-svc at ");
13795 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13797 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
13801 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13804 pw.println(" mHomeProcess: " + mHomeProcess);
13805 pw.println(" mPreviousProcess: " + mPreviousProcess);
13806 if (mHeavyWeightProcess != null) {
13807 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13814 * There are three ways to call this:
13815 * - no provider specified: dump all the providers
13816 * - a flattened component name that matched an existing provider was specified as the
13817 * first arg: dump that one provider
13818 * - the first arg isn't the flattened component name of an existing provider:
13819 * dump all providers whose component contains the first arg as a substring
13821 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13822 int opti, boolean dumpAll) {
13823 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13826 static class ItemMatcher {
13827 ArrayList<ComponentName> components;
13828 ArrayList<String> strings;
13829 ArrayList<Integer> objects;
13836 void build(String name) {
13837 ComponentName componentName = ComponentName.unflattenFromString(name);
13838 if (componentName != null) {
13839 if (components == null) {
13840 components = new ArrayList<ComponentName>();
13842 components.add(componentName);
13846 // Not a '/' separated full component name; maybe an object ID?
13848 objectId = Integer.parseInt(name, 16);
13849 if (objects == null) {
13850 objects = new ArrayList<Integer>();
13852 objects.add(objectId);
13854 } catch (RuntimeException e) {
13855 // Not an integer; just do string match.
13856 if (strings == null) {
13857 strings = new ArrayList<String>();
13865 int build(String[] args, int opti) {
13866 for (; opti<args.length; opti++) {
13867 String name = args[opti];
13868 if ("--".equals(name)) {
13876 boolean match(Object object, ComponentName comp) {
13880 if (components != null) {
13881 for (int i=0; i<components.size(); i++) {
13882 if (components.get(i).equals(comp)) {
13887 if (objects != null) {
13888 for (int i=0; i<objects.size(); i++) {
13889 if (System.identityHashCode(object) == objects.get(i)) {
13894 if (strings != null) {
13895 String flat = comp.flattenToString();
13896 for (int i=0; i<strings.size(); i++) {
13897 if (flat.contains(strings.get(i))) {
13907 * There are three things that cmd can be:
13908 * - a flattened component name that matches an existing activity
13909 * - the cmd arg isn't the flattened component name of an existing activity:
13910 * dump all activity whose component contains the cmd as a substring
13911 * - A hex number of the ActivityRecord object instance.
13913 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13914 int opti, boolean dumpAll) {
13915 ArrayList<ActivityRecord> activities;
13917 synchronized (this) {
13918 activities = mStackSupervisor.getDumpActivitiesLocked(name);
13921 if (activities.size() <= 0) {
13925 String[] newArgs = new String[args.length - opti];
13926 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13928 TaskRecord lastTask = null;
13929 boolean needSep = false;
13930 for (int i=activities.size()-1; i>=0; i--) {
13931 ActivityRecord r = activities.get(i);
13936 synchronized (this) {
13937 if (lastTask != r.task) {
13939 pw.print("TASK "); pw.print(lastTask.affinity);
13940 pw.print(" id="); pw.println(lastTask.taskId);
13942 lastTask.dump(pw, " ");
13946 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
13952 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13953 * there is a thread associated with the activity.
13955 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13956 final ActivityRecord r, String[] args, boolean dumpAll) {
13957 String innerPrefix = prefix + " ";
13958 synchronized (this) {
13959 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13960 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13962 if (r.app != null) pw.println(r.app.pid);
13963 else pw.println("(not running)");
13965 r.dump(pw, innerPrefix);
13968 if (r.app != null && r.app.thread != null) {
13969 // flush anything that is already in the PrintWriter since the thread is going
13970 // to write to the file descriptor directly
13973 TransferPipe tp = new TransferPipe();
13975 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13976 r.appToken, innerPrefix, args);
13981 } catch (IOException e) {
13982 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13983 } catch (RemoteException e) {
13984 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13989 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13990 int opti, boolean dumpAll, String dumpPackage) {
13991 boolean needSep = false;
13992 boolean onlyHistory = false;
13993 boolean printedAnything = false;
13995 if ("history".equals(dumpPackage)) {
13996 if (opti < args.length && "-s".equals(args[opti])) {
13999 onlyHistory = true;
14000 dumpPackage = null;
14003 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14004 if (!onlyHistory && dumpAll) {
14005 if (mRegisteredReceivers.size() > 0) {
14006 boolean printed = false;
14007 Iterator it = mRegisteredReceivers.values().iterator();
14008 while (it.hasNext()) {
14009 ReceiverList r = (ReceiverList)it.next();
14010 if (dumpPackage != null && (r.app == null ||
14011 !dumpPackage.equals(r.app.info.packageName))) {
14015 pw.println(" Registered Receivers:");
14018 printedAnything = true;
14020 pw.print(" * "); pw.println(r);
14025 if (mReceiverResolver.dump(pw, needSep ?
14026 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
14027 " ", dumpPackage, false, false)) {
14029 printedAnything = true;
14033 for (BroadcastQueue q : mBroadcastQueues) {
14034 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14035 printedAnything |= needSep;
14040 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14041 for (int user=0; user<mStickyBroadcasts.size(); user++) {
14046 printedAnything = true;
14047 pw.print(" Sticky broadcasts for user ");
14048 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14049 StringBuilder sb = new StringBuilder(128);
14050 for (Map.Entry<String, ArrayList<Intent>> ent
14051 : mStickyBroadcasts.valueAt(user).entrySet()) {
14052 pw.print(" * Sticky action "); pw.print(ent.getKey());
14055 ArrayList<Intent> intents = ent.getValue();
14056 final int N = intents.size();
14057 for (int i=0; i<N; i++) {
14059 sb.append(" Intent: ");
14060 intents.get(i).toShortString(sb, false, true, false, false);
14061 pw.println(sb.toString());
14062 Bundle bundle = intents.get(i).getExtras();
14063 if (bundle != null) {
14065 pw.println(bundle.toString());
14075 if (!onlyHistory && dumpAll) {
14077 for (BroadcastQueue queue : mBroadcastQueues) {
14078 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
14079 + queue.mBroadcastsScheduled);
14081 pw.println(" mHandler:");
14082 mHandler.dump(new PrintWriterPrinter(pw), " ");
14084 printedAnything = true;
14087 if (!printedAnything) {
14088 pw.println(" (nothing)");
14092 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14093 int opti, boolean dumpAll, String dumpPackage) {
14095 boolean printedAnything = false;
14097 ItemMatcher matcher = new ItemMatcher();
14098 matcher.build(args, opti);
14100 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14102 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14103 printedAnything |= needSep;
14105 if (mLaunchingProviders.size() > 0) {
14106 boolean printed = false;
14107 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14108 ContentProviderRecord r = mLaunchingProviders.get(i);
14109 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14113 if (needSep) pw.println();
14115 pw.println(" Launching content providers:");
14117 printedAnything = true;
14119 pw.print(" Launching #"); pw.print(i); pw.print(": ");
14124 if (!printedAnything) {
14125 pw.println(" (nothing)");
14129 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14130 int opti, boolean dumpAll, String dumpPackage) {
14131 boolean needSep = false;
14132 boolean printedAnything = false;
14134 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14136 if (mGrantedUriPermissions.size() > 0) {
14137 boolean printed = false;
14139 if (dumpPackage != null) {
14141 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14142 } catch (NameNotFoundException e) {
14146 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14147 int uid = mGrantedUriPermissions.keyAt(i);
14148 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14151 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14153 if (needSep) pw.println();
14155 pw.println(" Granted Uri Permissions:");
14157 printedAnything = true;
14159 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
14160 for (UriPermission perm : perms.values()) {
14161 pw.print(" "); pw.println(perm);
14163 perm.dump(pw, " ");
14169 if (!printedAnything) {
14170 pw.println(" (nothing)");
14174 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14175 int opti, boolean dumpAll, String dumpPackage) {
14176 boolean printed = false;
14178 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14180 if (mIntentSenderRecords.size() > 0) {
14181 Iterator<WeakReference<PendingIntentRecord>> it
14182 = mIntentSenderRecords.values().iterator();
14183 while (it.hasNext()) {
14184 WeakReference<PendingIntentRecord> ref = it.next();
14185 PendingIntentRecord rec = ref != null ? ref.get(): null;
14186 if (dumpPackage != null && (rec == null
14187 || !dumpPackage.equals(rec.key.packageName))) {
14192 pw.print(" * "); pw.println(rec);
14197 pw.print(" * "); pw.println(ref);
14203 pw.println(" (nothing)");
14207 private static final int dumpProcessList(PrintWriter pw,
14208 ActivityManagerService service, List list,
14209 String prefix, String normalLabel, String persistentLabel,
14210 String dumpPackage) {
14212 final int N = list.size()-1;
14213 for (int i=N; i>=0; i--) {
14214 ProcessRecord r = (ProcessRecord)list.get(i);
14215 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14218 pw.println(String.format("%s%s #%2d: %s",
14219 prefix, (r.persistent ? persistentLabel : normalLabel),
14221 if (r.persistent) {
14228 private static final boolean dumpProcessOomList(PrintWriter pw,
14229 ActivityManagerService service, List<ProcessRecord> origList,
14230 String prefix, String normalLabel, String persistentLabel,
14231 boolean inclDetails, String dumpPackage) {
14233 ArrayList<Pair<ProcessRecord, Integer>> list
14234 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14235 for (int i=0; i<origList.size(); i++) {
14236 ProcessRecord r = origList.get(i);
14237 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14240 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14243 if (list.size() <= 0) {
14247 Comparator<Pair<ProcessRecord, Integer>> comparator
14248 = new Comparator<Pair<ProcessRecord, Integer>>() {
14250 public int compare(Pair<ProcessRecord, Integer> object1,
14251 Pair<ProcessRecord, Integer> object2) {
14252 if (object1.first.setAdj != object2.first.setAdj) {
14253 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14255 if (object1.second.intValue() != object2.second.intValue()) {
14256 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14262 Collections.sort(list, comparator);
14264 final long curRealtime = SystemClock.elapsedRealtime();
14265 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14266 final long curUptime = SystemClock.uptimeMillis();
14267 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14269 for (int i=list.size()-1; i>=0; i--) {
14270 ProcessRecord r = list.get(i).first;
14271 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14273 switch (r.setSchedGroup) {
14274 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14277 case Process.THREAD_GROUP_DEFAULT:
14285 if (r.foregroundActivities) {
14287 } else if (r.foregroundServices) {
14292 String procState = ProcessList.makeProcStateString(r.curProcState);
14294 pw.print(r.persistent ? persistentLabel : normalLabel);
14296 int num = (origList.size()-1)-list.get(i).second;
14297 if (num < 10) pw.print(' ');
14302 pw.print(schedGroup);
14304 pw.print(foreground);
14306 pw.print(procState);
14308 if (r.trimMemoryLevel < 10) pw.print(' ');
14309 pw.print(r.trimMemoryLevel);
14311 pw.print(r.toShortString());
14313 pw.print(r.adjType);
14315 if (r.adjSource != null || r.adjTarget != null) {
14318 if (r.adjTarget instanceof ComponentName) {
14319 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14320 } else if (r.adjTarget != null) {
14321 pw.print(r.adjTarget.toString());
14323 pw.print("{null}");
14326 if (r.adjSource instanceof ProcessRecord) {
14328 pw.print(((ProcessRecord)r.adjSource).toShortString());
14330 } else if (r.adjSource != null) {
14331 pw.println(r.adjSource.toString());
14333 pw.println("{null}");
14339 pw.print("oom: max="); pw.print(r.maxAdj);
14340 pw.print(" curRaw="); pw.print(r.curRawAdj);
14341 pw.print(" setRaw="); pw.print(r.setRawAdj);
14342 pw.print(" cur="); pw.print(r.curAdj);
14343 pw.print(" set="); pw.println(r.setAdj);
14346 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14347 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14348 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14349 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14353 pw.print("cached="); pw.print(r.cached);
14354 pw.print(" empty="); pw.print(r.empty);
14355 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14357 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14358 if (r.lastWakeTime != 0) {
14360 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14361 synchronized (stats) {
14362 wtime = stats.getProcessWakeTime(r.info.uid,
14363 r.pid, curRealtime);
14365 long timeUsed = wtime - r.lastWakeTime;
14368 pw.print("keep awake over ");
14369 TimeUtils.formatDuration(realtimeSince, pw);
14370 pw.print(" used ");
14371 TimeUtils.formatDuration(timeUsed, pw);
14373 pw.print((timeUsed*100)/realtimeSince);
14376 if (r.lastCpuTime != 0) {
14377 long timeUsed = r.curCpuTime - r.lastCpuTime;
14380 pw.print("run cpu over ");
14381 TimeUtils.formatDuration(uptimeSince, pw);
14382 pw.print(" used ");
14383 TimeUtils.formatDuration(timeUsed, pw);
14385 pw.print((timeUsed*100)/uptimeSince);
14394 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14396 ArrayList<ProcessRecord> procs;
14397 synchronized (this) {
14398 if (args != null && args.length > start
14399 && args[start].charAt(0) != '-') {
14400 procs = new ArrayList<ProcessRecord>();
14403 pid = Integer.parseInt(args[start]);
14404 } catch (NumberFormatException e) {
14406 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14407 ProcessRecord proc = mLruProcesses.get(i);
14408 if (proc.pid == pid) {
14410 } else if (allPkgs && proc.pkgList != null
14411 && proc.pkgList.containsKey(args[start])) {
14413 } else if (proc.processName.equals(args[start])) {
14417 if (procs.size() <= 0) {
14421 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14427 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14428 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 long uptime = SystemClock.uptimeMillis();
14436 long realtime = SystemClock.elapsedRealtime();
14437 pw.println("Applications Graphics Acceleration Info:");
14438 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14440 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14441 ProcessRecord r = procs.get(i);
14442 if (r.thread != null) {
14443 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14446 TransferPipe tp = new TransferPipe();
14448 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14453 } catch (IOException e) {
14454 pw.println("Failure while dumping the app: " + r);
14456 } catch (RemoteException e) {
14457 pw.println("Got a RemoteException while dumping the app " + r);
14464 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14465 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14466 if (procs == null) {
14467 pw.println("No process found for: " + args[0]);
14471 pw.println("Applications Database Info:");
14473 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14474 ProcessRecord r = procs.get(i);
14475 if (r.thread != null) {
14476 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14479 TransferPipe tp = new TransferPipe();
14481 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14486 } catch (IOException e) {
14487 pw.println("Failure while dumping the app: " + r);
14489 } catch (RemoteException e) {
14490 pw.println("Got a RemoteException while dumping the app " + r);
14497 final static class MemItem {
14498 final boolean isProc;
14499 final String label;
14500 final String shortLabel;
14503 final boolean hasActivities;
14504 ArrayList<MemItem> subitems;
14506 public MemItem(String _label, String _shortLabel, long _pss, int _id,
14507 boolean _hasActivities) {
14510 shortLabel = _shortLabel;
14513 hasActivities = _hasActivities;
14516 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14519 shortLabel = _shortLabel;
14522 hasActivities = false;
14526 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14527 ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14528 if (sort && !isCompact) {
14529 Collections.sort(items, new Comparator<MemItem>() {
14531 public int compare(MemItem lhs, MemItem rhs) {
14532 if (lhs.pss < rhs.pss) {
14534 } else if (lhs.pss > rhs.pss) {
14542 for (int i=0; i<items.size(); i++) {
14543 MemItem mi = items.get(i);
14545 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14546 } else if (mi.isProc) {
14547 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14548 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14549 pw.println(mi.hasActivities ? ",a" : ",e");
14551 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14552 pw.println(mi.pss);
14554 if (mi.subitems != null) {
14555 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
14561 // These are in KB.
14562 static final long[] DUMP_MEM_BUCKETS = new long[] {
14563 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14564 120*1024, 160*1024, 200*1024,
14565 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14566 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14569 static final void appendMemBucket(StringBuilder out, long memKB, String label,
14570 boolean stackLike) {
14571 int start = label.lastIndexOf('.');
14572 if (start >= 0) start++;
14574 int end = label.length();
14575 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14576 if (DUMP_MEM_BUCKETS[i] >= memKB) {
14577 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14578 out.append(bucket);
14579 out.append(stackLike ? "MB." : "MB ");
14580 out.append(label, start, end);
14584 out.append(memKB/1024);
14585 out.append(stackLike ? "MB." : "MB ");
14586 out.append(label, start, end);
14589 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14590 ProcessList.NATIVE_ADJ,
14591 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14592 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14593 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14594 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14595 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14596 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14598 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14600 "System", "Persistent", "Persistent Service", "Foreground",
14601 "Visible", "Perceptible",
14602 "Heavy Weight", "Backup",
14603 "A Services", "Home",
14604 "Previous", "B Services", "Cached"
14606 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14608 "sys", "pers", "persvc", "fore",
14611 "servicea", "home",
14612 "prev", "serviceb", "cached"
14615 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14616 long realtime, boolean isCheckinRequest, boolean isCompact) {
14617 if (isCheckinRequest || isCompact) {
14618 // short checkin version
14619 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14621 pw.println("Applications Memory Usage (kB):");
14622 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14626 private static final int KSM_SHARED = 0;
14627 private static final int KSM_SHARING = 1;
14628 private static final int KSM_UNSHARED = 2;
14629 private static final int KSM_VOLATILE = 3;
14631 private final long[] getKsmInfo() {
14632 long[] longOut = new long[4];
14633 final int[] SINGLE_LONG_FORMAT = new int[] {
14634 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14636 long[] longTmp = new long[1];
14637 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14638 SINGLE_LONG_FORMAT, null, longTmp, null);
14639 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14641 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14642 SINGLE_LONG_FORMAT, null, longTmp, null);
14643 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14645 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14646 SINGLE_LONG_FORMAT, null, longTmp, null);
14647 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14649 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14650 SINGLE_LONG_FORMAT, null, longTmp, null);
14651 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14655 final void dumpApplicationMemoryUsage(FileDescriptor fd,
14656 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14657 boolean dumpDetails = false;
14658 boolean dumpFullDetails = false;
14659 boolean dumpDalvik = false;
14660 boolean dumpSummaryOnly = false;
14661 boolean oomOnly = false;
14662 boolean isCompact = false;
14663 boolean localOnly = false;
14664 boolean packages = false;
14667 while (opti < args.length) {
14668 String opt = args[opti];
14669 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14673 if ("-a".equals(opt)) {
14674 dumpDetails = true;
14675 dumpFullDetails = true;
14677 } else if ("-d".equals(opt)) {
14679 } else if ("-c".equals(opt)) {
14681 } else if ("-s".equals(opt)) {
14682 dumpDetails = true;
14683 dumpSummaryOnly = true;
14684 } else if ("--oom".equals(opt)) {
14686 } else if ("--local".equals(opt)) {
14688 } else if ("--package".equals(opt)) {
14690 } else if ("-h".equals(opt)) {
14691 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14692 pw.println(" -a: include all available information for each process.");
14693 pw.println(" -d: include dalvik details.");
14694 pw.println(" -c: dump in a compact machine-parseable representation.");
14695 pw.println(" -s: dump only summary of application memory usage.");
14696 pw.println(" --oom: only show processes organized by oom adj.");
14697 pw.println(" --local: only collect details locally, don't call process.");
14698 pw.println(" --package: interpret process arg as package, dumping all");
14699 pw.println(" processes that have loaded that package.");
14700 pw.println("If [process] is specified it can be the name or ");
14701 pw.println("pid of a specific process to dump.");
14704 pw.println("Unknown argument: " + opt + "; use -h for help");
14708 final boolean isCheckinRequest = scanArgs(args, "--checkin");
14709 long uptime = SystemClock.uptimeMillis();
14710 long realtime = SystemClock.elapsedRealtime();
14711 final long[] tmpLong = new long[1];
14713 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14714 if (procs == null) {
14715 // No Java processes. Maybe they want to print a native process.
14716 if (args != null && args.length > opti
14717 && args[opti].charAt(0) != '-') {
14718 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14719 = new ArrayList<ProcessCpuTracker.Stats>();
14720 updateCpuStatsNow();
14723 findPid = Integer.parseInt(args[opti]);
14724 } catch (NumberFormatException e) {
14726 synchronized (mProcessCpuTracker) {
14727 final int N = mProcessCpuTracker.countStats();
14728 for (int i=0; i<N; i++) {
14729 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14730 if (st.pid == findPid || (st.baseName != null
14731 && st.baseName.equals(args[opti]))) {
14732 nativeProcs.add(st);
14736 if (nativeProcs.size() > 0) {
14737 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14739 Debug.MemoryInfo mi = null;
14740 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14741 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14742 final int pid = r.pid;
14743 if (!isCheckinRequest && dumpDetails) {
14744 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14747 mi = new Debug.MemoryInfo();
14749 if (dumpDetails || (!brief && !oomOnly)) {
14750 Debug.getMemoryInfo(pid, mi);
14752 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14753 mi.dalvikPrivateDirty = (int)tmpLong[0];
14755 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14756 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14757 if (isCheckinRequest) {
14764 pw.println("No process found for: " + args[opti]);
14768 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14769 dumpDetails = true;
14772 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14774 String[] innerArgs = new String[args.length-opti];
14775 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14777 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14778 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14779 long nativePss = 0;
14780 long dalvikPss = 0;
14781 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14784 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14786 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14787 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14788 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14791 long cachedPss = 0;
14793 Debug.MemoryInfo mi = null;
14794 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14795 final ProcessRecord r = procs.get(i);
14796 final IApplicationThread thread;
14799 final boolean hasActivities;
14800 synchronized (this) {
14803 oomAdj = r.getSetAdjWithServices();
14804 hasActivities = r.activities.size() > 0;
14806 if (thread != null) {
14807 if (!isCheckinRequest && dumpDetails) {
14808 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14811 mi = new Debug.MemoryInfo();
14813 if (dumpDetails || (!brief && !oomOnly)) {
14814 Debug.getMemoryInfo(pid, mi);
14816 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14817 mi.dalvikPrivateDirty = (int)tmpLong[0];
14821 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14822 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14823 if (isCheckinRequest) {
14829 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14830 dumpDalvik, dumpSummaryOnly, innerArgs);
14831 } catch (RemoteException e) {
14832 if (!isCheckinRequest) {
14833 pw.println("Got RemoteException!");
14840 final long myTotalPss = mi.getTotalPss();
14841 final long myTotalUss = mi.getTotalUss();
14843 synchronized (this) {
14844 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14845 // Record this for posterity if the process has been stable.
14846 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14850 if (!isCheckinRequest && mi != null) {
14851 totalPss += myTotalPss;
14852 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14853 (hasActivities ? " / activities)" : ")"),
14854 r.processName, myTotalPss, pid, hasActivities);
14855 procMems.add(pssItem);
14856 procMemsMap.put(pid, pssItem);
14858 nativePss += mi.nativePss;
14859 dalvikPss += mi.dalvikPss;
14860 for (int j=0; j<dalvikSubitemPss.length; j++) {
14861 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14863 otherPss += mi.otherPss;
14864 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14865 long mem = mi.getOtherPss(j);
14870 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14871 cachedPss += myTotalPss;
14874 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14875 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14876 || oomIndex == (oomPss.length-1)) {
14877 oomPss[oomIndex] += myTotalPss;
14878 if (oomProcs[oomIndex] == null) {
14879 oomProcs[oomIndex] = new ArrayList<MemItem>();
14881 oomProcs[oomIndex].add(pssItem);
14889 long nativeProcTotalPss = 0;
14891 if (!isCheckinRequest && procs.size() > 1 && !packages) {
14892 // If we are showing aggregations, also look for native processes to
14893 // include so that our aggregations are more accurate.
14894 updateCpuStatsNow();
14896 synchronized (mProcessCpuTracker) {
14897 final int N = mProcessCpuTracker.countStats();
14898 for (int i=0; i<N; i++) {
14899 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14900 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14902 mi = new Debug.MemoryInfo();
14904 if (!brief && !oomOnly) {
14905 Debug.getMemoryInfo(st.pid, mi);
14907 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14908 mi.nativePrivateDirty = (int)tmpLong[0];
14911 final long myTotalPss = mi.getTotalPss();
14912 totalPss += myTotalPss;
14913 nativeProcTotalPss += myTotalPss;
14915 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14916 st.name, myTotalPss, st.pid, false);
14917 procMems.add(pssItem);
14919 nativePss += mi.nativePss;
14920 dalvikPss += mi.dalvikPss;
14921 for (int j=0; j<dalvikSubitemPss.length; j++) {
14922 dalvikSubitemPss[j] += mi.getOtherPss(
14923 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14925 otherPss += mi.otherPss;
14926 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14927 long mem = mi.getOtherPss(j);
14931 oomPss[0] += myTotalPss;
14932 if (oomProcs[0] == null) {
14933 oomProcs[0] = new ArrayList<MemItem>();
14935 oomProcs[0].add(pssItem);
14940 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14942 catMems.add(new MemItem("Native", "Native", nativePss, -1));
14943 final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14944 if (dalvikSubitemPss.length > 0) {
14945 dalvikItem.subitems = new ArrayList<MemItem>();
14946 for (int j=0; j<dalvikSubitemPss.length; j++) {
14947 final String name = Debug.MemoryInfo.getOtherLabel(
14948 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14949 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14952 catMems.add(dalvikItem);
14953 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14954 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14955 String label = Debug.MemoryInfo.getOtherLabel(j);
14956 catMems.add(new MemItem(label, label, miscPss[j], j));
14959 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14960 for (int j=0; j<oomPss.length; j++) {
14961 if (oomPss[j] != 0) {
14962 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14963 : DUMP_MEM_OOM_LABEL[j];
14964 MemItem item = new MemItem(label, label, oomPss[j],
14965 DUMP_MEM_OOM_ADJ[j]);
14966 item.subitems = oomProcs[j];
14971 if (!brief && !oomOnly && !isCompact) {
14973 pw.println("Total PSS by process:");
14974 dumpMemItems(pw, " ", "proc", procMems, true, isCompact);
14978 pw.println("Total PSS by OOM adjustment:");
14980 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact);
14981 if (!brief && !oomOnly) {
14982 PrintWriter out = categoryPw != null ? categoryPw : pw;
14985 out.println("Total PSS by category:");
14987 dumpMemItems(out, " ", "cat", catMems, true, isCompact);
14992 MemInfoReader memInfo = new MemInfoReader();
14993 memInfo.readMemInfo();
14994 if (nativeProcTotalPss > 0) {
14995 synchronized (this) {
14996 final long cachedKb = memInfo.getCachedSizeKb();
14997 final long freeKb = memInfo.getFreeSizeKb();
14998 final long zramKb = memInfo.getZramTotalSizeKb();
14999 final long kernelKb = memInfo.getKernelUsedSizeKb();
15000 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15001 kernelKb*1024, nativeProcTotalPss*1024);
15002 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15003 nativeProcTotalPss);
15008 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
15009 pw.print(" kB (status ");
15010 switch (mLastMemoryLevel) {
15011 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15012 pw.println("normal)");
15014 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15015 pw.println("moderate)");
15017 case ProcessStats.ADJ_MEM_FACTOR_LOW:
15018 pw.println("low)");
15020 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15021 pw.println("critical)");
15024 pw.print(mLastMemoryLevel);
15028 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
15029 + memInfo.getFreeSizeKb()); pw.print(" kB (");
15030 pw.print(cachedPss); pw.print(" cached pss + ");
15031 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
15032 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
15034 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15035 pw.print(cachedPss + memInfo.getCachedSizeKb()
15036 + memInfo.getFreeSizeKb()); pw.print(",");
15037 pw.println(totalPss - cachedPss);
15041 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15042 + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15043 pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15044 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15045 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15046 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15047 - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15050 if (memInfo.getZramTotalSizeKb() != 0) {
15052 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15053 pw.print(" kB physical used for ");
15054 pw.print(memInfo.getSwapTotalSizeKb()
15055 - memInfo.getSwapFreeSizeKb());
15056 pw.print(" kB in swap (");
15057 pw.print(memInfo.getSwapTotalSizeKb());
15058 pw.println(" kB total swap)");
15060 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15061 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15062 pw.println(memInfo.getSwapFreeSizeKb());
15065 final long[] ksm = getKsmInfo();
15067 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15068 || ksm[KSM_VOLATILE] != 0) {
15069 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]);
15070 pw.print(" kB saved from shared ");
15071 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15072 pw.print(" "); pw.print(ksm[KSM_UNSHARED]);
15073 pw.print(" kB unshared; ");
15074 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15076 pw.print(" Tuning: ");
15077 pw.print(ActivityManager.staticGetMemoryClass());
15078 pw.print(" (large ");
15079 pw.print(ActivityManager.staticGetLargeMemoryClass());
15080 pw.print("), oom ");
15081 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15083 pw.print(", restore limit ");
15084 pw.print(mProcessList.getCachedRestoreThresholdKb());
15086 if (ActivityManager.isLowRamDeviceStatic()) {
15087 pw.print(" (low-ram)");
15089 if (ActivityManager.isHighEndGfx()) {
15090 pw.print(" (high-end-gfx)");
15094 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15095 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15096 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15097 pw.print("tuning,");
15098 pw.print(ActivityManager.staticGetMemoryClass());
15100 pw.print(ActivityManager.staticGetLargeMemoryClass());
15102 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15103 if (ActivityManager.isLowRamDeviceStatic()) {
15104 pw.print(",low-ram");
15106 if (ActivityManager.isHighEndGfx()) {
15107 pw.print(",high-end-gfx");
15115 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15116 long memtrack, String name) {
15118 sb.append(ProcessList.makeOomAdjString(oomAdj));
15120 sb.append(ProcessList.makeProcStateString(procState));
15122 ProcessList.appendRamKb(sb, pss);
15123 sb.append(" kB: ");
15125 if (memtrack > 0) {
15127 sb.append(memtrack);
15128 sb.append(" kB memtrack)");
15132 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15133 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15134 sb.append(" (pid ");
15137 sb.append(mi.adjType);
15139 if (mi.adjReason != null) {
15141 sb.append(mi.adjReason);
15146 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15147 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15148 for (int i=0, N=memInfos.size(); i<N; i++) {
15149 ProcessMemInfo mi = memInfos.get(i);
15150 infoMap.put(mi.pid, mi);
15152 updateCpuStatsNow();
15153 long[] memtrackTmp = new long[1];
15154 synchronized (mProcessCpuTracker) {
15155 final int N = mProcessCpuTracker.countStats();
15156 for (int i=0; i<N; i++) {
15157 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15158 if (st.vsize > 0) {
15159 long pss = Debug.getPss(st.pid, null, memtrackTmp);
15161 if (infoMap.indexOfKey(st.pid) < 0) {
15162 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15163 ProcessList.NATIVE_ADJ, -1, "native", null);
15165 mi.memtrack = memtrackTmp[0];
15174 long totalMemtrack = 0;
15175 for (int i=0, N=memInfos.size(); i<N; i++) {
15176 ProcessMemInfo mi = memInfos.get(i);
15178 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15179 mi.memtrack = memtrackTmp[0];
15181 totalPss += mi.pss;
15182 totalMemtrack += mi.memtrack;
15184 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15185 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15186 if (lhs.oomAdj != rhs.oomAdj) {
15187 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15189 if (lhs.pss != rhs.pss) {
15190 return lhs.pss < rhs.pss ? 1 : -1;
15196 StringBuilder tag = new StringBuilder(128);
15197 StringBuilder stack = new StringBuilder(128);
15198 tag.append("Low on memory -- ");
15199 appendMemBucket(tag, totalPss, "total", false);
15200 appendMemBucket(stack, totalPss, "total", true);
15202 StringBuilder fullNativeBuilder = new StringBuilder(1024);
15203 StringBuilder shortNativeBuilder = new StringBuilder(1024);
15204 StringBuilder fullJavaBuilder = new StringBuilder(1024);
15206 boolean firstLine = true;
15207 int lastOomAdj = Integer.MIN_VALUE;
15208 long extraNativeRam = 0;
15209 long extraNativeMemtrack = 0;
15210 long cachedPss = 0;
15211 for (int i=0, N=memInfos.size(); i<N; i++) {
15212 ProcessMemInfo mi = memInfos.get(i);
15214 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15215 cachedPss += mi.pss;
15218 if (mi.oomAdj != ProcessList.NATIVE_ADJ
15219 && (mi.oomAdj < ProcessList.SERVICE_ADJ
15220 || mi.oomAdj == ProcessList.HOME_APP_ADJ
15221 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15222 if (lastOomAdj != mi.oomAdj) {
15223 lastOomAdj = mi.oomAdj;
15224 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15227 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15232 stack.append("\n\t at ");
15240 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15241 appendMemBucket(tag, mi.pss, mi.name, false);
15243 appendMemBucket(stack, mi.pss, mi.name, true);
15244 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15245 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15247 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15248 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15249 stack.append(DUMP_MEM_OOM_LABEL[k]);
15251 stack.append(DUMP_MEM_OOM_ADJ[k]);
15258 appendMemInfo(fullNativeBuilder, mi);
15259 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15260 // The short form only has native processes that are >= 512K.
15261 if (mi.pss >= 512) {
15262 appendMemInfo(shortNativeBuilder, mi);
15264 extraNativeRam += mi.pss;
15265 extraNativeMemtrack += mi.memtrack;
15268 // Short form has all other details, but if we have collected RAM
15269 // from smaller native processes let's dump a summary of that.
15270 if (extraNativeRam > 0) {
15271 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15272 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15273 shortNativeBuilder.append('\n');
15274 extraNativeRam = 0;
15276 appendMemInfo(fullJavaBuilder, mi);
15280 fullJavaBuilder.append(" ");
15281 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15282 fullJavaBuilder.append(" kB: TOTAL");
15283 if (totalMemtrack > 0) {
15284 fullJavaBuilder.append(" (");
15285 fullJavaBuilder.append(totalMemtrack);
15286 fullJavaBuilder.append(" kB memtrack)");
15289 fullJavaBuilder.append("\n");
15291 MemInfoReader memInfo = new MemInfoReader();
15292 memInfo.readMemInfo();
15293 final long[] infos = memInfo.getRawInfo();
15295 StringBuilder memInfoBuilder = new StringBuilder(1024);
15296 Debug.getMemInfo(infos);
15297 memInfoBuilder.append(" MemInfo: ");
15298 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15299 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15300 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15301 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15302 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15303 memInfoBuilder.append(" ");
15304 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15305 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15306 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15307 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15308 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15309 memInfoBuilder.append(" ZRAM: ");
15310 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15311 memInfoBuilder.append(" kB RAM, ");
15312 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15313 memInfoBuilder.append(" kB swap total, ");
15314 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15315 memInfoBuilder.append(" kB swap free\n");
15317 final long[] ksm = getKsmInfo();
15318 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15319 || ksm[KSM_VOLATILE] != 0) {
15320 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15321 memInfoBuilder.append(" kB saved from shared ");
15322 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15323 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15324 memInfoBuilder.append(" kB unshared; ");
15325 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15327 memInfoBuilder.append(" Free RAM: ");
15328 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15329 + memInfo.getFreeSizeKb());
15330 memInfoBuilder.append(" kB\n");
15331 memInfoBuilder.append(" Used RAM: ");
15332 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15333 memInfoBuilder.append(" kB\n");
15334 memInfoBuilder.append(" Lost RAM: ");
15335 memInfoBuilder.append(memInfo.getTotalSizeKb()
15336 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15337 - memInfo.getKernelUsedSizeKb());
15338 memInfoBuilder.append(" kB\n");
15339 Slog.i(TAG, "Low on memory:");
15340 Slog.i(TAG, shortNativeBuilder.toString());
15341 Slog.i(TAG, fullJavaBuilder.toString());
15342 Slog.i(TAG, memInfoBuilder.toString());
15344 StringBuilder dropBuilder = new StringBuilder(1024);
15346 StringWriter oomSw = new StringWriter();
15347 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15348 StringWriter catSw = new StringWriter();
15349 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15350 String[] emptyArgs = new String[] { };
15351 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
15353 String oomString = oomSw.toString();
15355 dropBuilder.append("Low on memory:");
15356 dropBuilder.append(stack);
15357 dropBuilder.append('\n');
15358 dropBuilder.append(fullNativeBuilder);
15359 dropBuilder.append(fullJavaBuilder);
15360 dropBuilder.append('\n');
15361 dropBuilder.append(memInfoBuilder);
15362 dropBuilder.append('\n');
15364 dropBuilder.append(oomString);
15365 dropBuilder.append('\n');
15367 StringWriter catSw = new StringWriter();
15368 synchronized (ActivityManagerService.this) {
15369 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15370 String[] emptyArgs = new String[] { };
15372 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15374 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15375 false, false, null);
15377 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15380 dropBuilder.append(catSw.toString());
15381 addErrorToDropBox("lowmem", null, "system_server", null,
15382 null, tag.toString(), dropBuilder.toString(), null, null);
15383 //Slog.i(TAG, "Sent to dropbox:");
15384 //Slog.i(TAG, dropBuilder.toString());
15385 synchronized (ActivityManagerService.this) {
15386 long now = SystemClock.uptimeMillis();
15387 if (mLastMemUsageReportTime < now) {
15388 mLastMemUsageReportTime = now;
15394 * Searches array of arguments for the specified string
15395 * @param args array of argument strings
15396 * @param value value to search for
15397 * @return true if the value is contained in the array
15399 private static boolean scanArgs(String[] args, String value) {
15400 if (args != null) {
15401 for (String arg : args) {
15402 if (value.equals(arg)) {
15410 private final boolean removeDyingProviderLocked(ProcessRecord proc,
15411 ContentProviderRecord cpr, boolean always) {
15412 final boolean inLaunching = mLaunchingProviders.contains(cpr);
15414 if (!inLaunching || always) {
15415 synchronized (cpr) {
15416 cpr.launchingApp = null;
15419 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15420 String names[] = cpr.info.authority.split(";");
15421 for (int j = 0; j < names.length; j++) {
15422 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15426 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15427 ContentProviderConnection conn = cpr.connections.get(i);
15428 if (conn.waiting) {
15429 // If this connection is waiting for the provider, then we don't
15430 // need to mess with its process unless we are always removing
15431 // or for some reason the provider is not currently launching.
15432 if (inLaunching && !always) {
15436 ProcessRecord capp = conn.client;
15438 if (conn.stableCount > 0) {
15439 if (!capp.persistent && capp.thread != null
15441 && capp.pid != MY_PID) {
15442 capp.kill("depends on provider "
15443 + cpr.name.flattenToShortString()
15444 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15446 } else if (capp.thread != null && conn.provider.provider != null) {
15448 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15449 } catch (RemoteException e) {
15451 // In the protocol here, we don't expect the client to correctly
15452 // clean up this connection, we'll just remove it.
15453 cpr.connections.remove(i);
15454 if (conn.client.conProviders.remove(conn)) {
15455 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15460 if (inLaunching && always) {
15461 mLaunchingProviders.remove(cpr);
15463 return inLaunching;
15467 * Main code for cleaning up a process when it has gone away. This is
15468 * called both as a result of the process dying, or directly when stopping
15469 * a process when running in single process mode.
15471 * @return Returns true if the given process has been restarted, so the
15472 * app that was passed in must remain on the process lists.
15474 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15475 boolean restarting, boolean allowRestart, int index) {
15477 removeLruProcessLocked(app);
15478 ProcessList.remove(app.pid);
15481 mProcessesToGc.remove(app);
15482 mPendingPssProcesses.remove(app);
15484 // Dismiss any open dialogs.
15485 if (app.crashDialog != null && !app.forceCrashReport) {
15486 app.crashDialog.dismiss();
15487 app.crashDialog = null;
15489 if (app.anrDialog != null) {
15490 app.anrDialog.dismiss();
15491 app.anrDialog = null;
15493 if (app.waitDialog != null) {
15494 app.waitDialog.dismiss();
15495 app.waitDialog = null;
15498 app.crashing = false;
15499 app.notResponding = false;
15501 app.resetPackageList(mProcessStats);
15502 app.unlinkDeathRecipient();
15503 app.makeInactive(mProcessStats);
15504 app.waitingToKill = null;
15505 app.forcingToForeground = null;
15506 updateProcessForegroundLocked(app, false, false);
15507 app.foregroundActivities = false;
15508 app.hasShownUi = false;
15509 app.treatLikeActivity = false;
15510 app.hasAboveClient = false;
15511 app.hasClientActivities = false;
15513 mServices.killServicesLocked(app, allowRestart);
15515 boolean restart = false;
15517 // Remove published content providers.
15518 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15519 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15520 final boolean always = app.bad || !allowRestart;
15521 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15522 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15523 // We left the provider in the launching list, need to
15528 cpr.provider = null;
15531 app.pubProviders.clear();
15533 // Take care of any launching providers waiting for this process.
15534 if (checkAppInLaunchingProvidersLocked(app, false)) {
15538 // Unregister from connected content providers.
15539 if (!app.conProviders.isEmpty()) {
15540 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15541 ContentProviderConnection conn = app.conProviders.get(i);
15542 conn.provider.connections.remove(conn);
15543 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15544 conn.provider.name);
15546 app.conProviders.clear();
15549 // At this point there may be remaining entries in mLaunchingProviders
15550 // where we were the only one waiting, so they are no longer of use.
15551 // Look for these and clean up if found.
15552 // XXX Commented out for now. Trying to figure out a way to reproduce
15553 // the actual situation to identify what is actually going on.
15555 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15556 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15557 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15558 synchronized (cpr) {
15559 cpr.launchingApp = null;
15566 skipCurrentReceiverLocked(app);
15568 // Unregister any receivers.
15569 for (int i = app.receivers.size() - 1; i >= 0; i--) {
15570 removeReceiverLocked(app.receivers.valueAt(i));
15572 app.receivers.clear();
15574 // If the app is undergoing backup, tell the backup manager about it
15575 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15576 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15577 + mBackupTarget.appInfo + " died during backup");
15579 IBackupManager bm = IBackupManager.Stub.asInterface(
15580 ServiceManager.getService(Context.BACKUP_SERVICE));
15581 bm.agentDisconnected(app.info.packageName);
15582 } catch (RemoteException e) {
15583 // can't happen; backup manager is local
15587 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15588 ProcessChangeItem item = mPendingProcessChanges.get(i);
15589 if (item.pid == app.pid) {
15590 mPendingProcessChanges.remove(i);
15591 mAvailProcessChanges.add(item);
15594 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15596 // If the caller is restarting this app, then leave it in its
15597 // current lists and let the caller take care of it.
15602 if (!app.persistent || app.isolated) {
15603 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15604 "Removing non-persistent process during cleanup: " + app);
15605 removeProcessNameLocked(app.processName, app.uid);
15606 if (mHeavyWeightProcess == app) {
15607 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15608 mHeavyWeightProcess.userId, 0));
15609 mHeavyWeightProcess = null;
15611 } else if (!app.removed) {
15612 // This app is persistent, so we need to keep its record around.
15613 // If it is not already on the pending app list, add it there
15614 // and start a new process for it.
15615 if (mPersistentStartingProcesses.indexOf(app) < 0) {
15616 mPersistentStartingProcesses.add(app);
15620 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15621 TAG_CLEANUP, "Clean-up removing on hold: " + app);
15622 mProcessesOnHold.remove(app);
15624 if (app == mHomeProcess) {
15625 mHomeProcess = null;
15627 if (app == mPreviousProcess) {
15628 mPreviousProcess = null;
15631 if (restart && !app.isolated) {
15632 // We have components that still need to be running in the
15633 // process, so re-launch it.
15635 ProcessList.remove(app.pid);
15637 addProcessNameLocked(app);
15638 startProcessLocked(app, "restart", app.processName);
15640 } else if (app.pid > 0 && app.pid != MY_PID) {
15643 synchronized (mPidsSelfLocked) {
15644 mPidsSelfLocked.remove(app.pid);
15645 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15647 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15648 if (app.isolated) {
15649 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15656 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15657 // Look through the content providers we are waiting to have launched,
15658 // and if any run in this process then either schedule a restart of
15659 // the process or kill the client waiting for it if this process has
15661 boolean restart = false;
15662 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15663 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15664 if (cpr.launchingApp == app) {
15665 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15668 removeDyingProviderLocked(app, cpr, true);
15675 // =========================================================
15677 // =========================================================
15680 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15682 enforceNotIsolatedCaller("getServices");
15683 synchronized (this) {
15684 return mServices.getRunningServiceInfoLocked(maxNum, flags);
15689 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15690 enforceNotIsolatedCaller("getRunningServiceControlPanel");
15691 synchronized (this) {
15692 return mServices.getRunningServiceControlPanelLocked(name);
15697 public ComponentName startService(IApplicationThread caller, Intent service,
15698 String resolvedType, String callingPackage, int userId)
15699 throws TransactionTooLargeException {
15700 enforceNotIsolatedCaller("startService");
15701 // Refuse possible leaked file descriptors
15702 if (service != null && service.hasFileDescriptors() == true) {
15703 throw new IllegalArgumentException("File descriptors passed in Intent");
15706 if (callingPackage == null) {
15707 throw new IllegalArgumentException("callingPackage cannot be null");
15710 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15711 "startService: " + service + " type=" + resolvedType);
15712 synchronized(this) {
15713 final int callingPid = Binder.getCallingPid();
15714 final int callingUid = Binder.getCallingUid();
15715 final long origId = Binder.clearCallingIdentity();
15716 ComponentName res = mServices.startServiceLocked(caller, service,
15717 resolvedType, callingPid, callingUid, callingPackage, userId);
15718 Binder.restoreCallingIdentity(origId);
15723 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15724 String callingPackage, int userId)
15725 throws TransactionTooLargeException {
15726 synchronized(this) {
15727 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15728 "startServiceInPackage: " + service + " type=" + resolvedType);
15729 final long origId = Binder.clearCallingIdentity();
15730 ComponentName res = mServices.startServiceLocked(null, service,
15731 resolvedType, -1, uid, callingPackage, userId);
15732 Binder.restoreCallingIdentity(origId);
15738 public int stopService(IApplicationThread caller, Intent service,
15739 String resolvedType, int userId) {
15740 enforceNotIsolatedCaller("stopService");
15741 // Refuse possible leaked file descriptors
15742 if (service != null && service.hasFileDescriptors() == true) {
15743 throw new IllegalArgumentException("File descriptors passed in Intent");
15746 synchronized(this) {
15747 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15752 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15753 enforceNotIsolatedCaller("peekService");
15754 // Refuse possible leaked file descriptors
15755 if (service != null && service.hasFileDescriptors() == true) {
15756 throw new IllegalArgumentException("File descriptors passed in Intent");
15759 if (callingPackage == null) {
15760 throw new IllegalArgumentException("callingPackage cannot be null");
15763 synchronized(this) {
15764 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15769 public boolean stopServiceToken(ComponentName className, IBinder token,
15771 synchronized(this) {
15772 return mServices.stopServiceTokenLocked(className, token, startId);
15777 public void setServiceForeground(ComponentName className, IBinder token,
15778 int id, Notification notification, boolean removeNotification) {
15779 synchronized(this) {
15780 mServices.setServiceForegroundLocked(className, token, id, notification,
15781 removeNotification);
15786 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15787 boolean requireFull, String name, String callerPackage) {
15788 return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15789 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15792 int unsafeConvertIncomingUser(int userId) {
15793 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15794 ? mCurrentUserId : userId;
15797 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15798 int allowMode, String name, String callerPackage) {
15799 final int callingUserId = UserHandle.getUserId(callingUid);
15800 if (callingUserId == userId) {
15804 // Note that we may be accessing mCurrentUserId outside of a lock...
15805 // shouldn't be a big deal, if this is being called outside
15806 // of a locked context there is intrinsically a race with
15807 // the value the caller will receive and someone else changing it.
15808 // We assume that USER_CURRENT_OR_SELF will use the current user; later
15809 // we will switch to the calling user if access to the current user fails.
15810 int targetUserId = unsafeConvertIncomingUser(userId);
15812 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15813 final boolean allow;
15814 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15815 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15816 // If the caller has this permission, they always pass go. And collect $200.
15818 } else if (allowMode == ALLOW_FULL_ONLY) {
15819 // We require full access, sucks to be you.
15821 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15822 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15823 // If the caller does not have either permission, they are always doomed.
15825 } else if (allowMode == ALLOW_NON_FULL) {
15826 // We are blanket allowing non-full access, you lucky caller!
15828 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15829 // We may or may not allow this depending on whether the two users are
15830 // in the same profile.
15831 synchronized (mUserProfileGroupIdsSelfLocked) {
15832 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15833 UserInfo.NO_PROFILE_GROUP_ID);
15834 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15835 UserInfo.NO_PROFILE_GROUP_ID);
15836 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15837 && callingProfile == targetProfile;
15840 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15843 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15844 // In this case, they would like to just execute as their
15845 // owner user instead of failing.
15846 targetUserId = callingUserId;
15848 StringBuilder builder = new StringBuilder(128);
15849 builder.append("Permission Denial: ");
15850 builder.append(name);
15851 if (callerPackage != null) {
15852 builder.append(" from ");
15853 builder.append(callerPackage);
15855 builder.append(" asks to run as user ");
15856 builder.append(userId);
15857 builder.append(" but is calling from user ");
15858 builder.append(UserHandle.getUserId(callingUid));
15859 builder.append("; this requires ");
15860 builder.append(INTERACT_ACROSS_USERS_FULL);
15861 if (allowMode != ALLOW_FULL_ONLY) {
15862 builder.append(" or ");
15863 builder.append(INTERACT_ACROSS_USERS);
15865 String msg = builder.toString();
15867 throw new SecurityException(msg);
15871 if (!allowAll && targetUserId < 0) {
15872 throw new IllegalArgumentException(
15873 "Call does not support special user #" + targetUserId);
15875 // Check shell permission
15876 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15877 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15879 throw new SecurityException("Shell does not have permission to access user "
15880 + targetUserId + "\n " + Debug.getCallers(3));
15883 return targetUserId;
15886 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15887 String className, int flags) {
15888 boolean result = false;
15889 // For apps that don't have pre-defined UIDs, check for permission
15890 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15891 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15892 if (ActivityManager.checkUidPermission(
15893 INTERACT_ACROSS_USERS,
15894 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15895 ComponentName comp = new ComponentName(aInfo.packageName, className);
15896 String msg = "Permission Denial: Component " + comp.flattenToShortString()
15897 + " requests FLAG_SINGLE_USER, but app does not hold "
15898 + INTERACT_ACROSS_USERS;
15900 throw new SecurityException(msg);
15902 // Permission passed
15905 } else if ("system".equals(componentProcessName)) {
15907 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15908 // Phone app and persistent apps are allowed to export singleuser providers.
15909 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15910 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15912 if (DEBUG_MU) Slog.v(TAG_MU,
15913 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15914 + Integer.toHexString(flags) + ") = " + result);
15919 * Checks to see if the caller is in the same app as the singleton
15920 * component, or the component is in a special app. It allows special apps
15921 * to export singleton components but prevents exporting singleton
15922 * components for regular apps.
15924 boolean isValidSingletonCall(int callingUid, int componentUid) {
15925 int componentAppId = UserHandle.getAppId(componentUid);
15926 return UserHandle.isSameApp(callingUid, componentUid)
15927 || componentAppId == Process.SYSTEM_UID
15928 || componentAppId == Process.PHONE_UID
15929 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15930 == PackageManager.PERMISSION_GRANTED;
15933 public int bindService(IApplicationThread caller, IBinder token, Intent service,
15934 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15935 int userId) throws TransactionTooLargeException {
15936 enforceNotIsolatedCaller("bindService");
15938 // Refuse possible leaked file descriptors
15939 if (service != null && service.hasFileDescriptors() == true) {
15940 throw new IllegalArgumentException("File descriptors passed in Intent");
15943 if (callingPackage == null) {
15944 throw new IllegalArgumentException("callingPackage cannot be null");
15947 synchronized(this) {
15948 return mServices.bindServiceLocked(caller, token, service,
15949 resolvedType, connection, flags, callingPackage, userId);
15953 public boolean unbindService(IServiceConnection connection) {
15954 synchronized (this) {
15955 return mServices.unbindServiceLocked(connection);
15959 public void publishService(IBinder token, Intent intent, IBinder service) {
15960 // Refuse possible leaked file descriptors
15961 if (intent != null && intent.hasFileDescriptors() == true) {
15962 throw new IllegalArgumentException("File descriptors passed in Intent");
15965 synchronized(this) {
15966 if (!(token instanceof ServiceRecord)) {
15967 throw new IllegalArgumentException("Invalid service token");
15969 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15973 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15974 // Refuse possible leaked file descriptors
15975 if (intent != null && intent.hasFileDescriptors() == true) {
15976 throw new IllegalArgumentException("File descriptors passed in Intent");
15979 synchronized(this) {
15980 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15984 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15985 synchronized(this) {
15986 if (!(token instanceof ServiceRecord)) {
15987 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15988 throw new IllegalArgumentException("Invalid service token");
15990 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15994 // =========================================================
15995 // BACKUP AND RESTORE
15996 // =========================================================
15998 // Cause the target app to be launched if necessary and its backup agent
15999 // instantiated. The backup agent will invoke backupAgentCreated() on the
16000 // activity manager to announce its creation.
16001 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16002 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16003 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16004 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16006 synchronized(this) {
16007 // !!! TODO: currently no check here that we're already bound
16008 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16009 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16010 synchronized (stats) {
16011 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16014 // Backup agent is now in use, its package can't be stopped.
16016 AppGlobals.getPackageManager().setPackageStoppedState(
16017 app.packageName, false, UserHandle.getUserId(app.uid));
16018 } catch (RemoteException e) {
16019 } catch (IllegalArgumentException e) {
16020 Slog.w(TAG, "Failed trying to unstop package "
16021 + app.packageName + ": " + e);
16024 BackupRecord r = new BackupRecord(ss, app, backupMode);
16025 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16026 ? new ComponentName(app.packageName, app.backupAgentName)
16027 : new ComponentName("android", "FullBackupAgent");
16028 // startProcessLocked() returns existing proc's record if it's already running
16029 ProcessRecord proc = startProcessLocked(app.processName, app,
16030 false, 0, "backup", hostingName, false, false, false);
16031 if (proc == null) {
16032 Slog.e(TAG, "Unable to start backup agent process " + r);
16038 mBackupAppName = app.packageName;
16040 // Try not to kill the process during backup
16041 updateOomAdjLocked(proc);
16043 // If the process is already attached, schedule the creation of the backup agent now.
16044 // If it is not yet live, this will be done when it attaches to the framework.
16045 if (proc.thread != null) {
16046 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16048 proc.thread.scheduleCreateBackupAgent(app,
16049 compatibilityInfoForPackageLocked(app), backupMode);
16050 } catch (RemoteException e) {
16051 // Will time out on the backup manager side
16054 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16056 // Invariants: at this point, the target app process exists and the application
16057 // is either already running or in the process of coming up. mBackupTarget and
16058 // mBackupAppName describe the app, so that when it binds back to the AM we
16059 // know that it's scheduled for a backup-agent operation.
16066 public void clearPendingBackup() {
16067 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16068 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16070 synchronized (this) {
16071 mBackupTarget = null;
16072 mBackupAppName = null;
16076 // A backup agent has just come up
16077 public void backupAgentCreated(String agentPackageName, IBinder agent) {
16078 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16081 synchronized(this) {
16082 if (!agentPackageName.equals(mBackupAppName)) {
16083 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16088 long oldIdent = Binder.clearCallingIdentity();
16090 IBackupManager bm = IBackupManager.Stub.asInterface(
16091 ServiceManager.getService(Context.BACKUP_SERVICE));
16092 bm.agentConnected(agentPackageName, agent);
16093 } catch (RemoteException e) {
16094 // can't happen; the backup manager service is local
16095 } catch (Exception e) {
16096 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16097 e.printStackTrace();
16099 Binder.restoreCallingIdentity(oldIdent);
16103 // done with this agent
16104 public void unbindBackupAgent(ApplicationInfo appInfo) {
16105 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16106 if (appInfo == null) {
16107 Slog.w(TAG, "unbind backup agent for null app");
16111 synchronized(this) {
16113 if (mBackupAppName == null) {
16114 Slog.w(TAG, "Unbinding backup agent with no active backup");
16118 if (!mBackupAppName.equals(appInfo.packageName)) {
16119 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16123 // Not backing this app up any more; reset its OOM adjustment
16124 final ProcessRecord proc = mBackupTarget.app;
16125 updateOomAdjLocked(proc);
16127 // If the app crashed during backup, 'thread' will be null here
16128 if (proc.thread != null) {
16130 proc.thread.scheduleDestroyBackupAgent(appInfo,
16131 compatibilityInfoForPackageLocked(appInfo));
16132 } catch (Exception e) {
16133 Slog.e(TAG, "Exception when unbinding backup agent:");
16134 e.printStackTrace();
16138 mBackupTarget = null;
16139 mBackupAppName = null;
16143 // =========================================================
16145 // =========================================================
16147 boolean isPendingBroadcastProcessLocked(int pid) {
16148 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16149 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16152 void skipPendingBroadcastLocked(int pid) {
16153 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16154 for (BroadcastQueue queue : mBroadcastQueues) {
16155 queue.skipPendingBroadcastLocked(pid);
16159 // The app just attached; send any pending broadcasts that it should receive
16160 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16161 boolean didSomething = false;
16162 for (BroadcastQueue queue : mBroadcastQueues) {
16163 didSomething |= queue.sendPendingBroadcastsLocked(app);
16165 return didSomething;
16168 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16169 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16170 enforceNotIsolatedCaller("registerReceiver");
16171 ArrayList<Intent> stickyIntents = null;
16172 ProcessRecord callerApp = null;
16175 synchronized(this) {
16176 if (caller != null) {
16177 callerApp = getRecordForAppLocked(caller);
16178 if (callerApp == null) {
16179 throw new SecurityException(
16180 "Unable to find app for caller " + caller
16181 + " (pid=" + Binder.getCallingPid()
16182 + ") when registering receiver " + receiver);
16184 if (callerApp.info.uid != Process.SYSTEM_UID &&
16185 !callerApp.pkgList.containsKey(callerPackage) &&
16186 !"android".equals(callerPackage)) {
16187 throw new SecurityException("Given caller package " + callerPackage
16188 + " is not running in process " + callerApp);
16190 callingUid = callerApp.info.uid;
16191 callingPid = callerApp.pid;
16193 callerPackage = null;
16194 callingUid = Binder.getCallingUid();
16195 callingPid = Binder.getCallingPid();
16198 userId = handleIncomingUser(callingPid, callingUid, userId,
16199 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16201 Iterator<String> actions = filter.actionsIterator();
16202 if (actions == null) {
16203 ArrayList<String> noAction = new ArrayList<String>(1);
16204 noAction.add(null);
16205 actions = noAction.iterator();
16208 // Collect stickies of users
16209 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16210 while (actions.hasNext()) {
16211 String action = actions.next();
16212 for (int id : userIds) {
16213 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16214 if (stickies != null) {
16215 ArrayList<Intent> intents = stickies.get(action);
16216 if (intents != null) {
16217 if (stickyIntents == null) {
16218 stickyIntents = new ArrayList<Intent>();
16220 stickyIntents.addAll(intents);
16227 ArrayList<Intent> allSticky = null;
16228 if (stickyIntents != null) {
16229 final ContentResolver resolver = mContext.getContentResolver();
16230 // Look for any matching sticky broadcasts...
16231 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16232 Intent intent = stickyIntents.get(i);
16233 // If intent has scheme "content", it will need to acccess
16234 // provider that needs to lock mProviderMap in ActivityThread
16235 // and also it may need to wait application response, so we
16236 // cannot lock ActivityManagerService here.
16237 if (filter.match(resolver, intent, true, TAG) >= 0) {
16238 if (allSticky == null) {
16239 allSticky = new ArrayList<Intent>();
16241 allSticky.add(intent);
16246 // The first sticky in the list is returned directly back to the client.
16247 Intent sticky = allSticky != null ? allSticky.get(0) : null;
16248 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16249 if (receiver == null) {
16253 synchronized (this) {
16254 if (callerApp != null && (callerApp.thread == null
16255 || callerApp.thread.asBinder() != caller.asBinder())) {
16256 // Original caller already died
16259 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16261 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16263 if (rl.app != null) {
16264 rl.app.receivers.add(rl);
16267 receiver.asBinder().linkToDeath(rl, 0);
16268 } catch (RemoteException e) {
16271 rl.linkedToDeath = true;
16273 mRegisteredReceivers.put(receiver.asBinder(), rl);
16274 } else if (rl.uid != callingUid) {
16275 throw new IllegalArgumentException(
16276 "Receiver requested to register for uid " + callingUid
16277 + " was previously registered for uid " + rl.uid);
16278 } else if (rl.pid != callingPid) {
16279 throw new IllegalArgumentException(
16280 "Receiver requested to register for pid " + callingPid
16281 + " was previously registered for pid " + rl.pid);
16282 } else if (rl.userId != userId) {
16283 throw new IllegalArgumentException(
16284 "Receiver requested to register for user " + userId
16285 + " was previously registered for user " + rl.userId);
16287 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16288 permission, callingUid, userId);
16290 if (!bf.debugCheck()) {
16291 Slog.w(TAG, "==> For Dynamic broadcast");
16293 mReceiverResolver.addFilter(bf);
16295 // Enqueue broadcasts for all existing stickies that match
16297 if (allSticky != null) {
16298 ArrayList receivers = new ArrayList();
16301 final int stickyCount = allSticky.size();
16302 for (int i = 0; i < stickyCount; i++) {
16303 Intent intent = allSticky.get(i);
16304 BroadcastQueue queue = broadcastQueueForIntent(intent);
16305 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16306 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16307 null, 0, null, null, false, true, true, -1);
16308 queue.enqueueParallelBroadcastLocked(r);
16309 queue.scheduleBroadcastsLocked();
16317 public void unregisterReceiver(IIntentReceiver receiver) {
16318 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16320 final long origId = Binder.clearCallingIdentity();
16322 boolean doTrim = false;
16324 synchronized(this) {
16325 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16327 final BroadcastRecord r = rl.curBroadcast;
16328 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16329 final boolean doNext = r.queue.finishReceiverLocked(
16330 r, r.resultCode, r.resultData, r.resultExtras,
16331 r.resultAbort, false);
16334 r.queue.processNextBroadcast(false);
16338 if (rl.app != null) {
16339 rl.app.receivers.remove(rl);
16341 removeReceiverLocked(rl);
16342 if (rl.linkedToDeath) {
16343 rl.linkedToDeath = false;
16344 rl.receiver.asBinder().unlinkToDeath(rl, 0);
16349 // If we actually concluded any broadcasts, we might now be able
16350 // to trim the recipients' apps from our working set
16352 trimApplications();
16357 Binder.restoreCallingIdentity(origId);
16361 void removeReceiverLocked(ReceiverList rl) {
16362 mRegisteredReceivers.remove(rl.receiver.asBinder());
16363 for (int i = rl.size() - 1; i >= 0; i--) {
16364 mReceiverResolver.removeFilter(rl.get(i));
16368 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16369 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16370 ProcessRecord r = mLruProcesses.get(i);
16371 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16373 r.thread.dispatchPackageBroadcast(cmd, packages);
16374 } catch (RemoteException ex) {
16380 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16381 int callingUid, int[] users) {
16382 List<ResolveInfo> receivers = null;
16384 HashSet<ComponentName> singleUserReceivers = null;
16385 boolean scannedFirstReceivers = false;
16386 for (int user : users) {
16387 // Skip users that have Shell restrictions
16388 if (callingUid == Process.SHELL_UID
16389 && getUserManagerLocked().hasUserRestriction(
16390 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16393 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16394 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16395 if (user != UserHandle.USER_OWNER && newReceivers != null) {
16396 // If this is not the primary user, we need to check for
16397 // any receivers that should be filtered out.
16398 for (int i=0; i<newReceivers.size(); i++) {
16399 ResolveInfo ri = newReceivers.get(i);
16400 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16401 newReceivers.remove(i);
16406 if (newReceivers != null && newReceivers.size() == 0) {
16407 newReceivers = null;
16409 if (receivers == null) {
16410 receivers = newReceivers;
16411 } else if (newReceivers != null) {
16412 // We need to concatenate the additional receivers
16413 // found with what we have do far. This would be easy,
16414 // but we also need to de-dup any receivers that are
16416 if (!scannedFirstReceivers) {
16417 // Collect any single user receivers we had already retrieved.
16418 scannedFirstReceivers = true;
16419 for (int i=0; i<receivers.size(); i++) {
16420 ResolveInfo ri = receivers.get(i);
16421 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16422 ComponentName cn = new ComponentName(
16423 ri.activityInfo.packageName, ri.activityInfo.name);
16424 if (singleUserReceivers == null) {
16425 singleUserReceivers = new HashSet<ComponentName>();
16427 singleUserReceivers.add(cn);
16431 // Add the new results to the existing results, tracking
16432 // and de-dupping single user receivers.
16433 for (int i=0; i<newReceivers.size(); i++) {
16434 ResolveInfo ri = newReceivers.get(i);
16435 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16436 ComponentName cn = new ComponentName(
16437 ri.activityInfo.packageName, ri.activityInfo.name);
16438 if (singleUserReceivers == null) {
16439 singleUserReceivers = new HashSet<ComponentName>();
16441 if (!singleUserReceivers.contains(cn)) {
16442 singleUserReceivers.add(cn);
16451 } catch (RemoteException ex) {
16452 // pm is in same process, this will never happen.
16457 private final int broadcastIntentLocked(ProcessRecord callerApp,
16458 String callerPackage, Intent intent, String resolvedType,
16459 IIntentReceiver resultTo, int resultCode, String resultData,
16460 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16461 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16462 intent = new Intent(intent);
16464 // By default broadcasts do not go to stopped apps.
16465 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16467 // If we have not finished booting, don't allow this to launch new processes.
16468 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16469 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16472 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16473 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16474 + " ordered=" + ordered + " userid=" + userId);
16475 if ((resultTo != null) && !ordered) {
16476 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16479 userId = handleIncomingUser(callingPid, callingUid, userId,
16480 true, ALLOW_NON_FULL, "broadcast", callerPackage);
16482 // Make sure that the user who is receiving this broadcast is running.
16483 // If not, we will just skip it. Make an exception for shutdown broadcasts
16484 // and upgrade steps.
16486 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16487 if ((callingUid != Process.SYSTEM_UID
16488 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16489 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16490 Slog.w(TAG, "Skipping broadcast of " + intent
16491 + ": user " + userId + " is stopped");
16492 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16496 BroadcastOptions brOptions = null;
16497 if (options != null) {
16498 brOptions = new BroadcastOptions(options);
16499 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16500 // See if the caller is allowed to do this. Note we are checking against
16501 // the actual real caller (not whoever provided the operation as say a
16502 // PendingIntent), because that who is actually supplied the arguments.
16503 if (checkComponentPermission(
16504 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16505 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16506 != PackageManager.PERMISSION_GRANTED) {
16507 String msg = "Permission Denial: " + intent.getAction()
16508 + " broadcast from " + callerPackage + " (pid=" + callingPid
16509 + ", uid=" + callingUid + ")"
16511 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16513 throw new SecurityException(msg);
16519 * Prevent non-system code (defined here to be non-persistent
16520 * processes) from sending protected broadcasts.
16522 int callingAppId = UserHandle.getAppId(callingUid);
16523 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16524 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16525 || callingAppId == Process.NFC_UID || callingUid == 0) {
16527 } else if (callerApp == null || !callerApp.persistent) {
16529 if (AppGlobals.getPackageManager().isProtectedBroadcast(
16530 intent.getAction())) {
16531 String msg = "Permission Denial: not allowed to send broadcast "
16532 + intent.getAction() + " from pid="
16533 + callingPid + ", uid=" + callingUid;
16535 throw new SecurityException(msg);
16536 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16537 // Special case for compatibility: we don't want apps to send this,
16538 // but historically it has not been protected and apps may be using it
16539 // to poke their own app widget. So, instead of making it protected,
16540 // just limit it to the caller.
16541 if (callerApp == null) {
16542 String msg = "Permission Denial: not allowed to send broadcast "
16543 + intent.getAction() + " from unknown caller.";
16545 throw new SecurityException(msg);
16546 } else if (intent.getComponent() != null) {
16547 // They are good enough to send to an explicit component... verify
16548 // it is being sent to the calling app.
16549 if (!intent.getComponent().getPackageName().equals(
16550 callerApp.info.packageName)) {
16551 String msg = "Permission Denial: not allowed to send broadcast "
16552 + intent.getAction() + " to "
16553 + intent.getComponent().getPackageName() + " from "
16554 + callerApp.info.packageName;
16556 throw new SecurityException(msg);
16559 // Limit broadcast to their own package.
16560 intent.setPackage(callerApp.info.packageName);
16563 } catch (RemoteException e) {
16564 Slog.w(TAG, "Remote exception", e);
16565 return ActivityManager.BROADCAST_SUCCESS;
16569 final String action = intent.getAction();
16570 if (action != null) {
16572 case Intent.ACTION_UID_REMOVED:
16573 case Intent.ACTION_PACKAGE_REMOVED:
16574 case Intent.ACTION_PACKAGE_CHANGED:
16575 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16576 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16577 // Handle special intents: if this broadcast is from the package
16578 // manager about a package being removed, we need to remove all of
16579 // its activities from the history stack.
16580 if (checkComponentPermission(
16581 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16582 callingPid, callingUid, -1, true)
16583 != PackageManager.PERMISSION_GRANTED) {
16584 String msg = "Permission Denial: " + intent.getAction()
16585 + " broadcast from " + callerPackage + " (pid=" + callingPid
16586 + ", uid=" + callingUid + ")"
16588 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16590 throw new SecurityException(msg);
16593 case Intent.ACTION_UID_REMOVED:
16594 final Bundle intentExtras = intent.getExtras();
16595 final int uid = intentExtras != null
16596 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16598 mBatteryStatsService.removeUid(uid);
16599 mAppOpsService.uidRemoved(uid);
16602 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16603 // If resources are unavailable just force stop all those packages
16604 // and flush the attribute cache as well.
16606 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16607 if (list != null && list.length > 0) {
16608 for (int i = 0; i < list.length; i++) {
16609 forceStopPackageLocked(list[i], -1, false, true, true,
16610 false, false, userId, "storage unmount");
16612 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16613 sendPackageBroadcastLocked(
16614 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16618 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16619 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16621 case Intent.ACTION_PACKAGE_REMOVED:
16622 case Intent.ACTION_PACKAGE_CHANGED:
16623 Uri data = intent.getData();
16625 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16626 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16627 boolean fullUninstall = removed &&
16628 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16629 final boolean killProcess =
16630 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16632 forceStopPackageLocked(ssp, UserHandle.getAppId(
16633 intent.getIntExtra(Intent.EXTRA_UID, -1)),
16634 false, true, true, false, fullUninstall, userId,
16635 removed ? "pkg removed" : "pkg changed");
16638 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16639 new String[] {ssp}, userId);
16640 if (fullUninstall) {
16641 mAppOpsService.packageRemoved(
16642 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16644 // Remove all permissions granted from/to this package
16645 removeUriPermissionsForPackageLocked(ssp, userId, true);
16647 removeTasksByPackageNameLocked(ssp, userId);
16648 mBatteryStatsService.notePackageUninstalled(ssp);
16651 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16652 intent.getStringArrayExtra(
16653 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16659 case Intent.ACTION_PACKAGE_ADDED:
16660 // Special case for adding a package: by default turn on compatibility mode.
16661 Uri data = intent.getData();
16663 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16664 final boolean replacing =
16665 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16666 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16669 ApplicationInfo ai = AppGlobals.getPackageManager().
16670 getApplicationInfo(ssp, 0, 0);
16671 mBatteryStatsService.notePackageInstalled(ssp,
16672 ai != null ? ai.versionCode : 0);
16673 } catch (RemoteException e) {
16677 case Intent.ACTION_TIMEZONE_CHANGED:
16678 // If this is the time zone changed action, queue up a message that will reset
16679 // the timezone of all currently running processes. This message will get
16680 // queued up before the broadcast happens.
16681 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16683 case Intent.ACTION_TIME_CHANGED:
16684 // If the user set the time, let all running processes know.
16685 final int is24Hour =
16686 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16688 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16689 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16690 synchronized (stats) {
16691 stats.noteCurrentTimeChangedLocked();
16694 case Intent.ACTION_CLEAR_DNS_CACHE:
16695 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16697 case Proxy.PROXY_CHANGE_ACTION:
16698 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16699 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16704 // Add to the sticky list if requested.
16706 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16707 callingPid, callingUid)
16708 != PackageManager.PERMISSION_GRANTED) {
16709 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16710 + callingPid + ", uid=" + callingUid
16711 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16713 throw new SecurityException(msg);
16715 if (requiredPermissions != null && requiredPermissions.length > 0) {
16716 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16717 + " and enforce permissions " + Arrays.toString(requiredPermissions));
16718 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16720 if (intent.getComponent() != null) {
16721 throw new SecurityException(
16722 "Sticky broadcasts can't target a specific component");
16724 // We use userId directly here, since the "all" target is maintained
16725 // as a separate set of sticky broadcasts.
16726 if (userId != UserHandle.USER_ALL) {
16727 // But first, if this is not a broadcast to all users, then
16728 // make sure it doesn't conflict with an existing broadcast to
16730 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16731 UserHandle.USER_ALL);
16732 if (stickies != null) {
16733 ArrayList<Intent> list = stickies.get(intent.getAction());
16734 if (list != null) {
16735 int N = list.size();
16737 for (i=0; i<N; i++) {
16738 if (intent.filterEquals(list.get(i))) {
16739 throw new IllegalArgumentException(
16740 "Sticky broadcast " + intent + " for user "
16741 + userId + " conflicts with existing global broadcast");
16747 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16748 if (stickies == null) {
16749 stickies = new ArrayMap<>();
16750 mStickyBroadcasts.put(userId, stickies);
16752 ArrayList<Intent> list = stickies.get(intent.getAction());
16753 if (list == null) {
16754 list = new ArrayList<>();
16755 stickies.put(intent.getAction(), list);
16757 final int stickiesCount = list.size();
16759 for (i = 0; i < stickiesCount; i++) {
16760 if (intent.filterEquals(list.get(i))) {
16761 // This sticky already exists, replace it.
16762 list.set(i, new Intent(intent));
16766 if (i >= stickiesCount) {
16767 list.add(new Intent(intent));
16772 if (userId == UserHandle.USER_ALL) {
16773 // Caller wants broadcast to go to all started users.
16774 users = mStartedUserArray;
16776 // Caller wants broadcast to go to one specific user.
16777 users = new int[] {userId};
16780 // Figure out who all will receive this broadcast.
16781 List receivers = null;
16782 List<BroadcastFilter> registeredReceivers = null;
16783 // Need to resolve the intent to interested receivers...
16784 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16786 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16788 if (intent.getComponent() == null) {
16789 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16790 // Query one target user at a time, excluding shell-restricted users
16791 UserManagerService ums = getUserManagerLocked();
16792 for (int i = 0; i < users.length; i++) {
16793 if (ums.hasUserRestriction(
16794 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16797 List<BroadcastFilter> registeredReceiversForUser =
16798 mReceiverResolver.queryIntent(intent,
16799 resolvedType, false, users[i]);
16800 if (registeredReceivers == null) {
16801 registeredReceivers = registeredReceiversForUser;
16802 } else if (registeredReceiversForUser != null) {
16803 registeredReceivers.addAll(registeredReceiversForUser);
16807 registeredReceivers = mReceiverResolver.queryIntent(intent,
16808 resolvedType, false, userId);
16812 final boolean replacePending =
16813 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16815 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16816 + " replacePending=" + replacePending);
16818 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16819 if (!ordered && NR > 0) {
16820 // If we are not serializing this broadcast, then send the
16821 // registered receivers separately so they don't wait for the
16822 // components to be launched.
16823 final BroadcastQueue queue = broadcastQueueForIntent(intent);
16824 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16825 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16826 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16827 resultExtras, ordered, sticky, false, userId);
16828 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16829 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16831 queue.enqueueParallelBroadcastLocked(r);
16832 queue.scheduleBroadcastsLocked();
16834 registeredReceivers = null;
16838 // Merge into one list.
16840 if (receivers != null) {
16841 // A special case for PACKAGE_ADDED: do not allow the package
16842 // being added to see this broadcast. This prevents them from
16843 // using this as a back door to get run as soon as they are
16844 // installed. Maybe in the future we want to have a special install
16845 // broadcast or such for apps, but we'd like to deliberately make
16847 String skipPackages[] = null;
16848 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16849 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16850 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16851 Uri data = intent.getData();
16852 if (data != null) {
16853 String pkgName = data.getSchemeSpecificPart();
16854 if (pkgName != null) {
16855 skipPackages = new String[] { pkgName };
16858 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16859 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16861 if (skipPackages != null && (skipPackages.length > 0)) {
16862 for (String skipPackage : skipPackages) {
16863 if (skipPackage != null) {
16864 int NT = receivers.size();
16865 for (int it=0; it<NT; it++) {
16866 ResolveInfo curt = (ResolveInfo)receivers.get(it);
16867 if (curt.activityInfo.packageName.equals(skipPackage)) {
16868 receivers.remove(it);
16877 int NT = receivers != null ? receivers.size() : 0;
16879 ResolveInfo curt = null;
16880 BroadcastFilter curr = null;
16881 while (it < NT && ir < NR) {
16882 if (curt == null) {
16883 curt = (ResolveInfo)receivers.get(it);
16885 if (curr == null) {
16886 curr = registeredReceivers.get(ir);
16888 if (curr.getPriority() >= curt.priority) {
16889 // Insert this broadcast record into the final list.
16890 receivers.add(it, curr);
16896 // Skip to the next ResolveInfo in the final list.
16903 if (receivers == null) {
16904 receivers = new ArrayList();
16906 receivers.add(registeredReceivers.get(ir));
16910 if ((receivers != null && receivers.size() > 0)
16911 || resultTo != null) {
16912 BroadcastQueue queue = broadcastQueueForIntent(intent);
16913 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16914 callerPackage, callingPid, callingUid, resolvedType,
16915 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16916 resultData, resultExtras, ordered, sticky, false, userId);
16918 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16919 + ": prev had " + queue.mOrderedBroadcasts.size());
16920 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16921 "Enqueueing broadcast " + r.intent.getAction());
16923 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16925 queue.enqueueOrderedBroadcastLocked(r);
16926 queue.scheduleBroadcastsLocked();
16930 return ActivityManager.BROADCAST_SUCCESS;
16933 final Intent verifyBroadcastLocked(Intent intent) {
16934 // Refuse possible leaked file descriptors
16935 if (intent != null && intent.hasFileDescriptors() == true) {
16936 throw new IllegalArgumentException("File descriptors passed in Intent");
16939 int flags = intent.getFlags();
16941 if (!mProcessesReady) {
16942 // if the caller really truly claims to know what they're doing, go
16943 // ahead and allow the broadcast without launching any receivers
16944 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16945 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16946 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16947 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16948 + " before boot completion");
16949 throw new IllegalStateException("Cannot broadcast before boot completed");
16953 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16954 throw new IllegalArgumentException(
16955 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16961 public final int broadcastIntent(IApplicationThread caller,
16962 Intent intent, String resolvedType, IIntentReceiver resultTo,
16963 int resultCode, String resultData, Bundle resultExtras,
16964 String[] requiredPermissions, int appOp, Bundle options,
16965 boolean serialized, boolean sticky, int userId) {
16966 enforceNotIsolatedCaller("broadcastIntent");
16967 synchronized(this) {
16968 intent = verifyBroadcastLocked(intent);
16970 final ProcessRecord callerApp = getRecordForAppLocked(caller);
16971 final int callingPid = Binder.getCallingPid();
16972 final int callingUid = Binder.getCallingUid();
16973 final long origId = Binder.clearCallingIdentity();
16974 int res = broadcastIntentLocked(callerApp,
16975 callerApp != null ? callerApp.info.packageName : null,
16976 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
16977 requiredPermissions, appOp, null, serialized, sticky,
16978 callingPid, callingUid, userId);
16979 Binder.restoreCallingIdentity(origId);
16985 int broadcastIntentInPackage(String packageName, int uid,
16986 Intent intent, String resolvedType, IIntentReceiver resultTo,
16987 int resultCode, String resultData, Bundle resultExtras,
16988 String requiredPermission, Bundle options, boolean serialized, boolean sticky,
16990 synchronized(this) {
16991 intent = verifyBroadcastLocked(intent);
16993 final long origId = Binder.clearCallingIdentity();
16994 String[] requiredPermissions = requiredPermission == null ? null
16995 : new String[] {requiredPermission};
16996 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16997 resultTo, resultCode, resultData, resultExtras,
16998 requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
16999 sticky, -1, uid, userId);
17000 Binder.restoreCallingIdentity(origId);
17005 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17006 // Refuse possible leaked file descriptors
17007 if (intent != null && intent.hasFileDescriptors() == true) {
17008 throw new IllegalArgumentException("File descriptors passed in Intent");
17011 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17012 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17014 synchronized(this) {
17015 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17016 != PackageManager.PERMISSION_GRANTED) {
17017 String msg = "Permission Denial: unbroadcastIntent() from pid="
17018 + Binder.getCallingPid()
17019 + ", uid=" + Binder.getCallingUid()
17020 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17022 throw new SecurityException(msg);
17024 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17025 if (stickies != null) {
17026 ArrayList<Intent> list = stickies.get(intent.getAction());
17027 if (list != null) {
17028 int N = list.size();
17030 for (i=0; i<N; i++) {
17031 if (intent.filterEquals(list.get(i))) {
17036 if (list.size() <= 0) {
17037 stickies.remove(intent.getAction());
17040 if (stickies.size() <= 0) {
17041 mStickyBroadcasts.remove(userId);
17047 void backgroundServicesFinishedLocked(int userId) {
17048 for (BroadcastQueue queue : mBroadcastQueues) {
17049 queue.backgroundServicesFinishedLocked(userId);
17053 public void finishReceiver(IBinder who, int resultCode, String resultData,
17054 Bundle resultExtras, boolean resultAbort, int flags) {
17055 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17057 // Refuse possible leaked file descriptors
17058 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17059 throw new IllegalArgumentException("File descriptors passed in Bundle");
17062 final long origId = Binder.clearCallingIdentity();
17064 boolean doNext = false;
17067 synchronized(this) {
17068 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17069 ? mFgBroadcastQueue : mBgBroadcastQueue;
17070 r = queue.getMatchingOrderedReceiver(who);
17072 doNext = r.queue.finishReceiverLocked(r, resultCode,
17073 resultData, resultExtras, resultAbort, true);
17078 r.queue.processNextBroadcast(false);
17080 trimApplications();
17082 Binder.restoreCallingIdentity(origId);
17086 // =========================================================
17088 // =========================================================
17090 public boolean startInstrumentation(ComponentName className,
17091 String profileFile, int flags, Bundle arguments,
17092 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17093 int userId, String abiOverride) {
17094 enforceNotIsolatedCaller("startInstrumentation");
17095 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17096 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17097 // Refuse possible leaked file descriptors
17098 if (arguments != null && arguments.hasFileDescriptors()) {
17099 throw new IllegalArgumentException("File descriptors passed in Bundle");
17102 synchronized(this) {
17103 InstrumentationInfo ii = null;
17104 ApplicationInfo ai = null;
17106 ii = mContext.getPackageManager().getInstrumentationInfo(
17107 className, STOCK_PM_FLAGS);
17108 ai = AppGlobals.getPackageManager().getApplicationInfo(
17109 ii.targetPackage, STOCK_PM_FLAGS, userId);
17110 } catch (PackageManager.NameNotFoundException e) {
17111 } catch (RemoteException e) {
17114 reportStartInstrumentationFailure(watcher, className,
17115 "Unable to find instrumentation info for: " + className);
17119 reportStartInstrumentationFailure(watcher, className,
17120 "Unable to find instrumentation target package: " + ii.targetPackage);
17124 int match = mContext.getPackageManager().checkSignatures(
17125 ii.targetPackage, ii.packageName);
17126 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17127 String msg = "Permission Denial: starting instrumentation "
17128 + className + " from pid="
17129 + Binder.getCallingPid()
17130 + ", uid=" + Binder.getCallingPid()
17131 + " not allowed because package " + ii.packageName
17132 + " does not have a signature matching the target "
17133 + ii.targetPackage;
17134 reportStartInstrumentationFailure(watcher, className, msg);
17135 throw new SecurityException(msg);
17138 final long origId = Binder.clearCallingIdentity();
17139 // Instrumentation can kill and relaunch even persistent processes
17140 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17142 ProcessRecord app = addAppLocked(ai, false, abiOverride);
17143 app.instrumentationClass = className;
17144 app.instrumentationInfo = ai;
17145 app.instrumentationProfileFile = profileFile;
17146 app.instrumentationArguments = arguments;
17147 app.instrumentationWatcher = watcher;
17148 app.instrumentationUiAutomationConnection = uiAutomationConnection;
17149 app.instrumentationResultClass = className;
17150 Binder.restoreCallingIdentity(origId);
17157 * Report errors that occur while attempting to start Instrumentation. Always writes the
17158 * error to the logs, but if somebody is watching, send the report there too. This enables
17159 * the "am" command to report errors with more information.
17161 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
17162 * @param cn The component name of the instrumentation.
17163 * @param report The error report.
17165 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17166 ComponentName cn, String report) {
17167 Slog.w(TAG, report);
17169 if (watcher != null) {
17170 Bundle results = new Bundle();
17171 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17172 results.putString("Error", report);
17173 watcher.instrumentationStatus(cn, -1, results);
17175 } catch (RemoteException e) {
17180 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17181 if (app.instrumentationWatcher != null) {
17183 // NOTE: IInstrumentationWatcher *must* be oneway here
17184 app.instrumentationWatcher.instrumentationFinished(
17185 app.instrumentationClass,
17188 } catch (RemoteException e) {
17192 // Can't call out of the system process with a lock held, so post a message.
17193 if (app.instrumentationUiAutomationConnection != null) {
17194 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17195 app.instrumentationUiAutomationConnection).sendToTarget();
17198 app.instrumentationWatcher = null;
17199 app.instrumentationUiAutomationConnection = null;
17200 app.instrumentationClass = null;
17201 app.instrumentationInfo = null;
17202 app.instrumentationProfileFile = null;
17203 app.instrumentationArguments = null;
17205 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17209 public void finishInstrumentation(IApplicationThread target,
17210 int resultCode, Bundle results) {
17211 int userId = UserHandle.getCallingUserId();
17212 // Refuse possible leaked file descriptors
17213 if (results != null && results.hasFileDescriptors()) {
17214 throw new IllegalArgumentException("File descriptors passed in Intent");
17217 synchronized(this) {
17218 ProcessRecord app = getRecordForAppLocked(target);
17220 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17223 final long origId = Binder.clearCallingIdentity();
17224 finishInstrumentationLocked(app, resultCode, results);
17225 Binder.restoreCallingIdentity(origId);
17229 // =========================================================
17231 // =========================================================
17233 public ConfigurationInfo getDeviceConfigurationInfo() {
17234 ConfigurationInfo config = new ConfigurationInfo();
17235 synchronized (this) {
17236 config.reqTouchScreen = mConfiguration.touchscreen;
17237 config.reqKeyboardType = mConfiguration.keyboard;
17238 config.reqNavigation = mConfiguration.navigation;
17239 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17240 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17241 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17243 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17244 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17245 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17247 config.reqGlEsVersion = GL_ES_VERSION;
17252 ActivityStack getFocusedStack() {
17253 return mStackSupervisor.getFocusedStack();
17257 public int getFocusedStackId() throws RemoteException {
17258 ActivityStack focusedStack = getFocusedStack();
17259 if (focusedStack != null) {
17260 return focusedStack.getStackId();
17265 public Configuration getConfiguration() {
17267 synchronized(this) {
17268 ci = new Configuration(mConfiguration);
17269 ci.userSetLocale = false;
17274 public void updatePersistentConfiguration(Configuration values) {
17275 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17276 "updateConfiguration()");
17277 enforceWriteSettingsPermission("updateConfiguration()");
17278 if (values == null) {
17279 throw new NullPointerException("Configuration must not be null");
17282 synchronized(this) {
17283 final long origId = Binder.clearCallingIdentity();
17284 updateConfigurationLocked(values, null, true, false);
17285 Binder.restoreCallingIdentity(origId);
17289 private void enforceWriteSettingsPermission(String func) {
17290 int uid = Binder.getCallingUid();
17291 if (uid == Process.ROOT_UID) {
17295 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17296 Settings.getPackageNameForUid(mContext, uid), false)) {
17300 String msg = "Permission Denial: " + func + " from pid="
17301 + Binder.getCallingPid()
17303 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17305 throw new SecurityException(msg);
17308 public void updateConfiguration(Configuration values) {
17309 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17310 "updateConfiguration()");
17312 synchronized(this) {
17313 if (values == null && mWindowManager != null) {
17314 // sentinel: fetch the current configuration from the window manager
17315 values = mWindowManager.computeNewConfiguration();
17318 if (mWindowManager != null) {
17319 mProcessList.applyDisplaySize(mWindowManager);
17322 final long origId = Binder.clearCallingIdentity();
17323 if (values != null) {
17324 Settings.System.clearConfiguration(values);
17326 updateConfigurationLocked(values, null, false, false);
17327 Binder.restoreCallingIdentity(origId);
17332 * Do either or both things: (1) change the current configuration, and (2)
17333 * make sure the given activity is running with the (now) current
17334 * configuration. Returns true if the activity has been left running, or
17335 * false if <var>starting</var> is being destroyed to match the new
17337 * @param persistent TODO
17339 boolean updateConfigurationLocked(Configuration values,
17340 ActivityRecord starting, boolean persistent, boolean initLocale) {
17343 if (values != null) {
17344 Configuration newConfig = new Configuration(mConfiguration);
17345 changes = newConfig.updateFrom(values);
17346 if (changes != 0) {
17347 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17348 "Updating configuration to: " + values);
17350 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17352 if (!initLocale && values.locale != null && values.userSetLocale) {
17353 final String languageTag = values.locale.toLanguageTag();
17354 SystemProperties.set("persist.sys.locale", languageTag);
17355 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17359 mConfigurationSeq++;
17360 if (mConfigurationSeq <= 0) {
17361 mConfigurationSeq = 1;
17363 newConfig.seq = mConfigurationSeq;
17364 mConfiguration = newConfig;
17365 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17366 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17367 //mUsageStatsService.noteStartConfig(newConfig);
17369 final Configuration configCopy = new Configuration(mConfiguration);
17371 // TODO: If our config changes, should we auto dismiss any currently
17372 // showing dialogs?
17373 mShowDialogs = shouldShowDialogs(newConfig);
17375 AttributeCache ac = AttributeCache.instance();
17377 ac.updateConfiguration(configCopy);
17380 // Make sure all resources in our process are updated
17381 // right now, so that anyone who is going to retrieve
17382 // resource values after we return will be sure to get
17383 // the new ones. This is especially important during
17384 // boot, where the first config change needs to guarantee
17385 // all resources have that config before following boot
17386 // code is executed.
17387 mSystemThread.applyConfigurationToResources(configCopy);
17389 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17390 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17391 msg.obj = new Configuration(configCopy);
17392 mHandler.sendMessage(msg);
17395 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17396 ProcessRecord app = mLruProcesses.get(i);
17398 if (app.thread != null) {
17399 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17400 + app.processName + " new config " + mConfiguration);
17401 app.thread.scheduleConfigurationChanged(configCopy);
17403 } catch (Exception e) {
17406 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17407 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17408 | Intent.FLAG_RECEIVER_REPLACE_PENDING
17409 | Intent.FLAG_RECEIVER_FOREGROUND);
17410 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17411 null, AppOpsManager.OP_NONE, null, false, false,
17412 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17413 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17414 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17415 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17416 if (!mProcessesReady) {
17417 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17419 broadcastIntentLocked(null, null, intent,
17420 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17421 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17426 boolean kept = true;
17427 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17428 // mainStack is null during startup.
17429 if (mainStack != null) {
17430 if (changes != 0 && starting == null) {
17431 // If the configuration changed, and the caller is not already
17432 // in the process of starting an activity, then find the top
17433 // activity to check if its configuration needs to change.
17434 starting = mainStack.topRunningActivityLocked(null);
17437 if (starting != null) {
17438 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17439 // And we need to make sure at this point that all other activities
17440 // are made visible with the correct configuration.
17441 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17445 if (values != null && mWindowManager != null) {
17446 mWindowManager.setNewConfiguration(mConfiguration);
17453 * Decide based on the configuration whether we should shouw the ANR,
17454 * crash, etc dialogs. The idea is that if there is no affordnace to
17455 * press the on-screen buttons, we shouldn't show the dialog.
17457 * A thought: SystemUI might also want to get told about this, the Power
17458 * dialog / global actions also might want different behaviors.
17460 private static final boolean shouldShowDialogs(Configuration config) {
17461 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17462 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17463 && config.navigation == Configuration.NAVIGATION_NONAV);
17467 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17468 synchronized (this) {
17469 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17470 if (srec != null) {
17471 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17477 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17478 Intent resultData) {
17480 synchronized (this) {
17481 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17483 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17489 public int getLaunchedFromUid(IBinder activityToken) {
17490 ActivityRecord srec;
17491 synchronized (this) {
17492 srec = ActivityRecord.forTokenLocked(activityToken);
17494 if (srec == null) {
17497 return srec.launchedFromUid;
17500 public String getLaunchedFromPackage(IBinder activityToken) {
17501 ActivityRecord srec;
17502 synchronized (this) {
17503 srec = ActivityRecord.forTokenLocked(activityToken);
17505 if (srec == null) {
17508 return srec.launchedFromPackage;
17511 // =========================================================
17512 // LIFETIME MANAGEMENT
17513 // =========================================================
17515 // Returns which broadcast queue the app is the current [or imminent] receiver
17516 // on, or 'null' if the app is not an active broadcast recipient.
17517 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17518 BroadcastRecord r = app.curReceiver;
17523 // It's not the current receiver, but it might be starting up to become one
17524 synchronized (this) {
17525 for (BroadcastQueue queue : mBroadcastQueues) {
17526 r = queue.mPendingBroadcast;
17527 if (r != null && r.curApp == app) {
17528 // found it; report which queue it's in
17537 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17538 ComponentName targetComponent, String targetProcess) {
17539 if (!mTrackingAssociations) {
17542 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17543 = mAssociations.get(targetUid);
17544 if (components == null) {
17545 components = new ArrayMap<>();
17546 mAssociations.put(targetUid, components);
17548 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17549 if (sourceUids == null) {
17550 sourceUids = new SparseArray<>();
17551 components.put(targetComponent, sourceUids);
17553 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17554 if (sourceProcesses == null) {
17555 sourceProcesses = new ArrayMap<>();
17556 sourceUids.put(sourceUid, sourceProcesses);
17558 Association ass = sourceProcesses.get(sourceProcess);
17560 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17562 sourceProcesses.put(sourceProcess, ass);
17566 if (ass.mNesting == 1) {
17567 ass.mStartTime = SystemClock.uptimeMillis();
17572 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17573 ComponentName targetComponent) {
17574 if (!mTrackingAssociations) {
17577 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17578 = mAssociations.get(targetUid);
17579 if (components == null) {
17582 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17583 if (sourceUids == null) {
17586 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17587 if (sourceProcesses == null) {
17590 Association ass = sourceProcesses.get(sourceProcess);
17591 if (ass == null || ass.mNesting <= 0) {
17595 if (ass.mNesting == 0) {
17596 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17600 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17601 boolean doingAll, long now) {
17602 if (mAdjSeq == app.adjSeq) {
17603 // This adjustment has already been computed.
17604 return app.curRawAdj;
17607 if (app.thread == null) {
17608 app.adjSeq = mAdjSeq;
17609 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17610 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17611 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17614 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17615 app.adjSource = null;
17616 app.adjTarget = null;
17618 app.cached = false;
17620 final int activitiesSize = app.activities.size();
17622 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17623 // The max adjustment doesn't allow this app to be anything
17624 // below foreground, so it is not worth doing work for it.
17625 app.adjType = "fixed";
17626 app.adjSeq = mAdjSeq;
17627 app.curRawAdj = app.maxAdj;
17628 app.foregroundActivities = false;
17629 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17630 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17631 // System processes can do UI, and when they do we want to have
17632 // them trim their memory after the user leaves the UI. To
17633 // facilitate this, here we need to determine whether or not it
17634 // is currently showing UI.
17635 app.systemNoUi = true;
17636 if (app == TOP_APP) {
17637 app.systemNoUi = false;
17638 } else if (activitiesSize > 0) {
17639 for (int j = 0; j < activitiesSize; j++) {
17640 final ActivityRecord r = app.activities.get(j);
17642 app.systemNoUi = false;
17646 if (!app.systemNoUi) {
17647 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17649 return (app.curAdj=app.maxAdj);
17652 app.systemNoUi = false;
17654 final int PROCESS_STATE_TOP = mTopProcessState;
17656 // Determine the importance of the process, starting with most
17657 // important to least, and assign an appropriate OOM adjustment.
17661 boolean foregroundActivities = false;
17662 BroadcastQueue queue;
17663 if (app == TOP_APP) {
17664 // The last app on the list is the foreground app.
17665 adj = ProcessList.FOREGROUND_APP_ADJ;
17666 schedGroup = Process.THREAD_GROUP_DEFAULT;
17667 app.adjType = "top-activity";
17668 foregroundActivities = true;
17669 procState = PROCESS_STATE_TOP;
17670 } else if (app.instrumentationClass != null) {
17671 // Don't want to kill running instrumentation.
17672 adj = ProcessList.FOREGROUND_APP_ADJ;
17673 schedGroup = Process.THREAD_GROUP_DEFAULT;
17674 app.adjType = "instrumentation";
17675 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17676 } else if ((queue = isReceivingBroadcast(app)) != null) {
17677 // An app that is currently receiving a broadcast also
17678 // counts as being in the foreground for OOM killer purposes.
17679 // It's placed in a sched group based on the nature of the
17680 // broadcast as reflected by which queue it's active in.
17681 adj = ProcessList.FOREGROUND_APP_ADJ;
17682 schedGroup = (queue == mFgBroadcastQueue)
17683 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17684 app.adjType = "broadcast";
17685 procState = ActivityManager.PROCESS_STATE_RECEIVER;
17686 } else if (app.executingServices.size() > 0) {
17687 // An app that is currently executing a service callback also
17688 // counts as being in the foreground.
17689 adj = ProcessList.FOREGROUND_APP_ADJ;
17690 schedGroup = app.execServicesFg ?
17691 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17692 app.adjType = "exec-service";
17693 procState = ActivityManager.PROCESS_STATE_SERVICE;
17694 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17696 // As far as we know the process is empty. We may change our mind later.
17697 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17698 // At this point we don't actually know the adjustment. Use the cached adj
17699 // value that the caller wants us to.
17701 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17704 app.adjType = "cch-empty";
17707 // Examine all activities if not already foreground.
17708 if (!foregroundActivities && activitiesSize > 0) {
17709 for (int j = 0; j < activitiesSize; j++) {
17710 final ActivityRecord r = app.activities.get(j);
17711 if (r.app != app) {
17712 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17713 + app + "?!? Using " + r.app + " instead.");
17717 // App has a visible activity; only upgrade adjustment.
17718 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17719 adj = ProcessList.VISIBLE_APP_ADJ;
17720 app.adjType = "visible";
17722 if (procState > PROCESS_STATE_TOP) {
17723 procState = PROCESS_STATE_TOP;
17725 schedGroup = Process.THREAD_GROUP_DEFAULT;
17726 app.cached = false;
17728 foregroundActivities = true;
17730 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17731 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17732 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17733 app.adjType = "pausing";
17735 if (procState > PROCESS_STATE_TOP) {
17736 procState = PROCESS_STATE_TOP;
17738 schedGroup = Process.THREAD_GROUP_DEFAULT;
17739 app.cached = false;
17741 foregroundActivities = true;
17742 } else if (r.state == ActivityState.STOPPING) {
17743 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17744 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17745 app.adjType = "stopping";
17747 // For the process state, we will at this point consider the
17748 // process to be cached. It will be cached either as an activity
17749 // or empty depending on whether the activity is finishing. We do
17750 // this so that we can treat the process as cached for purposes of
17751 // memory trimming (determing current memory level, trim command to
17752 // send to process) since there can be an arbitrary number of stopping
17753 // processes and they should soon all go into the cached state.
17754 if (!r.finishing) {
17755 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17756 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17759 app.cached = false;
17761 foregroundActivities = true;
17763 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17764 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17765 app.adjType = "cch-act";
17771 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17772 if (app.foregroundServices) {
17773 // The user is aware of this app, so make it visible.
17774 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17775 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17776 app.cached = false;
17777 app.adjType = "fg-service";
17778 schedGroup = Process.THREAD_GROUP_DEFAULT;
17779 } else if (app.forcingToForeground != null) {
17780 // The user is aware of this app, so make it visible.
17781 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17782 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17783 app.cached = false;
17784 app.adjType = "force-fg";
17785 app.adjSource = app.forcingToForeground;
17786 schedGroup = Process.THREAD_GROUP_DEFAULT;
17790 if (app == mHeavyWeightProcess) {
17791 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17792 // We don't want to kill the current heavy-weight process.
17793 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17794 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17795 app.cached = false;
17796 app.adjType = "heavy";
17798 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17799 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17803 if (app == mHomeProcess) {
17804 if (adj > ProcessList.HOME_APP_ADJ) {
17805 // This process is hosting what we currently consider to be the
17806 // home app, so we don't want to let it go into the background.
17807 adj = ProcessList.HOME_APP_ADJ;
17808 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17809 app.cached = false;
17810 app.adjType = "home";
17812 if (procState > ActivityManager.PROCESS_STATE_HOME) {
17813 procState = ActivityManager.PROCESS_STATE_HOME;
17817 if (app == mPreviousProcess && app.activities.size() > 0) {
17818 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17819 // This was the previous process that showed UI to the user.
17820 // We want to try to keep it around more aggressively, to give
17821 // a good experience around switching between two apps.
17822 adj = ProcessList.PREVIOUS_APP_ADJ;
17823 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17824 app.cached = false;
17825 app.adjType = "previous";
17827 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17828 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17832 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17833 + " reason=" + app.adjType);
17835 // By default, we use the computed adjustment. It may be changed if
17836 // there are applications dependent on our services or providers, but
17837 // this gives us a baseline and makes sure we don't get into an
17838 // infinite recursion.
17839 app.adjSeq = mAdjSeq;
17840 app.curRawAdj = adj;
17841 app.hasStartedServices = false;
17843 if (mBackupTarget != null && app == mBackupTarget.app) {
17844 // If possible we want to avoid killing apps while they're being backed up
17845 if (adj > ProcessList.BACKUP_APP_ADJ) {
17846 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17847 adj = ProcessList.BACKUP_APP_ADJ;
17848 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17849 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17851 app.adjType = "backup";
17852 app.cached = false;
17854 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17855 procState = ActivityManager.PROCESS_STATE_BACKUP;
17859 boolean mayBeTop = false;
17861 for (int is = app.services.size()-1;
17862 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17863 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17864 || procState > ActivityManager.PROCESS_STATE_TOP);
17866 ServiceRecord s = app.services.valueAt(is);
17867 if (s.startRequested) {
17868 app.hasStartedServices = true;
17869 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17870 procState = ActivityManager.PROCESS_STATE_SERVICE;
17872 if (app.hasShownUi && app != mHomeProcess) {
17873 // If this process has shown some UI, let it immediately
17874 // go to the LRU list because it may be pretty heavy with
17875 // UI stuff. We'll tag it with a label just to help
17876 // debug and understand what is going on.
17877 if (adj > ProcessList.SERVICE_ADJ) {
17878 app.adjType = "cch-started-ui-services";
17881 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17882 // This service has seen some activity within
17883 // recent memory, so we will keep its process ahead
17884 // of the background processes.
17885 if (adj > ProcessList.SERVICE_ADJ) {
17886 adj = ProcessList.SERVICE_ADJ;
17887 app.adjType = "started-services";
17888 app.cached = false;
17891 // If we have let the service slide into the background
17892 // state, still have some text describing what it is doing
17893 // even though the service no longer has an impact.
17894 if (adj > ProcessList.SERVICE_ADJ) {
17895 app.adjType = "cch-started-services";
17899 for (int conni = s.connections.size()-1;
17900 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17901 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17902 || procState > ActivityManager.PROCESS_STATE_TOP);
17904 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17906 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17907 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17908 || procState > ActivityManager.PROCESS_STATE_TOP);
17910 // XXX should compute this based on the max of
17911 // all connected clients.
17912 ConnectionRecord cr = clist.get(i);
17913 if (cr.binding.client == app) {
17914 // Binding to ourself is not interesting.
17917 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17918 ProcessRecord client = cr.binding.client;
17919 int clientAdj = computeOomAdjLocked(client, cachedAdj,
17920 TOP_APP, doingAll, now);
17921 int clientProcState = client.curProcState;
17922 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17923 // If the other app is cached for any reason, for purposes here
17924 // we are going to consider it empty. The specific cached state
17925 // doesn't propagate except under certain conditions.
17926 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17928 String adjType = null;
17929 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17930 // Not doing bind OOM management, so treat
17931 // this guy more like a started service.
17932 if (app.hasShownUi && app != mHomeProcess) {
17933 // If this process has shown some UI, let it immediately
17934 // go to the LRU list because it may be pretty heavy with
17935 // UI stuff. We'll tag it with a label just to help
17936 // debug and understand what is going on.
17937 if (adj > clientAdj) {
17938 adjType = "cch-bound-ui-services";
17940 app.cached = false;
17942 clientProcState = procState;
17944 if (now >= (s.lastActivity
17945 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17946 // This service has not seen activity within
17947 // recent memory, so allow it to drop to the
17948 // LRU list if there is no other reason to keep
17949 // it around. We'll also tag it with a label just
17950 // to help debug and undertand what is going on.
17951 if (adj > clientAdj) {
17952 adjType = "cch-bound-services";
17958 if (adj > clientAdj) {
17959 // If this process has recently shown UI, and
17960 // the process that is binding to it is less
17961 // important than being visible, then we don't
17962 // care about the binding as much as we care
17963 // about letting this process get into the LRU
17964 // list to be killed and restarted if needed for
17966 if (app.hasShownUi && app != mHomeProcess
17967 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17968 adjType = "cch-bound-ui-services";
17970 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17971 |Context.BIND_IMPORTANT)) != 0) {
17972 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17973 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17974 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17975 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17976 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17977 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17978 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17981 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17982 adj = ProcessList.VISIBLE_APP_ADJ;
17985 if (!client.cached) {
17986 app.cached = false;
17988 adjType = "service";
17991 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17992 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17993 schedGroup = Process.THREAD_GROUP_DEFAULT;
17995 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17996 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17997 // Special handling of clients who are in the top state.
17998 // We *may* want to consider this process to be in the
17999 // top state as well, but only if there is not another
18000 // reason for it to be running. Being on the top is a
18001 // special state, meaning you are specifically running
18002 // for the current top app. If the process is already
18003 // running in the background for some other reason, it
18004 // is more important to continue considering it to be
18005 // in the background state.
18007 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18009 // Special handling for above-top states (persistent
18010 // processes). These should not bring the current process
18011 // into the top state, since they are not on top. Instead
18012 // give them the best state after that.
18013 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18015 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18016 } else if (mWakefulness
18017 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18018 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18021 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18024 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18029 if (clientProcState <
18030 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18032 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18035 if (procState > clientProcState) {
18036 procState = clientProcState;
18038 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18039 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18040 app.pendingUiClean = true;
18042 if (adjType != null) {
18043 app.adjType = adjType;
18044 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18045 .REASON_SERVICE_IN_USE;
18046 app.adjSource = cr.binding.client;
18047 app.adjSourceProcState = clientProcState;
18048 app.adjTarget = s.name;
18051 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18052 app.treatLikeActivity = true;
18054 final ActivityRecord a = cr.activity;
18055 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18056 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18057 (a.visible || a.state == ActivityState.RESUMED
18058 || a.state == ActivityState.PAUSING)) {
18059 adj = ProcessList.FOREGROUND_APP_ADJ;
18060 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18061 schedGroup = Process.THREAD_GROUP_DEFAULT;
18063 app.cached = false;
18064 app.adjType = "service";
18065 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18066 .REASON_SERVICE_IN_USE;
18068 app.adjSourceProcState = procState;
18069 app.adjTarget = s.name;
18076 for (int provi = app.pubProviders.size()-1;
18077 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18078 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18079 || procState > ActivityManager.PROCESS_STATE_TOP);
18081 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18082 for (int i = cpr.connections.size()-1;
18083 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18084 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18085 || procState > ActivityManager.PROCESS_STATE_TOP);
18087 ContentProviderConnection conn = cpr.connections.get(i);
18088 ProcessRecord client = conn.client;
18089 if (client == app) {
18090 // Being our own client is not interesting.
18093 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18094 int clientProcState = client.curProcState;
18095 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18096 // If the other app is cached for any reason, for purposes here
18097 // we are going to consider it empty.
18098 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18100 if (adj > clientAdj) {
18101 if (app.hasShownUi && app != mHomeProcess
18102 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18103 app.adjType = "cch-ui-provider";
18105 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18106 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18107 app.adjType = "provider";
18109 app.cached &= client.cached;
18110 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18111 .REASON_PROVIDER_IN_USE;
18112 app.adjSource = client;
18113 app.adjSourceProcState = clientProcState;
18114 app.adjTarget = cpr.name;
18116 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18117 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18118 // Special handling of clients who are in the top state.
18119 // We *may* want to consider this process to be in the
18120 // top state as well, but only if there is not another
18121 // reason for it to be running. Being on the top is a
18122 // special state, meaning you are specifically running
18123 // for the current top app. If the process is already
18124 // running in the background for some other reason, it
18125 // is more important to continue considering it to be
18126 // in the background state.
18128 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18130 // Special handling for above-top states (persistent
18131 // processes). These should not bring the current process
18132 // into the top state, since they are not on top. Instead
18133 // give them the best state after that.
18135 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18138 if (procState > clientProcState) {
18139 procState = clientProcState;
18141 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18142 schedGroup = Process.THREAD_GROUP_DEFAULT;
18145 // If the provider has external (non-framework) process
18146 // dependencies, ensure that its adjustment is at least
18147 // FOREGROUND_APP_ADJ.
18148 if (cpr.hasExternalProcessHandles()) {
18149 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18150 adj = ProcessList.FOREGROUND_APP_ADJ;
18151 schedGroup = Process.THREAD_GROUP_DEFAULT;
18152 app.cached = false;
18153 app.adjType = "provider";
18154 app.adjTarget = cpr.name;
18156 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18157 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18162 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18163 // A client of one of our services or providers is in the top state. We
18164 // *may* want to be in the top state, but not if we are already running in
18165 // the background for some other reason. For the decision here, we are going
18166 // to pick out a few specific states that we want to remain in when a client
18167 // is top (states that tend to be longer-term) and otherwise allow it to go
18168 // to the top state.
18169 switch (procState) {
18170 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18171 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18172 case ActivityManager.PROCESS_STATE_SERVICE:
18173 // These all are longer-term states, so pull them up to the top
18174 // of the background states, but not all the way to the top state.
18175 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18178 // Otherwise, top is a better choice, so take it.
18179 procState = ActivityManager.PROCESS_STATE_TOP;
18184 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18185 if (app.hasClientActivities) {
18186 // This is a cached process, but with client activities. Mark it so.
18187 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18188 app.adjType = "cch-client-act";
18189 } else if (app.treatLikeActivity) {
18190 // This is a cached process, but somebody wants us to treat it like it has
18191 // an activity, okay!
18192 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18193 app.adjType = "cch-as-act";
18197 if (adj == ProcessList.SERVICE_ADJ) {
18199 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18200 mNewNumServiceProcs++;
18201 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18202 if (!app.serviceb) {
18203 // This service isn't far enough down on the LRU list to
18204 // normally be a B service, but if we are low on RAM and it
18205 // is large we want to force it down since we would prefer to
18206 // keep launcher over it.
18207 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18208 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18209 app.serviceHighRam = true;
18210 app.serviceb = true;
18211 //Slog.i(TAG, "ADJ " + app + " high ram!");
18213 mNewNumAServiceProcs++;
18214 //Slog.i(TAG, "ADJ " + app + " not high ram!");
18217 app.serviceHighRam = false;
18220 if (app.serviceb) {
18221 adj = ProcessList.SERVICE_B_ADJ;
18225 app.curRawAdj = adj;
18227 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18228 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18229 if (adj > app.maxAdj) {
18231 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18232 schedGroup = Process.THREAD_GROUP_DEFAULT;
18236 // Do final modification to adj. Everything we do between here and applying
18237 // the final setAdj must be done in this function, because we will also use
18238 // it when computing the final cached adj later. Note that we don't need to
18239 // worry about this for max adj above, since max adj will always be used to
18240 // keep it out of the cached vaues.
18241 app.curAdj = app.modifyRawOomAdj(adj);
18242 app.curSchedGroup = schedGroup;
18243 app.curProcState = procState;
18244 app.foregroundActivities = foregroundActivities;
18246 return app.curRawAdj;
18250 * Record new PSS sample for a process.
18252 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18253 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18254 proc.lastPssTime = now;
18255 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18256 if (DEBUG_PSS) Slog.d(TAG_PSS,
18257 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18258 + " state=" + ProcessList.makeProcStateString(procState));
18259 if (proc.initialIdlePss == 0) {
18260 proc.initialIdlePss = pss;
18262 proc.lastPss = pss;
18263 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18264 proc.lastCachedPss = pss;
18267 final SparseArray<Pair<Long, String>> watchUids
18268 = mMemWatchProcesses.getMap().get(proc.processName);
18270 if (watchUids != null) {
18271 Pair<Long, String> val = watchUids.get(proc.uid);
18273 val = watchUids.get(0);
18279 if (check != null) {
18280 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18281 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18282 if (!isDebuggable) {
18283 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18284 isDebuggable = true;
18287 if (isDebuggable) {
18288 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18289 final ProcessRecord myProc = proc;
18290 final File heapdumpFile = DumpHeapProvider.getJavaFile();
18291 mMemWatchDumpProcName = proc.processName;
18292 mMemWatchDumpFile = heapdumpFile.toString();
18293 mMemWatchDumpPid = proc.pid;
18294 mMemWatchDumpUid = proc.uid;
18295 BackgroundThread.getHandler().post(new Runnable() {
18297 public void run() {
18298 revokeUriPermission(ActivityThread.currentActivityThread()
18299 .getApplicationThread(),
18300 DumpHeapActivity.JAVA_URI,
18301 Intent.FLAG_GRANT_READ_URI_PERMISSION
18302 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18303 UserHandle.myUserId());
18304 ParcelFileDescriptor fd = null;
18306 heapdumpFile.delete();
18307 fd = ParcelFileDescriptor.open(heapdumpFile,
18308 ParcelFileDescriptor.MODE_CREATE |
18309 ParcelFileDescriptor.MODE_TRUNCATE |
18310 ParcelFileDescriptor.MODE_WRITE_ONLY |
18311 ParcelFileDescriptor.MODE_APPEND);
18312 IApplicationThread thread = myProc.thread;
18313 if (thread != null) {
18315 if (DEBUG_PSS) Slog.d(TAG_PSS,
18316 "Requesting dump heap from "
18317 + myProc + " to " + heapdumpFile);
18318 thread.dumpHeap(true, heapdumpFile.toString(), fd);
18319 } catch (RemoteException e) {
18322 } catch (FileNotFoundException e) {
18323 e.printStackTrace();
18328 } catch (IOException e) {
18335 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18336 + ", but debugging not enabled");
18343 * Schedule PSS collection of a process.
18345 void requestPssLocked(ProcessRecord proc, int procState) {
18346 if (mPendingPssProcesses.contains(proc)) {
18349 if (mPendingPssProcesses.size() == 0) {
18350 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18352 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18353 proc.pssProcState = procState;
18354 mPendingPssProcesses.add(proc);
18358 * Schedule PSS collection of all processes.
18360 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18362 if (now < (mLastFullPssTime +
18363 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18367 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
18368 mLastFullPssTime = now;
18369 mFullPssPending = true;
18370 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18371 mPendingPssProcesses.clear();
18372 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18373 ProcessRecord app = mLruProcesses.get(i);
18374 if (app.thread == null
18375 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18378 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18379 app.pssProcState = app.setProcState;
18380 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18381 mTestPssMode, isSleeping(), now);
18382 mPendingPssProcesses.add(app);
18385 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18388 public void setTestPssMode(boolean enabled) {
18389 synchronized (this) {
18390 mTestPssMode = enabled;
18392 // Whenever we enable the mode, we want to take a snapshot all of current
18393 // process mem use.
18394 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18400 * Ask a given process to GC right now.
18402 final void performAppGcLocked(ProcessRecord app) {
18404 app.lastRequestedGc = SystemClock.uptimeMillis();
18405 if (app.thread != null) {
18406 if (app.reportLowMemory) {
18407 app.reportLowMemory = false;
18408 app.thread.scheduleLowMemory();
18410 app.thread.processInBackground();
18413 } catch (Exception e) {
18419 * Returns true if things are idle enough to perform GCs.
18421 private final boolean canGcNowLocked() {
18422 boolean processingBroadcasts = false;
18423 for (BroadcastQueue q : mBroadcastQueues) {
18424 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18425 processingBroadcasts = true;
18428 return !processingBroadcasts
18429 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18433 * Perform GCs on all processes that are waiting for it, but only
18434 * if things are idle.
18436 final void performAppGcsLocked() {
18437 final int N = mProcessesToGc.size();
18441 if (canGcNowLocked()) {
18442 while (mProcessesToGc.size() > 0) {
18443 ProcessRecord proc = mProcessesToGc.remove(0);
18444 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18445 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18446 <= SystemClock.uptimeMillis()) {
18447 // To avoid spamming the system, we will GC processes one
18448 // at a time, waiting a few seconds between each.
18449 performAppGcLocked(proc);
18450 scheduleAppGcsLocked();
18453 // It hasn't been long enough since we last GCed this
18454 // process... put it in the list to wait for its time.
18455 addProcessToGcListLocked(proc);
18461 scheduleAppGcsLocked();
18466 * If all looks good, perform GCs on all processes waiting for them.
18468 final void performAppGcsIfAppropriateLocked() {
18469 if (canGcNowLocked()) {
18470 performAppGcsLocked();
18473 // Still not idle, wait some more.
18474 scheduleAppGcsLocked();
18478 * Schedule the execution of all pending app GCs.
18480 final void scheduleAppGcsLocked() {
18481 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18483 if (mProcessesToGc.size() > 0) {
18484 // Schedule a GC for the time to the next process.
18485 ProcessRecord proc = mProcessesToGc.get(0);
18486 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18488 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18489 long now = SystemClock.uptimeMillis();
18490 if (when < (now+GC_TIMEOUT)) {
18491 when = now + GC_TIMEOUT;
18493 mHandler.sendMessageAtTime(msg, when);
18498 * Add a process to the array of processes waiting to be GCed. Keeps the
18499 * list in sorted order by the last GC time. The process can't already be
18502 final void addProcessToGcListLocked(ProcessRecord proc) {
18503 boolean added = false;
18504 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18505 if (mProcessesToGc.get(i).lastRequestedGc <
18506 proc.lastRequestedGc) {
18508 mProcessesToGc.add(i+1, proc);
18513 mProcessesToGc.add(0, proc);
18518 * Set up to ask a process to GC itself. This will either do it
18519 * immediately, or put it on the list of processes to gc the next
18520 * time things are idle.
18522 final void scheduleAppGcLocked(ProcessRecord app) {
18523 long now = SystemClock.uptimeMillis();
18524 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18527 if (!mProcessesToGc.contains(app)) {
18528 addProcessToGcListLocked(app);
18529 scheduleAppGcsLocked();
18533 final void checkExcessivePowerUsageLocked(boolean doKills) {
18534 updateCpuStatsNow();
18536 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18537 boolean doWakeKills = doKills;
18538 boolean doCpuKills = doKills;
18539 if (mLastPowerCheckRealtime == 0) {
18540 doWakeKills = false;
18542 if (mLastPowerCheckUptime == 0) {
18543 doCpuKills = false;
18545 if (stats.isScreenOn()) {
18546 doWakeKills = false;
18548 final long curRealtime = SystemClock.elapsedRealtime();
18549 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18550 final long curUptime = SystemClock.uptimeMillis();
18551 final long uptimeSince = curUptime - mLastPowerCheckUptime;
18552 mLastPowerCheckRealtime = curRealtime;
18553 mLastPowerCheckUptime = curUptime;
18554 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18555 doWakeKills = false;
18557 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18558 doCpuKills = false;
18560 int i = mLruProcesses.size();
18563 ProcessRecord app = mLruProcesses.get(i);
18564 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18566 synchronized (stats) {
18567 wtime = stats.getProcessWakeTime(app.info.uid,
18568 app.pid, curRealtime);
18570 long wtimeUsed = wtime - app.lastWakeTime;
18571 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18573 StringBuilder sb = new StringBuilder(128);
18574 sb.append("Wake for ");
18575 app.toShortString(sb);
18576 sb.append(": over ");
18577 TimeUtils.formatDuration(realtimeSince, sb);
18578 sb.append(" used ");
18579 TimeUtils.formatDuration(wtimeUsed, sb);
18581 sb.append((wtimeUsed*100)/realtimeSince);
18583 Slog.i(TAG_POWER, sb.toString());
18585 sb.append("CPU for ");
18586 app.toShortString(sb);
18587 sb.append(": over ");
18588 TimeUtils.formatDuration(uptimeSince, sb);
18589 sb.append(" used ");
18590 TimeUtils.formatDuration(cputimeUsed, sb);
18592 sb.append((cputimeUsed*100)/uptimeSince);
18594 Slog.i(TAG_POWER, sb.toString());
18596 // If a process has held a wake lock for more
18597 // than 50% of the time during this period,
18598 // that sounds bad. Kill!
18599 if (doWakeKills && realtimeSince > 0
18600 && ((wtimeUsed*100)/realtimeSince) >= 50) {
18601 synchronized (stats) {
18602 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18603 realtimeSince, wtimeUsed);
18605 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18606 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18607 } else if (doCpuKills && uptimeSince > 0
18608 && ((cputimeUsed*100)/uptimeSince) >= 25) {
18609 synchronized (stats) {
18610 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18611 uptimeSince, cputimeUsed);
18613 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18614 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18616 app.lastWakeTime = wtime;
18617 app.lastCpuTime = app.curCpuTime;
18623 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18624 boolean success = true;
18626 if (app.curRawAdj != app.setRawAdj) {
18627 app.setRawAdj = app.curRawAdj;
18632 if (app.curAdj != app.setAdj) {
18633 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18634 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18635 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18637 app.setAdj = app.curAdj;
18640 if (app.setSchedGroup != app.curSchedGroup) {
18641 app.setSchedGroup = app.curSchedGroup;
18642 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18643 "Setting process group of " + app.processName
18644 + " to " + app.curSchedGroup);
18645 if (app.waitingToKill != null && app.curReceiver == null
18646 && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18647 app.kill(app.waitingToKill, true);
18651 long oldId = Binder.clearCallingIdentity();
18653 Process.setProcessGroup(app.pid, app.curSchedGroup);
18654 } catch (Exception e) {
18655 Slog.w(TAG, "Failed setting process group of " + app.pid
18656 + " to " + app.curSchedGroup);
18657 e.printStackTrace();
18659 Binder.restoreCallingIdentity(oldId);
18662 if (app.thread != null) {
18664 app.thread.setSchedulingGroup(app.curSchedGroup);
18665 } catch (RemoteException e) {
18669 Process.setSwappiness(app.pid,
18670 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18673 if (app.repForegroundActivities != app.foregroundActivities) {
18674 app.repForegroundActivities = app.foregroundActivities;
18675 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18677 if (app.repProcState != app.curProcState) {
18678 app.repProcState = app.curProcState;
18679 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18680 if (app.thread != null) {
18683 //RuntimeException h = new RuntimeException("here");
18684 Slog.i(TAG, "Sending new process state " + app.repProcState
18685 + " to " + app /*, h*/);
18687 app.thread.setProcessState(app.repProcState);
18688 } catch (RemoteException e) {
18692 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18693 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18694 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18695 // Experimental code to more aggressively collect pss while
18696 // running test... the problem is that this tends to collect
18697 // the data right when a process is transitioning between process
18698 // states, which well tend to give noisy data.
18699 long start = SystemClock.uptimeMillis();
18700 long pss = Debug.getPss(app.pid, mTmpLong, null);
18701 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18702 mPendingPssProcesses.remove(app);
18703 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18704 + " to " + app.curProcState + ": "
18705 + (SystemClock.uptimeMillis()-start) + "ms");
18707 app.lastStateTime = now;
18708 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18709 mTestPssMode, isSleeping(), now);
18710 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18711 + ProcessList.makeProcStateString(app.setProcState) + " to "
18712 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18713 + (app.nextPssTime-now) + ": " + app);
18715 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18716 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18718 requestPssLocked(app, app.setProcState);
18719 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18720 mTestPssMode, isSleeping(), now);
18721 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18722 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18724 if (app.setProcState != app.curProcState) {
18725 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18726 "Proc state change of " + app.processName
18727 + " to " + app.curProcState);
18728 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18729 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18730 if (setImportant && !curImportant) {
18731 // This app is no longer something we consider important enough to allow to
18732 // use arbitrary amounts of battery power. Note
18733 // its current wake lock time to later know to kill it if
18734 // it is not behaving well.
18735 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18736 synchronized (stats) {
18737 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18738 app.pid, SystemClock.elapsedRealtime());
18740 app.lastCpuTime = app.curCpuTime;
18743 // Inform UsageStats of important process state change
18744 // Must be called before updating setProcState
18745 maybeUpdateUsageStatsLocked(app);
18747 app.setProcState = app.curProcState;
18748 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18749 app.notCachedSinceIdle = false;
18752 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18754 app.procStateChanged = true;
18758 if (changes != 0) {
18759 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18760 "Changes in " + app + ": " + changes);
18761 int i = mPendingProcessChanges.size()-1;
18762 ProcessChangeItem item = null;
18764 item = mPendingProcessChanges.get(i);
18765 if (item.pid == app.pid) {
18766 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18767 "Re-using existing item: " + item);
18773 // No existing item in pending changes; need a new one.
18774 final int NA = mAvailProcessChanges.size();
18776 item = mAvailProcessChanges.remove(NA-1);
18777 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18778 "Retrieving available item: " + item);
18780 item = new ProcessChangeItem();
18781 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18782 "Allocating new item: " + item);
18785 item.pid = app.pid;
18786 item.uid = app.info.uid;
18787 if (mPendingProcessChanges.size() == 0) {
18788 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18789 "*** Enqueueing dispatch processes changed!");
18790 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18792 mPendingProcessChanges.add(item);
18794 item.changes |= changes;
18795 item.processState = app.repProcState;
18796 item.foregroundActivities = app.repForegroundActivities;
18797 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18798 "Item " + Integer.toHexString(System.identityHashCode(item))
18799 + " " + app.toShortString() + ": changes=" + item.changes
18800 + " procState=" + item.processState
18801 + " foreground=" + item.foregroundActivities
18802 + " type=" + app.adjType + " source=" + app.adjSource
18803 + " target=" + app.adjTarget);
18809 private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18810 if (uidRec.pendingChange == null) {
18811 if (mPendingUidChanges.size() == 0) {
18812 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18813 "*** Enqueueing dispatch uid changed!");
18814 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18816 final int NA = mAvailUidChanges.size();
18818 uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18819 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18820 "Retrieving available item: " + uidRec.pendingChange);
18822 uidRec.pendingChange = new UidRecord.ChangeItem();
18823 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18824 "Allocating new item: " + uidRec.pendingChange);
18826 uidRec.pendingChange.uidRecord = uidRec;
18827 uidRec.pendingChange.uid = uidRec.uid;
18828 mPendingUidChanges.add(uidRec.pendingChange);
18830 uidRec.pendingChange.gone = gone;
18831 uidRec.pendingChange.processState = uidRec.setProcState;
18834 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18835 String authority) {
18836 if (app == null) return;
18837 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18838 UserState userState = mStartedUsers.get(app.userId);
18839 if (userState == null) return;
18840 final long now = SystemClock.elapsedRealtime();
18841 Long lastReported = userState.mProviderLastReportedFg.get(authority);
18842 if (lastReported == null || lastReported < now - 60 * 1000L) {
18843 mUsageStatsService.reportContentProviderUsage(
18844 authority, providerPkgName, app.userId);
18845 userState.mProviderLastReportedFg.put(authority, now);
18850 private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18851 if (DEBUG_USAGE_STATS) {
18852 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18853 + "] state changes: old = " + app.setProcState + ", new = "
18854 + app.curProcState);
18856 if (mUsageStatsService == null) {
18859 boolean isInteraction;
18860 // To avoid some abuse patterns, we are going to be careful about what we consider
18861 // to be an app interaction. Being the top activity doesn't count while the display
18862 // is sleeping, nor do short foreground services.
18863 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18864 isInteraction = true;
18865 app.fgInteractionTime = 0;
18866 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18867 final long now = SystemClock.elapsedRealtime();
18868 if (app.fgInteractionTime == 0) {
18869 app.fgInteractionTime = now;
18870 isInteraction = false;
18872 isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18875 isInteraction = app.curProcState
18876 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18877 app.fgInteractionTime = 0;
18879 if (isInteraction && !app.reportedInteraction) {
18880 String[] packages = app.getPackageList();
18881 if (packages != null) {
18882 for (int i = 0; i < packages.length; i++) {
18883 mUsageStatsService.reportEvent(packages[i], app.userId,
18884 UsageEvents.Event.SYSTEM_INTERACTION);
18888 app.reportedInteraction = isInteraction;
18891 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18892 if (proc.thread != null) {
18893 if (proc.baseProcessTracker != null) {
18894 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18896 if (proc.repProcState >= 0) {
18897 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18898 proc.repProcState);
18903 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18904 ProcessRecord TOP_APP, boolean doingAll, long now) {
18905 if (app.thread == null) {
18909 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18911 return applyOomAdjLocked(app, doingAll, now);
18914 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18916 if (isForeground != proc.foregroundServices) {
18917 proc.foregroundServices = isForeground;
18918 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18920 if (isForeground) {
18921 if (curProcs == null) {
18922 curProcs = new ArrayList<ProcessRecord>();
18923 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18925 if (!curProcs.contains(proc)) {
18926 curProcs.add(proc);
18927 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18928 proc.info.packageName, proc.info.uid);
18931 if (curProcs != null) {
18932 if (curProcs.remove(proc)) {
18933 mBatteryStatsService.noteEvent(
18934 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18935 proc.info.packageName, proc.info.uid);
18936 if (curProcs.size() <= 0) {
18937 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18943 updateOomAdjLocked();
18948 private final ActivityRecord resumedAppLocked() {
18949 ActivityRecord act = mStackSupervisor.resumedAppLocked();
18953 pkg = act.packageName;
18954 uid = act.info.applicationInfo.uid;
18959 // Has the UID or resumed package name changed?
18960 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18961 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18962 if (mCurResumedPackage != null) {
18963 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18964 mCurResumedPackage, mCurResumedUid);
18966 mCurResumedPackage = pkg;
18967 mCurResumedUid = uid;
18968 if (mCurResumedPackage != null) {
18969 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18970 mCurResumedPackage, mCurResumedUid);
18976 final boolean updateOomAdjLocked(ProcessRecord app) {
18977 final ActivityRecord TOP_ACT = resumedAppLocked();
18978 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18979 final boolean wasCached = app.cached;
18983 // This is the desired cached adjusment we want to tell it to use.
18984 // If our app is currently cached, we know it, and that is it. Otherwise,
18985 // we don't know it yet, and it needs to now be cached we will then
18986 // need to do a complete oom adj.
18987 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18988 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18989 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18990 SystemClock.uptimeMillis());
18991 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18992 // Changed to/from cached state, so apps after it in the LRU
18993 // list may also be changed.
18994 updateOomAdjLocked();
18999 final void updateOomAdjLocked() {
19000 final ActivityRecord TOP_ACT = resumedAppLocked();
19001 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19002 final long now = SystemClock.uptimeMillis();
19003 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19004 final int N = mLruProcesses.size();
19007 RuntimeException e = new RuntimeException();
19008 e.fillInStackTrace();
19009 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19012 // Reset state in all uid records.
19013 for (int i=mActiveUids.size()-1; i>=0; i--) {
19014 final UidRecord uidRec = mActiveUids.valueAt(i);
19015 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19016 "Starting update of " + uidRec);
19021 mNewNumServiceProcs = 0;
19022 mNewNumAServiceProcs = 0;
19024 final int emptyProcessLimit;
19025 final int cachedProcessLimit;
19026 if (mProcessLimit <= 0) {
19027 emptyProcessLimit = cachedProcessLimit = 0;
19028 } else if (mProcessLimit == 1) {
19029 emptyProcessLimit = 1;
19030 cachedProcessLimit = 0;
19032 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19033 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19036 // Let's determine how many processes we have running vs.
19037 // how many slots we have for background processes; we may want
19038 // to put multiple processes in a slot of there are enough of
19040 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19041 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19042 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19043 if (numEmptyProcs > cachedProcessLimit) {
19044 // If there are more empty processes than our limit on cached
19045 // processes, then use the cached process limit for the factor.
19046 // This ensures that the really old empty processes get pushed
19047 // down to the bottom, so if we are running low on memory we will
19048 // have a better chance at keeping around more cached processes
19049 // instead of a gazillion empty processes.
19050 numEmptyProcs = cachedProcessLimit;
19052 int emptyFactor = numEmptyProcs/numSlots;
19053 if (emptyFactor < 1) emptyFactor = 1;
19054 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19055 if (cachedFactor < 1) cachedFactor = 1;
19056 int stepCached = 0;
19060 int numTrimming = 0;
19062 mNumNonCachedProcs = 0;
19063 mNumCachedHiddenProcs = 0;
19065 // First update the OOM adjustment for each of the
19066 // application processes based on their current state.
19067 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19068 int nextCachedAdj = curCachedAdj+1;
19069 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19070 int nextEmptyAdj = curEmptyAdj+2;
19071 for (int i=N-1; i>=0; i--) {
19072 ProcessRecord app = mLruProcesses.get(i);
19073 if (!app.killedByAm && app.thread != null) {
19074 app.procStateChanged = false;
19075 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19077 // If we haven't yet assigned the final cached adj
19078 // to the process, do that now.
19079 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19080 switch (app.curProcState) {
19081 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19082 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19083 // This process is a cached process holding activities...
19084 // assign it the next cached value for that type, and then
19085 // step that cached level.
19086 app.curRawAdj = curCachedAdj;
19087 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19088 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19089 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19091 if (curCachedAdj != nextCachedAdj) {
19093 if (stepCached >= cachedFactor) {
19095 curCachedAdj = nextCachedAdj;
19096 nextCachedAdj += 2;
19097 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19098 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19104 // For everything else, assign next empty cached process
19105 // level and bump that up. Note that this means that
19106 // long-running services that have dropped down to the
19107 // cached level will be treated as empty (since their process
19108 // state is still as a service), which is what we want.
19109 app.curRawAdj = curEmptyAdj;
19110 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19111 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19112 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19114 if (curEmptyAdj != nextEmptyAdj) {
19116 if (stepEmpty >= emptyFactor) {
19118 curEmptyAdj = nextEmptyAdj;
19120 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19121 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19129 applyOomAdjLocked(app, true, now);
19131 // Count the number of process types.
19132 switch (app.curProcState) {
19133 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19134 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19135 mNumCachedHiddenProcs++;
19137 if (numCached > cachedProcessLimit) {
19138 app.kill("cached #" + numCached, true);
19141 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19142 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19143 && app.lastActivityTime < oldTime) {
19144 app.kill("empty for "
19145 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19146 / 1000) + "s", true);
19149 if (numEmpty > emptyProcessLimit) {
19150 app.kill("empty #" + numEmpty, true);
19155 mNumNonCachedProcs++;
19159 if (app.isolated && app.services.size() <= 0) {
19160 // If this is an isolated process, and there are no
19161 // services running in it, then the process is no longer
19162 // needed. We agressively kill these because we can by
19163 // definition not re-use the same process again, and it is
19164 // good to avoid having whatever code was running in them
19165 // left sitting around after no longer needed.
19166 app.kill("isolated not needed", true);
19168 // Keeping this process, update its uid.
19169 final UidRecord uidRec = app.uidRecord;
19170 if (uidRec != null && uidRec.curProcState > app.curProcState) {
19171 uidRec.curProcState = app.curProcState;
19175 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19176 && !app.killedByAm) {
19182 mNumServiceProcs = mNewNumServiceProcs;
19184 // Now determine the memory trimming level of background processes.
19185 // Unfortunately we need to start at the back of the list to do this
19186 // properly. We only do this if the number of background apps we
19187 // are managing to keep around is less than half the maximum we desire;
19188 // if we are keeping a good number around, we'll let them use whatever
19189 // memory they want.
19190 final int numCachedAndEmpty = numCached + numEmpty;
19192 if (numCached <= ProcessList.TRIM_CACHED_APPS
19193 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19194 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19195 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19196 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19197 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19199 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19202 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19204 // We always allow the memory level to go up (better). We only allow it to go
19205 // down if we are in a state where that is allowed, *and* the total number of processes
19206 // has gone down since last time.
19207 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19208 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19209 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19210 if (memFactor > mLastMemoryLevel) {
19211 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19212 memFactor = mLastMemoryLevel;
19213 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19216 mLastMemoryLevel = memFactor;
19217 mLastNumProcesses = mLruProcesses.size();
19218 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19219 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19220 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19221 if (mLowRamStartTime == 0) {
19222 mLowRamStartTime = now;
19226 switch (memFactor) {
19227 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19228 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19230 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19231 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19234 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19237 int factor = numTrimming/3;
19239 if (mHomeProcess != null) minFactor++;
19240 if (mPreviousProcess != null) minFactor++;
19241 if (factor < minFactor) factor = minFactor;
19242 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19243 for (int i=N-1; i>=0; i--) {
19244 ProcessRecord app = mLruProcesses.get(i);
19245 if (allChanged || app.procStateChanged) {
19246 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19247 app.procStateChanged = false;
19249 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19250 && !app.killedByAm) {
19251 if (app.trimMemoryLevel < curLevel && app.thread != null) {
19253 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19254 "Trimming memory of " + app.processName + " to " + curLevel);
19255 app.thread.scheduleTrimMemory(curLevel);
19256 } catch (RemoteException e) {
19259 // For now we won't do this; our memory trimming seems
19260 // to be good enough at this point that destroying
19261 // activities causes more harm than good.
19262 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19263 && app != mHomeProcess && app != mPreviousProcess) {
19264 // Need to do this on its own message because the stack may not
19265 // be in a consistent state at this point.
19266 // For these apps we will also finish their activities
19267 // to help them free memory.
19268 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19272 app.trimMemoryLevel = curLevel;
19274 if (step >= factor) {
19276 switch (curLevel) {
19277 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19278 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19280 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19281 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19285 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19286 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19287 && app.thread != null) {
19289 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19290 "Trimming memory of heavy-weight " + app.processName
19291 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19292 app.thread.scheduleTrimMemory(
19293 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19294 } catch (RemoteException e) {
19297 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19299 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19300 || app.systemNoUi) && app.pendingUiClean) {
19301 // If this application is now in the background and it
19302 // had done UI, then give it the special trim level to
19303 // have it free UI resources.
19304 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19305 if (app.trimMemoryLevel < level && app.thread != null) {
19307 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19308 "Trimming memory of bg-ui " + app.processName
19310 app.thread.scheduleTrimMemory(level);
19311 } catch (RemoteException e) {
19314 app.pendingUiClean = false;
19316 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19318 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19319 "Trimming memory of fg " + app.processName
19320 + " to " + fgTrimLevel);
19321 app.thread.scheduleTrimMemory(fgTrimLevel);
19322 } catch (RemoteException e) {
19325 app.trimMemoryLevel = fgTrimLevel;
19329 if (mLowRamStartTime != 0) {
19330 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19331 mLowRamStartTime = 0;
19333 for (int i=N-1; i>=0; i--) {
19334 ProcessRecord app = mLruProcesses.get(i);
19335 if (allChanged || app.procStateChanged) {
19336 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19337 app.procStateChanged = false;
19339 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19340 || app.systemNoUi) && app.pendingUiClean) {
19341 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19342 && app.thread != null) {
19344 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19345 "Trimming memory of ui hidden " + app.processName
19346 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19347 app.thread.scheduleTrimMemory(
19348 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19349 } catch (RemoteException e) {
19352 app.pendingUiClean = false;
19354 app.trimMemoryLevel = 0;
19358 if (mAlwaysFinishActivities) {
19359 // Need to do this on its own message because the stack may not
19360 // be in a consistent state at this point.
19361 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19365 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19368 // Update from any uid changes.
19369 for (int i=mActiveUids.size()-1; i>=0; i--) {
19370 final UidRecord uidRec = mActiveUids.valueAt(i);
19371 if (uidRec.setProcState != uidRec.curProcState) {
19372 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19373 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19374 + " to " + uidRec.curProcState);
19375 uidRec.setProcState = uidRec.curProcState;
19376 enqueueUidChangeLocked(uidRec, false);
19380 if (mProcessStats.shouldWriteNowLocked(now)) {
19381 mHandler.post(new Runnable() {
19382 @Override public void run() {
19383 synchronized (ActivityManagerService.this) {
19384 mProcessStats.writeStateAsyncLocked();
19390 if (DEBUG_OOM_ADJ) {
19391 final long duration = SystemClock.uptimeMillis() - now;
19393 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19394 new RuntimeException("here").fillInStackTrace());
19396 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19401 final void trimApplications() {
19402 synchronized (this) {
19405 // First remove any unused application processes whose package
19406 // has been removed.
19407 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19408 final ProcessRecord app = mRemovedProcesses.get(i);
19409 if (app.activities.size() == 0
19410 && app.curReceiver == null && app.services.size() == 0) {
19412 TAG, "Exiting empty application process "
19413 + app.processName + " ("
19414 + (app.thread != null ? app.thread.asBinder() : null)
19416 if (app.pid > 0 && app.pid != MY_PID) {
19417 app.kill("empty", false);
19420 app.thread.scheduleExit();
19421 } catch (Exception e) {
19422 // Ignore exceptions.
19425 cleanUpApplicationRecordLocked(app, false, true, -1);
19426 mRemovedProcesses.remove(i);
19428 if (app.persistent) {
19429 addAppLocked(app.info, false, null /* ABI override */);
19434 // Now update the oom adj for all processes.
19435 updateOomAdjLocked();
19439 /** This method sends the specified signal to each of the persistent apps */
19440 public void signalPersistentProcesses(int sig) throws RemoteException {
19441 if (sig != Process.SIGNAL_USR1) {
19442 throw new SecurityException("Only SIGNAL_USR1 is allowed");
19445 synchronized (this) {
19446 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19447 != PackageManager.PERMISSION_GRANTED) {
19448 throw new SecurityException("Requires permission "
19449 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19452 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19453 ProcessRecord r = mLruProcesses.get(i);
19454 if (r.thread != null && r.persistent) {
19455 Process.sendSignal(r.pid, sig);
19461 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19462 if (proc == null || proc == mProfileProc) {
19463 proc = mProfileProc;
19464 profileType = mProfileType;
19465 clearProfilerLocked();
19467 if (proc == null) {
19471 proc.thread.profilerControl(false, null, profileType);
19472 } catch (RemoteException e) {
19473 throw new IllegalStateException("Process disappeared");
19477 private void clearProfilerLocked() {
19478 if (mProfileFd != null) {
19480 mProfileFd.close();
19481 } catch (IOException e) {
19484 mProfileApp = null;
19485 mProfileProc = null;
19486 mProfileFile = null;
19488 mAutoStopProfiler = false;
19489 mSamplingInterval = 0;
19492 public boolean profileControl(String process, int userId, boolean start,
19493 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19496 synchronized (this) {
19497 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19498 // its own permission.
19499 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19500 != PackageManager.PERMISSION_GRANTED) {
19501 throw new SecurityException("Requires permission "
19502 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19505 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19506 throw new IllegalArgumentException("null profile info or fd");
19509 ProcessRecord proc = null;
19510 if (process != null) {
19511 proc = findProcessLocked(process, userId, "profileControl");
19514 if (start && (proc == null || proc.thread == null)) {
19515 throw new IllegalArgumentException("Unknown process: " + process);
19519 stopProfilerLocked(null, 0);
19520 setProfileApp(proc.info, proc.processName, profilerInfo);
19521 mProfileProc = proc;
19522 mProfileType = profileType;
19523 ParcelFileDescriptor fd = profilerInfo.profileFd;
19526 } catch (IOException e) {
19529 profilerInfo.profileFd = fd;
19530 proc.thread.profilerControl(start, profilerInfo, profileType);
19534 stopProfilerLocked(proc, profileType);
19535 if (profilerInfo != null && profilerInfo.profileFd != null) {
19537 profilerInfo.profileFd.close();
19538 } catch (IOException e) {
19545 } catch (RemoteException e) {
19546 throw new IllegalStateException("Process disappeared");
19548 if (profilerInfo != null && profilerInfo.profileFd != null) {
19550 profilerInfo.profileFd.close();
19551 } catch (IOException e) {
19557 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19558 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19559 userId, true, ALLOW_FULL_ONLY, callName, null);
19560 ProcessRecord proc = null;
19562 int pid = Integer.parseInt(process);
19563 synchronized (mPidsSelfLocked) {
19564 proc = mPidsSelfLocked.get(pid);
19566 } catch (NumberFormatException e) {
19569 if (proc == null) {
19570 ArrayMap<String, SparseArray<ProcessRecord>> all
19571 = mProcessNames.getMap();
19572 SparseArray<ProcessRecord> procs = all.get(process);
19573 if (procs != null && procs.size() > 0) {
19574 proc = procs.valueAt(0);
19575 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19576 for (int i=1; i<procs.size(); i++) {
19577 ProcessRecord thisProc = procs.valueAt(i);
19578 if (thisProc.userId == userId) {
19590 public boolean dumpHeap(String process, int userId, boolean managed,
19591 String path, ParcelFileDescriptor fd) throws RemoteException {
19594 synchronized (this) {
19595 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19596 // its own permission (same as profileControl).
19597 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19598 != PackageManager.PERMISSION_GRANTED) {
19599 throw new SecurityException("Requires permission "
19600 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19604 throw new IllegalArgumentException("null fd");
19607 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19608 if (proc == null || proc.thread == null) {
19609 throw new IllegalArgumentException("Unknown process: " + process);
19612 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19613 if (!isDebuggable) {
19614 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19615 throw new SecurityException("Process not debuggable: " + proc);
19619 proc.thread.dumpHeap(managed, path, fd);
19623 } catch (RemoteException e) {
19624 throw new IllegalStateException("Process disappeared");
19629 } catch (IOException e) {
19636 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19637 String reportPackage) {
19638 if (processName != null) {
19639 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19640 "setDumpHeapDebugLimit()");
19642 synchronized (mPidsSelfLocked) {
19643 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19644 if (proc == null) {
19645 throw new SecurityException("No process found for calling pid "
19646 + Binder.getCallingPid());
19648 if (!Build.IS_DEBUGGABLE
19649 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19650 throw new SecurityException("Not running a debuggable build");
19652 processName = proc.processName;
19654 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19655 throw new SecurityException("Package " + reportPackage + " is not running in "
19660 synchronized (this) {
19661 if (maxMemSize > 0) {
19662 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19665 mMemWatchProcesses.remove(processName, uid);
19667 mMemWatchProcesses.getMap().remove(processName);
19674 public void dumpHeapFinished(String path) {
19675 synchronized (this) {
19676 if (Binder.getCallingPid() != mMemWatchDumpPid) {
19677 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19678 + " does not match last pid " + mMemWatchDumpPid);
19681 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19682 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19683 + " does not match last path " + mMemWatchDumpFile);
19686 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19687 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19691 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19692 public void monitor() {
19693 synchronized (this) { }
19696 void onCoreSettingsChange(Bundle settings) {
19697 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19698 ProcessRecord processRecord = mLruProcesses.get(i);
19700 if (processRecord.thread != null) {
19701 processRecord.thread.setCoreSettings(settings);
19703 } catch (RemoteException re) {
19709 // Multi-user methods
19712 * Start user, if its not already running, but don't bring it to foreground.
19715 public boolean startUserInBackground(final int userId) {
19716 return startUser(userId, /* foreground */ false);
19720 * Start user, if its not already running, and bring it to foreground.
19722 boolean startUserInForeground(final int userId, Dialog dlg) {
19723 boolean result = startUser(userId, /* foreground */ true);
19729 * Refreshes the list of users related to the current user when either a
19730 * user switch happens or when a new related user is started in the
19733 private void updateCurrentProfileIdsLocked() {
19734 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19735 mCurrentUserId, false /* enabledOnly */);
19736 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19737 for (int i = 0; i < currentProfileIds.length; i++) {
19738 currentProfileIds[i] = profiles.get(i).id;
19740 mCurrentProfileIds = currentProfileIds;
19742 synchronized (mUserProfileGroupIdsSelfLocked) {
19743 mUserProfileGroupIdsSelfLocked.clear();
19744 final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19745 for (int i = 0; i < users.size(); i++) {
19746 UserInfo user = users.get(i);
19747 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19748 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19754 private Set<Integer> getProfileIdsLocked(int userId) {
19755 Set<Integer> userIds = new HashSet<Integer>();
19756 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19757 userId, false /* enabledOnly */);
19758 for (UserInfo user : profiles) {
19759 userIds.add(Integer.valueOf(user.id));
19765 public boolean switchUser(final int userId) {
19766 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19768 synchronized (this) {
19769 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19770 if (userInfo == null) {
19771 Slog.w(TAG, "No user info for user #" + userId);
19774 if (userInfo.isManagedProfile()) {
19775 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19778 userName = userInfo.name;
19779 mTargetUserId = userId;
19781 mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19782 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19786 private void showUserSwitchDialog(int userId, String userName) {
19787 // The dialog will show and then initiate the user switch by calling startUserInForeground
19788 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19789 true /* above system */);
19793 private boolean startUser(final int userId, final boolean foreground) {
19794 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19795 != PackageManager.PERMISSION_GRANTED) {
19796 String msg = "Permission Denial: switchUser() from pid="
19797 + Binder.getCallingPid()
19798 + ", uid=" + Binder.getCallingUid()
19799 + " requires " + INTERACT_ACROSS_USERS_FULL;
19801 throw new SecurityException(msg);
19804 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19806 final long ident = Binder.clearCallingIdentity();
19808 synchronized (this) {
19809 final int oldUserId = mCurrentUserId;
19810 if (oldUserId == userId) {
19814 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19815 "startUser", false);
19817 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19818 if (userInfo == null) {
19819 Slog.w(TAG, "No user info for user #" + userId);
19822 if (foreground && userInfo.isManagedProfile()) {
19823 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19828 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19829 R.anim.screen_user_enter);
19832 boolean needStart = false;
19834 // If the user we are switching to is not currently started, then
19835 // we need to start it now.
19836 if (mStartedUsers.get(userId) == null) {
19837 mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19838 updateStartedUserArrayLocked();
19842 final Integer userIdInt = Integer.valueOf(userId);
19843 mUserLru.remove(userIdInt);
19844 mUserLru.add(userIdInt);
19847 mCurrentUserId = userId;
19848 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19849 updateCurrentProfileIdsLocked();
19850 mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19851 // Once the internal notion of the active user has switched, we lock the device
19852 // with the option to show the user switcher on the keyguard.
19853 mWindowManager.lockNow(null);
19855 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19856 updateCurrentProfileIdsLocked();
19857 mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19858 mUserLru.remove(currentUserIdInt);
19859 mUserLru.add(currentUserIdInt);
19862 final UserState uss = mStartedUsers.get(userId);
19864 // Make sure user is in the started state. If it is currently
19865 // stopping, we need to knock that off.
19866 if (uss.mState == UserState.STATE_STOPPING) {
19867 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19868 // so we can just fairly silently bring the user back from
19869 // the almost-dead.
19870 uss.mState = UserState.STATE_RUNNING;
19871 updateStartedUserArrayLocked();
19873 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19874 // This means ACTION_SHUTDOWN has been sent, so we will
19875 // need to treat this as a new boot of the user.
19876 uss.mState = UserState.STATE_BOOTING;
19877 updateStartedUserArrayLocked();
19881 if (uss.mState == UserState.STATE_BOOTING) {
19882 // Booting up a new user, need to tell system services about it.
19883 // Note that this is on the same handler as scheduling of broadcasts,
19884 // which is important because it needs to go first.
19885 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19889 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19891 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19892 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19893 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19894 oldUserId, userId, uss));
19895 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19896 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19900 // Send USER_STARTED broadcast
19901 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19902 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19903 | Intent.FLAG_RECEIVER_FOREGROUND);
19904 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19905 broadcastIntentLocked(null, null, intent,
19906 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19907 null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19910 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19911 if (userId != UserHandle.USER_OWNER) {
19912 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19913 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19914 broadcastIntentLocked(null, null, intent, null,
19915 new IIntentReceiver.Stub() {
19916 public void performReceive(Intent intent, int resultCode,
19917 String data, Bundle extras, boolean ordered,
19918 boolean sticky, int sendingUser) {
19919 onUserInitialized(uss, foreground, oldUserId, userId);
19921 }, 0, null, null, null, AppOpsManager.OP_NONE,
19922 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19923 uss.initializing = true;
19925 getUserManagerLocked().makeInitialized(userInfo.id);
19930 if (!uss.initializing) {
19931 moveUserToForeground(uss, oldUserId, userId);
19934 mStackSupervisor.startBackgroundUserLocked(userId, uss);
19938 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19939 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19940 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19941 broadcastIntentLocked(null, null, intent,
19942 null, new IIntentReceiver.Stub() {
19944 public void performReceive(Intent intent, int resultCode,
19945 String data, Bundle extras, boolean ordered, boolean sticky,
19946 int sendingUser) throws RemoteException {
19949 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
19950 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19954 Binder.restoreCallingIdentity(ident);
19960 void dispatchForegroundProfileChanged(int userId) {
19961 final int N = mUserSwitchObservers.beginBroadcast();
19962 for (int i = 0; i < N; i++) {
19964 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
19965 } catch (RemoteException e) {
19969 mUserSwitchObservers.finishBroadcast();
19972 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19973 long ident = Binder.clearCallingIdentity();
19976 if (oldUserId >= 0) {
19977 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19978 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19979 int count = profiles.size();
19980 for (int i = 0; i < count; i++) {
19981 int profileUserId = profiles.get(i).id;
19982 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19983 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19984 | Intent.FLAG_RECEIVER_FOREGROUND);
19985 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19986 broadcastIntentLocked(null, null, intent,
19987 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19988 null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19991 if (newUserId >= 0) {
19992 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19993 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19994 int count = profiles.size();
19995 for (int i = 0; i < count; i++) {
19996 int profileUserId = profiles.get(i).id;
19997 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19998 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19999 | Intent.FLAG_RECEIVER_FOREGROUND);
20000 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20001 broadcastIntentLocked(null, null, intent,
20002 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20003 null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20005 intent = new Intent(Intent.ACTION_USER_SWITCHED);
20006 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20007 | Intent.FLAG_RECEIVER_FOREGROUND);
20008 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
20009 broadcastIntentLocked(null, null, intent,
20010 null, null, 0, null, null,
20011 new String[] {android.Manifest.permission.MANAGE_USERS},
20012 AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20013 UserHandle.USER_ALL);
20016 Binder.restoreCallingIdentity(ident);
20020 void dispatchUserSwitch(final UserState uss, final int oldUserId,
20021 final int newUserId) {
20022 final int N = mUserSwitchObservers.beginBroadcast();
20024 final IRemoteCallback callback = new IRemoteCallback.Stub() {
20027 public void sendResult(Bundle data) throws RemoteException {
20028 synchronized (ActivityManagerService.this) {
20029 if (mCurUserSwitchCallback == this) {
20032 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20038 synchronized (this) {
20039 uss.switching = true;
20040 mCurUserSwitchCallback = callback;
20042 for (int i=0; i<N; i++) {
20044 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20045 newUserId, callback);
20046 } catch (RemoteException e) {
20050 synchronized (this) {
20051 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20054 mUserSwitchObservers.finishBroadcast();
20057 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20058 synchronized (this) {
20059 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20060 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20064 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20065 mCurUserSwitchCallback = null;
20066 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20067 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20068 oldUserId, newUserId, uss));
20071 void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20072 synchronized (this) {
20074 moveUserToForeground(uss, oldUserId, newUserId);
20078 completeSwitchAndInitialize(uss, newUserId, true, false);
20081 void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20082 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20084 startHomeActivityLocked(newUserId, "moveUserToFroreground");
20086 mStackSupervisor.resumeTopActivitiesLocked();
20088 EventLogTags.writeAmSwitchUser(newUserId);
20089 getUserManagerLocked().onUserForeground(newUserId);
20090 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20093 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20094 completeSwitchAndInitialize(uss, newUserId, false, true);
20097 void completeSwitchAndInitialize(UserState uss, int newUserId,
20098 boolean clearInitializing, boolean clearSwitching) {
20099 boolean unfrozen = false;
20100 synchronized (this) {
20101 if (clearInitializing) {
20102 uss.initializing = false;
20103 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20105 if (clearSwitching) {
20106 uss.switching = false;
20108 if (!uss.switching && !uss.initializing) {
20109 mWindowManager.stopFreezingScreen();
20114 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20115 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20118 stopGuestUserIfBackground();
20121 /** Called on handler thread */
20122 void dispatchUserSwitchComplete(int userId) {
20123 final int observerCount = mUserSwitchObservers.beginBroadcast();
20124 for (int i = 0; i < observerCount; i++) {
20126 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20127 } catch (RemoteException e) {
20130 mUserSwitchObservers.finishBroadcast();
20134 * Stops the guest user if it has gone to the background.
20136 private void stopGuestUserIfBackground() {
20137 synchronized (this) {
20138 final int num = mUserLru.size();
20139 for (int i = 0; i < num; i++) {
20140 Integer oldUserId = mUserLru.get(i);
20141 UserState oldUss = mStartedUsers.get(oldUserId);
20142 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20143 || oldUss.mState == UserState.STATE_STOPPING
20144 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20147 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20148 if (userInfo.isGuest()) {
20149 // This is a user to be stopped.
20150 stopUserLocked(oldUserId, null);
20157 void scheduleStartProfilesLocked() {
20158 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20159 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20160 DateUtils.SECOND_IN_MILLIS);
20164 void startProfilesLocked() {
20165 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20166 List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20167 mCurrentUserId, false /* enabledOnly */);
20168 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20169 for (UserInfo user : profiles) {
20170 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20171 && user.id != mCurrentUserId) {
20175 final int n = toStart.size();
20177 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20178 startUserInBackground(toStart.get(i).id);
20181 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20185 void finishUserBoot(UserState uss) {
20186 synchronized (this) {
20187 if (uss.mState == UserState.STATE_BOOTING
20188 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20189 uss.mState = UserState.STATE_RUNNING;
20190 final int userId = uss.mHandle.getIdentifier();
20191 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20192 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20193 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20194 broadcastIntentLocked(null, null, intent,
20195 null, null, 0, null, null,
20196 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20197 AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20203 void finishUserSwitch(UserState uss) {
20204 synchronized (this) {
20205 finishUserBoot(uss);
20207 startProfilesLocked();
20209 int num = mUserLru.size();
20211 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20212 Integer oldUserId = mUserLru.get(i);
20213 UserState oldUss = mStartedUsers.get(oldUserId);
20214 if (oldUss == null) {
20215 // Shouldn't happen, but be sane if it does.
20216 mUserLru.remove(i);
20220 if (oldUss.mState == UserState.STATE_STOPPING
20221 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20222 // This user is already stopping, doesn't count.
20227 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20228 // Owner and current can't be stopped, but count as running.
20232 // This is a user to be stopped.
20233 stopUserLocked(oldUserId, null);
20241 public int stopUser(final int userId, final IStopUserCallback callback) {
20242 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20243 != PackageManager.PERMISSION_GRANTED) {
20244 String msg = "Permission Denial: switchUser() from pid="
20245 + Binder.getCallingPid()
20246 + ", uid=" + Binder.getCallingUid()
20247 + " requires " + INTERACT_ACROSS_USERS_FULL;
20249 throw new SecurityException(msg);
20251 if (userId < 0 || userId == UserHandle.USER_OWNER) {
20252 throw new IllegalArgumentException("Can't stop primary user " + userId);
20254 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20255 synchronized (this) {
20256 return stopUserLocked(userId, callback);
20260 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20261 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20262 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20263 return ActivityManager.USER_OP_IS_CURRENT;
20266 final UserState uss = mStartedUsers.get(userId);
20268 // User is not started, nothing to do... but we do need to
20269 // callback if requested.
20270 if (callback != null) {
20271 mHandler.post(new Runnable() {
20273 public void run() {
20275 callback.userStopped(userId);
20276 } catch (RemoteException e) {
20281 return ActivityManager.USER_OP_SUCCESS;
20284 if (callback != null) {
20285 uss.mStopCallbacks.add(callback);
20288 if (uss.mState != UserState.STATE_STOPPING
20289 && uss.mState != UserState.STATE_SHUTDOWN) {
20290 uss.mState = UserState.STATE_STOPPING;
20291 updateStartedUserArrayLocked();
20293 long ident = Binder.clearCallingIdentity();
20295 // We are going to broadcast ACTION_USER_STOPPING and then
20296 // once that is done send a final ACTION_SHUTDOWN and then
20298 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20299 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20300 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20301 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20302 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20303 // This is the result receiver for the final shutdown broadcast.
20304 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20306 public void performReceive(Intent intent, int resultCode, String data,
20307 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20308 finishUserStop(uss);
20311 // This is the result receiver for the initial stopping broadcast.
20312 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20314 public void performReceive(Intent intent, int resultCode, String data,
20315 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20317 synchronized (ActivityManagerService.this) {
20318 if (uss.mState != UserState.STATE_STOPPING) {
20319 // Whoops, we are being started back up. Abort, abort!
20322 uss.mState = UserState.STATE_SHUTDOWN;
20324 mBatteryStatsService.noteEvent(
20325 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20326 Integer.toString(userId), userId);
20327 mSystemServiceManager.stopUser(userId);
20328 broadcastIntentLocked(null, null, shutdownIntent,
20329 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20330 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20333 // Kick things off.
20334 broadcastIntentLocked(null, null, stoppingIntent,
20335 null, stoppingReceiver, 0, null, null,
20336 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20337 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20339 Binder.restoreCallingIdentity(ident);
20343 return ActivityManager.USER_OP_SUCCESS;
20346 void finishUserStop(UserState uss) {
20347 final int userId = uss.mHandle.getIdentifier();
20349 ArrayList<IStopUserCallback> callbacks;
20350 synchronized (this) {
20351 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20352 if (mStartedUsers.get(userId) != uss) {
20354 } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20358 // User can no longer run.
20359 mStartedUsers.remove(userId);
20360 mUserLru.remove(Integer.valueOf(userId));
20361 updateStartedUserArrayLocked();
20363 // Clean up all state and processes associated with the user.
20364 // Kill all the processes for the user.
20365 forceStopUserLocked(userId, "finish user");
20368 // Explicitly remove the old information in mRecentTasks.
20369 mRecentTasks.removeTasksForUserLocked(userId);
20372 for (int i=0; i<callbacks.size(); i++) {
20374 if (stopped) callbacks.get(i).userStopped(userId);
20375 else callbacks.get(i).userStopAborted(userId);
20376 } catch (RemoteException e) {
20381 mSystemServiceManager.cleanupUser(userId);
20382 synchronized (this) {
20383 mStackSupervisor.removeUserLocked(userId);
20389 public UserInfo getCurrentUser() {
20390 if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20391 != PackageManager.PERMISSION_GRANTED) && (
20392 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20393 != PackageManager.PERMISSION_GRANTED)) {
20394 String msg = "Permission Denial: getCurrentUser() from pid="
20395 + Binder.getCallingPid()
20396 + ", uid=" + Binder.getCallingUid()
20397 + " requires " + INTERACT_ACROSS_USERS;
20399 throw new SecurityException(msg);
20401 synchronized (this) {
20402 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20403 return getUserManagerLocked().getUserInfo(userId);
20407 int getCurrentUserIdLocked() {
20408 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20412 public boolean isUserRunning(int userId, boolean orStopped) {
20413 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20414 != PackageManager.PERMISSION_GRANTED) {
20415 String msg = "Permission Denial: isUserRunning() from pid="
20416 + Binder.getCallingPid()
20417 + ", uid=" + Binder.getCallingUid()
20418 + " requires " + INTERACT_ACROSS_USERS;
20420 throw new SecurityException(msg);
20422 synchronized (this) {
20423 return isUserRunningLocked(userId, orStopped);
20427 boolean isUserRunningLocked(int userId, boolean orStopped) {
20428 UserState state = mStartedUsers.get(userId);
20429 if (state == null) {
20435 return state.mState != UserState.STATE_STOPPING
20436 && state.mState != UserState.STATE_SHUTDOWN;
20440 public int[] getRunningUserIds() {
20441 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20442 != PackageManager.PERMISSION_GRANTED) {
20443 String msg = "Permission Denial: isUserRunning() from pid="
20444 + Binder.getCallingPid()
20445 + ", uid=" + Binder.getCallingUid()
20446 + " requires " + INTERACT_ACROSS_USERS;
20448 throw new SecurityException(msg);
20450 synchronized (this) {
20451 return mStartedUserArray;
20455 private void updateStartedUserArrayLocked() {
20457 for (int i=0; i<mStartedUsers.size(); i++) {
20458 UserState uss = mStartedUsers.valueAt(i);
20459 // This list does not include stopping users.
20460 if (uss.mState != UserState.STATE_STOPPING
20461 && uss.mState != UserState.STATE_SHUTDOWN) {
20465 mStartedUserArray = new int[num];
20467 for (int i=0; i<mStartedUsers.size(); i++) {
20468 UserState uss = mStartedUsers.valueAt(i);
20469 if (uss.mState != UserState.STATE_STOPPING
20470 && uss.mState != UserState.STATE_SHUTDOWN) {
20471 mStartedUserArray[num] = mStartedUsers.keyAt(i);
20478 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20479 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20480 != PackageManager.PERMISSION_GRANTED) {
20481 String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20482 + Binder.getCallingPid()
20483 + ", uid=" + Binder.getCallingUid()
20484 + " requires " + INTERACT_ACROSS_USERS_FULL;
20486 throw new SecurityException(msg);
20489 mUserSwitchObservers.register(observer);
20493 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20494 mUserSwitchObservers.unregister(observer);
20497 int[] getUsersLocked() {
20498 UserManagerService ums = getUserManagerLocked();
20499 return ums != null ? ums.getUserIds() : new int[] { 0 };
20502 UserManagerService getUserManagerLocked() {
20503 if (mUserManager == null) {
20504 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20505 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20507 return mUserManager;
20510 private int applyUserId(int uid, int userId) {
20511 return UserHandle.getUid(userId, uid);
20514 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20515 if (info == null) return null;
20516 ApplicationInfo newInfo = new ApplicationInfo(info);
20517 newInfo.uid = applyUserId(info.uid, userId);
20518 newInfo.dataDir = Environment
20519 .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20520 .getAbsolutePath();
20524 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20526 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20530 ActivityInfo info = new ActivityInfo(aInfo);
20531 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20535 private final class LocalService extends ActivityManagerInternal {
20537 public void onWakefulnessChanged(int wakefulness) {
20538 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20542 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20543 String processName, String abiOverride, int uid, Runnable crashHandler) {
20544 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20545 processName, abiOverride, uid, crashHandler);
20549 public SleepToken acquireSleepToken(String tag) {
20550 Preconditions.checkNotNull(tag);
20552 synchronized (ActivityManagerService.this) {
20553 SleepTokenImpl token = new SleepTokenImpl(tag);
20554 mSleepTokens.add(token);
20555 updateSleepIfNeededLocked();
20561 public ComponentName getHomeActivityForUser(int userId) {
20562 synchronized (ActivityManagerService.this) {
20563 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20564 return homeActivity == null ? null : homeActivity.realActivity;
20569 private final class SleepTokenImpl extends SleepToken {
20570 private final String mTag;
20571 private final long mAcquireTime;
20573 public SleepTokenImpl(String tag) {
20575 mAcquireTime = SystemClock.uptimeMillis();
20579 public void release() {
20580 synchronized (ActivityManagerService.this) {
20581 if (mSleepTokens.remove(this)) {
20582 updateSleepIfNeededLocked();
20588 public String toString() {
20589 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20594 * An implementation of IAppTask, that allows an app to manage its own tasks via
20595 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
20596 * only the process that calls getAppTasks() can call the AppTask methods.
20598 class AppTaskImpl extends IAppTask.Stub {
20599 private int mTaskId;
20600 private int mCallingUid;
20602 public AppTaskImpl(int taskId, int callingUid) {
20604 mCallingUid = callingUid;
20607 private void checkCaller() {
20608 if (mCallingUid != Binder.getCallingUid()) {
20609 throw new SecurityException("Caller " + mCallingUid
20610 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20615 public void finishAndRemoveTask() {
20618 synchronized (ActivityManagerService.this) {
20619 long origId = Binder.clearCallingIdentity();
20621 if (!removeTaskByIdLocked(mTaskId, false)) {
20622 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20625 Binder.restoreCallingIdentity(origId);
20631 public ActivityManager.RecentTaskInfo getTaskInfo() {
20634 synchronized (ActivityManagerService.this) {
20635 long origId = Binder.clearCallingIdentity();
20637 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20639 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20641 return createRecentTaskInfoFromTaskRecord(tr);
20643 Binder.restoreCallingIdentity(origId);
20649 public void moveToFront() {
20651 // Will bring task to front if it already has a root activity.
20652 startActivityFromRecentsInner(mTaskId, null);
20656 public int startActivity(IBinder whoThread, String callingPackage,
20657 Intent intent, String resolvedType, Bundle options) {
20660 int callingUser = UserHandle.getCallingUserId();
20662 IApplicationThread appThread;
20663 synchronized (ActivityManagerService.this) {
20664 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20666 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20668 appThread = ApplicationThreadNative.asInterface(whoThread);
20669 if (appThread == null) {
20670 throw new IllegalArgumentException("Bad app thread " + appThread);
20673 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20674 resolvedType, null, null, null, null, 0, 0, null, null,
20675 null, options, false, callingUser, null, tr);
20679 public void setExcludeFromRecents(boolean exclude) {
20682 synchronized (ActivityManagerService.this) {
20683 long origId = Binder.clearCallingIdentity();
20685 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20687 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20689 Intent intent = tr.getBaseIntent();
20691 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20693 intent.setFlags(intent.getFlags()
20694 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20697 Binder.restoreCallingIdentity(origId);