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 org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31 import static org.xmlpull.v1.XmlPullParser.START_TAG;
32 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
35 import android.Manifest;
36 import android.app.AppOpsManager;
37 import android.app.ApplicationThreadNative;
38 import android.app.IActivityContainer;
39 import android.app.IActivityContainerCallback;
40 import android.app.IAppTask;
41 import android.app.ITaskStackListener;
42 import android.app.ProfilerInfo;
43 import android.app.admin.DevicePolicyManager;
44 import android.app.usage.UsageEvents;
45 import android.app.usage.UsageStatsManagerInternal;
46 import android.appwidget.AppWidgetManager;
47 import android.content.res.Resources;
48 import android.graphics.Bitmap;
49 import android.graphics.Point;
50 import android.graphics.Rect;
51 import android.os.BatteryStats;
52 import android.os.PersistableBundle;
53 import android.os.storage.IMountService;
54 import android.os.storage.StorageManager;
55 import android.service.voice.IVoiceInteractionSession;
56 import android.util.ArrayMap;
57 import android.util.ArraySet;
58 import android.util.SparseIntArray;
60 import android.view.Display;
61 import com.android.internal.R;
62 import com.android.internal.annotations.GuardedBy;
63 import com.android.internal.app.IAppOpsService;
64 import com.android.internal.app.IVoiceInteractor;
65 import com.android.internal.app.ProcessMap;
66 import com.android.internal.app.ProcessStats;
67 import com.android.internal.os.BackgroundThread;
68 import com.android.internal.os.BatteryStatsImpl;
69 import com.android.internal.os.ProcessCpuTracker;
70 import com.android.internal.os.TransferPipe;
71 import com.android.internal.os.Zygote;
72 import com.android.internal.util.FastPrintWriter;
73 import com.android.internal.util.FastXmlSerializer;
74 import com.android.internal.util.MemInfoReader;
75 import com.android.internal.util.Preconditions;
76 import com.android.server.AppOpsService;
77 import com.android.server.AttributeCache;
78 import com.android.server.IntentResolver;
79 import com.android.server.LocalServices;
80 import com.android.server.ServiceThread;
81 import com.android.server.SystemService;
82 import com.android.server.SystemServiceManager;
83 import com.android.server.Watchdog;
84 import com.android.server.am.ActivityStack.ActivityState;
85 import com.android.server.firewall.IntentFirewall;
86 import com.android.server.pm.Installer;
87 import com.android.server.pm.UserManagerService;
88 import com.android.server.statusbar.StatusBarManagerInternal;
89 import com.android.server.wm.AppTransition;
90 import com.android.server.wm.WindowManagerService;
91 import com.google.android.collect.Lists;
92 import com.google.android.collect.Maps;
94 import libcore.io.IoUtils;
95 import libcore.util.EmptyArray;
97 import org.xmlpull.v1.XmlPullParser;
98 import org.xmlpull.v1.XmlPullParserException;
99 import org.xmlpull.v1.XmlSerializer;
101 import android.app.Activity;
102 import android.app.ActivityManager;
103 import android.app.ActivityManager.RunningTaskInfo;
104 import android.app.ActivityManager.StackInfo;
105 import android.app.ActivityManagerInternal;
106 import android.app.ActivityManagerNative;
107 import android.app.ActivityOptions;
108 import android.app.ActivityThread;
109 import android.app.AlertDialog;
110 import android.app.AppGlobals;
111 import android.app.ApplicationErrorReport;
112 import android.app.Dialog;
113 import android.app.IActivityController;
114 import android.app.IApplicationThread;
115 import android.app.IInstrumentationWatcher;
116 import android.app.INotificationManager;
117 import android.app.IProcessObserver;
118 import android.app.IServiceConnection;
119 import android.app.IStopUserCallback;
120 import android.app.IUiAutomationConnection;
121 import android.app.IUserSwitchObserver;
122 import android.app.Instrumentation;
123 import android.app.Notification;
124 import android.app.NotificationManager;
125 import android.app.PendingIntent;
126 import android.app.backup.IBackupManager;
127 import android.content.ActivityNotFoundException;
128 import android.content.BroadcastReceiver;
129 import android.content.ClipData;
130 import android.content.ComponentCallbacks2;
131 import android.content.ComponentName;
132 import android.content.ContentProvider;
133 import android.content.ContentResolver;
134 import android.content.Context;
135 import android.content.DialogInterface;
136 import android.content.IContentProvider;
137 import android.content.IIntentReceiver;
138 import android.content.IIntentSender;
139 import android.content.Intent;
140 import android.content.IntentFilter;
141 import android.content.IntentSender;
142 import android.content.pm.ActivityInfo;
143 import android.content.pm.ApplicationInfo;
144 import android.content.pm.ConfigurationInfo;
145 import android.content.pm.IPackageDataObserver;
146 import android.content.pm.IPackageManager;
147 import android.content.pm.InstrumentationInfo;
148 import android.content.pm.PackageInfo;
149 import android.content.pm.PackageManager;
150 import android.content.pm.ParceledListSlice;
151 import android.content.pm.UserInfo;
152 import android.content.pm.PackageManager.NameNotFoundException;
153 import android.content.pm.PathPermission;
154 import android.content.pm.ProviderInfo;
155 import android.content.pm.ResolveInfo;
156 import android.content.pm.ServiceInfo;
157 import android.content.res.CompatibilityInfo;
158 import android.content.res.Configuration;
159 import android.net.Proxy;
160 import android.net.ProxyInfo;
161 import android.net.Uri;
162 import android.os.Binder;
163 import android.os.Build;
164 import android.os.Bundle;
165 import android.os.Debug;
166 import android.os.DropBoxManager;
167 import android.os.Environment;
168 import android.os.FactoryTest;
169 import android.os.FileObserver;
170 import android.os.FileUtils;
171 import android.os.Handler;
172 import android.os.IBinder;
173 import android.os.IPermissionController;
174 import android.os.IProcessInfoService;
175 import android.os.IRemoteCallback;
176 import android.os.IUserManager;
177 import android.os.Looper;
178 import android.os.Message;
179 import android.os.Parcel;
180 import android.os.ParcelFileDescriptor;
181 import android.os.PowerManagerInternal;
182 import android.os.Process;
183 import android.os.RemoteCallbackList;
184 import android.os.RemoteException;
185 import android.os.SELinux;
186 import android.os.ServiceManager;
187 import android.os.StrictMode;
188 import android.os.SystemClock;
189 import android.os.SystemProperties;
190 import android.os.UpdateLock;
191 import android.os.UserHandle;
192 import android.os.UserManager;
193 import android.provider.Settings;
194 import android.text.format.DateUtils;
195 import android.text.format.Time;
196 import android.util.AtomicFile;
197 import android.util.EventLog;
198 import android.util.Log;
199 import android.util.Pair;
200 import android.util.PrintWriterPrinter;
201 import android.util.Slog;
202 import android.util.SparseArray;
203 import android.util.TimeUtils;
204 import android.util.Xml;
205 import android.view.Gravity;
206 import android.view.LayoutInflater;
207 import android.view.View;
208 import android.view.WindowManager;
210 import dalvik.system.VMRuntime;
212 import java.io.BufferedInputStream;
213 import java.io.BufferedOutputStream;
214 import java.io.DataInputStream;
215 import java.io.DataOutputStream;
217 import java.io.FileDescriptor;
218 import java.io.FileInputStream;
219 import java.io.FileNotFoundException;
220 import java.io.FileOutputStream;
221 import java.io.IOException;
222 import java.io.InputStreamReader;
223 import java.io.PrintWriter;
224 import java.io.StringWriter;
225 import java.lang.ref.WeakReference;
226 import java.util.ArrayList;
227 import java.util.Arrays;
228 import java.util.Collections;
229 import java.util.Comparator;
230 import java.util.HashMap;
231 import java.util.HashSet;
232 import java.util.Iterator;
233 import java.util.List;
234 import java.util.Locale;
235 import java.util.Map;
236 import java.util.Set;
237 import java.util.concurrent.atomic.AtomicBoolean;
238 import java.util.concurrent.atomic.AtomicLong;
240 public final class ActivityManagerService extends ActivityManagerNative
241 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
243 private static final String USER_DATA_DIR = "/data/user/";
244 // File that stores last updated system version and called preboot receivers
245 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
247 static final String TAG = "ActivityManager";
248 static final String TAG_MU = "ActivityManagerServiceMU";
249 static final boolean DEBUG = false;
250 static final boolean localLOGV = DEBUG;
251 static final boolean DEBUG_BACKUP = localLOGV || false;
252 static final boolean DEBUG_BROADCAST = localLOGV || false;
253 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
254 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
255 static final boolean DEBUG_CLEANUP = localLOGV || false;
256 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
257 static final boolean DEBUG_FOCUS = false;
258 static final boolean DEBUG_IMMERSIVE = localLOGV || false;
259 static final boolean DEBUG_MU = localLOGV || false;
260 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
261 static final boolean DEBUG_LRU = localLOGV || false;
262 static final boolean DEBUG_PAUSE = localLOGV || false;
263 static final boolean DEBUG_POWER = localLOGV || false;
264 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
265 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
266 static final boolean DEBUG_PROCESSES = localLOGV || false;
267 static final boolean DEBUG_PROVIDER = localLOGV || false;
268 static final boolean DEBUG_RESULTS = localLOGV || false;
269 static final boolean DEBUG_SERVICE = localLOGV || false;
270 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
271 static final boolean DEBUG_STACK = localLOGV || false;
272 static final boolean DEBUG_SWITCH = localLOGV || false;
273 static final boolean DEBUG_TASKS = localLOGV || false;
274 static final boolean DEBUG_THUMBNAILS = localLOGV || false;
275 static final boolean DEBUG_TRANSITION = localLOGV || false;
276 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
277 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
278 static final boolean DEBUG_VISBILITY = localLOGV || false;
279 static final boolean DEBUG_PSS = localLOGV || false;
280 static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
281 static final boolean DEBUG_RECENTS = localLOGV || false;
282 static final boolean VALIDATE_TOKENS = false;
283 static final boolean SHOW_ACTIVITY_START_TIME = true;
285 // Control over CPU and battery monitoring.
286 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
287 static final boolean MONITOR_CPU_USAGE = true;
288 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
289 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
290 static final boolean MONITOR_THREAD_CPU_USAGE = false;
292 // The flags that are set for all calls we make to the package manager.
293 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
295 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
297 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
299 // Maximum number recent bitmaps to keep in memory.
300 static final int MAX_RECENT_BITMAPS = 3;
302 // Amount of time after a call to stopAppSwitches() during which we will
303 // prevent further untrusted switches from happening.
304 static final long APP_SWITCH_DELAY_TIME = 5*1000;
306 // How long we wait for a launched process to attach to the activity manager
307 // before we decide it's never going to come up for real.
308 static final int PROC_START_TIMEOUT = 10*1000;
310 // How long we wait for a launched process to attach to the activity manager
311 // before we decide it's never going to come up for real, when the process was
312 // started with a wrapper for instrumentation (such as Valgrind) because it
313 // could take much longer than usual.
314 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
316 // How long to wait after going idle before forcing apps to GC.
317 static final int GC_TIMEOUT = 5*1000;
319 // The minimum amount of time between successive GC requests for a process.
320 static final int GC_MIN_INTERVAL = 60*1000;
322 // The minimum amount of time between successive PSS requests for a process.
323 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
325 // The minimum amount of time between successive PSS requests for a process
326 // when the request is due to the memory state being lowered.
327 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
329 // The rate at which we check for apps using excessive power -- 15 mins.
330 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
332 // The minimum sample duration we will allow before deciding we have
333 // enough data on wake locks to start killing things.
334 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
336 // The minimum sample duration we will allow before deciding we have
337 // enough data on CPU usage to start killing things.
338 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
340 // How long we allow a receiver to run before giving up on it.
341 static final int BROADCAST_FG_TIMEOUT = 10*1000;
342 static final int BROADCAST_BG_TIMEOUT = 60*1000;
344 // How long we wait until we timeout on key dispatching.
345 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
347 // How long we wait until we timeout on key dispatching during instrumentation.
348 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
350 // Amount of time we wait for observers to handle a user switch before
351 // giving up on them and unfreezing the screen.
352 static final int USER_SWITCH_TIMEOUT = 2*1000;
354 // Maximum number of users we allow to be running at a time.
355 static final int MAX_RUNNING_USERS = 3;
357 // How long to wait in getAssistContextExtras for the activity and foreground services
358 // to respond with the result.
359 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
361 // Maximum number of persisted Uri grants a package is allowed
362 static final int MAX_PERSISTED_URI_GRANTS = 128;
364 static final int MY_PID = Process.myPid();
366 static final String[] EMPTY_STRING_ARRAY = new String[0];
368 // How many bytes to write into the dropbox log before truncating
369 static final int DROPBOX_MAX_SIZE = 256 * 1024;
371 // Access modes for handleIncomingUser.
372 static final int ALLOW_NON_FULL = 0;
373 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
374 static final int ALLOW_FULL_ONLY = 2;
376 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
378 // Delay in notifying task stack change listeners (in millis)
379 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
381 // Necessary ApplicationInfo flags to mark an app as persistent
382 private static final int PERSISTENT_MASK =
383 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
385 /** All system services */
386 SystemServiceManager mSystemServiceManager;
388 private Installer mInstaller;
390 /** Run all ActivityStacks through this */
391 ActivityStackSupervisor mStackSupervisor;
393 /** Task stack change listeners. */
394 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
395 new RemoteCallbackList<ITaskStackListener>();
397 public IntentFirewall mIntentFirewall;
399 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
400 // default actuion automatically. Important for devices without direct input
402 private boolean mShowDialogs = true;
404 BroadcastQueue mFgBroadcastQueue;
405 BroadcastQueue mBgBroadcastQueue;
406 // Convenient for easy iteration over the queues. Foreground is first
407 // so that dispatch of foreground broadcasts gets precedence.
408 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
410 BroadcastQueue broadcastQueueForIntent(Intent intent) {
411 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
412 if (DEBUG_BACKGROUND_BROADCAST) {
413 Slog.i(TAG, "Broadcast intent " + intent + " on "
414 + (isFg ? "foreground" : "background")
417 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
421 * Activity we have told the window manager to have key focus.
423 ActivityRecord mFocusedActivity = null;
426 * List of intents that were used to start the most recent tasks.
428 ArrayList<TaskRecord> mRecentTasks;
429 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
432 * For addAppTask: cached of the last activity component that was added.
434 ComponentName mLastAddedTaskComponent;
437 * For addAppTask: cached of the last activity uid that was added.
439 int mLastAddedTaskUid;
442 * For addAppTask: cached of the last ActivityInfo that was added.
444 ActivityInfo mLastAddedTaskActivity;
446 public class PendingAssistExtras extends Binder implements Runnable {
447 public final ActivityRecord activity;
448 public final Bundle extras;
449 public final Intent intent;
450 public final String hint;
451 public final int userHandle;
452 public boolean haveResult = false;
453 public Bundle result = null;
454 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
455 String _hint, int _userHandle) {
456 activity = _activity;
460 userHandle = _userHandle;
464 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
465 synchronized (this) {
472 final ArrayList<PendingAssistExtras> mPendingAssistExtras
473 = new ArrayList<PendingAssistExtras>();
476 * Process management.
478 final ProcessList mProcessList = new ProcessList();
481 * All of the applications we currently have running organized by name.
482 * The keys are strings of the application package name (as
483 * returned by the package manager), and the keys are ApplicationRecord
486 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
489 * Tracking long-term execution of processes to look for abuse and other
492 final ProcessStatsService mProcessStats;
495 * The currently running isolated processes.
497 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
500 * Counter for assigning isolated process uids, to avoid frequently reusing the
503 int mNextIsolatedProcessUid = 0;
506 * The currently running heavy-weight process, if any.
508 ProcessRecord mHeavyWeightProcess = null;
511 * The last time that various processes have crashed.
513 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
516 * Information about a process that is currently marked as bad.
518 static final class BadProcessInfo {
519 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
521 this.shortMsg = shortMsg;
522 this.longMsg = longMsg;
527 final String shortMsg;
528 final String longMsg;
533 * Set of applications that we consider to be bad, and will reject
534 * incoming broadcasts from (which the user has no control over).
535 * Processes are added to this set when they have crashed twice within
536 * a minimum amount of time; they are removed from it when they are
537 * later restarted (hopefully due to some user action). The value is the
538 * time it was added to the list.
540 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
543 * All of the processes we currently have running organized by pid.
544 * The keys are the pid running the application.
546 * <p>NOTE: This object is protected by its own lock, NOT the global
547 * activity manager lock!
549 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
552 * All of the processes that have been forced to be foreground. The key
553 * is the pid of the caller who requested it (we hold a death
556 abstract class ForegroundToken implements IBinder.DeathRecipient {
560 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
563 * List of records for processes that someone had tried to start before the
564 * system was ready. We don't start them at that point, but ensure they
565 * are started by the time booting is complete.
567 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
570 * List of persistent applications that are in the process
573 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
576 * Processes that are being forcibly torn down.
578 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
581 * List of running applications, sorted by recent usage.
582 * The first entry in the list is the least recently used.
584 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
587 * Where in mLruProcesses that the processes hosting activities start.
589 int mLruProcessActivityStart = 0;
592 * Where in mLruProcesses that the processes hosting services start.
593 * This is after (lower index) than mLruProcessesActivityStart.
595 int mLruProcessServiceStart = 0;
598 * List of processes that should gc as soon as things are idle.
600 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
603 * Processes we want to collect PSS data from.
605 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
608 * Last time we requested PSS data of all processes.
610 long mLastFullPssTime = SystemClock.uptimeMillis();
613 * If set, the next time we collect PSS data we should do a full collection
614 * with data from native processes and the kernel.
616 boolean mFullPssPending = false;
619 * This is the process holding what we currently consider to be
620 * the "home" activity.
622 ProcessRecord mHomeProcess;
625 * This is the process holding the activity the user last visited that
626 * is in a different process from the one they are currently in.
628 ProcessRecord mPreviousProcess;
631 * The time at which the previous process was last visible.
633 long mPreviousProcessVisibleTime;
636 * Which uses have been started, so are allowed to run code.
638 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
641 * LRU list of history of current users. Most recently current is at the end.
643 final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
646 * Constant array of the users that are currently started.
648 int[] mStartedUserArray = new int[] { 0 };
651 * Registered observers of the user switching mechanics.
653 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
654 = new RemoteCallbackList<IUserSwitchObserver>();
657 * Currently active user switch.
659 Object mCurUserSwitchCallback;
662 * Packages that the user has asked to have run in screen size
663 * compatibility mode instead of filling the screen.
665 final CompatModePackages mCompatModePackages;
668 * Set of IntentSenderRecord objects that are currently active.
670 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
671 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
674 * Fingerprints (hashCode()) of stack traces that we've
675 * already logged DropBox entries for. Guarded by itself. If
676 * something (rogue user app) forces this over
677 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
679 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
680 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
683 * Strict Mode background batched logging state.
685 * The string buffer is guarded by itself, and its lock is also
686 * used to determine if another batched write is already
689 private final StringBuilder mStrictModeBuffer = new StringBuilder();
692 * Keeps track of all IIntentReceivers that have been registered for
693 * broadcasts. Hash keys are the receiver IBinder, hash value is
696 final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
697 new HashMap<IBinder, ReceiverList>();
700 * Resolver for broadcast intents to registered receivers.
701 * Holds BroadcastFilter (subclass of IntentFilter).
703 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
704 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
706 protected boolean allowFilterResult(
707 BroadcastFilter filter, List<BroadcastFilter> dest) {
708 IBinder target = filter.receiverList.receiver.asBinder();
709 for (int i=dest.size()-1; i>=0; i--) {
710 if (dest.get(i).receiverList.receiver.asBinder() == target) {
718 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
719 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
720 || userId == filter.owningUserId) {
721 return super.newResult(filter, match, userId);
727 protected BroadcastFilter[] newArray(int size) {
728 return new BroadcastFilter[size];
732 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
733 return packageName.equals(filter.packageName);
738 * State of all active sticky broadcasts per user. Keys are the action of the
739 * sticky Intent, values are an ArrayList of all broadcasted intents with
740 * that action (which should usually be one). The SparseArray is keyed
741 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
742 * for stickies that are sent to all users.
744 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
745 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
747 final ActiveServices mServices;
749 final static class Association {
750 final int mSourceUid;
751 final String mSourceProcess;
752 final int mTargetUid;
753 final ComponentName mTargetComponent;
754 final String mTargetProcess;
762 Association(int sourceUid, String sourceProcess, int targetUid,
763 ComponentName targetComponent, String targetProcess) {
764 mSourceUid = sourceUid;
765 mSourceProcess = sourceProcess;
766 mTargetUid = targetUid;
767 mTargetComponent = targetComponent;
768 mTargetProcess = targetProcess;
773 * When service association tracking is enabled, this is all of the associations we
774 * have seen. Mapping is target uid -> target component -> source uid -> source process name
775 * -> association data.
777 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
778 mAssociations = new SparseArray<>();
779 boolean mTrackingAssociations;
782 * Backup/restore process management
784 String mBackupAppName = null;
785 BackupRecord mBackupTarget = null;
787 final ProviderMap mProviderMap;
790 * List of content providers who have clients waiting for them. The
791 * application is currently being launched and the provider will be
792 * removed from this list once it is published.
794 final ArrayList<ContentProviderRecord> mLaunchingProviders
795 = new ArrayList<ContentProviderRecord>();
798 * File storing persisted {@link #mGrantedUriPermissions}.
800 private final AtomicFile mGrantFile;
802 /** XML constants used in {@link #mGrantFile} */
803 private static final String TAG_URI_GRANTS = "uri-grants";
804 private static final String TAG_URI_GRANT = "uri-grant";
805 private static final String ATTR_USER_HANDLE = "userHandle";
806 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
807 private static final String ATTR_TARGET_USER_ID = "targetUserId";
808 private static final String ATTR_SOURCE_PKG = "sourcePkg";
809 private static final String ATTR_TARGET_PKG = "targetPkg";
810 private static final String ATTR_URI = "uri";
811 private static final String ATTR_MODE_FLAGS = "modeFlags";
812 private static final String ATTR_CREATED_TIME = "createdTime";
813 private static final String ATTR_PREFIX = "prefix";
816 * Global set of specific {@link Uri} permissions that have been granted.
817 * This optimized lookup structure maps from {@link UriPermission#targetUid}
818 * to {@link UriPermission#uri} to {@link UriPermission}.
821 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
822 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
824 public static class GrantUri {
825 public final int sourceUserId;
826 public final Uri uri;
827 public boolean prefix;
829 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
830 this.sourceUserId = sourceUserId;
832 this.prefix = prefix;
836 public int hashCode() {
838 hashCode = 31 * hashCode + sourceUserId;
839 hashCode = 31 * hashCode + uri.hashCode();
840 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
845 public boolean equals(Object o) {
846 if (o instanceof GrantUri) {
847 GrantUri other = (GrantUri) o;
848 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
849 && prefix == other.prefix;
855 public String toString() {
856 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
857 if (prefix) result += " [prefix]";
861 public String toSafeString() {
862 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
863 if (prefix) result += " [prefix]";
867 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
868 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
869 ContentProvider.getUriWithoutUserId(uri), false);
873 CoreSettingsObserver mCoreSettingsObserver;
876 * Thread-local storage used to carry caller permissions over through
877 * indirect content-provider access.
879 private class Identity {
880 public final IBinder token;
881 public final int pid;
882 public final int uid;
884 Identity(IBinder _token, int _pid, int _uid) {
891 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
894 * All information we have collected about the runtime performance of
895 * any user id that can impact battery performance.
897 final BatteryStatsService mBatteryStatsService;
900 * Information about component usage
902 UsageStatsManagerInternal mUsageStatsService;
905 * Information about and control over application operations
907 final AppOpsService mAppOpsService;
910 * Save recent tasks information across reboots.
912 final TaskPersister mTaskPersister;
915 * Current configuration information. HistoryRecord objects are given
916 * a reference to this object to indicate which configuration they are
917 * currently running in, so this object must be kept immutable.
919 Configuration mConfiguration = new Configuration();
922 * Current sequencing integer of the configuration, for skipping old
925 int mConfigurationSeq = 0;
928 * Hardware-reported OpenGLES version.
930 final int GL_ES_VERSION;
933 * List of initialization arguments to pass to all processes when binding applications to them.
934 * For example, references to the commonly used services.
936 HashMap<String, IBinder> mAppBindArgs;
939 * Temporary to avoid allocations. Protected by main lock.
941 final StringBuilder mStringBuilder = new StringBuilder(256);
944 * Used to control how we initialize the service.
946 ComponentName mTopComponent;
947 String mTopAction = Intent.ACTION_MAIN;
949 boolean mProcessesReady = false;
950 boolean mSystemReady = false;
951 boolean mBooting = false;
952 boolean mCallFinishBooting = false;
953 boolean mBootAnimationComplete = false;
954 boolean mWaitingUpdate = false;
955 boolean mDidUpdate = false;
956 boolean mOnBattery = false;
957 boolean mLaunchWarningShown = false;
963 boolean mCheckedForSetup;
966 * The time at which we will allow normal application switches again,
967 * after a call to {@link #stopAppSwitches()}.
969 long mAppSwitchesAllowedTime;
972 * This is set to true after the first switch after mAppSwitchesAllowedTime
973 * is set; any switches after that will clear the time.
975 boolean mDidAppSwitch;
978 * Last time (in realtime) at which we checked for power usage.
980 long mLastPowerCheckRealtime;
983 * Last time (in uptime) at which we checked for power usage.
985 long mLastPowerCheckUptime;
988 * Set while we are wanting to sleep, to prevent any
989 * activities from being started/resumed.
991 private boolean mSleeping = false;
994 * Set while we are running a voice interaction. This overrides
995 * sleeping while it is active.
997 private boolean mRunningVoice = false;
1000 * State of external calls telling us if the device is awake or asleep.
1002 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1004 static final int LOCK_SCREEN_HIDDEN = 0;
1005 static final int LOCK_SCREEN_LEAVING = 1;
1006 static final int LOCK_SCREEN_SHOWN = 2;
1008 * State of external call telling us if the lock screen is shown.
1010 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1013 * Set if we are shutting down the system, similar to sleeping.
1015 boolean mShuttingDown = false;
1018 * Current sequence id for oom_adj computation traversal.
1023 * Current sequence id for process LRU updating.
1028 * Keep track of the non-cached/empty process we last found, to help
1029 * determine how to distribute cached/empty processes next time.
1031 int mNumNonCachedProcs = 0;
1034 * Keep track of the number of cached hidden procs, to balance oom adj
1035 * distribution between those and empty procs.
1037 int mNumCachedHiddenProcs = 0;
1040 * Keep track of the number of service processes we last found, to
1041 * determine on the next iteration which should be B services.
1043 int mNumServiceProcs = 0;
1044 int mNewNumAServiceProcs = 0;
1045 int mNewNumServiceProcs = 0;
1048 * Allow the current computed overall memory level of the system to go down?
1049 * This is set to false when we are killing processes for reasons other than
1050 * memory management, so that the now smaller process list will not be taken as
1051 * an indication that memory is tighter.
1053 boolean mAllowLowerMemLevel = false;
1056 * The last computed memory level, for holding when we are in a state that
1057 * processes are going away for other reasons.
1059 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1062 * The last total number of process we have, to determine if changes actually look
1063 * like a shrinking number of process due to lower RAM.
1065 int mLastNumProcesses;
1068 * The uptime of the last time we performed idle maintenance.
1070 long mLastIdleTime = SystemClock.uptimeMillis();
1073 * Total time spent with RAM that has been added in the past since the last idle time.
1075 long mLowRamTimeSinceLastIdle = 0;
1078 * If RAM is currently low, when that horrible situation started.
1080 long mLowRamStartTime = 0;
1083 * For reporting to battery stats the current top application.
1085 private String mCurResumedPackage = null;
1086 private int mCurResumedUid = -1;
1089 * For reporting to battery stats the apps currently running foreground
1090 * service. The ProcessMap is package/uid tuples; each of these contain
1091 * an array of the currently foreground processes.
1093 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1094 = new ProcessMap<ArrayList<ProcessRecord>>();
1097 * This is set if we had to do a delayed dexopt of an app before launching
1098 * it, to increase the ANR timeouts in that case.
1103 * Set if the systemServer made a call to enterSafeMode.
1108 * If true, we are running under a test environment so will sample PSS from processes
1109 * much more rapidly to try to collect better data when the tests are rapidly
1110 * running through apps.
1112 boolean mTestPssMode = false;
1114 String mDebugApp = null;
1115 boolean mWaitForDebugger = false;
1116 boolean mDebugTransient = false;
1117 String mOrigDebugApp = null;
1118 boolean mOrigWaitForDebugger = false;
1119 boolean mAlwaysFinishActivities = false;
1120 IActivityController mController = null;
1121 String mProfileApp = null;
1122 ProcessRecord mProfileProc = null;
1123 String mProfileFile;
1124 ParcelFileDescriptor mProfileFd;
1125 int mSamplingInterval = 0;
1126 boolean mAutoStopProfiler = false;
1127 int mProfileType = 0;
1128 String mOpenGlTraceApp = null;
1130 final long[] mTmpLong = new long[1];
1132 static class ProcessChangeItem {
1133 static final int CHANGE_ACTIVITIES = 1<<0;
1134 static final int CHANGE_PROCESS_STATE = 1<<1;
1139 boolean foregroundActivities;
1142 final RemoteCallbackList<IProcessObserver> mProcessObservers
1143 = new RemoteCallbackList<IProcessObserver>();
1144 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1146 final ArrayList<ProcessChangeItem> mPendingProcessChanges
1147 = new ArrayList<ProcessChangeItem>();
1148 final ArrayList<ProcessChangeItem> mAvailProcessChanges
1149 = new ArrayList<ProcessChangeItem>();
1152 * Runtime CPU use collection thread. This object's lock is used to
1153 * perform synchronization with the thread (notifying it to run).
1155 final Thread mProcessCpuThread;
1158 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1159 * Must acquire this object's lock when accessing it.
1160 * NOTE: this lock will be held while doing long operations (trawling
1161 * through all processes in /proc), so it should never be acquired by
1162 * any critical paths such as when holding the main activity manager lock.
1164 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1165 MONITOR_THREAD_CPU_USAGE);
1166 final AtomicLong mLastCpuTime = new AtomicLong(0);
1167 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1169 long mLastWriteTime = 0;
1172 * Used to retain an update lock when the foreground activity is in
1175 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1178 * Set to true after the system has finished booting.
1180 boolean mBooted = false;
1182 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1183 int mProcessLimitOverride = -1;
1185 WindowManagerService mWindowManager;
1187 final ActivityThread mSystemThread;
1189 // Holds the current foreground user's id
1190 int mCurrentUserId = 0;
1191 // Holds the target user's id during a user switch
1192 int mTargetUserId = UserHandle.USER_NULL;
1193 // If there are multiple profiles for the current user, their ids are here
1194 // Currently only the primary user can have managed profiles
1195 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1198 * Mapping from each known user ID to the profile group ID it is associated with.
1200 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1202 private UserManagerService mUserManager;
1204 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1205 final ProcessRecord mApp;
1207 final IApplicationThread mAppThread;
1209 AppDeathRecipient(ProcessRecord app, int pid,
1210 IApplicationThread thread) {
1211 if (localLOGV) Slog.v(
1212 TAG, "New death recipient " + this
1213 + " for thread " + thread.asBinder());
1216 mAppThread = thread;
1220 public void binderDied() {
1221 if (localLOGV) Slog.v(
1222 TAG, "Death received in " + this
1223 + " for thread " + mAppThread.asBinder());
1224 synchronized(ActivityManagerService.this) {
1225 appDiedLocked(mApp, mPid, mAppThread, true);
1230 static final int SHOW_ERROR_MSG = 1;
1231 static final int SHOW_NOT_RESPONDING_MSG = 2;
1232 static final int SHOW_FACTORY_ERROR_MSG = 3;
1233 static final int UPDATE_CONFIGURATION_MSG = 4;
1234 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1235 static final int WAIT_FOR_DEBUGGER_MSG = 6;
1236 static final int SERVICE_TIMEOUT_MSG = 12;
1237 static final int UPDATE_TIME_ZONE = 13;
1238 static final int SHOW_UID_ERROR_MSG = 14;
1239 static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1240 static final int PROC_START_TIMEOUT_MSG = 20;
1241 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1242 static final int KILL_APPLICATION_MSG = 22;
1243 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1244 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1245 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1246 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1247 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1248 static final int CLEAR_DNS_CACHE_MSG = 28;
1249 static final int UPDATE_HTTP_PROXY_MSG = 29;
1250 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1251 static final int DISPATCH_PROCESSES_CHANGED = 31;
1252 static final int DISPATCH_PROCESS_DIED = 32;
1253 static final int REPORT_MEM_USAGE_MSG = 33;
1254 static final int REPORT_USER_SWITCH_MSG = 34;
1255 static final int CONTINUE_USER_SWITCH_MSG = 35;
1256 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1257 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1258 static final int PERSIST_URI_GRANTS_MSG = 38;
1259 static final int REQUEST_ALL_PSS_MSG = 39;
1260 static final int START_PROFILES_MSG = 40;
1261 static final int UPDATE_TIME = 41;
1262 static final int SYSTEM_USER_START_MSG = 42;
1263 static final int SYSTEM_USER_CURRENT_MSG = 43;
1264 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1265 static final int FINISH_BOOTING_MSG = 45;
1266 static final int START_USER_SWITCH_MSG = 46;
1267 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1268 static final int DISMISS_DIALOG_MSG = 48;
1269 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1270 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1272 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1273 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1274 static final int FIRST_COMPAT_MODE_MSG = 300;
1275 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1277 CompatModeDialog mCompatModeDialog;
1278 long mLastMemUsageReportTime = 0;
1281 * Flag whether the current user is a "monkey", i.e. whether
1282 * the UI is driven by a UI automation tool.
1284 private boolean mUserIsMonkey;
1286 /** Flag whether the device has a Recents UI */
1287 boolean mHasRecents;
1289 /** The dimensions of the thumbnails in the Recents UI. */
1290 int mThumbnailWidth;
1291 int mThumbnailHeight;
1293 final ServiceThread mHandlerThread;
1294 final MainHandler mHandler;
1295 final UiHandler mUiHandler;
1297 final class UiHandler extends Handler {
1298 public UiHandler() {
1299 super(com.android.server.UiThread.get().getLooper(), null, true);
1303 public void handleMessage(Message msg) {
1305 case SHOW_ERROR_MSG: {
1306 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1307 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1308 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1309 synchronized (ActivityManagerService.this) {
1310 ProcessRecord proc = (ProcessRecord)data.get("app");
1311 AppErrorResult res = (AppErrorResult) data.get("result");
1312 if (proc != null && proc.crashDialog != null) {
1313 Slog.e(TAG, "App already has crash dialog: " + proc);
1319 boolean isBackground = (UserHandle.getAppId(proc.uid)
1320 >= Process.FIRST_APPLICATION_UID
1321 && proc.pid != MY_PID);
1322 for (int userId : mCurrentProfileIds) {
1323 isBackground &= (proc.userId != userId);
1325 if (isBackground && !showBackground) {
1326 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1332 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1333 Dialog d = new AppErrorDialog(mContext,
1334 ActivityManagerService.this, res, proc);
1336 proc.crashDialog = d;
1338 // The device is asleep, so just pretend that the user
1339 // saw a crash dialog and hit "force quit".
1346 ensureBootCompleted();
1348 case SHOW_NOT_RESPONDING_MSG: {
1349 synchronized (ActivityManagerService.this) {
1350 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1351 ProcessRecord proc = (ProcessRecord)data.get("app");
1352 if (proc != null && proc.anrDialog != null) {
1353 Slog.e(TAG, "App already has anr dialog: " + proc);
1357 Intent intent = new Intent("android.intent.action.ANR");
1358 if (!mProcessesReady) {
1359 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1360 | Intent.FLAG_RECEIVER_FOREGROUND);
1362 broadcastIntentLocked(null, null, intent,
1363 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1364 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1367 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1368 mContext, proc, (ActivityRecord)data.get("activity"),
1373 // Just kill the app if there is no dialog to be shown.
1374 killAppAtUsersRequest(proc, null);
1378 ensureBootCompleted();
1380 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1381 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1382 synchronized (ActivityManagerService.this) {
1383 ProcessRecord proc = (ProcessRecord) data.get("app");
1385 Slog.e(TAG, "App not found when showing strict mode dialog.");
1388 if (proc.crashDialog != null) {
1389 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1392 AppErrorResult res = (AppErrorResult) data.get("result");
1393 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1394 Dialog d = new StrictModeViolationDialog(mContext,
1395 ActivityManagerService.this, res, proc);
1397 proc.crashDialog = d;
1399 // The device is asleep, so just pretend that the user
1400 // saw a crash dialog and hit "force quit".
1404 ensureBootCompleted();
1406 case SHOW_FACTORY_ERROR_MSG: {
1407 Dialog d = new FactoryErrorDialog(
1408 mContext, msg.getData().getCharSequence("msg"));
1410 ensureBootCompleted();
1412 case WAIT_FOR_DEBUGGER_MSG: {
1413 synchronized (ActivityManagerService.this) {
1414 ProcessRecord app = (ProcessRecord)msg.obj;
1415 if (msg.arg1 != 0) {
1416 if (!app.waitedForDebugger) {
1417 Dialog d = new AppWaitingForDebuggerDialog(
1418 ActivityManagerService.this,
1421 app.waitedForDebugger = true;
1425 if (app.waitDialog != null) {
1426 app.waitDialog.dismiss();
1427 app.waitDialog = null;
1432 case SHOW_UID_ERROR_MSG: {
1434 AlertDialog d = new BaseErrorDialog(mContext);
1435 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1436 d.setCancelable(false);
1437 d.setTitle(mContext.getText(R.string.android_system_label));
1438 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1439 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1440 obtainMessage(DISMISS_DIALOG_MSG, d));
1444 case SHOW_FINGERPRINT_ERROR_MSG: {
1446 AlertDialog d = new BaseErrorDialog(mContext);
1447 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1448 d.setCancelable(false);
1449 d.setTitle(mContext.getText(R.string.android_system_label));
1450 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1451 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1452 obtainMessage(DISMISS_DIALOG_MSG, d));
1456 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1457 synchronized (ActivityManagerService.this) {
1458 ActivityRecord ar = (ActivityRecord) msg.obj;
1459 if (mCompatModeDialog != null) {
1460 if (mCompatModeDialog.mAppInfo.packageName.equals(
1461 ar.info.applicationInfo.packageName)) {
1464 mCompatModeDialog.dismiss();
1465 mCompatModeDialog = null;
1467 if (ar != null && false) {
1468 if (mCompatModePackages.getPackageAskCompatModeLocked(
1470 int mode = mCompatModePackages.computeCompatModeLocked(
1471 ar.info.applicationInfo);
1472 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1473 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1474 mCompatModeDialog = new CompatModeDialog(
1475 ActivityManagerService.this, mContext,
1476 ar.info.applicationInfo);
1477 mCompatModeDialog.show();
1484 case START_USER_SWITCH_MSG: {
1485 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1488 case DISMISS_DIALOG_MSG: {
1489 final Dialog d = (Dialog) msg.obj;
1497 final class MainHandler extends Handler {
1498 public MainHandler(Looper looper) {
1499 super(looper, null, true);
1503 public void handleMessage(Message msg) {
1505 case UPDATE_CONFIGURATION_MSG: {
1506 final ContentResolver resolver = mContext.getContentResolver();
1507 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1509 case GC_BACKGROUND_PROCESSES_MSG: {
1510 synchronized (ActivityManagerService.this) {
1511 performAppGcsIfAppropriateLocked();
1514 case SERVICE_TIMEOUT_MSG: {
1517 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1519 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1522 mServices.serviceTimeout((ProcessRecord)msg.obj);
1524 case UPDATE_TIME_ZONE: {
1525 synchronized (ActivityManagerService.this) {
1526 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1527 ProcessRecord r = mLruProcesses.get(i);
1528 if (r.thread != null) {
1530 r.thread.updateTimeZone();
1531 } catch (RemoteException ex) {
1532 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1538 case CLEAR_DNS_CACHE_MSG: {
1539 synchronized (ActivityManagerService.this) {
1540 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1541 ProcessRecord r = mLruProcesses.get(i);
1542 if (r.thread != null) {
1544 r.thread.clearDnsCache();
1545 } catch (RemoteException ex) {
1546 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1552 case UPDATE_HTTP_PROXY_MSG: {
1553 ProxyInfo proxy = (ProxyInfo)msg.obj;
1556 String exclList = "";
1557 Uri pacFileUrl = Uri.EMPTY;
1558 if (proxy != null) {
1559 host = proxy.getHost();
1560 port = Integer.toString(proxy.getPort());
1561 exclList = proxy.getExclusionListAsString();
1562 pacFileUrl = proxy.getPacFileUrl();
1564 synchronized (ActivityManagerService.this) {
1565 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1566 ProcessRecord r = mLruProcesses.get(i);
1567 if (r.thread != null) {
1569 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1570 } catch (RemoteException ex) {
1571 Slog.w(TAG, "Failed to update http proxy for: " +
1572 r.info.processName);
1578 case PROC_START_TIMEOUT_MSG: {
1581 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1583 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1586 ProcessRecord app = (ProcessRecord)msg.obj;
1587 synchronized (ActivityManagerService.this) {
1588 processStartTimedOutLocked(app);
1591 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1592 synchronized (ActivityManagerService.this) {
1593 mStackSupervisor.doPendingActivityLaunchesLocked(true);
1596 case KILL_APPLICATION_MSG: {
1597 synchronized (ActivityManagerService.this) {
1598 int appid = msg.arg1;
1599 boolean restart = (msg.arg2 == 1);
1600 Bundle bundle = (Bundle)msg.obj;
1601 String pkg = bundle.getString("pkg");
1602 String reason = bundle.getString("reason");
1603 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1604 false, UserHandle.USER_ALL, reason);
1607 case FINALIZE_PENDING_INTENT_MSG: {
1608 ((PendingIntentRecord)msg.obj).completeFinalize();
1610 case POST_HEAVY_NOTIFICATION_MSG: {
1611 INotificationManager inm = NotificationManager.getService();
1616 ActivityRecord root = (ActivityRecord)msg.obj;
1617 ProcessRecord process = root.app;
1618 if (process == null) {
1623 Context context = mContext.createPackageContext(process.info.packageName, 0);
1624 String text = mContext.getString(R.string.heavy_weight_notification,
1625 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1626 Notification notification = new Notification();
1627 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1628 notification.when = 0;
1629 notification.flags = Notification.FLAG_ONGOING_EVENT;
1630 notification.tickerText = text;
1631 notification.defaults = 0; // please be quiet
1632 notification.sound = null;
1633 notification.vibrate = null;
1634 notification.color = mContext.getResources().getColor(
1635 com.android.internal.R.color.system_notification_accent_color);
1636 notification.setLatestEventInfo(context, text,
1637 mContext.getText(R.string.heavy_weight_notification_detail),
1638 PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1639 PendingIntent.FLAG_CANCEL_CURRENT, null,
1640 new UserHandle(root.userId)));
1643 int[] outId = new int[1];
1644 inm.enqueueNotificationWithTag("android", "android", null,
1645 R.string.heavy_weight_notification,
1646 notification, outId, root.userId);
1647 } catch (RuntimeException e) {
1648 Slog.w(ActivityManagerService.TAG,
1649 "Error showing notification for heavy-weight app", e);
1650 } catch (RemoteException e) {
1652 } catch (NameNotFoundException e) {
1653 Slog.w(TAG, "Unable to create context for heavy notification", e);
1656 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1657 INotificationManager inm = NotificationManager.getService();
1662 inm.cancelNotificationWithTag("android", null,
1663 R.string.heavy_weight_notification, msg.arg1);
1664 } catch (RuntimeException e) {
1665 Slog.w(ActivityManagerService.TAG,
1666 "Error canceling notification for service", e);
1667 } catch (RemoteException e) {
1670 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1671 synchronized (ActivityManagerService.this) {
1672 checkExcessivePowerUsageLocked(true);
1673 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1674 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1675 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1678 case DISPATCH_PROCESSES_CHANGED: {
1679 dispatchProcessesChanged();
1682 case DISPATCH_PROCESS_DIED: {
1683 final int pid = msg.arg1;
1684 final int uid = msg.arg2;
1685 dispatchProcessDied(pid, uid);
1688 case REPORT_MEM_USAGE_MSG: {
1689 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1690 Thread thread = new Thread() {
1691 @Override public void run() {
1692 reportMemUsage(memInfos);
1698 case REPORT_USER_SWITCH_MSG: {
1699 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1702 case CONTINUE_USER_SWITCH_MSG: {
1703 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1706 case USER_SWITCH_TIMEOUT_MSG: {
1707 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1710 case IMMERSIVE_MODE_LOCK_MSG: {
1711 final boolean nextState = (msg.arg1 != 0);
1712 if (mUpdateLock.isHeld() != nextState) {
1713 if (DEBUG_IMMERSIVE) {
1714 final ActivityRecord r = (ActivityRecord) msg.obj;
1715 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1718 mUpdateLock.acquire();
1720 mUpdateLock.release();
1725 case PERSIST_URI_GRANTS_MSG: {
1726 writeGrantedUriPermissions();
1729 case REQUEST_ALL_PSS_MSG: {
1730 synchronized (ActivityManagerService.this) {
1731 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1735 case START_PROFILES_MSG: {
1736 synchronized (ActivityManagerService.this) {
1737 startProfilesLocked();
1742 synchronized (ActivityManagerService.this) {
1743 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1744 ProcessRecord r = mLruProcesses.get(i);
1745 if (r.thread != null) {
1747 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1748 } catch (RemoteException ex) {
1749 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1756 case SYSTEM_USER_START_MSG: {
1757 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1758 Integer.toString(msg.arg1), msg.arg1);
1759 mSystemServiceManager.startUser(msg.arg1);
1762 case SYSTEM_USER_CURRENT_MSG: {
1763 mBatteryStatsService.noteEvent(
1764 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1765 Integer.toString(msg.arg2), msg.arg2);
1766 mBatteryStatsService.noteEvent(
1767 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1768 Integer.toString(msg.arg1), msg.arg1);
1769 mSystemServiceManager.switchUser(msg.arg1);
1772 case ENTER_ANIMATION_COMPLETE_MSG: {
1773 synchronized (ActivityManagerService.this) {
1774 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1775 if (r != null && r.app != null && r.app.thread != null) {
1777 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1778 } catch (RemoteException e) {
1784 case FINISH_BOOTING_MSG: {
1785 if (msg.arg1 != 0) {
1788 if (msg.arg2 != 0) {
1789 enableScreenAfterBoot();
1793 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1795 Locale l = (Locale) msg.obj;
1796 IBinder service = ServiceManager.getService("mount");
1797 IMountService mountService = IMountService.Stub.asInterface(service);
1798 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1799 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1800 } catch (RemoteException e) {
1801 Log.e(TAG, "Error storing locale for decryption UI", e);
1805 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1806 synchronized (ActivityManagerService.this) {
1807 int i = mTaskStackListeners.beginBroadcast();
1811 // Make a one-way callback to the listener
1812 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1813 } catch (RemoteException e){
1814 // Handled by the RemoteCallbackList
1817 mTaskStackListeners.finishBroadcast();
1821 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1822 final int uid = msg.arg1;
1823 final byte[] firstPacket = (byte[]) msg.obj;
1825 synchronized (mPidsSelfLocked) {
1826 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1827 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1830 p.thread.notifyCleartextNetwork(firstPacket);
1831 } catch (RemoteException ignored) {
1842 static final int COLLECT_PSS_BG_MSG = 1;
1844 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1846 public void handleMessage(Message msg) {
1848 case COLLECT_PSS_BG_MSG: {
1849 long start = SystemClock.uptimeMillis();
1850 MemInfoReader memInfo = null;
1851 synchronized (ActivityManagerService.this) {
1852 if (mFullPssPending) {
1853 mFullPssPending = false;
1854 memInfo = new MemInfoReader();
1857 if (memInfo != null) {
1858 updateCpuStatsNow();
1859 long nativeTotalPss = 0;
1860 synchronized (mProcessCpuTracker) {
1861 final int N = mProcessCpuTracker.countStats();
1862 for (int j=0; j<N; j++) {
1863 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1864 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1865 // This is definitely an application process; skip it.
1868 synchronized (mPidsSelfLocked) {
1869 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1870 // This is one of our own processes; skip it.
1874 nativeTotalPss += Debug.getPss(st.pid, null, null);
1877 memInfo.readMemInfo();
1878 synchronized (ActivityManagerService.this) {
1879 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1880 + (SystemClock.uptimeMillis()-start) + "ms");
1881 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1882 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1883 memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1888 long[] tmp = new long[1];
1894 synchronized (ActivityManagerService.this) {
1895 if (mPendingPssProcesses.size() <= 0) {
1896 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1897 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1898 mPendingPssProcesses.clear();
1901 proc = mPendingPssProcesses.remove(0);
1902 procState = proc.pssProcState;
1903 lastPssTime = proc.lastPssTime;
1904 if (proc.thread != null && procState == proc.setProcState
1905 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1906 < SystemClock.uptimeMillis()) {
1914 long pss = Debug.getPss(pid, tmp, null);
1915 synchronized (ActivityManagerService.this) {
1916 if (pss != 0 && proc.thread != null && proc.setProcState == procState
1917 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1919 recordPssSample(proc, procState, pss, tmp[0],
1920 SystemClock.uptimeMillis());
1930 public void setSystemProcess() {
1932 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1933 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1934 ServiceManager.addService("meminfo", new MemBinder(this));
1935 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1936 ServiceManager.addService("dbinfo", new DbBinder(this));
1937 if (MONITOR_CPU_USAGE) {
1938 ServiceManager.addService("cpuinfo", new CpuBinder(this));
1940 ServiceManager.addService("permission", new PermissionController(this));
1941 ServiceManager.addService("processinfo", new ProcessInfoService(this));
1943 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1944 "android", STOCK_PM_FLAGS);
1945 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1947 synchronized (this) {
1948 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1949 app.persistent = true;
1951 app.maxAdj = ProcessList.SYSTEM_ADJ;
1952 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1953 mProcessNames.put(app.processName, app.uid, app);
1954 synchronized (mPidsSelfLocked) {
1955 mPidsSelfLocked.put(app.pid, app);
1957 updateLruProcessLocked(app, false, null);
1958 updateOomAdjLocked();
1960 } catch (PackageManager.NameNotFoundException e) {
1961 throw new RuntimeException(
1962 "Unable to find android system package", e);
1966 public void setWindowManager(WindowManagerService wm) {
1967 mWindowManager = wm;
1968 mStackSupervisor.setWindowManager(wm);
1971 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1972 mUsageStatsService = usageStatsManager;
1975 public void startObservingNativeCrashes() {
1976 final NativeCrashListener ncl = new NativeCrashListener(this);
1980 public IAppOpsService getAppOpsService() {
1981 return mAppOpsService;
1984 static class MemBinder extends Binder {
1985 ActivityManagerService mActivityManagerService;
1986 MemBinder(ActivityManagerService activityManagerService) {
1987 mActivityManagerService = activityManagerService;
1991 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1992 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1993 != PackageManager.PERMISSION_GRANTED) {
1994 pw.println("Permission Denial: can't dump meminfo from from pid="
1995 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1996 + " without permission " + android.Manifest.permission.DUMP);
2000 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2004 static class GraphicsBinder extends Binder {
2005 ActivityManagerService mActivityManagerService;
2006 GraphicsBinder(ActivityManagerService activityManagerService) {
2007 mActivityManagerService = activityManagerService;
2011 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2012 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2013 != PackageManager.PERMISSION_GRANTED) {
2014 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2015 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2016 + " without permission " + android.Manifest.permission.DUMP);
2020 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2024 static class DbBinder extends Binder {
2025 ActivityManagerService mActivityManagerService;
2026 DbBinder(ActivityManagerService activityManagerService) {
2027 mActivityManagerService = activityManagerService;
2031 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2032 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2033 != PackageManager.PERMISSION_GRANTED) {
2034 pw.println("Permission Denial: can't dump dbinfo from from pid="
2035 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2036 + " without permission " + android.Manifest.permission.DUMP);
2040 mActivityManagerService.dumpDbInfo(fd, pw, args);
2044 static class CpuBinder extends Binder {
2045 ActivityManagerService mActivityManagerService;
2046 CpuBinder(ActivityManagerService activityManagerService) {
2047 mActivityManagerService = activityManagerService;
2051 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2052 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2053 != PackageManager.PERMISSION_GRANTED) {
2054 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2055 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2056 + " without permission " + android.Manifest.permission.DUMP);
2060 synchronized (mActivityManagerService.mProcessCpuTracker) {
2061 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2062 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2063 SystemClock.uptimeMillis()));
2068 public static final class Lifecycle extends SystemService {
2069 private final ActivityManagerService mService;
2071 public Lifecycle(Context context) {
2073 mService = new ActivityManagerService(context);
2077 public void onStart() {
2081 public ActivityManagerService getService() {
2086 // Note: This method is invoked on the main thread but may need to attach various
2087 // handlers to other threads. So take care to be explicit about the looper.
2088 public ActivityManagerService(Context systemContext) {
2089 mContext = systemContext;
2090 mFactoryTest = FactoryTest.getMode();
2091 mSystemThread = ActivityThread.currentActivityThread();
2093 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2095 mHandlerThread = new ServiceThread(TAG,
2096 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2097 mHandlerThread.start();
2098 mHandler = new MainHandler(mHandlerThread.getLooper());
2099 mUiHandler = new UiHandler();
2101 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2102 "foreground", BROADCAST_FG_TIMEOUT, false);
2103 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2104 "background", BROADCAST_BG_TIMEOUT, true);
2105 mBroadcastQueues[0] = mFgBroadcastQueue;
2106 mBroadcastQueues[1] = mBgBroadcastQueue;
2108 mServices = new ActiveServices(this);
2109 mProviderMap = new ProviderMap(this);
2111 // TODO: Move creation of battery stats service outside of activity manager service.
2112 File dataDir = Environment.getDataDirectory();
2113 File systemDir = new File(dataDir, "system");
2115 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2116 mBatteryStatsService.getActiveStatistics().readLocked();
2117 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2118 mOnBattery = DEBUG_POWER ? true
2119 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2120 mBatteryStatsService.getActiveStatistics().setCallback(this);
2122 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2124 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2126 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2128 // User 0 is the first and only user that runs at boot.
2129 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2130 mUserLru.add(Integer.valueOf(0));
2131 updateStartedUserArrayLocked();
2133 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2134 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2136 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2138 mConfiguration.setToDefaults();
2139 mConfiguration.locale = Locale.getDefault();
2141 mConfigurationSeq = mConfiguration.seq = 1;
2142 mProcessCpuTracker.init();
2144 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2145 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2146 mStackSupervisor = new ActivityStackSupervisor(this);
2147 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2149 mProcessCpuThread = new Thread("CpuTracker") {
2155 synchronized(this) {
2156 final long now = SystemClock.uptimeMillis();
2157 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2158 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2159 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2160 // + ", write delay=" + nextWriteDelay);
2161 if (nextWriteDelay < nextCpuDelay) {
2162 nextCpuDelay = nextWriteDelay;
2164 if (nextCpuDelay > 0) {
2165 mProcessCpuMutexFree.set(true);
2166 this.wait(nextCpuDelay);
2169 } catch (InterruptedException e) {
2171 updateCpuStatsNow();
2172 } catch (Exception e) {
2173 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2179 Watchdog.getInstance().addMonitor(this);
2180 Watchdog.getInstance().addThread(mHandler);
2183 public void setSystemServiceManager(SystemServiceManager mgr) {
2184 mSystemServiceManager = mgr;
2187 public void setInstaller(Installer installer) {
2188 mInstaller = installer;
2191 private void start() {
2192 Process.removeAllProcessGroups();
2193 mProcessCpuThread.start();
2195 mBatteryStatsService.publish(mContext);
2196 mAppOpsService.publish(mContext);
2197 Slog.d("AppOps", "AppOpsService published");
2198 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2201 public void initPowerManagement() {
2202 mStackSupervisor.initPowerManagement();
2203 mBatteryStatsService.initPowerManagement();
2207 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2208 throws RemoteException {
2209 if (code == SYSPROPS_TRANSACTION) {
2210 // We need to tell all apps about the system property change.
2211 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2212 synchronized(this) {
2213 final int NP = mProcessNames.getMap().size();
2214 for (int ip=0; ip<NP; ip++) {
2215 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2216 final int NA = apps.size();
2217 for (int ia=0; ia<NA; ia++) {
2218 ProcessRecord app = apps.valueAt(ia);
2219 if (app.thread != null) {
2220 procs.add(app.thread.asBinder());
2226 int N = procs.size();
2227 for (int i=0; i<N; i++) {
2228 Parcel data2 = Parcel.obtain();
2230 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2231 } catch (RemoteException e) {
2237 return super.onTransact(code, data, reply, flags);
2238 } catch (RuntimeException e) {
2239 // The activity manager only throws security exceptions, so let's
2241 if (!(e instanceof SecurityException)) {
2242 Slog.wtf(TAG, "Activity Manager Crash", e);
2248 void updateCpuStats() {
2249 final long now = SystemClock.uptimeMillis();
2250 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2253 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2254 synchronized (mProcessCpuThread) {
2255 mProcessCpuThread.notify();
2260 void updateCpuStatsNow() {
2261 synchronized (mProcessCpuTracker) {
2262 mProcessCpuMutexFree.set(false);
2263 final long now = SystemClock.uptimeMillis();
2264 boolean haveNewCpuStats = false;
2266 if (MONITOR_CPU_USAGE &&
2267 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2268 mLastCpuTime.set(now);
2269 haveNewCpuStats = true;
2270 mProcessCpuTracker.update();
2271 //Slog.i(TAG, mProcessCpu.printCurrentState());
2272 //Slog.i(TAG, "Total CPU usage: "
2273 // + mProcessCpu.getTotalCpuPercent() + "%");
2275 // Slog the cpu usage if the property is set.
2276 if ("true".equals(SystemProperties.get("events.cpu"))) {
2277 int user = mProcessCpuTracker.getLastUserTime();
2278 int system = mProcessCpuTracker.getLastSystemTime();
2279 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2280 int irq = mProcessCpuTracker.getLastIrqTime();
2281 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2282 int idle = mProcessCpuTracker.getLastIdleTime();
2284 int total = user + system + iowait + irq + softIrq + idle;
2285 if (total == 0) total = 1;
2287 EventLog.writeEvent(EventLogTags.CPU,
2288 ((user+system+iowait+irq+softIrq) * 100) / total,
2289 (user * 100) / total,
2290 (system * 100) / total,
2291 (iowait * 100) / total,
2292 (irq * 100) / total,
2293 (softIrq * 100) / total);
2297 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2298 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2299 synchronized(bstats) {
2300 synchronized(mPidsSelfLocked) {
2301 if (haveNewCpuStats) {
2303 int perc = bstats.startAddingCpuLocked();
2306 final int N = mProcessCpuTracker.countStats();
2307 for (int i=0; i<N; i++) {
2308 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2312 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2313 int otherUTime = (st.rel_utime*perc)/100;
2314 int otherSTime = (st.rel_stime*perc)/100;
2315 totalUTime += otherUTime;
2316 totalSTime += otherSTime;
2318 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2319 if (ps == null || !ps.isActive()) {
2320 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2321 pr.info.uid, pr.processName);
2323 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2324 st.rel_stime-otherSTime);
2325 ps.addSpeedStepTimes(cpuSpeedTimes);
2326 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2328 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2329 if (ps == null || !ps.isActive()) {
2330 st.batteryStats = ps = bstats.getProcessStatsLocked(
2331 bstats.mapUid(st.uid), st.name);
2333 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2334 st.rel_stime-otherSTime);
2335 ps.addSpeedStepTimes(cpuSpeedTimes);
2338 bstats.finishAddingCpuLocked(perc, totalUTime,
2339 totalSTime, cpuSpeedTimes);
2344 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2345 mLastWriteTime = now;
2346 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2353 public void batteryNeedsCpuUpdate() {
2354 updateCpuStatsNow();
2358 public void batteryPowerChanged(boolean onBattery) {
2359 // When plugging in, update the CPU stats first before changing
2361 updateCpuStatsNow();
2362 synchronized (this) {
2363 synchronized(mPidsSelfLocked) {
2364 mOnBattery = DEBUG_POWER ? true : onBattery;
2370 * Initialize the application bind args. These are passed to each
2371 * process when the bindApplication() IPC is sent to the process. They're
2372 * lazily setup to make sure the services are running when they're asked for.
2374 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2375 if (mAppBindArgs == null) {
2376 mAppBindArgs = new HashMap<>();
2378 // Isolated processes won't get this optimization, so that we don't
2379 // violate the rules about which services they have access to.
2381 // Setup the application init args
2382 mAppBindArgs.put("package", ServiceManager.getService("package"));
2383 mAppBindArgs.put("window", ServiceManager.getService("window"));
2384 mAppBindArgs.put(Context.ALARM_SERVICE,
2385 ServiceManager.getService(Context.ALARM_SERVICE));
2388 return mAppBindArgs;
2391 final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2392 if (mFocusedActivity != r) {
2393 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2394 mFocusedActivity = r;
2395 if (r.task != null && r.task.voiceInteractor != null) {
2396 startRunningVoiceLocked();
2398 finishRunningVoiceLocked();
2400 mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
2402 mWindowManager.setFocusedApp(r.appToken, true);
2404 applyUpdateLockStateLocked(r);
2406 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2407 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2410 final void clearFocusedActivity(ActivityRecord r) {
2411 if (mFocusedActivity == r) {
2412 mFocusedActivity = null;
2417 public void setFocusedStack(int stackId) {
2418 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2419 synchronized (ActivityManagerService.this) {
2420 ActivityStack stack = mStackSupervisor.getStack(stackId);
2421 if (stack != null) {
2422 ActivityRecord r = stack.topRunningActivityLocked(null);
2424 setFocusedActivityLocked(r, "setFocusedStack");
2430 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2432 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2433 synchronized (ActivityManagerService.this) {
2434 if (listener != null) {
2435 mTaskStackListeners.register(listener);
2441 public void notifyActivityDrawn(IBinder token) {
2442 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2443 synchronized (this) {
2444 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2446 r.task.stack.notifyActivityDrawnLocked(r);
2451 final void applyUpdateLockStateLocked(ActivityRecord r) {
2452 // Modifications to the UpdateLock state are done on our handler, outside
2453 // the activity manager's locks. The new state is determined based on the
2454 // state *now* of the relevant activity record. The object is passed to
2455 // the handler solely for logging detail, not to be consulted/modified.
2456 final boolean nextState = r != null && r.immersive;
2457 mHandler.sendMessage(
2458 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2461 final void showAskCompatModeDialogLocked(ActivityRecord r) {
2462 Message msg = Message.obtain();
2463 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2464 msg.obj = r.task.askedCompatMode ? null : r;
2465 mUiHandler.sendMessage(msg);
2468 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2469 String what, Object obj, ProcessRecord srcApp) {
2470 app.lastActivityTime = now;
2472 if (app.activities.size() > 0) {
2473 // Don't want to touch dependent processes that are hosting activities.
2477 int lrui = mLruProcesses.lastIndexOf(app);
2479 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2480 + what + " " + obj + " from " + srcApp);
2484 if (lrui >= index) {
2485 // Don't want to cause this to move dependent processes *back* in the
2486 // list as if they were less frequently used.
2490 if (lrui >= mLruProcessActivityStart) {
2491 // Don't want to touch dependent processes that are hosting activities.
2495 mLruProcesses.remove(lrui);
2499 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2500 + " in LRU list: " + app);
2501 mLruProcesses.add(index, app);
2505 final void removeLruProcessLocked(ProcessRecord app) {
2506 int lrui = mLruProcesses.lastIndexOf(app);
2509 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2510 Process.killProcessQuiet(app.pid);
2511 Process.killProcessGroup(app.info.uid, app.pid);
2513 if (lrui <= mLruProcessActivityStart) {
2514 mLruProcessActivityStart--;
2516 if (lrui <= mLruProcessServiceStart) {
2517 mLruProcessServiceStart--;
2519 mLruProcesses.remove(lrui);
2523 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2524 ProcessRecord client) {
2525 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2526 || app.treatLikeActivity;
2527 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2528 if (!activityChange && hasActivity) {
2529 // The process has activities, so we are only allowing activity-based adjustments
2530 // to move it. It should be kept in the front of the list with other
2531 // processes that have activities, and we don't want those to change their
2532 // order except due to activity operations.
2537 final long now = SystemClock.uptimeMillis();
2538 app.lastActivityTime = now;
2540 // First a quick reject: if the app is already at the position we will
2541 // put it, then there is nothing to do.
2543 final int N = mLruProcesses.size();
2544 if (N > 0 && mLruProcesses.get(N-1) == app) {
2545 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2549 if (mLruProcessServiceStart > 0
2550 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2551 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2556 int lrui = mLruProcesses.lastIndexOf(app);
2558 if (app.persistent && lrui >= 0) {
2559 // We don't care about the position of persistent processes, as long as
2560 // they are in the list.
2561 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2565 /* In progress: compute new position first, so we can avoid doing work
2566 if the process is not actually going to move. Not yet working.
2569 boolean inActivity = false, inService = false;
2571 // Process has activities, put it at the very tipsy-top.
2572 addIndex = mLruProcesses.size();
2573 nextIndex = mLruProcessServiceStart;
2575 } else if (hasService) {
2576 // Process has services, put it at the top of the service list.
2577 addIndex = mLruProcessActivityStart;
2578 nextIndex = mLruProcessServiceStart;
2582 // Process not otherwise of interest, it goes to the top of the non-service area.
2583 addIndex = mLruProcessServiceStart;
2584 if (client != null) {
2585 int clientIndex = mLruProcesses.lastIndexOf(client);
2586 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2588 if (clientIndex >= 0 && addIndex > clientIndex) {
2589 addIndex = clientIndex;
2592 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2595 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2596 + mLruProcessActivityStart + "): " + app);
2600 if (lrui < mLruProcessActivityStart) {
2601 mLruProcessActivityStart--;
2603 if (lrui < mLruProcessServiceStart) {
2604 mLruProcessServiceStart--;
2607 if (addIndex > lrui) {
2610 if (nextIndex > lrui) {
2614 mLruProcesses.remove(lrui);
2618 mLruProcesses.add(addIndex, app);
2620 mLruProcessActivityStart++;
2623 mLruProcessActivityStart++;
2629 final int N = mLruProcesses.size();
2630 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2631 // Process doesn't have activities, but has clients with
2632 // activities... move it up, but one below the top (the top
2633 // should always have a real activity).
2634 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2635 mLruProcesses.add(N-1, app);
2636 // To keep it from spamming the LRU list (by making a bunch of clients),
2637 // we will push down any other entries owned by the app.
2638 final int uid = app.info.uid;
2639 for (int i=N-2; i>mLruProcessActivityStart; i--) {
2640 ProcessRecord subProc = mLruProcesses.get(i);
2641 if (subProc.info.uid == uid) {
2642 // We want to push this one down the list. If the process after
2643 // it is for the same uid, however, don't do so, because we don't
2644 // want them internally to be re-ordered.
2645 if (mLruProcesses.get(i-1).info.uid != uid) {
2646 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2647 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2648 ProcessRecord tmp = mLruProcesses.get(i);
2649 mLruProcesses.set(i, mLruProcesses.get(i-1));
2650 mLruProcesses.set(i-1, tmp);
2654 // A gap, we can stop here.
2659 // Process has activities, put it at the very tipsy-top.
2660 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2661 mLruProcesses.add(app);
2663 nextIndex = mLruProcessServiceStart;
2664 } else if (hasService) {
2665 // Process has services, put it at the top of the service list.
2666 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2667 mLruProcesses.add(mLruProcessActivityStart, app);
2668 nextIndex = mLruProcessServiceStart;
2669 mLruProcessActivityStart++;
2671 // Process not otherwise of interest, it goes to the top of the non-service area.
2672 int index = mLruProcessServiceStart;
2673 if (client != null) {
2674 // If there is a client, don't allow the process to be moved up higher
2675 // in the list than that client.
2676 int clientIndex = mLruProcesses.lastIndexOf(client);
2677 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2678 + " when updating " + app);
2679 if (clientIndex <= lrui) {
2680 // Don't allow the client index restriction to push it down farther in the
2681 // list than it already is.
2684 if (clientIndex >= 0 && index > clientIndex) {
2685 index = clientIndex;
2688 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2689 mLruProcesses.add(index, app);
2690 nextIndex = index-1;
2691 mLruProcessActivityStart++;
2692 mLruProcessServiceStart++;
2695 // If the app is currently using a content provider or service,
2696 // bump those processes as well.
2697 for (int j=app.connections.size()-1; j>=0; j--) {
2698 ConnectionRecord cr = app.connections.valueAt(j);
2699 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2700 && cr.binding.service.app != null
2701 && cr.binding.service.app.lruSeq != mLruSeq
2702 && !cr.binding.service.app.persistent) {
2703 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2704 "service connection", cr, app);
2707 for (int j=app.conProviders.size()-1; j>=0; j--) {
2708 ContentProviderRecord cpr = app.conProviders.get(j).provider;
2709 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2710 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2711 "provider reference", cpr, app);
2716 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2717 if (uid == Process.SYSTEM_UID) {
2718 // The system gets to run in any process. If there are multiple
2719 // processes with the same uid, just pick the first (this
2720 // should never happen).
2721 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2722 if (procs == null) return null;
2723 final int procCount = procs.size();
2724 for (int i = 0; i < procCount; i++) {
2725 final int procUid = procs.keyAt(i);
2726 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2727 // Don't use an app process or different user process for system component.
2730 return procs.valueAt(i);
2733 ProcessRecord proc = mProcessNames.get(processName, uid);
2734 if (false && proc != null && !keepIfLarge
2735 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2736 && proc.lastCachedPss >= 4000) {
2737 // Turn this condition on to cause killing to happen regularly, for testing.
2738 if (proc.baseProcessTracker != null) {
2739 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2741 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2742 } else if (proc != null && !keepIfLarge
2743 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2744 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2745 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2746 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2747 if (proc.baseProcessTracker != null) {
2748 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2750 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2756 void ensurePackageDexOpt(String packageName) {
2757 IPackageManager pm = AppGlobals.getPackageManager();
2759 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2762 } catch (RemoteException e) {
2766 boolean isNextTransitionForward() {
2767 int transit = mWindowManager.getPendingAppTransition();
2768 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2769 || transit == AppTransition.TRANSIT_TASK_OPEN
2770 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2773 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2774 String processName, String abiOverride, int uid, Runnable crashHandler) {
2775 synchronized(this) {
2776 ApplicationInfo info = new ApplicationInfo();
2777 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2778 // For isolated processes, the former contains the parent's uid and the latter the
2779 // actual uid of the isolated process.
2780 // In the special case introduced by this method (which is, starting an isolated
2781 // process directly from the SystemServer without an actual parent app process) the
2782 // closest thing to a parent's uid is SYSTEM_UID.
2783 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2784 // the |isolated| logic in the ProcessRecord constructor.
2785 info.uid = Process.SYSTEM_UID;
2786 info.processName = processName;
2787 info.className = entryPoint;
2788 info.packageName = "android";
2789 ProcessRecord proc = startProcessLocked(processName, info /* info */,
2790 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
2791 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2792 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2794 return proc != null ? proc.pid : 0;
2798 final ProcessRecord startProcessLocked(String processName,
2799 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2800 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2801 boolean isolated, boolean keepIfLarge) {
2802 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2803 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2804 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2805 null /* crashHandler */);
2808 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2809 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2810 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2811 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2812 long startTime = SystemClock.elapsedRealtime();
2815 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2816 checkTime(startTime, "startProcess: after getProcessRecord");
2818 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
2819 // If we are in the background, then check to see if this process
2820 // is bad. If so, we will just silently fail.
2821 if (mBadProcesses.get(info.processName, info.uid) != null) {
2822 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2823 + "/" + info.processName);
2827 // When the user is explicitly starting a process, then clear its
2828 // crash count so that we won't make it bad until they see at
2829 // least one crash dialog again, and make the process good again
2830 // if it had been bad.
2831 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2832 + "/" + info.processName);
2833 mProcessCrashTimes.remove(info.processName, info.uid);
2834 if (mBadProcesses.get(info.processName, info.uid) != null) {
2835 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2836 UserHandle.getUserId(info.uid), info.uid,
2838 mBadProcesses.remove(info.processName, info.uid);
2845 // If this is an isolated process, it can't re-use an existing process.
2849 // We don't have to do anything more if:
2850 // (1) There is an existing application record; and
2851 // (2) The caller doesn't think it is dead, OR there is no thread
2852 // object attached to it so we know it couldn't have crashed; and
2853 // (3) There is a pid assigned to it, so it is either starting or
2855 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2856 + " app=" + app + " knownToBeDead=" + knownToBeDead
2857 + " thread=" + (app != null ? app.thread : null)
2858 + " pid=" + (app != null ? app.pid : -1));
2859 if (app != null && app.pid > 0) {
2860 if (!knownToBeDead || app.thread == null) {
2861 // We already have the app running, or are waiting for it to
2862 // come up (we have a pid but not yet its thread), so keep it.
2863 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2864 // If this is a new package in the process, add the package to the list
2865 app.addPackage(info.packageName, info.versionCode, mProcessStats);
2866 checkTime(startTime, "startProcess: done, added package to proc");
2870 // An application record is attached to a previous process,
2872 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2873 checkTime(startTime, "startProcess: bad proc running, killing");
2874 Process.killProcessGroup(app.info.uid, app.pid);
2875 handleAppDiedLocked(app, true, true);
2876 checkTime(startTime, "startProcess: done killing old proc");
2879 String hostingNameStr = hostingName != null
2880 ? hostingName.flattenToShortString() : null;
2883 checkTime(startTime, "startProcess: creating new process record");
2884 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2886 Slog.w(TAG, "Failed making new process record for "
2887 + processName + "/" + info.uid + " isolated=" + isolated);
2890 app.crashHandler = crashHandler;
2891 mProcessNames.put(processName, app.uid, app);
2893 mIsolatedProcesses.put(app.uid, app);
2895 checkTime(startTime, "startProcess: done creating new process record");
2897 // If this is a new package in the process, add the package to the list
2898 app.addPackage(info.packageName, info.versionCode, mProcessStats);
2899 checkTime(startTime, "startProcess: added package to existing proc");
2902 // If the system is not ready yet, then hold off on starting this
2903 // process until it is.
2904 if (!mProcessesReady
2905 && !isAllowedWhileBooting(info)
2906 && !allowWhileBooting) {
2907 if (!mProcessesOnHold.contains(app)) {
2908 mProcessesOnHold.add(app);
2910 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2911 checkTime(startTime, "startProcess: returning with proc on hold");
2915 checkTime(startTime, "startProcess: stepping in to startProcess");
2917 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2918 checkTime(startTime, "startProcess: done starting proc!");
2919 return (app.pid != 0) ? app : null;
2922 boolean isAllowedWhileBooting(ApplicationInfo ai) {
2923 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2926 private final void startProcessLocked(ProcessRecord app,
2927 String hostingType, String hostingNameStr) {
2928 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2929 null /* entryPoint */, null /* entryPointArgs */);
2932 private final void startProcessLocked(ProcessRecord app, String hostingType,
2933 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2934 long startTime = SystemClock.elapsedRealtime();
2935 if (app.pid > 0 && app.pid != MY_PID) {
2936 checkTime(startTime, "startProcess: removing from pids map");
2937 synchronized (mPidsSelfLocked) {
2938 mPidsSelfLocked.remove(app.pid);
2939 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2941 checkTime(startTime, "startProcess: done removing from pids map");
2945 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2946 "startProcessLocked removing on hold: " + app);
2947 mProcessesOnHold.remove(app);
2949 checkTime(startTime, "startProcess: starting to update cpu stats");
2951 checkTime(startTime, "startProcess: done updating cpu stats");
2957 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2958 if (!app.isolated) {
2959 int[] permGids = null;
2961 checkTime(startTime, "startProcess: getting gids from package manager");
2962 final PackageManager pm = mContext.getPackageManager();
2963 permGids = pm.getPackageGids(app.info.packageName);
2965 if (Environment.isExternalStorageEmulated()) {
2966 checkTime(startTime, "startProcess: checking external storage perm");
2967 if (pm.checkPermission(
2968 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2969 app.info.packageName) == PERMISSION_GRANTED) {
2970 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2972 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2975 } catch (PackageManager.NameNotFoundException e) {
2976 Slog.w(TAG, "Unable to retrieve gids", e);
2980 * Add shared application and profile GIDs so applications can share some
2981 * resources like shared libraries and access user-wide resources
2983 if (permGids == null) {
2986 gids = new int[permGids.length + 2];
2987 System.arraycopy(permGids, 0, gids, 2, permGids.length);
2989 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2990 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2992 checkTime(startTime, "startProcess: building args");
2993 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2994 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2995 && mTopComponent != null
2996 && app.processName.equals(mTopComponent.getPackageName())) {
2999 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3000 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3005 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3006 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3007 // Also turn on CheckJNI for debuggable apps. It's quite
3008 // awkward to turn on otherwise.
3009 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3011 // Run the app in safe mode if its manifest requests so or the
3012 // system is booted in safe mode.
3013 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3014 mSafeMode == true) {
3015 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3017 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3018 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3020 String jitDebugProperty = SystemProperties.get("debug.usejit");
3021 if ("true".equals(jitDebugProperty)) {
3022 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3023 } else if (!"false".equals(jitDebugProperty)) {
3024 // If we didn't force disable by setting false, defer to the dalvik vm options.
3025 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3026 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3029 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3030 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3032 if ("1".equals(SystemProperties.get("debug.assert"))) {
3033 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3036 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3037 if (requiredAbi == null) {
3038 requiredAbi = Build.SUPPORTED_ABIS[0];
3041 String instructionSet = null;
3042 if (app.info.primaryCpuAbi != null) {
3043 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3047 app.requiredAbi = requiredAbi;
3048 app.instructionSet = instructionSet;
3050 // Start the process. It will either succeed and return a result containing
3051 // the PID of the new process, or else throw a RuntimeException.
3052 boolean isActivityProcess = (entryPoint == null);
3053 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3054 checkTime(startTime, "startProcess: asking zygote to start proc");
3055 Process.ProcessStartResult startResult = Process.start(entryPoint,
3056 app.processName, uid, uid, gids, debugFlags, mountExternal,
3057 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3058 app.info.dataDir, entryPointArgs);
3059 checkTime(startTime, "startProcess: returned from zygote!");
3062 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3064 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3065 checkTime(startTime, "startProcess: done updating battery stats");
3067 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3068 UserHandle.getUserId(uid), startResult.pid, uid,
3069 app.processName, hostingType,
3070 hostingNameStr != null ? hostingNameStr : "");
3072 if (app.persistent) {
3073 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3076 checkTime(startTime, "startProcess: building log message");
3077 StringBuilder buf = mStringBuilder;
3079 buf.append("Start proc ");
3080 buf.append(startResult.pid);
3082 buf.append(app.processName);
3084 UserHandle.formatUid(buf, uid);
3085 if (!isActivityProcess) {
3087 buf.append(entryPoint);
3090 buf.append(" for ");
3091 buf.append(hostingType);
3092 if (hostingNameStr != null) {
3094 buf.append(hostingNameStr);
3096 Slog.i(TAG, buf.toString());
3097 app.setPid(startResult.pid);
3098 app.usingWrapper = startResult.usingWrapper;
3099 app.removed = false;
3101 app.killedByAm = false;
3102 checkTime(startTime, "startProcess: starting to update pids map");
3103 synchronized (mPidsSelfLocked) {
3104 this.mPidsSelfLocked.put(startResult.pid, app);
3105 if (isActivityProcess) {
3106 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3108 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3109 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3112 checkTime(startTime, "startProcess: done updating pids map");
3113 } catch (RuntimeException e) {
3114 // XXX do better error recovery.
3116 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3118 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3120 Slog.e(TAG, "Failure starting process " + app.processName, e);
3124 void updateUsageStats(ActivityRecord component, boolean resumed) {
3125 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3126 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3128 if (mUsageStatsService != null) {
3129 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3130 UsageEvents.Event.MOVE_TO_FOREGROUND);
3132 synchronized (stats) {
3133 stats.noteActivityResumedLocked(component.app.uid);
3136 if (mUsageStatsService != null) {
3137 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3138 UsageEvents.Event.MOVE_TO_BACKGROUND);
3140 synchronized (stats) {
3141 stats.noteActivityPausedLocked(component.app.uid);
3146 Intent getHomeIntent() {
3147 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3148 intent.setComponent(mTopComponent);
3149 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3150 intent.addCategory(Intent.CATEGORY_HOME);
3155 boolean startHomeActivityLocked(int userId, String reason) {
3156 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3157 && mTopAction == null) {
3158 // We are running in factory test mode, but unable to find
3159 // the factory test app, so just sit around displaying the
3160 // error message and don't try to start anything.
3163 Intent intent = getHomeIntent();
3164 ActivityInfo aInfo =
3165 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3166 if (aInfo != null) {
3167 intent.setComponent(new ComponentName(
3168 aInfo.applicationInfo.packageName, aInfo.name));
3169 // Don't do this if the home app is currently being
3171 aInfo = new ActivityInfo(aInfo);
3172 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3173 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3174 aInfo.applicationInfo.uid, true);
3175 if (app == null || app.instrumentationClass == null) {
3176 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3177 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3184 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3185 ActivityInfo ai = null;
3186 ComponentName comp = intent.getComponent();
3189 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3191 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3193 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3197 ai = info.activityInfo;
3200 } catch (RemoteException e) {
3208 * Starts the "new version setup screen" if appropriate.
3210 void startSetupActivityLocked() {
3211 // Only do this once per boot.
3212 if (mCheckedForSetup) {
3216 // We will show this screen if the current one is a different
3217 // version than the last one shown, and we are not running in
3218 // low-level factory test mode.
3219 final ContentResolver resolver = mContext.getContentResolver();
3220 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3221 Settings.Global.getInt(resolver,
3222 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3223 mCheckedForSetup = true;
3225 // See if we should be showing the platform update setup UI.
3226 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3227 List<ResolveInfo> ris = mContext.getPackageManager()
3228 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3230 // We don't allow third party apps to replace this.
3231 ResolveInfo ri = null;
3232 for (int i=0; ris != null && i<ris.size(); i++) {
3233 if ((ris.get(i).activityInfo.applicationInfo.flags
3234 & ApplicationInfo.FLAG_SYSTEM) != 0) {
3241 String vers = ri.activityInfo.metaData != null
3242 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3244 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3245 vers = ri.activityInfo.applicationInfo.metaData.getString(
3246 Intent.METADATA_SETUP_VERSION);
3248 String lastVers = Settings.Secure.getString(
3249 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3250 if (vers != null && !vers.equals(lastVers)) {
3251 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3252 intent.setComponent(new ComponentName(
3253 ri.activityInfo.packageName, ri.activityInfo.name));
3254 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3255 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3262 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3263 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3266 void enforceNotIsolatedCaller(String caller) {
3267 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3268 throw new SecurityException("Isolated process not allowed to call " + caller);
3272 void enforceShellRestriction(String restriction, int userHandle) {
3273 if (Binder.getCallingUid() == Process.SHELL_UID) {
3275 || mUserManager.hasUserRestriction(restriction, userHandle)) {
3276 throw new SecurityException("Shell does not have permission to access user "
3283 public int getFrontActivityScreenCompatMode() {
3284 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3285 synchronized (this) {
3286 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3291 public void setFrontActivityScreenCompatMode(int mode) {
3292 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3293 "setFrontActivityScreenCompatMode");
3294 synchronized (this) {
3295 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3300 public int getPackageScreenCompatMode(String packageName) {
3301 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3302 synchronized (this) {
3303 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3308 public void setPackageScreenCompatMode(String packageName, int mode) {
3309 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3310 "setPackageScreenCompatMode");
3311 synchronized (this) {
3312 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3317 public boolean getPackageAskScreenCompat(String packageName) {
3318 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3319 synchronized (this) {
3320 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3325 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3326 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3327 "setPackageAskScreenCompat");
3328 synchronized (this) {
3329 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3333 private void dispatchProcessesChanged() {
3335 synchronized (this) {
3336 N = mPendingProcessChanges.size();
3337 if (mActiveProcessChanges.length < N) {
3338 mActiveProcessChanges = new ProcessChangeItem[N];
3340 mPendingProcessChanges.toArray(mActiveProcessChanges);
3341 mAvailProcessChanges.addAll(mPendingProcessChanges);
3342 mPendingProcessChanges.clear();
3343 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3346 int i = mProcessObservers.beginBroadcast();
3349 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3350 if (observer != null) {
3352 for (int j=0; j<N; j++) {
3353 ProcessChangeItem item = mActiveProcessChanges[j];
3354 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3355 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3356 + item.pid + " uid=" + item.uid + ": "
3357 + item.foregroundActivities);
3358 observer.onForegroundActivitiesChanged(item.pid, item.uid,
3359 item.foregroundActivities);
3361 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3362 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3363 + item.pid + " uid=" + item.uid + ": " + item.processState);
3364 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3367 } catch (RemoteException e) {
3371 mProcessObservers.finishBroadcast();
3374 private void dispatchProcessDied(int pid, int uid) {
3375 int i = mProcessObservers.beginBroadcast();
3378 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3379 if (observer != null) {
3381 observer.onProcessDied(pid, uid);
3382 } catch (RemoteException e) {
3386 mProcessObservers.finishBroadcast();
3390 public final int startActivity(IApplicationThread caller, String callingPackage,
3391 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3392 int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3393 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3394 resultWho, requestCode, startFlags, profilerInfo, options,
3395 UserHandle.getCallingUserId());
3399 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3400 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3401 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3402 enforceNotIsolatedCaller("startActivity");
3403 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3404 false, ALLOW_FULL_ONLY, "startActivity", null);
3405 // TODO: Switch to user app stacks here.
3406 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3407 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3408 profilerInfo, null, null, options, userId, null, null);
3412 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3413 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3414 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3416 // This is very dangerous -- it allows you to perform a start activity (including
3417 // permission grants) as any app that may launch one of your own activities. So
3418 // we will only allow this to be done from activities that are part of the core framework,
3419 // and then only when they are running as the system.
3420 final ActivityRecord sourceRecord;
3421 final int targetUid;
3422 final String targetPackage;
3423 synchronized (this) {
3424 if (resultTo == null) {
3425 throw new SecurityException("Must be called from an activity");
3427 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3428 if (sourceRecord == null) {
3429 throw new SecurityException("Called with bad activity token: " + resultTo);
3431 if (!sourceRecord.info.packageName.equals("android")) {
3432 throw new SecurityException(
3433 "Must be called from an activity that is declared in the android package");
3435 if (sourceRecord.app == null) {
3436 throw new SecurityException("Called without a process attached to activity");
3438 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3439 // This is still okay, as long as this activity is running under the
3440 // uid of the original calling activity.
3441 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3442 throw new SecurityException(
3443 "Calling activity in uid " + sourceRecord.app.uid
3444 + " must be system uid or original calling uid "
3445 + sourceRecord.launchedFromUid);
3448 targetUid = sourceRecord.launchedFromUid;
3449 targetPackage = sourceRecord.launchedFromPackage;
3452 if (userId == UserHandle.USER_NULL) {
3453 userId = UserHandle.getUserId(sourceRecord.app.uid);
3456 // TODO: Switch to user app stacks here.
3458 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3459 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3460 null, null, options, userId, null, null);
3462 } catch (SecurityException e) {
3463 // XXX need to figure out how to propagate to original app.
3464 // A SecurityException here is generally actually a fault of the original
3465 // calling activity (such as a fairly granting permissions), so propagate it
3468 StringBuilder msg = new StringBuilder();
3469 msg.append("While launching");
3470 msg.append(intent.toString());
3472 msg.append(e.getMessage());
3479 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3480 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3481 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3482 enforceNotIsolatedCaller("startActivityAndWait");
3483 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3484 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3485 WaitResult res = new WaitResult();
3486 // TODO: Switch to user app stacks here.
3487 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3488 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3489 options, userId, null, null);
3494 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3495 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3496 int startFlags, Configuration config, Bundle options, int userId) {
3497 enforceNotIsolatedCaller("startActivityWithConfig");
3498 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3499 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3500 // TODO: Switch to user app stacks here.
3501 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3502 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3503 null, null, config, options, userId, null, null);
3508 public int startActivityIntentSender(IApplicationThread caller,
3509 IntentSender intent, Intent fillInIntent, String resolvedType,
3510 IBinder resultTo, String resultWho, int requestCode,
3511 int flagsMask, int flagsValues, Bundle options) {
3512 enforceNotIsolatedCaller("startActivityIntentSender");
3513 // Refuse possible leaked file descriptors
3514 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3515 throw new IllegalArgumentException("File descriptors passed in Intent");
3518 IIntentSender sender = intent.getTarget();
3519 if (!(sender instanceof PendingIntentRecord)) {
3520 throw new IllegalArgumentException("Bad PendingIntent object");
3523 PendingIntentRecord pir = (PendingIntentRecord)sender;
3525 synchronized (this) {
3526 // If this is coming from the currently resumed activity, it is
3527 // effectively saying that app switches are allowed at this point.
3528 final ActivityStack stack = getFocusedStack();
3529 if (stack.mResumedActivity != null &&
3530 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3531 mAppSwitchesAllowedTime = 0;
3534 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3535 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3540 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3541 Intent intent, String resolvedType, IVoiceInteractionSession session,
3542 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3543 Bundle options, int userId) {
3544 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3545 != PackageManager.PERMISSION_GRANTED) {
3546 String msg = "Permission Denial: startVoiceActivity() from pid="
3547 + Binder.getCallingPid()
3548 + ", uid=" + Binder.getCallingUid()
3549 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3551 throw new SecurityException(msg);
3553 if (session == null || interactor == null) {
3554 throw new NullPointerException("null session or interactor");
3556 userId = handleIncomingUser(callingPid, callingUid, userId,
3557 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3558 // TODO: Switch to user app stacks here.
3559 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3560 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3561 null, options, userId, null, null);
3565 public boolean startNextMatchingActivity(IBinder callingActivity,
3566 Intent intent, Bundle options) {
3567 // Refuse possible leaked file descriptors
3568 if (intent != null && intent.hasFileDescriptors() == true) {
3569 throw new IllegalArgumentException("File descriptors passed in Intent");
3572 synchronized (this) {
3573 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3575 ActivityOptions.abort(options);
3578 if (r.app == null || r.app.thread == null) {
3579 // The caller is not running... d'oh!
3580 ActivityOptions.abort(options);
3583 intent = new Intent(intent);
3584 // The caller is not allowed to change the data.
3585 intent.setDataAndType(r.intent.getData(), r.intent.getType());
3586 // And we are resetting to find the next component...
3587 intent.setComponent(null);
3589 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3591 ActivityInfo aInfo = null;
3593 List<ResolveInfo> resolves =
3594 AppGlobals.getPackageManager().queryIntentActivities(
3595 intent, r.resolvedType,
3596 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3597 UserHandle.getCallingUserId());
3599 // Look for the original activity in the list...
3600 final int N = resolves != null ? resolves.size() : 0;
3601 for (int i=0; i<N; i++) {
3602 ResolveInfo rInfo = resolves.get(i);
3603 if (rInfo.activityInfo.packageName.equals(r.packageName)
3604 && rInfo.activityInfo.name.equals(r.info.name)) {
3605 // We found the current one... the next matching is
3609 aInfo = resolves.get(i).activityInfo;
3612 Slog.v(TAG, "Next matching activity: found current " + r.packageName
3613 + "/" + r.info.name);
3614 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3615 + "/" + aInfo.name);
3620 } catch (RemoteException e) {
3623 if (aInfo == null) {
3624 // Nobody who is next!
3625 ActivityOptions.abort(options);
3626 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3630 intent.setComponent(new ComponentName(
3631 aInfo.applicationInfo.packageName, aInfo.name));
3632 intent.setFlags(intent.getFlags()&~(
3633 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3634 Intent.FLAG_ACTIVITY_CLEAR_TOP|
3635 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3636 Intent.FLAG_ACTIVITY_NEW_TASK));
3638 // Okay now we need to start the new activity, replacing the
3639 // currently running activity. This is a little tricky because
3640 // we want to start the new one as if the current one is finished,
3641 // but not finish the current one first so that there is no flicker.
3643 final boolean wasFinishing = r.finishing;
3646 // Propagate reply information over to the new activity.
3647 final ActivityRecord resultTo = r.resultTo;
3648 final String resultWho = r.resultWho;
3649 final int requestCode = r.requestCode;
3651 if (resultTo != null) {
3652 resultTo.removeResultsLocked(r, resultWho, requestCode);
3655 final long origId = Binder.clearCallingIdentity();
3656 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3657 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3658 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3659 -1, r.launchedFromUid, 0, options, false, null, null, null);
3660 Binder.restoreCallingIdentity(origId);
3662 r.finishing = wasFinishing;
3663 if (res != ActivityManager.START_SUCCESS) {
3671 public final int startActivityFromRecents(int taskId, Bundle options) {
3672 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3673 String msg = "Permission Denial: startActivityFromRecents called without " +
3674 START_TASKS_FROM_RECENTS;
3676 throw new SecurityException(msg);
3678 return startActivityFromRecentsInner(taskId, options);
3681 final int startActivityFromRecentsInner(int taskId, Bundle options) {
3682 final TaskRecord task;
3683 final int callingUid;
3684 final String callingPackage;
3685 final Intent intent;
3687 synchronized (this) {
3688 task = recentTaskForIdLocked(taskId);
3690 throw new IllegalArgumentException("Task " + taskId + " not found.");
3692 if (task.getRootActivity() != null) {
3693 moveTaskToFrontLocked(task.taskId, 0, null);
3694 return ActivityManager.START_TASK_TO_FRONT;
3696 callingUid = task.mCallingUid;
3697 callingPackage = task.mCallingPackage;
3698 intent = task.intent;
3699 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3700 userId = task.userId;
3702 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3703 options, userId, null, task);
3706 final int startActivityInPackage(int uid, String callingPackage,
3707 Intent intent, String resolvedType, IBinder resultTo,
3708 String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3709 IActivityContainer container, TaskRecord inTask) {
3711 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3712 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3714 // TODO: Switch to user app stacks here.
3715 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3716 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3717 null, null, null, options, userId, container, inTask);
3722 public final int startActivities(IApplicationThread caller, String callingPackage,
3723 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3725 enforceNotIsolatedCaller("startActivities");
3726 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3727 false, ALLOW_FULL_ONLY, "startActivity", null);
3728 // TODO: Switch to user app stacks here.
3729 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3730 resolvedTypes, resultTo, options, userId);
3734 final int startActivitiesInPackage(int uid, String callingPackage,
3735 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3736 Bundle options, int userId) {
3738 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3739 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3740 // TODO: Switch to user app stacks here.
3741 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3742 resultTo, options, userId);
3746 //explicitly remove thd old information in mRecentTasks when removing existing user.
3747 private void removeRecentTasksForUserLocked(int userId) {
3749 Slog.i(TAG, "Can't remove recent task on user " + userId);
3753 for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3754 TaskRecord tr = mRecentTasks.get(i);
3755 if (tr.userId == userId) {
3756 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3757 + " when finishing user" + userId);
3758 mRecentTasks.remove(i);
3759 tr.removedFromRecents();
3763 // Remove tasks from persistent storage.
3764 notifyTaskPersisterLocked(null, true);
3768 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3770 public int compare(TaskRecord lhs, TaskRecord rhs) {
3771 return rhs.taskId - lhs.taskId;
3775 // Extract the affiliates of the chain containing mRecentTasks[start].
3776 private int processNextAffiliateChainLocked(int start) {
3777 final TaskRecord startTask = mRecentTasks.get(start);
3778 final int affiliateId = startTask.mAffiliatedTaskId;
3780 // Quick identification of isolated tasks. I.e. those not launched behind.
3781 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3782 startTask.mNextAffiliate == null) {
3783 // There is still a slim chance that there are other tasks that point to this task
3784 // and that the chain is so messed up that this task no longer points to them but
3785 // the gain of this optimization outweighs the risk.
3786 startTask.inRecents = true;
3790 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3791 mTmpRecents.clear();
3792 for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3793 final TaskRecord task = mRecentTasks.get(i);
3794 if (task.mAffiliatedTaskId == affiliateId) {
3795 mRecentTasks.remove(i);
3796 mTmpRecents.add(task);
3800 // Sort them all by taskId. That is the order they were create in and that order will
3801 // always be correct.
3802 Collections.sort(mTmpRecents, mTaskRecordComparator);
3804 // Go through and fix up the linked list.
3805 // The first one is the end of the chain and has no next.
3806 final TaskRecord first = mTmpRecents.get(0);
3807 first.inRecents = true;
3808 if (first.mNextAffiliate != null) {
3809 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3810 first.setNextAffiliate(null);
3811 notifyTaskPersisterLocked(first, false);
3813 // Everything in the middle is doubly linked from next to prev.
3814 final int tmpSize = mTmpRecents.size();
3815 for (int i = 0; i < tmpSize - 1; ++i) {
3816 final TaskRecord next = mTmpRecents.get(i);
3817 final TaskRecord prev = mTmpRecents.get(i + 1);
3818 if (next.mPrevAffiliate != prev) {
3819 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3820 " setting prev=" + prev);
3821 next.setPrevAffiliate(prev);
3822 notifyTaskPersisterLocked(next, false);
3824 if (prev.mNextAffiliate != next) {
3825 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3826 " setting next=" + next);
3827 prev.setNextAffiliate(next);
3828 notifyTaskPersisterLocked(prev, false);
3830 prev.inRecents = true;
3832 // The last one is the beginning of the list and has no prev.
3833 final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3834 if (last.mPrevAffiliate != null) {
3835 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3836 last.setPrevAffiliate(null);
3837 notifyTaskPersisterLocked(last, false);
3840 // Insert the group back into mRecentTasks at start.
3841 mRecentTasks.addAll(start, mTmpRecents);
3843 // Let the caller know where we left off.
3844 return start + tmpSize;
3848 * Update the recent tasks lists: make sure tasks should still be here (their
3849 * applications / activities still exist), update their availability, fixup ordering
3852 void cleanupRecentTasksLocked(int userId) {
3853 if (mRecentTasks == null) {
3854 // Happens when called from the packagemanager broadcast before boot.
3858 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3859 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3860 final IPackageManager pm = AppGlobals.getPackageManager();
3861 final ActivityInfo dummyAct = new ActivityInfo();
3862 final ApplicationInfo dummyApp = new ApplicationInfo();
3864 int N = mRecentTasks.size();
3866 int[] users = userId == UserHandle.USER_ALL
3867 ? getUsersLocked() : new int[] { userId };
3868 for (int user : users) {
3869 for (int i = 0; i < N; i++) {
3870 TaskRecord task = mRecentTasks.get(i);
3871 if (task.userId != user) {
3872 // Only look at tasks for the user ID of interest.
3875 if (task.autoRemoveRecents && task.getTopActivity() == null) {
3876 // This situation is broken, and we should just get rid of it now.
3877 mRecentTasks.remove(i);
3878 task.removedFromRecents();
3881 Slog.w(TAG, "Removing auto-remove without activity: " + task);
3884 // Check whether this activity is currently available.
3885 if (task.realActivity != null) {
3886 ActivityInfo ai = availActCache.get(task.realActivity);
3889 ai = pm.getActivityInfo(task.realActivity,
3890 PackageManager.GET_UNINSTALLED_PACKAGES
3891 | PackageManager.GET_DISABLED_COMPONENTS, user);
3892 } catch (RemoteException e) {
3893 // Will never happen.
3899 availActCache.put(task.realActivity, ai);
3901 if (ai == dummyAct) {
3902 // This could be either because the activity no longer exists, or the
3903 // app is temporarily gone. For the former we want to remove the recents
3904 // entry; for the latter we want to mark it as unavailable.
3905 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3908 app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3909 PackageManager.GET_UNINSTALLED_PACKAGES
3910 | PackageManager.GET_DISABLED_COMPONENTS, user);
3911 } catch (RemoteException e) {
3912 // Will never happen.
3918 availAppCache.put(task.realActivity.getPackageName(), app);
3920 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3921 // Doesn't exist any more! Good-bye.
3922 mRecentTasks.remove(i);
3923 task.removedFromRecents();
3926 Slog.w(TAG, "Removing no longer valid recent: " + task);
3929 // Otherwise just not available for now.
3930 if (task.isAvailable) {
3931 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3934 task.isAvailable = false;
3937 if (!ai.enabled || !ai.applicationInfo.enabled
3938 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3939 if (task.isAvailable) {
3940 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3941 + task + " (enabled=" + ai.enabled + "/"
3942 + ai.applicationInfo.enabled + " flags="
3943 + Integer.toHexString(ai.applicationInfo.flags) + ")");
3945 task.isAvailable = false;
3947 if (!task.isAvailable) {
3948 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3951 task.isAvailable = true;
3958 // Verify the affiliate chain for each task.
3959 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3962 mTmpRecents.clear();
3963 // mRecentTasks is now in sorted, affiliated order.
3966 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3967 int N = mRecentTasks.size();
3968 TaskRecord top = task;
3969 int topIndex = taskIndex;
3970 while (top.mNextAffiliate != null && topIndex > 0) {
3971 top = top.mNextAffiliate;
3974 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3975 + topIndex + " from intial " + taskIndex);
3976 // Find the end of the chain, doing a sanity check along the way.
3977 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3978 int endIndex = topIndex;
3979 TaskRecord prev = top;
3980 while (endIndex < N) {
3981 TaskRecord cur = mRecentTasks.get(endIndex);
3982 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3983 + endIndex + " " + cur);
3985 // Verify start of the chain.
3986 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3987 Slog.wtf(TAG, "Bad chain @" + endIndex
3988 + ": first task has next affiliate: " + prev);
3993 // Verify middle of the chain's next points back to the one before.
3994 if (cur.mNextAffiliate != prev
3995 || cur.mNextAffiliateTaskId != prev.taskId) {
3996 Slog.wtf(TAG, "Bad chain @" + endIndex
3997 + ": middle task " + cur + " @" + endIndex
3998 + " has bad next affiliate "
3999 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4000 + ", expected " + prev);
4005 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
4007 if (cur.mPrevAffiliate != null) {
4008 Slog.wtf(TAG, "Bad chain @" + endIndex
4009 + ": last task " + cur + " has previous affiliate "
4010 + cur.mPrevAffiliate);
4013 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4016 // Verify middle of the chain's prev points to a valid item.
4017 if (cur.mPrevAffiliate == null) {
4018 Slog.wtf(TAG, "Bad chain @" + endIndex
4019 + ": task " + cur + " has previous affiliate "
4020 + cur.mPrevAffiliate + " but should be id "
4021 + cur.mPrevAffiliate);
4026 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4027 Slog.wtf(TAG, "Bad chain @" + endIndex
4028 + ": task " + cur + " has affiliated id "
4029 + cur.mAffiliatedTaskId + " but should be "
4030 + task.mAffiliatedTaskId);
4036 if (endIndex >= N) {
4037 Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4038 + ": last task " + prev);
4044 if (endIndex < taskIndex) {
4045 Slog.wtf(TAG, "Bad chain @" + endIndex
4046 + ": did not extend to task " + task + " @" + taskIndex);
4051 // All looks good, we can just move all of the affiliated tasks
4053 for (int i=topIndex; i<=endIndex; i++) {
4054 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4055 + " from " + i + " to " + (i-topIndex));
4056 TaskRecord cur = mRecentTasks.remove(i);
4057 mRecentTasks.add(i-topIndex, cur);
4059 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex
4060 + " to " + endIndex);
4064 // Whoops, couldn't do it.
4068 final void addRecentTaskLocked(TaskRecord task) {
4069 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4070 || task.mNextAffiliateTaskId != INVALID_TASK_ID
4071 || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4073 int N = mRecentTasks.size();
4074 // Quick case: check if the top-most recent task is the same.
4075 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4076 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4079 // Another quick case: check if this is part of a set of affiliated
4080 // tasks that are at the top.
4081 if (isAffiliated && N > 0 && task.inRecents
4082 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4083 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4084 + " at top when adding " + task);
4087 // Another quick case: never add voice sessions.
4088 if (task.voiceSession != null) {
4089 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4093 boolean needAffiliationFix = false;
4095 // Slightly less quick case: the task is already in recents, so all we need
4096 // to do is move it.
4097 if (task.inRecents) {
4098 int taskIndex = mRecentTasks.indexOf(task);
4099 if (taskIndex >= 0) {
4100 if (!isAffiliated) {
4101 // Simple case: this is not an affiliated task, so we just move it to the front.
4102 mRecentTasks.remove(taskIndex);
4103 mRecentTasks.add(0, task);
4104 notifyTaskPersisterLocked(task, false);
4105 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4106 + " from " + taskIndex);
4109 // More complicated: need to keep all affiliated tasks together.
4110 if (moveAffiliatedTasksToFront(task, taskIndex)) {
4115 // Uh oh... something bad in the affiliation chain, try to rebuild
4116 // everything and then go through our general path of adding a new task.
4117 needAffiliationFix = true;
4120 Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4121 needAffiliationFix = true;
4125 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4126 trimRecentsForTaskLocked(task, true);
4128 N = mRecentTasks.size();
4129 while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4130 final TaskRecord tr = mRecentTasks.remove(N - 1);
4131 tr.removedFromRecents();
4134 task.inRecents = true;
4135 if (!isAffiliated || needAffiliationFix) {
4136 // If this is a simple non-affiliated task, or we had some failure trying to
4137 // handle it as part of an affilated task, then just place it at the top.
4138 mRecentTasks.add(0, task);
4139 } else if (isAffiliated) {
4140 // If this is a new affiliated task, then move all of the affiliated tasks
4141 // to the front and insert this new one.
4142 TaskRecord other = task.mNextAffiliate;
4143 if (other == null) {
4144 other = task.mPrevAffiliate;
4146 if (other != null) {
4147 int otherIndex = mRecentTasks.indexOf(other);
4148 if (otherIndex >= 0) {
4149 // Insert new task at appropriate location.
4151 if (other == task.mNextAffiliate) {
4152 // We found the index of our next affiliation, which is who is
4153 // before us in the list, so add after that point.
4154 taskIndex = otherIndex+1;
4156 // We found the index of our previous affiliation, which is who is
4157 // after us in the list, so add at their position.
4158 taskIndex = otherIndex;
4160 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4161 + taskIndex + ": " + task);
4162 mRecentTasks.add(taskIndex, task);
4164 // Now move everything to the front.
4165 if (moveAffiliatedTasksToFront(task, taskIndex)) {
4170 // Uh oh... something bad in the affiliation chain, try to rebuild
4171 // everything and then go through our general path of adding a new task.
4172 needAffiliationFix = true;
4174 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4176 needAffiliationFix = true;
4179 if (DEBUG_RECENTS) Slog.d(TAG,
4180 "addRecent: adding affiliated task without next/prev:" + task);
4181 needAffiliationFix = true;
4184 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4186 if (needAffiliationFix) {
4187 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4188 cleanupRecentTasksLocked(task.userId);
4193 * If needed, remove oldest existing entries in recents that are for the same kind
4194 * of task as the given one.
4196 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4197 int N = mRecentTasks.size();
4198 final Intent intent = task.intent;
4199 final boolean document = intent != null && intent.isDocument();
4201 int maxRecents = task.maxRecents - 1;
4202 for (int i=0; i<N; i++) {
4203 final TaskRecord tr = mRecentTasks.get(i);
4205 if (task.userId != tr.userId) {
4208 if (i > MAX_RECENT_BITMAPS) {
4209 tr.freeLastThumbnail();
4211 final Intent trIntent = tr.intent;
4212 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4213 (intent == null || !intent.filterEquals(trIntent))) {
4216 final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4217 if (document && trIsDocument) {
4218 // These are the same document activity (not necessarily the same doc).
4219 if (maxRecents > 0) {
4223 // Hit the maximum number of documents for this task. Fall through
4224 // and remove this document from recents.
4225 } else if (document || trIsDocument) {
4226 // Only one of these is a document. Not the droid we're looking for.
4232 // If the caller is not actually asking for a trim, just tell them we reached
4233 // a point where the trim would happen.
4237 // Either task and tr are the same or, their affinities match or their intents match
4238 // and neither of them is a document, or they are documents using the same activity
4239 // and their maxRecents has been reached.
4240 tr.disposeThumbnail();
4241 mRecentTasks.remove(i);
4243 tr.removedFromRecents();
4247 if (task.intent == null) {
4248 // If the new recent task we are adding is not fully
4249 // specified, then replace it with the existing recent task.
4252 notifyTaskPersisterLocked(tr, false);
4259 public void reportActivityFullyDrawn(IBinder token) {
4260 synchronized (this) {
4261 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4265 r.reportFullyDrawnLocked();
4270 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4271 synchronized (this) {
4272 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4276 final long origId = Binder.clearCallingIdentity();
4277 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4278 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4279 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4280 if (config != null) {
4281 r.frozenBeforeDestroy = true;
4282 if (!updateConfigurationLocked(config, r, false, false)) {
4283 mStackSupervisor.resumeTopActivitiesLocked();
4286 Binder.restoreCallingIdentity(origId);
4291 public int getRequestedOrientation(IBinder token) {
4292 synchronized (this) {
4293 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4295 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4297 return mWindowManager.getAppOrientation(r.appToken);
4302 * This is the internal entry point for handling Activity.finish().
4304 * @param token The Binder token referencing the Activity we want to finish.
4305 * @param resultCode Result code, if any, from this Activity.
4306 * @param resultData Result data (Intent), if any, from this Activity.
4307 * @param finishTask Whether to finish the task associated with this Activity. Only applies to
4308 * the root Activity in the task.
4310 * @return Returns true if the activity successfully finished, or false if it is still running.
4313 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4314 boolean finishTask) {
4315 // Refuse possible leaked file descriptors
4316 if (resultData != null && resultData.hasFileDescriptors() == true) {
4317 throw new IllegalArgumentException("File descriptors passed in Intent");
4320 synchronized(this) {
4321 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4325 // Keep track of the root activity of the task before we finish it
4326 TaskRecord tr = r.task;
4327 ActivityRecord rootR = tr.getRootActivity();
4328 if (rootR == null) {
4329 Slog.w(TAG, "Finishing task with all activities already finished");
4331 // Do not allow task to finish in Lock Task mode.
4332 if (tr == mStackSupervisor.mLockTaskModeTask) {
4334 Slog.i(TAG, "Not finishing task in lock task mode");
4335 mStackSupervisor.showLockTaskToast();
4339 if (mController != null) {
4340 // Find the first activity that is not finishing.
4341 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4343 // ask watcher if this is allowed
4344 boolean resumeOK = true;
4346 resumeOK = mController.activityResuming(next.packageName);
4347 } catch (RemoteException e) {
4349 Watchdog.getInstance().setActivityController(null);
4353 Slog.i(TAG, "Not finishing activity because controller resumed");
4358 final long origId = Binder.clearCallingIdentity();
4361 if (finishTask && r == rootR) {
4362 // If requested, remove the task that is associated to this activity only if it
4363 // was the root activity in the task. The result code and data is ignored
4364 // because we don't support returning them across task boundaries.
4365 res = removeTaskByIdLocked(tr.taskId, false);
4367 Slog.i(TAG, "Removing task failed to finish activity");
4370 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4371 resultData, "app-request", true);
4373 Slog.i(TAG, "Failed to finish by app-request");
4378 Binder.restoreCallingIdentity(origId);
4384 public final void finishHeavyWeightApp() {
4385 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4386 != PackageManager.PERMISSION_GRANTED) {
4387 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4388 + Binder.getCallingPid()
4389 + ", uid=" + Binder.getCallingUid()
4390 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4392 throw new SecurityException(msg);
4395 synchronized(this) {
4396 if (mHeavyWeightProcess == null) {
4400 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4401 mHeavyWeightProcess.activities);
4402 for (int i=0; i<activities.size(); i++) {
4403 ActivityRecord r = activities.get(i);
4405 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4406 null, "finish-heavy", true);
4410 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4411 mHeavyWeightProcess.userId, 0));
4412 mHeavyWeightProcess = null;
4417 public void crashApplication(int uid, int initialPid, String packageName,
4419 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4420 != PackageManager.PERMISSION_GRANTED) {
4421 String msg = "Permission Denial: crashApplication() from pid="
4422 + Binder.getCallingPid()
4423 + ", uid=" + Binder.getCallingUid()
4424 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4426 throw new SecurityException(msg);
4429 synchronized(this) {
4430 ProcessRecord proc = null;
4432 // Figure out which process to kill. We don't trust that initialPid
4433 // still has any relation to current pids, so must scan through the
4435 synchronized (mPidsSelfLocked) {
4436 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4437 ProcessRecord p = mPidsSelfLocked.valueAt(i);
4441 if (p.pid == initialPid) {
4445 if (p.pkgList.containsKey(packageName)) {
4452 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4453 + " initialPid=" + initialPid
4454 + " packageName=" + packageName);
4458 if (proc.thread != null) {
4459 if (proc.pid == Process.myPid()) {
4460 Log.w(TAG, "crashApplication: trying to crash self!");
4463 long ident = Binder.clearCallingIdentity();
4465 proc.thread.scheduleCrash(message);
4466 } catch (RemoteException e) {
4468 Binder.restoreCallingIdentity(ident);
4474 public final void finishSubActivity(IBinder token, String resultWho,
4476 synchronized(this) {
4477 final long origId = Binder.clearCallingIdentity();
4478 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4480 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4482 Binder.restoreCallingIdentity(origId);
4487 public boolean finishActivityAffinity(IBinder token) {
4488 synchronized(this) {
4489 final long origId = Binder.clearCallingIdentity();
4491 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4493 ActivityRecord rootR = r.task.getRootActivity();
4494 // Do not allow task to finish in Lock Task mode.
4495 if (r.task == mStackSupervisor.mLockTaskModeTask) {
4497 mStackSupervisor.showLockTaskToast();
4501 boolean res = false;
4503 res = r.task.stack.finishActivityAffinityLocked(r);
4507 Binder.restoreCallingIdentity(origId);
4513 public void finishVoiceTask(IVoiceInteractionSession session) {
4514 synchronized(this) {
4515 final long origId = Binder.clearCallingIdentity();
4517 mStackSupervisor.finishVoiceTask(session);
4519 Binder.restoreCallingIdentity(origId);
4526 public boolean releaseActivityInstance(IBinder token) {
4527 synchronized(this) {
4528 final long origId = Binder.clearCallingIdentity();
4530 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4531 if (r.task == null || r.task.stack == null) {
4534 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4536 Binder.restoreCallingIdentity(origId);
4542 public void releaseSomeActivities(IApplicationThread appInt) {
4543 synchronized(this) {
4544 final long origId = Binder.clearCallingIdentity();
4546 ProcessRecord app = getRecordForAppLocked(appInt);
4547 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4549 Binder.restoreCallingIdentity(origId);
4555 public boolean willActivityBeVisible(IBinder token) {
4556 synchronized(this) {
4557 ActivityStack stack = ActivityRecord.getStackLocked(token);
4558 if (stack != null) {
4559 return stack.willActivityBeVisibleLocked(token);
4566 public void overridePendingTransition(IBinder token, String packageName,
4567 int enterAnim, int exitAnim) {
4568 synchronized(this) {
4569 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4574 final long origId = Binder.clearCallingIdentity();
4576 if (self.state == ActivityState.RESUMED
4577 || self.state == ActivityState.PAUSING) {
4578 mWindowManager.overridePendingAppTransition(packageName,
4579 enterAnim, exitAnim, null);
4582 Binder.restoreCallingIdentity(origId);
4587 * Main function for removing an existing process from the activity manager
4588 * as a result of that process going away. Clears out all connections
4591 private final void handleAppDiedLocked(ProcessRecord app,
4592 boolean restarting, boolean allowRestart) {
4594 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4595 if (!kept && !restarting) {
4596 removeLruProcessLocked(app);
4598 ProcessList.remove(pid);
4602 if (mProfileProc == app) {
4603 clearProfilerLocked();
4606 // Remove this application's activities from active lists.
4607 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4609 app.activities.clear();
4611 if (app.instrumentationClass != null) {
4612 Slog.w(TAG, "Crash of app " + app.processName
4613 + " running instrumentation " + app.instrumentationClass);
4614 Bundle info = new Bundle();
4615 info.putString("shortMsg", "Process crashed.");
4616 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4619 if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4620 // If there was nothing to resume, and we are not already
4621 // restarting this process, but there is a visible activity that
4622 // is hosted by the process... then make sure all visible
4623 // activities are running, taking care of restarting this
4625 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4629 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4630 IBinder threadBinder = thread.asBinder();
4631 // Find the application record.
4632 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4633 ProcessRecord rec = mLruProcesses.get(i);
4634 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4641 final ProcessRecord getRecordForAppLocked(
4642 IApplicationThread thread) {
4643 if (thread == null) {
4647 int appIndex = getLRURecordIndexForAppLocked(thread);
4648 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4651 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4652 // If there are no longer any background processes running,
4653 // and the app that died was not running instrumentation,
4654 // then tell everyone we are now low on memory.
4655 boolean haveBg = false;
4656 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4657 ProcessRecord rec = mLruProcesses.get(i);
4658 if (rec.thread != null
4659 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4666 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4668 long now = SystemClock.uptimeMillis();
4669 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4672 mLastMemUsageReportTime = now;
4675 final ArrayList<ProcessMemInfo> memInfos
4676 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4677 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4678 long now = SystemClock.uptimeMillis();
4679 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4680 ProcessRecord rec = mLruProcesses.get(i);
4681 if (rec == dyingProc || rec.thread == null) {
4685 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4686 rec.setProcState, rec.adjType, rec.makeAdjReason()));
4688 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4689 // The low memory report is overriding any current
4690 // state for a GC request. Make sure to do
4691 // heavy/important/visible/foreground processes first.
4692 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4693 rec.lastRequestedGc = 0;
4695 rec.lastRequestedGc = rec.lastLowMemory;
4697 rec.reportLowMemory = true;
4698 rec.lastLowMemory = now;
4699 mProcessesToGc.remove(rec);
4700 addProcessToGcListLocked(rec);
4704 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4705 mHandler.sendMessage(msg);
4707 scheduleAppGcsLocked();
4711 final void appDiedLocked(ProcessRecord app) {
4712 appDiedLocked(app, app.pid, app.thread, false);
4715 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4716 boolean fromBinderDied) {
4717 // First check if this ProcessRecord is actually active for the pid.
4718 synchronized (mPidsSelfLocked) {
4719 ProcessRecord curProc = mPidsSelfLocked.get(pid);
4720 if (curProc != app) {
4721 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4726 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4727 synchronized (stats) {
4728 stats.noteProcessDiedLocked(app.info.uid, pid);
4732 if (!fromBinderDied) {
4733 Process.killProcessQuiet(pid);
4735 Process.killProcessGroup(app.info.uid, pid);
4739 // Clean up already done if the process has been re-started.
4740 if (app.pid == pid && app.thread != null &&
4741 app.thread.asBinder() == thread.asBinder()) {
4742 boolean doLowMem = app.instrumentationClass == null;
4743 boolean doOomAdj = doLowMem;
4744 if (!app.killedByAm) {
4745 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4747 mAllowLowerMemLevel = true;
4749 // Note that we always want to do oom adj to update our state with the
4750 // new number of procs.
4751 mAllowLowerMemLevel = false;
4754 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4755 if (DEBUG_CLEANUP) Slog.v(
4756 TAG, "Dying app: " + app + ", pid: " + pid
4757 + ", thread: " + thread.asBinder());
4758 handleAppDiedLocked(app, false, true);
4761 updateOomAdjLocked();
4764 doLowMemReportIfNeededLocked(app);
4766 } else if (app.pid != pid) {
4767 // A new process has already been started.
4768 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4769 + ") has died and restarted (pid " + app.pid + ").");
4770 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4771 } else if (DEBUG_PROCESSES) {
4772 Slog.d(TAG, "Received spurious death notification for thread "
4773 + thread.asBinder());
4778 * If a stack trace dump file is configured, dump process stack traces.
4779 * @param clearTraces causes the dump file to be erased prior to the new
4780 * traces being written, if true; when false, the new traces will be
4781 * appended to any existing file content.
4782 * @param firstPids of dalvik VM processes to dump stack traces for first
4783 * @param lastPids of dalvik VM processes to dump stack traces for last
4784 * @param nativeProcs optional list of native process names to dump stack crawls
4785 * @return file containing stack traces, or null if no dump file is configured
4787 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4788 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4789 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4790 if (tracesPath == null || tracesPath.length() == 0) {
4794 File tracesFile = new File(tracesPath);
4796 File tracesDir = tracesFile.getParentFile();
4797 if (!tracesDir.exists()) {
4799 if (!SELinux.restorecon(tracesDir)) {
4803 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4805 if (clearTraces && tracesFile.exists()) tracesFile.delete();
4806 tracesFile.createNewFile();
4807 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4808 } catch (IOException e) {
4809 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4813 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4817 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4818 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4819 // Use a FileObserver to detect when traces finish writing.
4820 // The order of traces is considered important to maintain for legibility.
4821 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4823 public synchronized void onEvent(int event, String path) { notify(); }
4827 observer.startWatching();
4829 // First collect all of the stacks of the most important pids.
4830 if (firstPids != null) {
4832 int num = firstPids.size();
4833 for (int i = 0; i < num; i++) {
4834 synchronized (observer) {
4835 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4836 observer.wait(200); // Wait for write-close, give up after 200msec
4839 } catch (InterruptedException e) {
4844 // Next collect the stacks of the native pids
4845 if (nativeProcs != null) {
4846 int[] pids = Process.getPidsForCommands(nativeProcs);
4848 for (int pid : pids) {
4849 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4854 // Lastly, measure CPU usage.
4855 if (processCpuTracker != null) {
4856 processCpuTracker.init();
4858 processCpuTracker.update();
4860 synchronized (processCpuTracker) {
4861 processCpuTracker.wait(500); // measure over 1/2 second.
4863 } catch (InterruptedException e) {
4865 processCpuTracker.update();
4867 // We'll take the stack crawls of just the top apps using CPU.
4868 final int N = processCpuTracker.countWorkingStats();
4870 for (int i=0; i<N && numProcs<5; i++) {
4871 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4872 if (lastPids.indexOfKey(stats.pid) >= 0) {
4875 synchronized (observer) {
4876 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4877 observer.wait(200); // Wait for write-close, give up after 200msec
4879 } catch (InterruptedException e) {
4887 observer.stopWatching();
4891 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4892 if (true || IS_USER_BUILD) {
4895 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4896 if (tracesPath == null || tracesPath.length() == 0) {
4900 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4901 StrictMode.allowThreadDiskWrites();
4903 final File tracesFile = new File(tracesPath);
4904 final File tracesDir = tracesFile.getParentFile();
4905 final File tracesTmp = new File(tracesDir, "__tmp__");
4907 if (!tracesDir.exists()) {
4909 if (!SELinux.restorecon(tracesDir.getPath())) {
4913 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4915 if (tracesFile.exists()) {
4917 tracesFile.renameTo(tracesTmp);
4919 StringBuilder sb = new StringBuilder();
4920 Time tobj = new Time();
4921 tobj.set(System.currentTimeMillis());
4922 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4924 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4925 sb.append(" since ");
4927 FileOutputStream fos = new FileOutputStream(tracesFile);
4928 fos.write(sb.toString().getBytes());
4930 fos.write("\n*** No application process!".getBytes());
4933 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4934 } catch (IOException e) {
4935 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4940 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4941 firstPids.add(app.pid);
4942 dumpStackTraces(tracesPath, firstPids, null, null, null);
4945 File lastTracesFile = null;
4946 File curTracesFile = null;
4947 for (int i=9; i>=0; i--) {
4948 String name = String.format(Locale.US, "slow%02d.txt", i);
4949 curTracesFile = new File(tracesDir, name);
4950 if (curTracesFile.exists()) {
4951 if (lastTracesFile != null) {
4952 curTracesFile.renameTo(lastTracesFile);
4954 curTracesFile.delete();
4957 lastTracesFile = curTracesFile;
4959 tracesFile.renameTo(curTracesFile);
4960 if (tracesTmp.exists()) {
4961 tracesTmp.renameTo(tracesFile);
4964 StrictMode.setThreadPolicy(oldPolicy);
4968 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4969 ActivityRecord parent, boolean aboveSystem, final String annotation) {
4970 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4971 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4973 if (mController != null) {
4975 // 0 == continue, -1 = kill process immediately
4976 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4977 if (res < 0 && app.pid != MY_PID) {
4978 app.kill("anr", true);
4980 } catch (RemoteException e) {
4982 Watchdog.getInstance().setActivityController(null);
4986 long anrTime = SystemClock.uptimeMillis();
4987 if (MONITOR_CPU_USAGE) {
4988 updateCpuStatsNow();
4991 synchronized (this) {
4992 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4993 if (mShuttingDown) {
4994 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4996 } else if (app.notResponding) {
4997 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4999 } else if (app.crashing) {
5000 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5004 // In case we come through here for the same app before completing
5005 // this one, mark as anring now so we will bail out.
5006 app.notResponding = true;
5008 // Log the ANR to the event log.
5009 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5010 app.processName, app.info.flags, annotation);
5012 // Dump thread traces as quickly as we can, starting with "interesting" processes.
5013 firstPids.add(app.pid);
5015 int parentPid = app.pid;
5016 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5017 if (parentPid != app.pid) firstPids.add(parentPid);
5019 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5021 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5022 ProcessRecord r = mLruProcesses.get(i);
5023 if (r != null && r.thread != null) {
5025 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5029 lastPids.put(pid, Boolean.TRUE);
5036 // Log the ANR to the main log.
5037 StringBuilder info = new StringBuilder();
5039 info.append("ANR in ").append(app.processName);
5040 if (activity != null && activity.shortComponentName != null) {
5041 info.append(" (").append(activity.shortComponentName).append(")");
5044 info.append("PID: ").append(app.pid).append("\n");
5045 if (annotation != null) {
5046 info.append("Reason: ").append(annotation).append("\n");
5048 if (parent != null && parent != activity) {
5049 info.append("Parent: ").append(parent.shortComponentName).append("\n");
5052 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5054 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5055 NATIVE_STACKS_OF_INTEREST);
5057 String cpuInfo = null;
5058 if (MONITOR_CPU_USAGE) {
5059 updateCpuStatsNow();
5060 synchronized (mProcessCpuTracker) {
5061 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5063 info.append(processCpuTracker.printCurrentLoad());
5064 info.append(cpuInfo);
5067 info.append(processCpuTracker.printCurrentState(anrTime));
5069 Slog.e(TAG, info.toString());
5070 if (tracesFile == null) {
5071 // There is no trace file, so dump (only) the alleged culprit's threads to the log
5072 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5075 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5076 cpuInfo, tracesFile, null);
5078 if (mController != null) {
5080 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5081 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5083 if (res < 0 && app.pid != MY_PID) {
5084 app.kill("anr", true);
5086 synchronized (this) {
5087 mServices.scheduleServiceTimeoutLocked(app);
5092 } catch (RemoteException e) {
5094 Watchdog.getInstance().setActivityController(null);
5098 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5099 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5100 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5102 synchronized (this) {
5103 mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5105 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5106 app.kill("bg anr", true);
5110 // Set the app's notResponding state, and look up the errorReportReceiver
5111 makeAppNotRespondingLocked(app,
5112 activity != null ? activity.shortComponentName : null,
5113 annotation != null ? "ANR " + annotation : "ANR",
5116 // Bring up the infamous App Not Responding dialog
5117 Message msg = Message.obtain();
5118 HashMap<String, Object> map = new HashMap<String, Object>();
5119 msg.what = SHOW_NOT_RESPONDING_MSG;
5121 msg.arg1 = aboveSystem ? 1 : 0;
5122 map.put("app", app);
5123 if (activity != null) {
5124 map.put("activity", activity);
5127 mUiHandler.sendMessage(msg);
5131 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5132 if (!mLaunchWarningShown) {
5133 mLaunchWarningShown = true;
5134 mUiHandler.post(new Runnable() {
5137 synchronized (ActivityManagerService.this) {
5138 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5140 mUiHandler.postDelayed(new Runnable() {
5143 synchronized (ActivityManagerService.this) {
5145 mLaunchWarningShown = false;
5156 public boolean clearApplicationUserData(final String packageName,
5157 final IPackageDataObserver observer, int userId) {
5158 enforceNotIsolatedCaller("clearApplicationUserData");
5159 int uid = Binder.getCallingUid();
5160 int pid = Binder.getCallingPid();
5161 userId = handleIncomingUser(pid, uid,
5162 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5163 long callingId = Binder.clearCallingIdentity();
5165 IPackageManager pm = AppGlobals.getPackageManager();
5167 synchronized(this) {
5169 pkgUid = pm.getPackageUid(packageName, userId);
5170 } catch (RemoteException e) {
5173 Slog.w(TAG, "Invalid packageName: " + packageName);
5174 if (observer != null) {
5176 observer.onRemoveCompleted(packageName, false);
5177 } catch (RemoteException e) {
5178 Slog.i(TAG, "Observer no longer exists.");
5183 if (uid == pkgUid || checkComponentPermission(
5184 android.Manifest.permission.CLEAR_APP_USER_DATA,
5186 == PackageManager.PERMISSION_GRANTED) {
5187 forceStopPackageLocked(packageName, pkgUid, "clear data");
5189 throw new SecurityException("PID " + pid + " does not have permission "
5190 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5191 + " of package " + packageName);
5194 // Remove all tasks match the cleared application package and user
5195 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5196 final TaskRecord tr = mRecentTasks.get(i);
5197 final String taskPackageName =
5198 tr.getBaseIntent().getComponent().getPackageName();
5199 if (tr.userId != userId) continue;
5200 if (!taskPackageName.equals(packageName)) continue;
5201 removeTaskByIdLocked(tr.taskId, false);
5206 // Clear application user data
5207 pm.clearApplicationUserData(packageName, observer, userId);
5209 synchronized(this) {
5210 // Remove all permissions granted from/to this package
5211 removeUriPermissionsForPackageLocked(packageName, userId, true);
5214 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5215 Uri.fromParts("package", packageName, null));
5216 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5217 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5218 null, null, 0, null, null, null, false, false, userId);
5219 } catch (RemoteException e) {
5222 Binder.restoreCallingIdentity(callingId);
5228 public void killBackgroundProcesses(final String packageName, int userId) {
5229 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5230 != PackageManager.PERMISSION_GRANTED &&
5231 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5232 != PackageManager.PERMISSION_GRANTED) {
5233 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5234 + Binder.getCallingPid()
5235 + ", uid=" + Binder.getCallingUid()
5236 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5238 throw new SecurityException(msg);
5241 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5242 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5243 long callingId = Binder.clearCallingIdentity();
5245 IPackageManager pm = AppGlobals.getPackageManager();
5246 synchronized(this) {
5249 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5250 } catch (RemoteException e) {
5253 Slog.w(TAG, "Invalid packageName: " + packageName);
5256 killPackageProcessesLocked(packageName, appId, userId,
5257 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5260 Binder.restoreCallingIdentity(callingId);
5265 public void killAllBackgroundProcesses() {
5266 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5267 != PackageManager.PERMISSION_GRANTED) {
5268 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5269 + Binder.getCallingPid()
5270 + ", uid=" + Binder.getCallingUid()
5271 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5273 throw new SecurityException(msg);
5276 long callingId = Binder.clearCallingIdentity();
5278 synchronized(this) {
5279 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5280 final int NP = mProcessNames.getMap().size();
5281 for (int ip=0; ip<NP; ip++) {
5282 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5283 final int NA = apps.size();
5284 for (int ia=0; ia<NA; ia++) {
5285 ProcessRecord app = apps.valueAt(ia);
5286 if (app.persistent) {
5287 // we don't kill persistent processes
5292 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5299 int N = procs.size();
5300 for (int i=0; i<N; i++) {
5301 removeProcessLocked(procs.get(i), false, true, "kill all background");
5303 mAllowLowerMemLevel = true;
5304 updateOomAdjLocked();
5305 doLowMemReportIfNeededLocked(null);
5308 Binder.restoreCallingIdentity(callingId);
5313 public void forceStopPackage(final String packageName, int userId) {
5314 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5315 != PackageManager.PERMISSION_GRANTED) {
5316 String msg = "Permission Denial: forceStopPackage() from pid="
5317 + Binder.getCallingPid()
5318 + ", uid=" + Binder.getCallingUid()
5319 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5321 throw new SecurityException(msg);
5323 final int callingPid = Binder.getCallingPid();
5324 userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5325 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5326 long callingId = Binder.clearCallingIdentity();
5328 IPackageManager pm = AppGlobals.getPackageManager();
5329 synchronized(this) {
5330 int[] users = userId == UserHandle.USER_ALL
5331 ? getUsersLocked() : new int[] { userId };
5332 for (int user : users) {
5335 pkgUid = pm.getPackageUid(packageName, user);
5336 } catch (RemoteException e) {
5339 Slog.w(TAG, "Invalid packageName: " + packageName);
5343 pm.setPackageStoppedState(packageName, true, user);
5344 } catch (RemoteException e) {
5345 } catch (IllegalArgumentException e) {
5346 Slog.w(TAG, "Failed trying to unstop package "
5347 + packageName + ": " + e);
5349 if (isUserRunningLocked(user, false)) {
5350 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5355 Binder.restoreCallingIdentity(callingId);
5360 public void addPackageDependency(String packageName) {
5361 synchronized (this) {
5362 int callingPid = Binder.getCallingPid();
5363 if (callingPid == Process.myPid()) {
5368 synchronized (mPidsSelfLocked) {
5369 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5372 if (proc.pkgDeps == null) {
5373 proc.pkgDeps = new ArraySet<String>(1);
5375 proc.pkgDeps.add(packageName);
5381 * The pkg name and app id have to be specified.
5384 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5388 // Make sure the uid is valid.
5390 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5393 int callerUid = Binder.getCallingUid();
5394 // Only the system server can kill an application
5395 if (callerUid == Process.SYSTEM_UID) {
5396 // Post an aysnc message to kill the application
5397 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5400 Bundle bundle = new Bundle();
5401 bundle.putString("pkg", pkg);
5402 bundle.putString("reason", reason);
5404 mHandler.sendMessage(msg);
5406 throw new SecurityException(callerUid + " cannot kill pkg: " +
5412 public void closeSystemDialogs(String reason) {
5413 enforceNotIsolatedCaller("closeSystemDialogs");
5415 final int pid = Binder.getCallingPid();
5416 final int uid = Binder.getCallingUid();
5417 final long origId = Binder.clearCallingIdentity();
5419 synchronized (this) {
5420 // Only allow this from foreground processes, so that background
5421 // applications can't abuse it to prevent system UI from being shown.
5422 if (uid >= Process.FIRST_APPLICATION_UID) {
5424 synchronized (mPidsSelfLocked) {
5425 proc = mPidsSelfLocked.get(pid);
5427 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5428 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5429 + " from background process " + proc);
5433 closeSystemDialogsLocked(reason);
5436 Binder.restoreCallingIdentity(origId);
5440 void closeSystemDialogsLocked(String reason) {
5441 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5442 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5443 | Intent.FLAG_RECEIVER_FOREGROUND);
5444 if (reason != null) {
5445 intent.putExtra("reason", reason);
5447 mWindowManager.closeSystemDialogs(reason);
5449 mStackSupervisor.closeSystemDialogsLocked();
5451 broadcastIntentLocked(null, null, intent, null,
5452 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5453 Process.SYSTEM_UID, UserHandle.USER_ALL);
5457 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5458 enforceNotIsolatedCaller("getProcessMemoryInfo");
5459 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5460 for (int i=pids.length-1; i>=0; i--) {
5463 synchronized (this) {
5464 synchronized (mPidsSelfLocked) {
5465 proc = mPidsSelfLocked.get(pids[i]);
5466 oomAdj = proc != null ? proc.setAdj : 0;
5469 infos[i] = new Debug.MemoryInfo();
5470 Debug.getMemoryInfo(pids[i], infos[i]);
5472 synchronized (this) {
5473 if (proc.thread != null && proc.setAdj == oomAdj) {
5474 // Record this for posterity if the process has been stable.
5475 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5476 infos[i].getTotalUss(), false, proc.pkgList);
5485 public long[] getProcessPss(int[] pids) {
5486 enforceNotIsolatedCaller("getProcessPss");
5487 long[] pss = new long[pids.length];
5488 for (int i=pids.length-1; i>=0; i--) {
5491 synchronized (this) {
5492 synchronized (mPidsSelfLocked) {
5493 proc = mPidsSelfLocked.get(pids[i]);
5494 oomAdj = proc != null ? proc.setAdj : 0;
5497 long[] tmpUss = new long[1];
5498 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5500 synchronized (this) {
5501 if (proc.thread != null && proc.setAdj == oomAdj) {
5502 // Record this for posterity if the process has been stable.
5503 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5512 public void killApplicationProcess(String processName, int uid) {
5513 if (processName == null) {
5517 int callerUid = Binder.getCallingUid();
5518 // Only the system server can kill an application
5519 if (callerUid == Process.SYSTEM_UID) {
5520 synchronized (this) {
5521 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5522 if (app != null && app.thread != null) {
5524 app.thread.scheduleSuicide();
5525 } catch (RemoteException e) {
5526 // If the other end already died, then our work here is done.
5529 Slog.w(TAG, "Process/uid not found attempting kill of "
5530 + processName + " / " + uid);
5534 throw new SecurityException(callerUid + " cannot kill app process: " +
5539 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5540 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5541 false, true, false, false, UserHandle.getUserId(uid), reason);
5542 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5543 Uri.fromParts("package", packageName, null));
5544 if (!mProcessesReady) {
5545 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5546 | Intent.FLAG_RECEIVER_FOREGROUND);
5548 intent.putExtra(Intent.EXTRA_UID, uid);
5549 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5550 broadcastIntentLocked(null, null, intent,
5551 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5553 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5556 private void forceStopUserLocked(int userId, String reason) {
5557 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5558 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5559 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5560 | Intent.FLAG_RECEIVER_FOREGROUND);
5561 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5562 broadcastIntentLocked(null, null, intent,
5563 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5565 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5568 private final boolean killPackageProcessesLocked(String packageName, int appId,
5569 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5570 boolean doit, boolean evenPersistent, String reason) {
5571 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5573 // Remove all processes this package may have touched: all with the
5574 // same UID (except for the system or root user), and all whose name
5575 // matches the package name.
5576 final int NP = mProcessNames.getMap().size();
5577 for (int ip=0; ip<NP; ip++) {
5578 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5579 final int NA = apps.size();
5580 for (int ia=0; ia<NA; ia++) {
5581 ProcessRecord app = apps.valueAt(ia);
5582 if (app.persistent && !evenPersistent) {
5583 // we don't kill persistent processes
5593 // Skip process if it doesn't meet our oom adj requirement.
5594 if (app.setAdj < minOomAdj) {
5598 // If no package is specified, we call all processes under the
5600 if (packageName == null) {
5601 if (app.userId != userId) {
5604 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5607 // Package has been specified, we want to hit all processes
5608 // that match it. We need to qualify this by the processes
5609 // that are running under the specified app and user ID.
5611 final boolean isDep = app.pkgDeps != null
5612 && app.pkgDeps.contains(packageName);
5613 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5616 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5619 if (!app.pkgList.containsKey(packageName) && !isDep) {
5624 // Process has passed all conditions, kill it!
5633 int N = procs.size();
5634 for (int i=0; i<N; i++) {
5635 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5637 updateOomAdjLocked();
5641 private final boolean forceStopPackageLocked(String name, int appId,
5642 boolean callerWillRestart, boolean purgeCache, boolean doit,
5643 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5647 if (userId == UserHandle.USER_ALL && name == null) {
5648 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5651 if (appId < 0 && name != null) {
5653 appId = UserHandle.getAppId(
5654 AppGlobals.getPackageManager().getPackageUid(name, 0));
5655 } catch (RemoteException e) {
5661 Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5662 + " user=" + userId + ": " + reason);
5664 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5667 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5668 for (int ip=pmap.size()-1; ip>=0; ip--) {
5669 SparseArray<Long> ba = pmap.valueAt(ip);
5670 for (i=ba.size()-1; i>=0; i--) {
5671 boolean remove = false;
5672 final int entUid = ba.keyAt(i);
5674 if (userId == UserHandle.USER_ALL) {
5675 if (UserHandle.getAppId(entUid) == appId) {
5679 if (entUid == UserHandle.getUid(userId, appId)) {
5683 } else if (UserHandle.getUserId(entUid) == userId) {
5690 if (ba.size() == 0) {
5696 boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5697 -100, callerWillRestart, true, doit, evenPersistent,
5698 name == null ? ("stop user " + userId) : ("stop " + name));
5700 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5704 didSomething = true;
5707 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5711 didSomething = true;
5715 // Remove all sticky broadcasts from this user.
5716 mStickyBroadcasts.remove(userId);
5719 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5720 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5721 userId, providers)) {
5725 didSomething = true;
5727 N = providers.size();
5728 for (i=0; i<N; i++) {
5729 removeDyingProviderLocked(null, providers.get(i), true);
5732 // Remove transient permissions granted from/to this package/user
5733 removeUriPermissionsForPackageLocked(name, userId, false);
5735 if (name == null || uninstalling) {
5736 // Remove pending intents. For now we only do this when force
5737 // stopping users, because we have some problems when doing this
5738 // for packages -- app widgets are not currently cleaned up for
5739 // such packages, so they can be left with bad pending intents.
5740 if (mIntentSenderRecords.size() > 0) {
5741 Iterator<WeakReference<PendingIntentRecord>> it
5742 = mIntentSenderRecords.values().iterator();
5743 while (it.hasNext()) {
5744 WeakReference<PendingIntentRecord> wpir = it.next();
5749 PendingIntentRecord pir = wpir.get();
5755 // Stopping user, remove all objects for the user.
5756 if (pir.key.userId != userId) {
5757 // Not the same user, skip it.
5761 if (UserHandle.getAppId(pir.uid) != appId) {
5762 // Different app id, skip it.
5765 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5766 // Different user, skip it.
5769 if (!pir.key.packageName.equals(name)) {
5770 // Different package, skip it.
5777 didSomething = true;
5779 pir.canceled = true;
5780 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5781 pir.key.activity.pendingResults.remove(pir.ref);
5788 if (purgeCache && name != null) {
5789 AttributeCache ac = AttributeCache.instance();
5791 ac.removePackage(name);
5795 mStackSupervisor.resumeTopActivitiesLocked();
5796 mStackSupervisor.scheduleIdleLocked();
5800 return didSomething;
5803 private final boolean removeProcessLocked(ProcessRecord app,
5804 boolean callerWillRestart, boolean allowRestart, String reason) {
5805 final String name = app.processName;
5806 final int uid = app.uid;
5807 if (DEBUG_PROCESSES) Slog.d(
5808 TAG, "Force removing proc " + app.toShortString() + " (" + name
5811 mProcessNames.remove(name, uid);
5812 mIsolatedProcesses.remove(app.uid);
5813 if (mHeavyWeightProcess == app) {
5814 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5815 mHeavyWeightProcess.userId, 0));
5816 mHeavyWeightProcess = null;
5818 boolean needRestart = false;
5819 if (app.pid > 0 && app.pid != MY_PID) {
5821 synchronized (mPidsSelfLocked) {
5822 mPidsSelfLocked.remove(pid);
5823 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5825 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5827 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5829 boolean willRestart = false;
5830 if (app.persistent && !app.isolated) {
5831 if (!callerWillRestart) {
5837 app.kill(reason, true);
5838 handleAppDiedLocked(app, willRestart, allowRestart);
5840 removeLruProcessLocked(app);
5841 addAppLocked(app.info, false, null /* ABI override */);
5844 mRemovedProcesses.add(app);
5850 private final void processStartTimedOutLocked(ProcessRecord app) {
5851 final int pid = app.pid;
5852 boolean gone = false;
5853 synchronized (mPidsSelfLocked) {
5854 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5855 if (knownApp != null && knownApp.thread == null) {
5856 mPidsSelfLocked.remove(pid);
5862 Slog.w(TAG, "Process " + app + " failed to attach");
5863 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5864 pid, app.uid, app.processName);
5865 mProcessNames.remove(app.processName, app.uid);
5866 mIsolatedProcesses.remove(app.uid);
5867 if (mHeavyWeightProcess == app) {
5868 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5869 mHeavyWeightProcess.userId, 0));
5870 mHeavyWeightProcess = null;
5872 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5874 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5876 // Take care of any launching providers waiting for this process.
5877 checkAppInLaunchingProvidersLocked(app, true);
5878 // Take care of any services that are waiting for the process.
5879 mServices.processStartTimedOutLocked(app);
5880 app.kill("start timeout", true);
5881 removeLruProcessLocked(app);
5882 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5883 Slog.w(TAG, "Unattached app died before backup, skipping");
5885 IBackupManager bm = IBackupManager.Stub.asInterface(
5886 ServiceManager.getService(Context.BACKUP_SERVICE));
5887 bm.agentDisconnected(app.info.packageName);
5888 } catch (RemoteException e) {
5889 // Can't happen; the backup manager is local
5892 if (isPendingBroadcastProcessLocked(pid)) {
5893 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5894 skipPendingBroadcastLocked(pid);
5897 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5901 private final boolean attachApplicationLocked(IApplicationThread thread,
5904 // Find the application record that is being attached... either via
5905 // the pid if we are running in multiple processes, or just pull the
5906 // next app record if we are emulating process with anonymous threads.
5908 if (pid != MY_PID && pid >= 0) {
5909 synchronized (mPidsSelfLocked) {
5910 app = mPidsSelfLocked.get(pid);
5917 Slog.w(TAG, "No pending application record for pid " + pid
5918 + " (IApplicationThread " + thread + "); dropping process");
5919 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5920 if (pid > 0 && pid != MY_PID) {
5921 Process.killProcessQuiet(pid);
5922 //TODO: Process.killProcessGroup(app.info.uid, pid);
5925 thread.scheduleExit();
5926 } catch (Exception e) {
5927 // Ignore exceptions.
5933 // If this application record is still attached to a previous
5934 // process, clean it up now.
5935 if (app.thread != null) {
5936 handleAppDiedLocked(app, true, true);
5939 // Tell the process all about itself.
5941 if (localLOGV) Slog.v(
5942 TAG, "Binding process pid " + pid + " to record " + app);
5944 final String processName = app.processName;
5946 AppDeathRecipient adr = new AppDeathRecipient(
5948 thread.asBinder().linkToDeath(adr, 0);
5949 app.deathRecipient = adr;
5950 } catch (RemoteException e) {
5951 app.resetPackageList(mProcessStats);
5952 startProcessLocked(app, "link fail", processName);
5956 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5958 app.makeActive(thread, mProcessStats);
5959 app.curAdj = app.setAdj = -100;
5960 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5961 app.forcingToForeground = null;
5962 updateProcessForegroundLocked(app, false, false);
5963 app.hasShownUi = false;
5964 app.debugging = false;
5966 app.killedByAm = false;
5968 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5970 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5971 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5974 Slog.i(TAG, "Launching preboot mode app: " + app);
5977 if (localLOGV) Slog.v(
5978 TAG, "New app record " + app
5979 + " thread=" + thread.asBinder() + " pid=" + pid);
5981 int testMode = IApplicationThread.DEBUG_OFF;
5982 if (mDebugApp != null && mDebugApp.equals(processName)) {
5983 testMode = mWaitForDebugger
5984 ? IApplicationThread.DEBUG_WAIT
5985 : IApplicationThread.DEBUG_ON;
5986 app.debugging = true;
5987 if (mDebugTransient) {
5988 mDebugApp = mOrigDebugApp;
5989 mWaitForDebugger = mOrigWaitForDebugger;
5992 String profileFile = app.instrumentationProfileFile;
5993 ParcelFileDescriptor profileFd = null;
5994 int samplingInterval = 0;
5995 boolean profileAutoStop = false;
5996 if (mProfileApp != null && mProfileApp.equals(processName)) {
5998 profileFile = mProfileFile;
5999 profileFd = mProfileFd;
6000 samplingInterval = mSamplingInterval;
6001 profileAutoStop = mAutoStopProfiler;
6003 boolean enableOpenGlTrace = false;
6004 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6005 enableOpenGlTrace = true;
6006 mOpenGlTraceApp = null;
6009 // If the app is being launched for restore or full backup, set it up specially
6010 boolean isRestrictedBackupMode = false;
6011 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6012 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6013 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6014 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6017 ensurePackageDexOpt(app.instrumentationInfo != null
6018 ? app.instrumentationInfo.packageName
6019 : app.info.packageName);
6020 if (app.instrumentationClass != null) {
6021 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6023 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6024 + processName + " with config " + mConfiguration);
6025 ApplicationInfo appInfo = app.instrumentationInfo != null
6026 ? app.instrumentationInfo : app.info;
6027 app.compat = compatibilityInfoForPackageLocked(appInfo);
6028 if (profileFd != null) {
6029 profileFd = profileFd.dup();
6031 ProfilerInfo profilerInfo = profileFile == null ? null
6032 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6033 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6034 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6035 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6036 isRestrictedBackupMode || !normalMode, app.persistent,
6037 new Configuration(mConfiguration), app.compat,
6038 getCommonServicesLocked(app.isolated),
6039 mCoreSettingsObserver.getCoreSettingsLocked());
6040 updateLruProcessLocked(app, false, null);
6041 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6042 } catch (Exception e) {
6043 // todo: Yikes! What should we do? For now we will try to
6044 // start another process, but that could easily get us in
6045 // an infinite loop of restarting processes...
6046 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6048 app.resetPackageList(mProcessStats);
6049 app.unlinkDeathRecipient();
6050 startProcessLocked(app, "bind fail", processName);
6054 // Remove this record from the list of starting applications.
6055 mPersistentStartingProcesses.remove(app);
6056 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6057 "Attach application locked removing on hold: " + app);
6058 mProcessesOnHold.remove(app);
6060 boolean badApp = false;
6061 boolean didSomething = false;
6063 // See if the top visible activity is waiting to run in this process...
6066 if (mStackSupervisor.attachApplicationLocked(app)) {
6067 didSomething = true;
6069 } catch (Exception e) {
6070 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6075 // Find any services that should be running in this process...
6078 didSomething |= mServices.attachApplicationLocked(app, processName);
6079 } catch (Exception e) {
6080 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6085 // Check if a next-broadcast receiver is in this process...
6086 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6088 didSomething |= sendPendingBroadcastsLocked(app);
6089 } catch (Exception e) {
6090 // If the app died trying to launch the receiver we declare it 'bad'
6091 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6096 // Check whether the next backup agent is in this process...
6097 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6098 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6099 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6101 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6102 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6103 mBackupTarget.backupMode);
6104 } catch (Exception e) {
6105 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6111 app.kill("error during init", true);
6112 handleAppDiedLocked(app, false, true);
6116 if (!didSomething) {
6117 updateOomAdjLocked();
6124 public final void attachApplication(IApplicationThread thread) {
6125 synchronized (this) {
6126 int callingPid = Binder.getCallingPid();
6127 final long origId = Binder.clearCallingIdentity();
6128 attachApplicationLocked(thread, callingPid);
6129 Binder.restoreCallingIdentity(origId);
6134 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6135 final long origId = Binder.clearCallingIdentity();
6136 synchronized (this) {
6137 ActivityStack stack = ActivityRecord.getStackLocked(token);
6138 if (stack != null) {
6140 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6141 if (stopProfiling) {
6142 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6145 } catch (IOException e) {
6147 clearProfilerLocked();
6152 Binder.restoreCallingIdentity(origId);
6155 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6156 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6157 finishBooting? 1 : 0, enableScreen ? 1 : 0));
6160 void enableScreenAfterBoot() {
6161 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6162 SystemClock.uptimeMillis());
6163 mWindowManager.enableScreenAfterBoot();
6165 synchronized (this) {
6166 updateEventDispatchingLocked();
6171 public void showBootMessage(final CharSequence msg, final boolean always) {
6172 enforceNotIsolatedCaller("showBootMessage");
6173 mWindowManager.showBootMessage(msg, always);
6177 public void keyguardWaitingForActivityDrawn() {
6178 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6179 final long token = Binder.clearCallingIdentity();
6181 synchronized (this) {
6182 if (DEBUG_LOCKSCREEN) logLockScreen("");
6183 mWindowManager.keyguardWaitingForActivityDrawn();
6184 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6185 mLockScreenShown = LOCK_SCREEN_LEAVING;
6186 updateSleepIfNeededLocked();
6190 Binder.restoreCallingIdentity(token);
6194 final void finishBooting() {
6195 synchronized (this) {
6196 if (!mBootAnimationComplete) {
6197 mCallFinishBooting = true;
6200 mCallFinishBooting = false;
6203 ArraySet<String> completedIsas = new ArraySet<String>();
6204 for (String abi : Build.SUPPORTED_ABIS) {
6205 Process.establishZygoteConnectionForAbi(abi);
6206 final String instructionSet = VMRuntime.getInstructionSet(abi);
6207 if (!completedIsas.contains(instructionSet)) {
6208 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6209 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6211 completedIsas.add(instructionSet);
6215 IntentFilter pkgFilter = new IntentFilter();
6216 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6217 pkgFilter.addDataScheme("package");
6218 mContext.registerReceiver(new BroadcastReceiver() {
6220 public void onReceive(Context context, Intent intent) {
6221 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6223 for (String pkg : pkgs) {
6224 synchronized (ActivityManagerService.this) {
6225 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6226 0, "finished booting")) {
6227 setResultCode(Activity.RESULT_OK);
6236 // Let system services know.
6237 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6239 synchronized (this) {
6240 // Ensure that any processes we had put on hold are now started
6242 final int NP = mProcessesOnHold.size();
6244 ArrayList<ProcessRecord> procs =
6245 new ArrayList<ProcessRecord>(mProcessesOnHold);
6246 for (int ip=0; ip<NP; ip++) {
6247 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6249 startProcessLocked(procs.get(ip), "on-hold", null);
6253 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6254 // Start looking for apps that are abusing wake locks.
6255 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6256 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6257 // Tell anyone interested that we are done booting!
6258 SystemProperties.set("sys.boot_completed", "1");
6260 // And trigger dev.bootcomplete if we are not showing encryption progress
6261 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6262 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6263 SystemProperties.set("dev.bootcomplete", "1");
6265 for (int i=0; i<mStartedUsers.size(); i++) {
6266 UserStartedState uss = mStartedUsers.valueAt(i);
6267 if (uss.mState == UserStartedState.STATE_BOOTING) {
6268 uss.mState = UserStartedState.STATE_RUNNING;
6269 final int userId = mStartedUsers.keyAt(i);
6270 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6271 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6272 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6273 broadcastIntentLocked(null, null, intent, null,
6274 new IIntentReceiver.Stub() {
6276 public void performReceive(Intent intent, int resultCode,
6277 String data, Bundle extras, boolean ordered,
6278 boolean sticky, int sendingUser) {
6279 synchronized (ActivityManagerService.this) {
6280 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6286 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6287 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6291 scheduleStartProfilesLocked();
6297 public void bootAnimationComplete() {
6298 final boolean callFinishBooting;
6299 synchronized (this) {
6300 callFinishBooting = mCallFinishBooting;
6301 mBootAnimationComplete = true;
6303 if (callFinishBooting) {
6309 public void systemBackupRestored() {
6310 synchronized (this) {
6312 mTaskPersister.restoreTasksFromOtherDeviceLocked();
6314 Slog.w(TAG, "System backup restored before system is ready");
6319 final void ensureBootCompleted() {
6321 boolean enableScreen;
6322 synchronized (this) {
6325 enableScreen = !mBooted;
6334 enableScreenAfterBoot();
6339 public final void activityResumed(IBinder token) {
6340 final long origId = Binder.clearCallingIdentity();
6341 synchronized(this) {
6342 ActivityStack stack = ActivityRecord.getStackLocked(token);
6343 if (stack != null) {
6344 ActivityRecord.activityResumedLocked(token);
6347 Binder.restoreCallingIdentity(origId);
6351 public final void activityPaused(IBinder token) {
6352 final long origId = Binder.clearCallingIdentity();
6353 synchronized(this) {
6354 ActivityStack stack = ActivityRecord.getStackLocked(token);
6355 if (stack != null) {
6356 stack.activityPausedLocked(token, false);
6359 Binder.restoreCallingIdentity(origId);
6363 public final void activityStopped(IBinder token, Bundle icicle,
6364 PersistableBundle persistentState, CharSequence description) {
6365 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6367 // Refuse possible leaked file descriptors
6368 if (icicle != null && icicle.hasFileDescriptors()) {
6369 throw new IllegalArgumentException("File descriptors passed in Bundle");
6372 final long origId = Binder.clearCallingIdentity();
6374 synchronized (this) {
6375 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6377 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6383 Binder.restoreCallingIdentity(origId);
6387 public final void activityDestroyed(IBinder token) {
6388 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6389 synchronized (this) {
6390 ActivityStack stack = ActivityRecord.getStackLocked(token);
6391 if (stack != null) {
6392 stack.activityDestroyedLocked(token, "activityDestroyed");
6398 public final void backgroundResourcesReleased(IBinder token) {
6399 final long origId = Binder.clearCallingIdentity();
6401 synchronized (this) {
6402 ActivityStack stack = ActivityRecord.getStackLocked(token);
6403 if (stack != null) {
6404 stack.backgroundResourcesReleased();
6408 Binder.restoreCallingIdentity(origId);
6413 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6414 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6418 public final void notifyEnterAnimationComplete(IBinder token) {
6419 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6423 public String getCallingPackage(IBinder token) {
6424 synchronized (this) {
6425 ActivityRecord r = getCallingRecordLocked(token);
6426 return r != null ? r.info.packageName : null;
6431 public ComponentName getCallingActivity(IBinder token) {
6432 synchronized (this) {
6433 ActivityRecord r = getCallingRecordLocked(token);
6434 return r != null ? r.intent.getComponent() : null;
6438 private ActivityRecord getCallingRecordLocked(IBinder token) {
6439 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6447 public ComponentName getActivityClassForToken(IBinder token) {
6448 synchronized(this) {
6449 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6453 return r.intent.getComponent();
6458 public String getPackageForToken(IBinder token) {
6459 synchronized(this) {
6460 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6464 return r.packageName;
6469 public IIntentSender getIntentSender(int type,
6470 String packageName, IBinder token, String resultWho,
6471 int requestCode, Intent[] intents, String[] resolvedTypes,
6472 int flags, Bundle options, int userId) {
6473 enforceNotIsolatedCaller("getIntentSender");
6474 // Refuse possible leaked file descriptors
6475 if (intents != null) {
6476 if (intents.length < 1) {
6477 throw new IllegalArgumentException("Intents array length must be >= 1");
6479 for (int i=0; i<intents.length; i++) {
6480 Intent intent = intents[i];
6481 if (intent != null) {
6482 if (intent.hasFileDescriptors()) {
6483 throw new IllegalArgumentException("File descriptors passed in Intent");
6485 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6486 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6487 throw new IllegalArgumentException(
6488 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6490 intents[i] = new Intent(intent);
6493 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6494 throw new IllegalArgumentException(
6495 "Intent array length does not match resolvedTypes length");
6498 if (options != null) {
6499 if (options.hasFileDescriptors()) {
6500 throw new IllegalArgumentException("File descriptors passed in options");
6504 synchronized(this) {
6505 int callingUid = Binder.getCallingUid();
6506 int origUserId = userId;
6507 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6508 type == ActivityManager.INTENT_SENDER_BROADCAST,
6509 ALLOW_NON_FULL, "getIntentSender", null);
6510 if (origUserId == UserHandle.USER_CURRENT) {
6511 // We don't want to evaluate this until the pending intent is
6512 // actually executed. However, we do want to always do the
6513 // security checking for it above.
6514 userId = UserHandle.USER_CURRENT;
6517 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6518 int uid = AppGlobals.getPackageManager()
6519 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6520 if (!UserHandle.isSameApp(callingUid, uid)) {
6521 String msg = "Permission Denial: getIntentSender() from pid="
6522 + Binder.getCallingPid()
6523 + ", uid=" + Binder.getCallingUid()
6524 + ", (need uid=" + uid + ")"
6525 + " is not allowed to send as package " + packageName;
6527 throw new SecurityException(msg);
6531 return getIntentSenderLocked(type, packageName, callingUid, userId,
6532 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6534 } catch (RemoteException e) {
6535 throw new SecurityException(e);
6540 IIntentSender getIntentSenderLocked(int type, String packageName,
6541 int callingUid, int userId, IBinder token, String resultWho,
6542 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6545 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6546 ActivityRecord activity = null;
6547 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6548 activity = ActivityRecord.isInStackLocked(token);
6549 if (activity == null) {
6552 if (activity.finishing) {
6557 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6558 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6559 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6560 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6561 |PendingIntent.FLAG_UPDATE_CURRENT);
6563 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6564 type, packageName, activity, resultWho,
6565 requestCode, intents, resolvedTypes, flags, options, userId);
6566 WeakReference<PendingIntentRecord> ref;
6567 ref = mIntentSenderRecords.get(key);
6568 PendingIntentRecord rec = ref != null ? ref.get() : null;
6570 if (!cancelCurrent) {
6571 if (updateCurrent) {
6572 if (rec.key.requestIntent != null) {
6573 rec.key.requestIntent.replaceExtras(intents != null ?
6574 intents[intents.length - 1] : null);
6576 if (intents != null) {
6577 intents[intents.length-1] = rec.key.requestIntent;
6578 rec.key.allIntents = intents;
6579 rec.key.allResolvedTypes = resolvedTypes;
6581 rec.key.allIntents = null;
6582 rec.key.allResolvedTypes = null;
6587 rec.canceled = true;
6588 mIntentSenderRecords.remove(key);
6593 rec = new PendingIntentRecord(this, key, callingUid);
6594 mIntentSenderRecords.put(key, rec.ref);
6595 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6596 if (activity.pendingResults == null) {
6597 activity.pendingResults
6598 = new HashSet<WeakReference<PendingIntentRecord>>();
6600 activity.pendingResults.add(rec.ref);
6606 public void cancelIntentSender(IIntentSender sender) {
6607 if (!(sender instanceof PendingIntentRecord)) {
6610 synchronized(this) {
6611 PendingIntentRecord rec = (PendingIntentRecord)sender;
6613 int uid = AppGlobals.getPackageManager()
6614 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6615 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6616 String msg = "Permission Denial: cancelIntentSender() from pid="
6617 + Binder.getCallingPid()
6618 + ", uid=" + Binder.getCallingUid()
6619 + " is not allowed to cancel packges "
6620 + rec.key.packageName;
6622 throw new SecurityException(msg);
6624 } catch (RemoteException e) {
6625 throw new SecurityException(e);
6627 cancelIntentSenderLocked(rec, true);
6631 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6632 rec.canceled = true;
6633 mIntentSenderRecords.remove(rec.key);
6634 if (cleanActivity && rec.key.activity != null) {
6635 rec.key.activity.pendingResults.remove(rec.ref);
6640 public String getPackageForIntentSender(IIntentSender pendingResult) {
6641 if (!(pendingResult instanceof PendingIntentRecord)) {
6645 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6646 return res.key.packageName;
6647 } catch (ClassCastException e) {
6653 public int getUidForIntentSender(IIntentSender sender) {
6654 if (sender instanceof PendingIntentRecord) {
6656 PendingIntentRecord res = (PendingIntentRecord)sender;
6658 } catch (ClassCastException e) {
6665 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6666 if (!(pendingResult instanceof PendingIntentRecord)) {
6670 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6671 if (res.key.allIntents == null) {
6674 for (int i=0; i<res.key.allIntents.length; i++) {
6675 Intent intent = res.key.allIntents[i];
6676 if (intent.getPackage() != null && intent.getComponent() != null) {
6681 } catch (ClassCastException e) {
6687 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6688 if (!(pendingResult instanceof PendingIntentRecord)) {
6692 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6693 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6697 } catch (ClassCastException e) {
6703 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6704 if (!(pendingResult instanceof PendingIntentRecord)) {
6708 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6709 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6710 } catch (ClassCastException e) {
6716 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6717 if (!(pendingResult instanceof PendingIntentRecord)) {
6721 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6722 Intent intent = res.key.requestIntent;
6723 if (intent != null) {
6724 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6725 || res.lastTagPrefix.equals(prefix))) {
6728 res.lastTagPrefix = prefix;
6729 StringBuilder sb = new StringBuilder(128);
6730 if (prefix != null) {
6733 if (intent.getAction() != null) {
6734 sb.append(intent.getAction());
6735 } else if (intent.getComponent() != null) {
6736 intent.getComponent().appendShortString(sb);
6740 return res.lastTag = sb.toString();
6742 } catch (ClassCastException e) {
6748 public void setProcessLimit(int max) {
6749 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6750 "setProcessLimit()");
6751 synchronized (this) {
6752 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6753 mProcessLimitOverride = max;
6759 public int getProcessLimit() {
6760 synchronized (this) {
6761 return mProcessLimitOverride;
6765 void foregroundTokenDied(ForegroundToken token) {
6766 synchronized (ActivityManagerService.this) {
6767 synchronized (mPidsSelfLocked) {
6769 = mForegroundProcesses.get(token.pid);
6773 mForegroundProcesses.remove(token.pid);
6774 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6778 pr.forcingToForeground = null;
6779 updateProcessForegroundLocked(pr, false, false);
6781 updateOomAdjLocked();
6786 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6787 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6788 "setProcessForeground()");
6789 synchronized(this) {
6790 boolean changed = false;
6792 synchronized (mPidsSelfLocked) {
6793 ProcessRecord pr = mPidsSelfLocked.get(pid);
6794 if (pr == null && isForeground) {
6795 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6798 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6799 if (oldToken != null) {
6800 oldToken.token.unlinkToDeath(oldToken, 0);
6801 mForegroundProcesses.remove(pid);
6803 pr.forcingToForeground = null;
6807 if (isForeground && token != null) {
6808 ForegroundToken newToken = new ForegroundToken() {
6810 public void binderDied() {
6811 foregroundTokenDied(this);
6815 newToken.token = token;
6817 token.linkToDeath(newToken, 0);
6818 mForegroundProcesses.put(pid, newToken);
6819 pr.forcingToForeground = token;
6821 } catch (RemoteException e) {
6822 // If the process died while doing this, we will later
6823 // do the cleanup with the process death link.
6829 updateOomAdjLocked();
6834 // =========================================================
6836 // =========================================================
6838 static class ProcessInfoService extends IProcessInfoService.Stub {
6839 final ActivityManagerService mActivityManagerService;
6840 ProcessInfoService(ActivityManagerService activityManagerService) {
6841 mActivityManagerService = activityManagerService;
6845 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
6846 mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
6851 * For each PID in the given input array, write the current process state
6852 * for that process into the output array, or -1 to indicate that no
6853 * process with the given PID exists.
6855 public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
6857 throw new NullPointerException("pids");
6858 } else if (states == null) {
6859 throw new NullPointerException("states");
6860 } else if (pids.length != states.length) {
6861 throw new IllegalArgumentException("input and output arrays have different lengths!");
6864 synchronized (mPidsSelfLocked) {
6865 for (int i = 0; i < pids.length; i++) {
6866 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
6867 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
6873 // =========================================================
6875 // =========================================================
6877 static class PermissionController extends IPermissionController.Stub {
6878 ActivityManagerService mActivityManagerService;
6879 PermissionController(ActivityManagerService activityManagerService) {
6880 mActivityManagerService = activityManagerService;
6884 public boolean checkPermission(String permission, int pid, int uid) {
6885 return mActivityManagerService.checkPermission(permission, pid,
6886 uid) == PackageManager.PERMISSION_GRANTED;
6890 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6892 public int checkComponentPermission(String permission, int pid, int uid,
6893 int owningUid, boolean exported) {
6894 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6895 owningUid, exported);
6899 public Object getAMSLock() {
6900 return ActivityManagerService.this;
6905 * This can be called with or without the global lock held.
6907 int checkComponentPermission(String permission, int pid, int uid,
6908 int owningUid, boolean exported) {
6909 if (pid == MY_PID) {
6910 return PackageManager.PERMISSION_GRANTED;
6912 return ActivityManager.checkComponentPermission(permission, uid,
6913 owningUid, exported);
6917 * As the only public entry point for permissions checking, this method
6918 * can enforce the semantic that requesting a check on a null global
6919 * permission is automatically denied. (Internally a null permission
6920 * string is used when calling {@link #checkComponentPermission} in cases
6921 * when only uid-based security is needed.)
6923 * This can be called with or without the global lock held.
6926 public int checkPermission(String permission, int pid, int uid) {
6927 if (permission == null) {
6928 return PackageManager.PERMISSION_DENIED;
6930 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6934 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6935 if (permission == null) {
6936 return PackageManager.PERMISSION_DENIED;
6939 // We might be performing an operation on behalf of an indirect binder
6940 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
6941 // client identity accordingly before proceeding.
6942 Identity tlsIdentity = sCallerIdentity.get();
6943 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6944 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6945 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6946 uid = tlsIdentity.uid;
6947 pid = tlsIdentity.pid;
6950 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6954 * Binder IPC calls go through the public entry point.
6955 * This can be called with or without the global lock held.
6957 int checkCallingPermission(String permission) {
6958 return checkPermission(permission,
6959 Binder.getCallingPid(),
6960 UserHandle.getAppId(Binder.getCallingUid()));
6964 * This can be called with or without the global lock held.
6966 void enforceCallingPermission(String permission, String func) {
6967 if (checkCallingPermission(permission)
6968 == PackageManager.PERMISSION_GRANTED) {
6972 String msg = "Permission Denial: " + func + " from pid="
6973 + Binder.getCallingPid()
6974 + ", uid=" + Binder.getCallingUid()
6975 + " requires " + permission;
6977 throw new SecurityException(msg);
6981 * Determine if UID is holding permissions required to access {@link Uri} in
6982 * the given {@link ProviderInfo}. Final permission checking is always done
6983 * in {@link ContentProvider}.
6985 private final boolean checkHoldingPermissionsLocked(
6986 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6987 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6988 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6989 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6990 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6991 != PERMISSION_GRANTED) {
6995 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6998 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6999 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7000 if (pi.applicationInfo.uid == uid) {
7002 } else if (!pi.exported) {
7006 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7007 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7009 // check if target holds top-level <provider> permissions
7010 if (!readMet && pi.readPermission != null && considerUidPermissions
7011 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7014 if (!writeMet && pi.writePermission != null && considerUidPermissions
7015 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7019 // track if unprotected read/write is allowed; any denied
7020 // <path-permission> below removes this ability
7021 boolean allowDefaultRead = pi.readPermission == null;
7022 boolean allowDefaultWrite = pi.writePermission == null;
7024 // check if target holds any <path-permission> that match uri
7025 final PathPermission[] pps = pi.pathPermissions;
7027 final String path = grantUri.uri.getPath();
7029 while (i > 0 && (!readMet || !writeMet)) {
7031 PathPermission pp = pps[i];
7032 if (pp.match(path)) {
7034 final String pprperm = pp.getReadPermission();
7035 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7036 + pprperm + " for " + pp.getPath()
7037 + ": match=" + pp.match(path)
7038 + " check=" + pm.checkUidPermission(pprperm, uid));
7039 if (pprperm != null) {
7040 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7041 == PERMISSION_GRANTED) {
7044 allowDefaultRead = false;
7049 final String ppwperm = pp.getWritePermission();
7050 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7051 + ppwperm + " for " + pp.getPath()
7052 + ": match=" + pp.match(path)
7053 + " check=" + pm.checkUidPermission(ppwperm, uid));
7054 if (ppwperm != null) {
7055 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7056 == PERMISSION_GRANTED) {
7059 allowDefaultWrite = false;
7067 // grant unprotected <provider> read/write, if not blocked by
7068 // <path-permission> above
7069 if (allowDefaultRead) readMet = true;
7070 if (allowDefaultWrite) writeMet = true;
7072 } catch (RemoteException e) {
7076 return readMet && writeMet;
7079 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7080 ProviderInfo pi = null;
7081 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7086 pi = AppGlobals.getPackageManager().resolveContentProvider(
7087 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7088 } catch (RemoteException ex) {
7094 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7095 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7096 if (targetUris != null) {
7097 return targetUris.get(grantUri);
7102 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7103 String targetPkg, int targetUid, GrantUri grantUri) {
7104 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7105 if (targetUris == null) {
7106 targetUris = Maps.newArrayMap();
7107 mGrantedUriPermissions.put(targetUid, targetUris);
7110 UriPermission perm = targetUris.get(grantUri);
7112 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7113 targetUris.put(grantUri, perm);
7119 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7120 final int modeFlags) {
7121 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7122 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7123 : UriPermission.STRENGTH_OWNED;
7125 // Root gets to do everything.
7130 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7131 if (perms == null) return false;
7133 // First look for exact match
7134 final UriPermission exactPerm = perms.get(grantUri);
7135 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7139 // No exact match, look for prefixes
7140 final int N = perms.size();
7141 for (int i = 0; i < N; i++) {
7142 final UriPermission perm = perms.valueAt(i);
7143 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7144 && perm.getStrength(modeFlags) >= minStrength) {
7153 * @param uri This uri must NOT contain an embedded userId.
7154 * @param userId The userId in which the uri is to be resolved.
7157 public int checkUriPermission(Uri uri, int pid, int uid,
7158 final int modeFlags, int userId, IBinder callerToken) {
7159 enforceNotIsolatedCaller("checkUriPermission");
7161 // Another redirected-binder-call permissions check as in
7162 // {@link checkPermissionWithToken}.
7163 Identity tlsIdentity = sCallerIdentity.get();
7164 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7165 uid = tlsIdentity.uid;
7166 pid = tlsIdentity.pid;
7169 // Our own process gets to do everything.
7170 if (pid == MY_PID) {
7171 return PackageManager.PERMISSION_GRANTED;
7173 synchronized (this) {
7174 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7175 ? PackageManager.PERMISSION_GRANTED
7176 : PackageManager.PERMISSION_DENIED;
7181 * Check if the targetPkg can be granted permission to access uri by
7182 * the callingUid using the given modeFlags. Throws a security exception
7183 * if callingUid is not allowed to do this. Returns the uid of the target
7184 * if the URI permission grant should be performed; returns -1 if it is not
7185 * needed (for example targetPkg already has permission to access the URI).
7186 * If you already know the uid of the target, you can supply it in
7187 * lastTargetUid else set that to -1.
7189 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7190 final int modeFlags, int lastTargetUid) {
7191 if (!Intent.isAccessUriMode(modeFlags)) {
7195 if (targetPkg != null) {
7196 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7197 "Checking grant " + targetPkg + " permission to " + grantUri);
7200 final IPackageManager pm = AppGlobals.getPackageManager();
7202 // If this is not a content: uri, we can't do anything with it.
7203 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7204 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7205 "Can't grant URI permission for non-content URI: " + grantUri);
7209 final String authority = grantUri.uri.getAuthority();
7210 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7212 Slog.w(TAG, "No content provider found for permission check: " +
7213 grantUri.uri.toSafeString());
7217 int targetUid = lastTargetUid;
7218 if (targetUid < 0 && targetPkg != null) {
7220 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7221 if (targetUid < 0) {
7222 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7223 "Can't grant URI permission no uid for: " + targetPkg);
7226 } catch (RemoteException ex) {
7231 if (targetUid >= 0) {
7232 // First... does the target actually need this permission?
7233 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7234 // No need to grant the target this permission.
7235 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7236 "Target " + targetPkg + " already has full permission to " + grantUri);
7240 // First... there is no target package, so can anyone access it?
7241 boolean allowed = pi.exported;
7242 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7243 if (pi.readPermission != null) {
7247 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7248 if (pi.writePermission != null) {
7257 /* There is a special cross user grant if:
7258 * - The target is on another user.
7259 * - Apps on the current user can access the uri without any uid permissions.
7260 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7261 * grant uri permissions.
7263 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7264 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7265 modeFlags, false /*without considering the uid permissions*/);
7267 // Second... is the provider allowing granting of URI permissions?
7268 if (!specialCrossUserGrant) {
7269 if (!pi.grantUriPermissions) {
7270 throw new SecurityException("Provider " + pi.packageName
7272 + " does not allow granting of Uri permissions (uri "
7275 if (pi.uriPermissionPatterns != null) {
7276 final int N = pi.uriPermissionPatterns.length;
7277 boolean allowed = false;
7278 for (int i=0; i<N; i++) {
7279 if (pi.uriPermissionPatterns[i] != null
7280 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7286 throw new SecurityException("Provider " + pi.packageName
7288 + " does not allow granting of permission to path of Uri "
7294 // Third... does the caller itself have permission to access
7296 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7297 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7298 // Require they hold a strong enough Uri permission
7299 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7300 throw new SecurityException("Uid " + callingUid
7301 + " does not have permission to uri " + grantUri);
7309 * @param uri This uri must NOT contain an embedded userId.
7310 * @param userId The userId in which the uri is to be resolved.
7313 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7314 final int modeFlags, int userId) {
7315 enforceNotIsolatedCaller("checkGrantUriPermission");
7316 synchronized(this) {
7317 return checkGrantUriPermissionLocked(callingUid, targetPkg,
7318 new GrantUri(userId, uri, false), modeFlags, -1);
7322 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7323 final int modeFlags, UriPermissionOwner owner) {
7324 if (!Intent.isAccessUriMode(modeFlags)) {
7328 // So here we are: the caller has the assumed permission
7329 // to the uri, and the target doesn't. Let's now give this to
7332 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7333 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7335 final String authority = grantUri.uri.getAuthority();
7336 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7338 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7342 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7343 grantUri.prefix = true;
7345 final UriPermission perm = findOrCreateUriPermissionLocked(
7346 pi.packageName, targetPkg, targetUid, grantUri);
7347 perm.grantModes(modeFlags, owner);
7350 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7351 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7352 if (targetPkg == null) {
7353 throw new NullPointerException("targetPkg");
7356 final IPackageManager pm = AppGlobals.getPackageManager();
7358 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7359 } catch (RemoteException ex) {
7363 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7365 if (targetUid < 0) {
7369 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7373 static class NeededUriGrants extends ArrayList<GrantUri> {
7374 final String targetPkg;
7375 final int targetUid;
7378 NeededUriGrants(String targetPkg, int targetUid, int flags) {
7379 this.targetPkg = targetPkg;
7380 this.targetUid = targetUid;
7386 * Like checkGrantUriPermissionLocked, but takes an Intent.
7388 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7389 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7390 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7391 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7392 + " clip=" + (intent != null ? intent.getClipData() : null)
7393 + " from " + intent + "; flags=0x"
7394 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7396 if (targetPkg == null) {
7397 throw new NullPointerException("targetPkg");
7400 if (intent == null) {
7403 Uri data = intent.getData();
7404 ClipData clip = intent.getClipData();
7405 if (data == null && clip == null) {
7408 // Default userId for uris in the intent (if they don't specify it themselves)
7409 int contentUserHint = intent.getContentUserHint();
7410 if (contentUserHint == UserHandle.USER_CURRENT) {
7411 contentUserHint = UserHandle.getUserId(callingUid);
7413 final IPackageManager pm = AppGlobals.getPackageManager();
7415 if (needed != null) {
7416 targetUid = needed.targetUid;
7419 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7420 } catch (RemoteException ex) {
7423 if (targetUid < 0) {
7424 if (DEBUG_URI_PERMISSION) {
7425 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7426 + " on user " + targetUserId);
7432 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7433 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7435 if (targetUid > 0) {
7436 if (needed == null) {
7437 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7439 needed.add(grantUri);
7443 for (int i=0; i<clip.getItemCount(); i++) {
7444 Uri uri = clip.getItemAt(i).getUri();
7446 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7447 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7449 if (targetUid > 0) {
7450 if (needed == null) {
7451 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7453 needed.add(grantUri);
7456 Intent clipIntent = clip.getItemAt(i).getIntent();
7457 if (clipIntent != null) {
7458 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7459 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7460 if (newNeeded != null) {
7472 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7474 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7475 UriPermissionOwner owner) {
7476 if (needed != null) {
7477 for (int i=0; i<needed.size(); i++) {
7478 GrantUri grantUri = needed.get(i);
7479 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7480 grantUri, needed.flags, owner);
7485 void grantUriPermissionFromIntentLocked(int callingUid,
7486 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7487 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7488 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7489 if (needed == null) {
7493 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7497 * @param uri This uri must NOT contain an embedded userId.
7498 * @param userId The userId in which the uri is to be resolved.
7501 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7502 final int modeFlags, int userId) {
7503 enforceNotIsolatedCaller("grantUriPermission");
7504 GrantUri grantUri = new GrantUri(userId, uri, false);
7505 synchronized(this) {
7506 final ProcessRecord r = getRecordForAppLocked(caller);
7508 throw new SecurityException("Unable to find app for caller "
7510 + " when granting permission to uri " + grantUri);
7512 if (targetPkg == null) {
7513 throw new IllegalArgumentException("null target");
7515 if (grantUri == null) {
7516 throw new IllegalArgumentException("null uri");
7519 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7520 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7521 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7522 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7524 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7525 UserHandle.getUserId(r.uid));
7529 void removeUriPermissionIfNeededLocked(UriPermission perm) {
7530 if (perm.modeFlags == 0) {
7531 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7533 if (perms != null) {
7534 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7535 "Removing " + perm.targetUid + " permission to " + perm.uri);
7537 perms.remove(perm.uri);
7538 if (perms.isEmpty()) {
7539 mGrantedUriPermissions.remove(perm.targetUid);
7545 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7546 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7548 final IPackageManager pm = AppGlobals.getPackageManager();
7549 final String authority = grantUri.uri.getAuthority();
7550 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7552 Slog.w(TAG, "No content provider found for permission revoke: "
7553 + grantUri.toSafeString());
7557 // Does the caller have this permission on the URI?
7558 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7559 // If they don't have direct access to the URI, then revoke any
7560 // ownerless URI permissions that have been granted to them.
7561 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7562 if (perms != null) {
7563 boolean persistChanged = false;
7564 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7565 final UriPermission perm = it.next();
7566 if (perm.uri.sourceUserId == grantUri.sourceUserId
7567 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7568 if (DEBUG_URI_PERMISSION)
7569 Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7570 " permission to " + perm.uri);
7571 persistChanged |= perm.revokeModes(
7572 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7573 if (perm.modeFlags == 0) {
7578 if (perms.isEmpty()) {
7579 mGrantedUriPermissions.remove(callingUid);
7581 if (persistChanged) {
7582 schedulePersistUriGrants();
7588 boolean persistChanged = false;
7590 // Go through all of the permissions and remove any that match.
7591 int N = mGrantedUriPermissions.size();
7592 for (int i = 0; i < N; i++) {
7593 final int targetUid = mGrantedUriPermissions.keyAt(i);
7594 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7596 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7597 final UriPermission perm = it.next();
7598 if (perm.uri.sourceUserId == grantUri.sourceUserId
7599 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7600 if (DEBUG_URI_PERMISSION)
7602 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7603 persistChanged |= perm.revokeModes(
7604 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7605 if (perm.modeFlags == 0) {
7611 if (perms.isEmpty()) {
7612 mGrantedUriPermissions.remove(targetUid);
7618 if (persistChanged) {
7619 schedulePersistUriGrants();
7624 * @param uri This uri must NOT contain an embedded userId.
7625 * @param userId The userId in which the uri is to be resolved.
7628 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7630 enforceNotIsolatedCaller("revokeUriPermission");
7631 synchronized(this) {
7632 final ProcessRecord r = getRecordForAppLocked(caller);
7634 throw new SecurityException("Unable to find app for caller "
7636 + " when revoking permission to uri " + uri);
7639 Slog.w(TAG, "revokeUriPermission: null uri");
7643 if (!Intent.isAccessUriMode(modeFlags)) {
7647 final IPackageManager pm = AppGlobals.getPackageManager();
7648 final String authority = uri.getAuthority();
7649 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7651 Slog.w(TAG, "No content provider found for permission revoke: "
7652 + uri.toSafeString());
7656 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7661 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7664 * @param packageName Package name to match, or {@code null} to apply to all
7666 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7668 * @param persistable If persistable grants should be removed.
7670 private void removeUriPermissionsForPackageLocked(
7671 String packageName, int userHandle, boolean persistable) {
7672 if (userHandle == UserHandle.USER_ALL && packageName == null) {
7673 throw new IllegalArgumentException("Must narrow by either package or user");
7676 boolean persistChanged = false;
7678 int N = mGrantedUriPermissions.size();
7679 for (int i = 0; i < N; i++) {
7680 final int targetUid = mGrantedUriPermissions.keyAt(i);
7681 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7683 // Only inspect grants matching user
7684 if (userHandle == UserHandle.USER_ALL
7685 || userHandle == UserHandle.getUserId(targetUid)) {
7686 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7687 final UriPermission perm = it.next();
7689 // Only inspect grants matching package
7690 if (packageName == null || perm.sourcePkg.equals(packageName)
7691 || perm.targetPkg.equals(packageName)) {
7692 persistChanged |= perm.revokeModes(persistable
7693 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7695 // Only remove when no modes remain; any persisted grants
7696 // will keep this alive.
7697 if (perm.modeFlags == 0) {
7703 if (perms.isEmpty()) {
7704 mGrantedUriPermissions.remove(targetUid);
7711 if (persistChanged) {
7712 schedulePersistUriGrants();
7717 public IBinder newUriPermissionOwner(String name) {
7718 enforceNotIsolatedCaller("newUriPermissionOwner");
7719 synchronized(this) {
7720 UriPermissionOwner owner = new UriPermissionOwner(this, name);
7721 return owner.getExternalTokenLocked();
7726 * @param uri This uri must NOT contain an embedded userId.
7727 * @param sourceUserId The userId in which the uri is to be resolved.
7728 * @param targetUserId The userId of the app that receives the grant.
7731 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7732 final int modeFlags, int sourceUserId, int targetUserId) {
7733 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7734 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7735 synchronized(this) {
7736 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7737 if (owner == null) {
7738 throw new IllegalArgumentException("Unknown owner: " + token);
7740 if (fromUid != Binder.getCallingUid()) {
7741 if (Binder.getCallingUid() != Process.myUid()) {
7742 // Only system code can grant URI permissions on behalf
7744 throw new SecurityException("nice try");
7747 if (targetPkg == null) {
7748 throw new IllegalArgumentException("null target");
7751 throw new IllegalArgumentException("null uri");
7754 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7755 modeFlags, owner, targetUserId);
7760 * @param uri This uri must NOT contain an embedded userId.
7761 * @param userId The userId in which the uri is to be resolved.
7764 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7765 synchronized(this) {
7766 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7767 if (owner == null) {
7768 throw new IllegalArgumentException("Unknown owner: " + token);
7772 owner.removeUriPermissionsLocked(mode);
7774 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7779 private void schedulePersistUriGrants() {
7780 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7781 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7782 10 * DateUtils.SECOND_IN_MILLIS);
7786 private void writeGrantedUriPermissions() {
7787 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7789 // Snapshot permissions so we can persist without lock
7790 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7791 synchronized (this) {
7792 final int size = mGrantedUriPermissions.size();
7793 for (int i = 0; i < size; i++) {
7794 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7795 for (UriPermission perm : perms.values()) {
7796 if (perm.persistedModeFlags != 0) {
7797 persist.add(perm.snapshot());
7803 FileOutputStream fos = null;
7805 fos = mGrantFile.startWrite();
7807 XmlSerializer out = new FastXmlSerializer();
7808 out.setOutput(fos, "utf-8");
7809 out.startDocument(null, true);
7810 out.startTag(null, TAG_URI_GRANTS);
7811 for (UriPermission.Snapshot perm : persist) {
7812 out.startTag(null, TAG_URI_GRANT);
7813 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7814 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7815 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7816 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7817 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7818 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7819 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7820 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7821 out.endTag(null, TAG_URI_GRANT);
7823 out.endTag(null, TAG_URI_GRANTS);
7826 mGrantFile.finishWrite(fos);
7827 } catch (IOException e) {
7829 mGrantFile.failWrite(fos);
7834 private void readGrantedUriPermissionsLocked() {
7835 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7837 final long now = System.currentTimeMillis();
7839 FileInputStream fis = null;
7841 fis = mGrantFile.openRead();
7842 final XmlPullParser in = Xml.newPullParser();
7843 in.setInput(fis, null);
7846 while ((type = in.next()) != END_DOCUMENT) {
7847 final String tag = in.getName();
7848 if (type == START_TAG) {
7849 if (TAG_URI_GRANT.equals(tag)) {
7850 final int sourceUserId;
7851 final int targetUserId;
7852 final int userHandle = readIntAttribute(in,
7853 ATTR_USER_HANDLE, UserHandle.USER_NULL);
7854 if (userHandle != UserHandle.USER_NULL) {
7855 // For backwards compatibility.
7856 sourceUserId = userHandle;
7857 targetUserId = userHandle;
7859 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7860 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7862 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7863 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7864 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7865 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7866 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7867 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7869 // Sanity check that provider still belongs to source package
7870 final ProviderInfo pi = getProviderInfoLocked(
7871 uri.getAuthority(), sourceUserId);
7872 if (pi != null && sourcePkg.equals(pi.packageName)) {
7875 targetUid = AppGlobals.getPackageManager()
7876 .getPackageUid(targetPkg, targetUserId);
7877 } catch (RemoteException e) {
7879 if (targetUid != -1) {
7880 final UriPermission perm = findOrCreateUriPermissionLocked(
7881 sourcePkg, targetPkg, targetUid,
7882 new GrantUri(sourceUserId, uri, prefix));
7883 perm.initPersistedModes(modeFlags, createdTime);
7886 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7887 + " but instead found " + pi);
7892 } catch (FileNotFoundException e) {
7893 // Missing grants is okay
7894 } catch (IOException e) {
7895 Slog.wtf(TAG, "Failed reading Uri grants", e);
7896 } catch (XmlPullParserException e) {
7897 Slog.wtf(TAG, "Failed reading Uri grants", e);
7899 IoUtils.closeQuietly(fis);
7904 * @param uri This uri must NOT contain an embedded userId.
7905 * @param userId The userId in which the uri is to be resolved.
7908 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7909 enforceNotIsolatedCaller("takePersistableUriPermission");
7911 Preconditions.checkFlagsArgument(modeFlags,
7912 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7914 synchronized (this) {
7915 final int callingUid = Binder.getCallingUid();
7916 boolean persistChanged = false;
7917 GrantUri grantUri = new GrantUri(userId, uri, false);
7919 UriPermission exactPerm = findUriPermissionLocked(callingUid,
7920 new GrantUri(userId, uri, false));
7921 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7922 new GrantUri(userId, uri, true));
7924 final boolean exactValid = (exactPerm != null)
7925 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7926 final boolean prefixValid = (prefixPerm != null)
7927 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7929 if (!(exactValid || prefixValid)) {
7930 throw new SecurityException("No persistable permission grants found for UID "
7931 + callingUid + " and Uri " + grantUri.toSafeString());
7935 persistChanged |= exactPerm.takePersistableModes(modeFlags);
7938 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7941 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7943 if (persistChanged) {
7944 schedulePersistUriGrants();
7950 * @param uri This uri must NOT contain an embedded userId.
7951 * @param userId The userId in which the uri is to be resolved.
7954 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7955 enforceNotIsolatedCaller("releasePersistableUriPermission");
7957 Preconditions.checkFlagsArgument(modeFlags,
7958 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7960 synchronized (this) {
7961 final int callingUid = Binder.getCallingUid();
7962 boolean persistChanged = false;
7964 UriPermission exactPerm = findUriPermissionLocked(callingUid,
7965 new GrantUri(userId, uri, false));
7966 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7967 new GrantUri(userId, uri, true));
7968 if (exactPerm == null && prefixPerm == null) {
7969 throw new SecurityException("No permission grants found for UID " + callingUid
7970 + " and Uri " + uri.toSafeString());
7973 if (exactPerm != null) {
7974 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7975 removeUriPermissionIfNeededLocked(exactPerm);
7977 if (prefixPerm != null) {
7978 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7979 removeUriPermissionIfNeededLocked(prefixPerm);
7982 if (persistChanged) {
7983 schedulePersistUriGrants();
7989 * Prune any older {@link UriPermission} for the given UID until outstanding
7990 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7992 * @return if any mutations occured that require persisting.
7994 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7995 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7996 if (perms == null) return false;
7997 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7999 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8000 for (UriPermission perm : perms.values()) {
8001 if (perm.persistedModeFlags != 0) {
8002 persisted.add(perm);
8006 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8007 if (trimCount <= 0) return false;
8009 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8010 for (int i = 0; i < trimCount; i++) {
8011 final UriPermission perm = persisted.get(i);
8013 if (DEBUG_URI_PERMISSION) {
8014 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8017 perm.releasePersistableModes(~0);
8018 removeUriPermissionIfNeededLocked(perm);
8025 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8026 String packageName, boolean incoming) {
8027 enforceNotIsolatedCaller("getPersistedUriPermissions");
8028 Preconditions.checkNotNull(packageName, "packageName");
8030 final int callingUid = Binder.getCallingUid();
8031 final IPackageManager pm = AppGlobals.getPackageManager();
8033 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8034 if (packageUid != callingUid) {
8035 throw new SecurityException(
8036 "Package " + packageName + " does not belong to calling UID " + callingUid);
8038 } catch (RemoteException e) {
8039 throw new SecurityException("Failed to verify package name ownership");
8042 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8043 synchronized (this) {
8045 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8047 if (perms == null) {
8048 Slog.w(TAG, "No permission grants found for " + packageName);
8050 for (UriPermission perm : perms.values()) {
8051 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8052 result.add(perm.buildPersistedPublicApiObject());
8057 final int size = mGrantedUriPermissions.size();
8058 for (int i = 0; i < size; i++) {
8059 final ArrayMap<GrantUri, UriPermission> perms =
8060 mGrantedUriPermissions.valueAt(i);
8061 for (UriPermission perm : perms.values()) {
8062 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8063 result.add(perm.buildPersistedPublicApiObject());
8069 return new ParceledListSlice<android.content.UriPermission>(result);
8073 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8074 synchronized (this) {
8076 who != null ? getRecordForAppLocked(who) : null;
8077 if (app == null) return;
8079 Message msg = Message.obtain();
8080 msg.what = WAIT_FOR_DEBUGGER_MSG;
8082 msg.arg1 = waiting ? 1 : 0;
8083 mUiHandler.sendMessage(msg);
8088 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8089 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8090 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8091 outInfo.availMem = Process.getFreeMemory();
8092 outInfo.totalMem = Process.getTotalMemory();
8093 outInfo.threshold = homeAppMem;
8094 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8095 outInfo.hiddenAppThreshold = cachedAppMem;
8096 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8097 ProcessList.SERVICE_ADJ);
8098 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8099 ProcessList.VISIBLE_APP_ADJ);
8100 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8101 ProcessList.FOREGROUND_APP_ADJ);
8104 // =========================================================
8106 // =========================================================
8109 public List<IAppTask> getAppTasks(String callingPackage) {
8110 int callingUid = Binder.getCallingUid();
8111 long ident = Binder.clearCallingIdentity();
8113 synchronized(this) {
8114 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8116 if (localLOGV) Slog.v(TAG, "getAppTasks");
8118 final int N = mRecentTasks.size();
8119 for (int i = 0; i < N; i++) {
8120 TaskRecord tr = mRecentTasks.get(i);
8121 // Skip tasks that do not match the caller. We don't need to verify
8122 // callingPackage, because we are also limiting to callingUid and know
8123 // that will limit to the correct security sandbox.
8124 if (tr.effectiveUid != callingUid) {
8127 Intent intent = tr.getBaseIntent();
8128 if (intent == null ||
8129 !callingPackage.equals(intent.getComponent().getPackageName())) {
8132 ActivityManager.RecentTaskInfo taskInfo =
8133 createRecentTaskInfoFromTaskRecord(tr);
8134 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8138 Binder.restoreCallingIdentity(ident);
8145 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8146 final int callingUid = Binder.getCallingUid();
8147 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8149 synchronized(this) {
8150 if (localLOGV) Slog.v(
8151 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8153 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8156 // TODO: Improve with MRU list from all ActivityStacks.
8157 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8164 * Creates a new RecentTaskInfo from a TaskRecord.
8166 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8167 // Update the task description to reflect any changes in the task stack
8168 tr.updateTaskDescription();
8170 // Compose the recent task info
8171 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8172 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8173 rti.persistentId = tr.taskId;
8174 rti.baseIntent = new Intent(tr.getBaseIntent());
8175 rti.origActivity = tr.origActivity;
8176 rti.description = tr.lastDescription;
8177 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8178 rti.userId = tr.userId;
8179 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8180 rti.firstActiveTime = tr.firstActiveTime;
8181 rti.lastActiveTime = tr.lastActiveTime;
8182 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8183 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8187 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8188 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8189 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8191 if (checkPermission(android.Manifest.permission.GET_TASKS,
8192 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8193 // Temporary compatibility: some existing apps on the system image may
8194 // still be requesting the old permission and not switched to the new
8195 // one; if so, we'll still allow them full access. This means we need
8196 // to see if they are holding the old permission and are a system app.
8198 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8200 Slog.w(TAG, caller + ": caller " + callingUid
8201 + " is using old GET_TASKS but privileged; allowing");
8203 } catch (RemoteException e) {
8208 Slog.w(TAG, caller + ": caller " + callingUid
8209 + " does not hold REAL_GET_TASKS; limiting output");
8215 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8216 final int callingUid = Binder.getCallingUid();
8217 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8218 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8220 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8221 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8222 synchronized (this) {
8223 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8225 final boolean detailed = checkCallingPermission(
8226 android.Manifest.permission.GET_DETAILED_TASKS)
8227 == PackageManager.PERMISSION_GRANTED;
8229 final int N = mRecentTasks.size();
8230 ArrayList<ActivityManager.RecentTaskInfo> res
8231 = new ArrayList<ActivityManager.RecentTaskInfo>(
8232 maxNum < N ? maxNum : N);
8234 final Set<Integer> includedUsers;
8235 if (includeProfiles) {
8236 includedUsers = getProfileIdsLocked(userId);
8238 includedUsers = new HashSet<Integer>();
8240 includedUsers.add(Integer.valueOf(userId));
8242 for (int i=0; i<N && maxNum > 0; i++) {
8243 TaskRecord tr = mRecentTasks.get(i);
8244 // Only add calling user or related users recent tasks
8245 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8246 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8250 // Return the entry if desired by the caller. We always return
8251 // the first entry, because callers always expect this to be the
8252 // foreground app. We may filter others if the caller has
8253 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8254 // we should exclude the entry.
8258 || (tr.intent == null)
8259 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8262 // If the caller doesn't have the GET_TASKS permission, then only
8263 // allow them to see a small subset of tasks -- their own and home.
8264 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8265 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8269 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8270 if (tr.stack != null && tr.stack.isHomeStack()) {
8271 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8275 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8276 // Don't include auto remove tasks that are finished or finishing.
8277 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8281 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8282 && !tr.isAvailable) {
8283 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8287 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8289 rti.baseIntent.replaceExtras((Bundle)null);
8300 TaskRecord recentTaskForIdLocked(int id) {
8301 final int N = mRecentTasks.size();
8302 for (int i=0; i<N; i++) {
8303 TaskRecord tr = mRecentTasks.get(i);
8304 if (tr.taskId == id) {
8312 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8313 synchronized (this) {
8314 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8315 "getTaskThumbnail()");
8316 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8318 return tr.getTaskThumbnailLocked();
8325 public int addAppTask(IBinder activityToken, Intent intent,
8326 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8327 final int callingUid = Binder.getCallingUid();
8328 final long callingIdent = Binder.clearCallingIdentity();
8331 synchronized (this) {
8332 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8334 throw new IllegalArgumentException("Activity does not exist; token="
8337 ComponentName comp = intent.getComponent();
8339 throw new IllegalArgumentException("Intent " + intent
8340 + " must specify explicit component");
8342 if (thumbnail.getWidth() != mThumbnailWidth
8343 || thumbnail.getHeight() != mThumbnailHeight) {
8344 throw new IllegalArgumentException("Bad thumbnail size: got "
8345 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8346 + mThumbnailWidth + "x" + mThumbnailHeight);
8348 if (intent.getSelector() != null) {
8349 intent.setSelector(null);
8351 if (intent.getSourceBounds() != null) {
8352 intent.setSourceBounds(null);
8354 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8355 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8356 // The caller has added this as an auto-remove task... that makes no
8357 // sense, so turn off auto-remove.
8358 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8360 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8361 // Must be a new task.
8362 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8364 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8365 mLastAddedTaskActivity = null;
8367 ActivityInfo ainfo = mLastAddedTaskActivity;
8368 if (ainfo == null) {
8369 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8370 comp, 0, UserHandle.getUserId(callingUid));
8371 if (ainfo.applicationInfo.uid != callingUid) {
8372 throw new SecurityException(
8373 "Can't add task for another application: target uid="
8374 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8378 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8379 intent, description);
8381 int trimIdx = trimRecentsForTaskLocked(task, false);
8383 // If this would have caused a trim, then we'll abort because that
8384 // means it would be added at the end of the list but then just removed.
8385 return INVALID_TASK_ID;
8388 final int N = mRecentTasks.size();
8389 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8390 final TaskRecord tr = mRecentTasks.remove(N - 1);
8391 tr.removedFromRecents();
8394 task.inRecents = true;
8395 mRecentTasks.add(task);
8396 r.task.stack.addTask(task, false, false);
8398 task.setLastThumbnail(thumbnail);
8399 task.freeLastThumbnail();
8404 Binder.restoreCallingIdentity(callingIdent);
8409 public Point getAppTaskThumbnailSize() {
8410 synchronized (this) {
8411 return new Point(mThumbnailWidth, mThumbnailHeight);
8416 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8417 synchronized (this) {
8418 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8420 r.setTaskDescription(td);
8421 r.task.updateTaskDescription();
8427 public Bitmap getTaskDescriptionIcon(String filename) {
8428 if (!FileUtils.isValidExtFilename(filename)
8429 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8430 throw new IllegalArgumentException("Bad filename: " + filename);
8432 return mTaskPersister.getTaskDescriptionIcon(filename);
8436 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8437 throws RemoteException {
8438 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8439 opts.getCustomInPlaceResId() == 0) {
8440 throw new IllegalArgumentException("Expected in-place ActivityOption " +
8441 "with valid animation");
8443 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8444 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8445 opts.getCustomInPlaceResId());
8446 mWindowManager.executeAppTransition();
8449 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8450 mRecentTasks.remove(tr);
8451 tr.removedFromRecents();
8452 ComponentName component = tr.getBaseIntent().getComponent();
8453 if (component == null) {
8454 Slog.w(TAG, "No component for base intent of task: " + tr);
8462 // Determine if the process(es) for this task should be killed.
8463 final String pkg = component.getPackageName();
8464 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8465 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8466 for (int i = 0; i < pmap.size(); i++) {
8468 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8469 for (int j = 0; j < uids.size(); j++) {
8470 ProcessRecord proc = uids.valueAt(j);
8471 if (proc.userId != tr.userId) {
8472 // Don't kill process for a different user.
8475 if (proc == mHomeProcess) {
8476 // Don't kill the home process along with tasks from the same package.
8479 if (!proc.pkgList.containsKey(pkg)) {
8480 // Don't kill process that is not associated with this task.
8484 for (int k = 0; k < proc.activities.size(); k++) {
8485 TaskRecord otherTask = proc.activities.get(k).task;
8486 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8487 // Don't kill process(es) that has an activity in a different task that is
8493 // Add process to kill list.
8494 procsToKill.add(proc);
8498 // Find any running services associated with this app and stop if needed.
8499 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8501 // Kill the running processes.
8502 for (int i = 0; i < procsToKill.size(); i++) {
8503 ProcessRecord pr = procsToKill.get(i);
8504 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8505 pr.kill("remove task", true);
8507 pr.waitingToKill = "remove task";
8512 private void removeTasksByPackageNameLocked(String packageName, int userId) {
8513 // Remove all tasks with activities in the specified package from the list of recent tasks
8514 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8515 TaskRecord tr = mRecentTasks.get(i);
8516 if (tr.userId != userId) continue;
8518 ComponentName cn = tr.intent.getComponent();
8519 if (cn != null && cn.getPackageName().equals(packageName)) {
8520 // If the package name matches, remove the task.
8521 removeTaskByIdLocked(tr.taskId, true);
8526 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8527 final IPackageManager pm = AppGlobals.getPackageManager();
8528 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8530 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8531 TaskRecord tr = mRecentTasks.get(i);
8532 if (tr.userId != userId) continue;
8534 ComponentName cn = tr.intent.getComponent();
8535 if (cn != null && cn.getPackageName().equals(packageName)) {
8536 // Skip if component still exists in the package.
8537 if (componentsKnownToExist.contains(cn)) continue;
8540 ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8542 componentsKnownToExist.add(cn);
8544 removeTaskByIdLocked(tr.taskId, false);
8546 } catch (RemoteException e) {
8547 Log.e(TAG, "Activity info query failed. component=" + cn, e);
8554 * Removes the task with the specified task id.
8556 * @param taskId Identifier of the task to be removed.
8557 * @param killProcess Kill any process associated with the task if possible.
8558 * @return Returns true if the given task was found and removed.
8560 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8561 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8563 tr.removeTaskActivitiesLocked();
8564 cleanUpRemovedTaskLocked(tr, killProcess);
8565 if (tr.isPersistable) {
8566 notifyTaskPersisterLocked(null, true);
8570 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8575 public boolean removeTask(int taskId) {
8576 synchronized (this) {
8577 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8579 long ident = Binder.clearCallingIdentity();
8581 return removeTaskByIdLocked(taskId, true);
8583 Binder.restoreCallingIdentity(ident);
8589 * TODO: Add mController hook
8592 public void moveTaskToFront(int taskId, int flags, Bundle options) {
8593 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8594 "moveTaskToFront()");
8596 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8597 synchronized(this) {
8598 moveTaskToFrontLocked(taskId, flags, options);
8602 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8603 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8604 Binder.getCallingUid(), -1, -1, "Task to front")) {
8605 ActivityOptions.abort(options);
8608 final long origId = Binder.clearCallingIdentity();
8610 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8612 Slog.d(TAG, "Could not find task for id: "+ taskId);
8615 if (mStackSupervisor.isLockTaskModeViolation(task)) {
8616 mStackSupervisor.showLockTaskToast();
8617 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8620 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8621 if (prev != null && prev.isRecentsActivity()) {
8622 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8624 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8626 Binder.restoreCallingIdentity(origId);
8628 ActivityOptions.abort(options);
8632 public void moveTaskToBack(int taskId) {
8633 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8634 "moveTaskToBack()");
8636 synchronized(this) {
8637 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8639 if (tr == mStackSupervisor.mLockTaskModeTask) {
8640 mStackSupervisor.showLockTaskToast();
8643 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8644 ActivityStack stack = tr.stack;
8645 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8646 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8647 Binder.getCallingUid(), -1, -1, "Task to back")) {
8651 final long origId = Binder.clearCallingIdentity();
8653 stack.moveTaskToBackLocked(taskId);
8655 Binder.restoreCallingIdentity(origId);
8662 * Moves an activity, and all of the other activities within the same task, to the bottom
8663 * of the history stack. The activity's order within the task is unchanged.
8665 * @param token A reference to the activity we wish to move
8666 * @param nonRoot If false then this only works if the activity is the root
8667 * of a task; if true it will work for any activity in a task.
8668 * @return Returns true if the move completed, false if not.
8671 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8672 enforceNotIsolatedCaller("moveActivityTaskToBack");
8673 synchronized(this) {
8674 final long origId = Binder.clearCallingIdentity();
8676 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8678 if ((mStackSupervisor.mLockTaskModeTask != null)
8679 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8680 mStackSupervisor.showLockTaskToast();
8683 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8686 Binder.restoreCallingIdentity(origId);
8693 public void moveTaskBackwards(int task) {
8694 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8695 "moveTaskBackwards()");
8697 synchronized(this) {
8698 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8699 Binder.getCallingUid(), -1, -1, "Task backwards")) {
8702 final long origId = Binder.clearCallingIdentity();
8703 moveTaskBackwardsLocked(task);
8704 Binder.restoreCallingIdentity(origId);
8708 private final void moveTaskBackwardsLocked(int task) {
8709 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8713 public IBinder getHomeActivityToken() throws RemoteException {
8714 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8715 "getHomeActivityToken()");
8716 synchronized (this) {
8717 return mStackSupervisor.getHomeActivityToken();
8722 public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8723 IActivityContainerCallback callback) throws RemoteException {
8724 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8725 "createActivityContainer()");
8726 synchronized (this) {
8727 if (parentActivityToken == null) {
8728 throw new IllegalArgumentException("parent token must not be null");
8730 ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8734 if (callback == null) {
8735 throw new IllegalArgumentException("callback must not be null");
8737 return mStackSupervisor.createActivityContainer(r, callback);
8742 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8743 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8744 "deleteActivityContainer()");
8745 synchronized (this) {
8746 mStackSupervisor.deleteActivityContainer(container);
8751 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8752 synchronized (this) {
8753 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8754 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8755 return stack.mActivityContainer.getDisplayId();
8757 return Display.DEFAULT_DISPLAY;
8762 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8763 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8764 "moveTaskToStack()");
8765 if (stackId == HOME_STACK_ID) {
8766 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8767 new RuntimeException("here").fillInStackTrace());
8769 synchronized (this) {
8770 long ident = Binder.clearCallingIdentity();
8772 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8773 + stackId + " toTop=" + toTop);
8774 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8776 Binder.restoreCallingIdentity(ident);
8782 public void resizeStack(int stackBoxId, Rect bounds) {
8783 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8784 "resizeStackBox()");
8785 long ident = Binder.clearCallingIdentity();
8787 mWindowManager.resizeStack(stackBoxId, bounds);
8789 Binder.restoreCallingIdentity(ident);
8794 public List<StackInfo> getAllStackInfos() {
8795 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8796 "getAllStackInfos()");
8797 long ident = Binder.clearCallingIdentity();
8799 synchronized (this) {
8800 return mStackSupervisor.getAllStackInfosLocked();
8803 Binder.restoreCallingIdentity(ident);
8808 public StackInfo getStackInfo(int stackId) {
8809 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8811 long ident = Binder.clearCallingIdentity();
8813 synchronized (this) {
8814 return mStackSupervisor.getStackInfoLocked(stackId);
8817 Binder.restoreCallingIdentity(ident);
8822 public boolean isInHomeStack(int taskId) {
8823 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8825 long ident = Binder.clearCallingIdentity();
8827 synchronized (this) {
8828 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8829 return tr != null && tr.stack != null && tr.stack.isHomeStack();
8832 Binder.restoreCallingIdentity(ident);
8837 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8838 synchronized(this) {
8839 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8843 private boolean isLockTaskAuthorized(String pkg) {
8844 final DevicePolicyManager dpm = (DevicePolicyManager)
8845 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8847 int uid = mContext.getPackageManager().getPackageUid(pkg,
8848 Binder.getCallingUserHandle().getIdentifier());
8849 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8850 } catch (NameNotFoundException e) {
8855 void startLockTaskMode(TaskRecord task) {
8857 synchronized (this) {
8858 pkg = task.intent.getComponent().getPackageName();
8860 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8861 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8862 StatusBarManagerInternal statusBarManager = LocalServices.getService(
8863 StatusBarManagerInternal.class);
8864 if (statusBarManager != null) {
8865 statusBarManager.showScreenPinningRequest();
8869 long ident = Binder.clearCallingIdentity();
8871 synchronized (this) {
8872 // Since we lost lock on task, make sure it is still there.
8873 task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8875 if (!isSystemInitiated
8876 && ((mStackSupervisor.getFocusedStack() == null)
8877 || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8878 throw new IllegalArgumentException("Invalid task, not in foreground");
8880 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
8885 Binder.restoreCallingIdentity(ident);
8890 public void startLockTaskMode(int taskId) {
8891 final TaskRecord task;
8892 long ident = Binder.clearCallingIdentity();
8894 synchronized (this) {
8895 task = mStackSupervisor.anyTaskForIdLocked(taskId);
8898 Binder.restoreCallingIdentity(ident);
8901 startLockTaskMode(task);
8906 public void startLockTaskMode(IBinder token) {
8907 final TaskRecord task;
8908 long ident = Binder.clearCallingIdentity();
8910 synchronized (this) {
8911 final ActivityRecord r = ActivityRecord.forToken(token);
8918 Binder.restoreCallingIdentity(ident);
8921 startLockTaskMode(task);
8926 public void startLockTaskModeOnCurrent() throws RemoteException {
8927 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8928 "startLockTaskModeOnCurrent");
8929 long ident = Binder.clearCallingIdentity();
8931 ActivityRecord r = null;
8932 synchronized (this) {
8933 r = mStackSupervisor.topRunningActivityLocked();
8935 startLockTaskMode(r.task);
8937 Binder.restoreCallingIdentity(ident);
8942 public void stopLockTaskMode() {
8943 // Verify that the user matches the package of the intent for the TaskRecord
8944 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode
8945 // and stopLockTaskMode.
8946 final int callingUid = Binder.getCallingUid();
8947 if (callingUid != Process.SYSTEM_UID) {
8950 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8951 int uid = mContext.getPackageManager().getPackageUid(pkg,
8952 Binder.getCallingUserHandle().getIdentifier());
8953 if (uid != callingUid) {
8954 throw new SecurityException("Invalid uid, expected " + uid);
8956 } catch (NameNotFoundException e) {
8957 Log.d(TAG, "stopLockTaskMode " + e);
8961 long ident = Binder.clearCallingIdentity();
8963 Log.d(TAG, "stopLockTaskMode");
8965 synchronized (this) {
8966 mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
8969 Binder.restoreCallingIdentity(ident);
8974 public void stopLockTaskModeOnCurrent() throws RemoteException {
8975 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8976 "stopLockTaskModeOnCurrent");
8977 long ident = Binder.clearCallingIdentity();
8981 Binder.restoreCallingIdentity(ident);
8986 public boolean isInLockTaskMode() {
8987 synchronized (this) {
8988 return mStackSupervisor.isInLockTaskMode();
8992 // =========================================================
8993 // CONTENT PROVIDERS
8994 // =========================================================
8996 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8997 List<ProviderInfo> providers = null;
8999 providers = AppGlobals.getPackageManager().
9000 queryContentProviders(app.processName, app.uid,
9001 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9002 } catch (RemoteException ex) {
9005 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9006 int userId = app.userId;
9007 if (providers != null) {
9008 int N = providers.size();
9009 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9010 for (int i=0; i<N; i++) {
9012 (ProviderInfo)providers.get(i);
9013 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9014 cpi.name, cpi.flags);
9015 if (singleton && UserHandle.getUserId(app.uid) != 0) {
9016 // This is a singleton provider, but a user besides the
9017 // default user is asking to initialize a process it runs
9018 // in... well, no, it doesn't actually run in this process,
9019 // it runs in the process of the default user. Get rid of it.
9020 providers.remove(i);
9026 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9027 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9029 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9030 mProviderMap.putProviderByClass(comp, cpr);
9033 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9034 app.pubProviders.put(cpi.name, cpr);
9035 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9036 // Don't add this if it is a platform component that is marked
9037 // to run in multiple processes, because this is actually
9038 // part of the framework so doesn't make sense to track as a
9039 // separate apk in the process.
9040 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9043 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9050 * Check if {@link ProcessRecord} has a possible chance at accessing the
9051 * given {@link ProviderInfo}. Final permission checking is always done
9052 * in {@link ContentProvider}.
9054 private final String checkContentProviderPermissionLocked(
9055 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9056 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9057 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9058 boolean checkedGrants = false;
9060 // Looking for cross-user grants before enforcing the typical cross-users permissions
9061 int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9062 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9063 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9066 checkedGrants = true;
9068 userId = handleIncomingUser(callingPid, callingUid, userId,
9069 false, ALLOW_NON_FULL,
9070 "checkContentProviderPermissionLocked " + cpi.authority, null);
9071 if (userId != tmpTargetUserId) {
9072 // When we actually went to determine the final targer user ID, this ended
9073 // up different than our initial check for the authority. This is because
9074 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9075 // SELF. So we need to re-check the grants again.
9076 checkedGrants = false;
9079 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9080 cpi.applicationInfo.uid, cpi.exported)
9081 == PackageManager.PERMISSION_GRANTED) {
9084 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9085 cpi.applicationInfo.uid, cpi.exported)
9086 == PackageManager.PERMISSION_GRANTED) {
9090 PathPermission[] pps = cpi.pathPermissions;
9095 PathPermission pp = pps[i];
9096 String pprperm = pp.getReadPermission();
9097 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9098 cpi.applicationInfo.uid, cpi.exported)
9099 == PackageManager.PERMISSION_GRANTED) {
9102 String ppwperm = pp.getWritePermission();
9103 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9104 cpi.applicationInfo.uid, cpi.exported)
9105 == PackageManager.PERMISSION_GRANTED) {
9110 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9115 if (!cpi.exported) {
9116 msg = "Permission Denial: opening provider " + cpi.name
9117 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9118 + ", uid=" + callingUid + ") that is not exported from uid "
9119 + cpi.applicationInfo.uid;
9121 msg = "Permission Denial: opening provider " + cpi.name
9122 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9123 + ", uid=" + callingUid + ") requires "
9124 + cpi.readPermission + " or " + cpi.writePermission;
9131 * Returns if the ContentProvider has granted a uri to callingUid
9133 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9134 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9135 if (perms != null) {
9136 for (int i=perms.size()-1; i>=0; i--) {
9137 GrantUri grantUri = perms.keyAt(i);
9138 if (grantUri.sourceUserId == userId || !checkUser) {
9139 if (matchesProvider(grantUri.uri, cpi)) {
9149 * Returns true if the uri authority is one of the authorities specified in the provider.
9151 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9152 String uriAuth = uri.getAuthority();
9153 String cpiAuth = cpi.authority;
9154 if (cpiAuth.indexOf(';') == -1) {
9155 return cpiAuth.equals(uriAuth);
9157 String[] cpiAuths = cpiAuth.split(";");
9158 int length = cpiAuths.length;
9159 for (int i = 0; i < length; i++) {
9160 if (cpiAuths[i].equals(uriAuth)) return true;
9165 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9166 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9168 for (int i=0; i<r.conProviders.size(); i++) {
9169 ContentProviderConnection conn = r.conProviders.get(i);
9170 if (conn.provider == cpr) {
9171 if (DEBUG_PROVIDER) Slog.v(TAG,
9172 "Adding provider requested by "
9173 + r.processName + " from process "
9174 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9175 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9178 conn.numStableIncs++;
9180 conn.unstableCount++;
9181 conn.numUnstableIncs++;
9186 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9188 conn.stableCount = 1;
9189 conn.numStableIncs = 1;
9191 conn.unstableCount = 1;
9192 conn.numUnstableIncs = 1;
9194 cpr.connections.add(conn);
9195 r.conProviders.add(conn);
9196 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9199 cpr.addExternalProcessHandleLocked(externalProcessToken);
9203 boolean decProviderCountLocked(ContentProviderConnection conn,
9204 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9206 cpr = conn.provider;
9207 if (DEBUG_PROVIDER) Slog.v(TAG,
9208 "Removing provider requested by "
9209 + conn.client.processName + " from process "
9210 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9211 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9215 conn.unstableCount--;
9217 if (conn.stableCount == 0 && conn.unstableCount == 0) {
9218 cpr.connections.remove(conn);
9219 conn.client.conProviders.remove(conn);
9220 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9225 cpr.removeExternalProcessHandleLocked(externalProcessToken);
9229 private void checkTime(long startTime, String where) {
9230 long now = SystemClock.elapsedRealtime();
9231 if ((now-startTime) > 1000) {
9232 // If we are taking more than a second, log about it.
9233 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9237 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9238 String name, IBinder token, boolean stable, int userId) {
9239 ContentProviderRecord cpr;
9240 ContentProviderConnection conn = null;
9241 ProviderInfo cpi = null;
9243 synchronized(this) {
9244 long startTime = SystemClock.elapsedRealtime();
9246 ProcessRecord r = null;
9247 if (caller != null) {
9248 r = getRecordForAppLocked(caller);
9250 throw new SecurityException(
9251 "Unable to find app for caller " + caller
9252 + " (pid=" + Binder.getCallingPid()
9253 + ") when getting content provider " + name);
9257 boolean checkCrossUser = true;
9259 checkTime(startTime, "getContentProviderImpl: getProviderByName");
9261 // First check if this content provider has been published...
9262 cpr = mProviderMap.getProviderByName(name, userId);
9263 // If that didn't work, check if it exists for user 0 and then
9264 // verify that it's a singleton provider before using it.
9265 if (cpr == null && userId != UserHandle.USER_OWNER) {
9266 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9269 if (isSingleton(cpi.processName, cpi.applicationInfo,
9270 cpi.name, cpi.flags)
9271 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9272 userId = UserHandle.USER_OWNER;
9273 checkCrossUser = false;
9281 boolean providerRunning = cpr != null;
9282 if (providerRunning) {
9285 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9286 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9288 throw new SecurityException(msg);
9290 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9292 if (r != null && cpr.canRunHere(r)) {
9293 // This provider has been published or is in the process
9294 // of being published... but it is also allowed to run
9295 // in the caller's process, so don't make a connection
9296 // and just let the caller instantiate its own instance.
9297 ContentProviderHolder holder = cpr.newHolder(null);
9298 // don't give caller the provider object, it needs
9300 holder.provider = null;
9304 final long origId = Binder.clearCallingIdentity();
9306 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9308 // In this case the provider instance already exists, so we can
9309 // return it right away.
9310 conn = incProviderCountLocked(r, cpr, token, stable);
9311 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9312 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9313 // If this is a perceptible app accessing the provider,
9314 // make sure to count it as being accessed and thus
9315 // back up on the LRU list. This is good because
9316 // content providers are often expensive to start.
9317 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9318 updateLruProcessLocked(cpr.proc, false, null);
9319 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9323 if (cpr.proc != null) {
9325 if (cpr.name.flattenToShortString().equals(
9326 "com.android.providers.calendar/.CalendarProvider2")) {
9327 Slog.v(TAG, "****************** KILLING "
9328 + cpr.name.flattenToShortString());
9329 Process.killProcess(cpr.proc.pid);
9332 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9333 boolean success = updateOomAdjLocked(cpr.proc);
9334 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9335 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9336 // NOTE: there is still a race here where a signal could be
9337 // pending on the process even though we managed to update its
9338 // adj level. Not sure what to do about this, but at least
9339 // the race is now smaller.
9341 // Uh oh... it looks like the provider's process
9342 // has been killed on us. We need to wait for a new
9343 // process to be started, and make sure its death
9344 // doesn't kill our process.
9346 "Existing provider " + cpr.name.flattenToShortString()
9347 + " is crashing; detaching " + r);
9348 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9349 checkTime(startTime, "getContentProviderImpl: before appDied");
9350 appDiedLocked(cpr.proc);
9351 checkTime(startTime, "getContentProviderImpl: after appDied");
9353 // This wasn't the last ref our process had on
9354 // the provider... we have now been killed, bail.
9357 providerRunning = false;
9362 Binder.restoreCallingIdentity(origId);
9366 if (!providerRunning) {
9368 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9369 cpi = AppGlobals.getPackageManager().
9370 resolveContentProvider(name,
9371 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9372 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9373 } catch (RemoteException ex) {
9378 // If the provider is a singleton AND
9379 // (it's a call within the same user || the provider is a
9381 // Then allow connecting to the singleton provider
9382 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9383 cpi.name, cpi.flags)
9384 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9386 userId = UserHandle.USER_OWNER;
9388 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9389 checkTime(startTime, "getContentProviderImpl: got app info for user");
9392 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9393 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9395 throw new SecurityException(msg);
9397 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9399 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9400 && !cpi.processName.equals("system")) {
9401 // If this content provider does not run in the system
9402 // process, and the system is not yet ready to run other
9403 // processes, then fail fast instead of hanging.
9404 throw new IllegalArgumentException(
9405 "Attempt to launch content provider before system ready");
9408 // Make sure that the user who owns this provider is running. If not,
9409 // we don't want to allow it to run.
9410 if (!isUserRunningLocked(userId, false)) {
9411 Slog.w(TAG, "Unable to launch app "
9412 + cpi.applicationInfo.packageName + "/"
9413 + cpi.applicationInfo.uid + " for provider "
9414 + name + ": user " + userId + " is stopped");
9418 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9419 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9420 cpr = mProviderMap.getProviderByClass(comp, userId);
9421 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9422 final boolean firstClass = cpr == null;
9424 final long ident = Binder.clearCallingIdentity();
9426 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9427 ApplicationInfo ai =
9428 AppGlobals.getPackageManager().
9430 cpi.applicationInfo.packageName,
9431 STOCK_PM_FLAGS, userId);
9432 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9434 Slog.w(TAG, "No package info for content provider "
9438 ai = getAppInfoForUser(ai, userId);
9439 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9440 } catch (RemoteException ex) {
9441 // pm is in same process, this will never happen.
9443 Binder.restoreCallingIdentity(ident);
9447 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9449 if (r != null && cpr.canRunHere(r)) {
9450 // If this is a multiprocess provider, then just return its
9451 // info and allow the caller to instantiate it. Only do
9452 // this if the provider is the same user as the caller's
9453 // process, or can run as root (so can be in any process).
9454 return cpr.newHolder(null);
9457 if (DEBUG_PROVIDER) {
9458 RuntimeException e = new RuntimeException("here");
9459 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9460 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9463 // This is single process, and our app is now connecting to it.
9464 // See if we are already in the process of launching this
9466 final int N = mLaunchingProviders.size();
9468 for (i=0; i<N; i++) {
9469 if (mLaunchingProviders.get(i) == cpr) {
9474 // If the provider is not already being launched, then get it
9477 final long origId = Binder.clearCallingIdentity();
9480 // Content provider is now in use, its package can't be stopped.
9482 checkTime(startTime, "getContentProviderImpl: before set stopped state");
9483 AppGlobals.getPackageManager().setPackageStoppedState(
9484 cpr.appInfo.packageName, false, userId);
9485 checkTime(startTime, "getContentProviderImpl: after set stopped state");
9486 } catch (RemoteException e) {
9487 } catch (IllegalArgumentException e) {
9488 Slog.w(TAG, "Failed trying to unstop package "
9489 + cpr.appInfo.packageName + ": " + e);
9492 // Use existing process if already started
9493 checkTime(startTime, "getContentProviderImpl: looking for process record");
9494 ProcessRecord proc = getProcessRecordLocked(
9495 cpi.processName, cpr.appInfo.uid, false);
9496 if (proc != null && proc.thread != null) {
9497 if (DEBUG_PROVIDER) {
9498 Slog.d(TAG, "Installing in existing process " + proc);
9500 if (!proc.pubProviders.containsKey(cpi.name)) {
9501 checkTime(startTime, "getContentProviderImpl: scheduling install");
9502 proc.pubProviders.put(cpi.name, cpr);
9504 proc.thread.scheduleInstallProvider(cpi);
9505 } catch (RemoteException e) {
9509 checkTime(startTime, "getContentProviderImpl: before start process");
9510 proc = startProcessLocked(cpi.processName,
9511 cpr.appInfo, false, 0, "content provider",
9512 new ComponentName(cpi.applicationInfo.packageName,
9513 cpi.name), false, false, false);
9514 checkTime(startTime, "getContentProviderImpl: after start process");
9516 Slog.w(TAG, "Unable to launch app "
9517 + cpi.applicationInfo.packageName + "/"
9518 + cpi.applicationInfo.uid + " for provider "
9519 + name + ": process is bad");
9523 cpr.launchingApp = proc;
9524 mLaunchingProviders.add(cpr);
9526 Binder.restoreCallingIdentity(origId);
9530 checkTime(startTime, "getContentProviderImpl: updating data structures");
9532 // Make sure the provider is published (the same provider class
9533 // may be published under multiple names).
9535 mProviderMap.putProviderByClass(comp, cpr);
9538 mProviderMap.putProviderByName(name, cpr);
9539 conn = incProviderCountLocked(r, cpr, token, stable);
9541 conn.waiting = true;
9544 checkTime(startTime, "getContentProviderImpl: done!");
9547 // Wait for the provider to be published...
9548 synchronized (cpr) {
9549 while (cpr.provider == null) {
9550 if (cpr.launchingApp == null) {
9551 Slog.w(TAG, "Unable to launch app "
9552 + cpi.applicationInfo.packageName + "/"
9553 + cpi.applicationInfo.uid + " for provider "
9554 + name + ": launching app became null");
9555 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9556 UserHandle.getUserId(cpi.applicationInfo.uid),
9557 cpi.applicationInfo.packageName,
9558 cpi.applicationInfo.uid, name);
9563 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9564 + cpr.launchingApp);
9567 conn.waiting = true;
9570 } catch (InterruptedException ex) {
9573 conn.waiting = false;
9578 return cpr != null ? cpr.newHolder(conn) : null;
9582 public final ContentProviderHolder getContentProvider(
9583 IApplicationThread caller, String name, int userId, boolean stable) {
9584 enforceNotIsolatedCaller("getContentProvider");
9585 if (caller == null) {
9586 String msg = "null IApplicationThread when getting content provider "
9589 throw new SecurityException(msg);
9591 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9592 // with cross-user grant.
9593 return getContentProviderImpl(caller, name, null, stable, userId);
9596 public ContentProviderHolder getContentProviderExternal(
9597 String name, int userId, IBinder token) {
9598 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9599 "Do not have permission in call getContentProviderExternal()");
9600 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9601 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9602 return getContentProviderExternalUnchecked(name, token, userId);
9605 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9606 IBinder token, int userId) {
9607 return getContentProviderImpl(null, name, token, true, userId);
9611 * Drop a content provider from a ProcessRecord's bookkeeping
9613 public void removeContentProvider(IBinder connection, boolean stable) {
9614 enforceNotIsolatedCaller("removeContentProvider");
9615 long ident = Binder.clearCallingIdentity();
9617 synchronized (this) {
9618 ContentProviderConnection conn;
9620 conn = (ContentProviderConnection)connection;
9621 } catch (ClassCastException e) {
9622 String msg ="removeContentProvider: " + connection
9623 + " not a ContentProviderConnection";
9625 throw new IllegalArgumentException(msg);
9628 throw new NullPointerException("connection is null");
9630 if (decProviderCountLocked(conn, null, null, stable)) {
9631 updateOomAdjLocked();
9635 Binder.restoreCallingIdentity(ident);
9639 public void removeContentProviderExternal(String name, IBinder token) {
9640 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9641 "Do not have permission in call removeContentProviderExternal()");
9642 int userId = UserHandle.getCallingUserId();
9643 long ident = Binder.clearCallingIdentity();
9645 removeContentProviderExternalUnchecked(name, token, userId);
9647 Binder.restoreCallingIdentity(ident);
9651 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9652 synchronized (this) {
9653 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9655 //remove from mProvidersByClass
9656 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9660 //update content provider record entry info
9661 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9662 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9663 if (localCpr.hasExternalProcessHandles()) {
9664 if (localCpr.removeExternalProcessHandleLocked(token)) {
9665 updateOomAdjLocked();
9667 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9668 + " with no external reference for token: "
9672 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9673 + " with no external references.");
9678 public final void publishContentProviders(IApplicationThread caller,
9679 List<ContentProviderHolder> providers) {
9680 if (providers == null) {
9684 enforceNotIsolatedCaller("publishContentProviders");
9685 synchronized (this) {
9686 final ProcessRecord r = getRecordForAppLocked(caller);
9688 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9690 throw new SecurityException(
9691 "Unable to find app for caller " + caller
9692 + " (pid=" + Binder.getCallingPid()
9693 + ") when publishing content providers");
9696 final long origId = Binder.clearCallingIdentity();
9698 final int N = providers.size();
9699 for (int i=0; i<N; i++) {
9700 ContentProviderHolder src = providers.get(i);
9701 if (src == null || src.info == null || src.provider == null) {
9704 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9706 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9708 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9709 mProviderMap.putProviderByClass(comp, dst);
9710 String names[] = dst.info.authority.split(";");
9711 for (int j = 0; j < names.length; j++) {
9712 mProviderMap.putProviderByName(names[j], dst);
9715 int NL = mLaunchingProviders.size();
9717 for (j=0; j<NL; j++) {
9718 if (mLaunchingProviders.get(j) == dst) {
9719 mLaunchingProviders.remove(j);
9724 synchronized (dst) {
9725 dst.provider = src.provider;
9729 updateOomAdjLocked(r);
9733 Binder.restoreCallingIdentity(origId);
9737 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9738 ContentProviderConnection conn;
9740 conn = (ContentProviderConnection)connection;
9741 } catch (ClassCastException e) {
9742 String msg ="refContentProvider: " + connection
9743 + " not a ContentProviderConnection";
9745 throw new IllegalArgumentException(msg);
9748 throw new NullPointerException("connection is null");
9751 synchronized (this) {
9753 conn.numStableIncs += stable;
9755 stable = conn.stableCount + stable;
9757 throw new IllegalStateException("stableCount < 0: " + stable);
9761 conn.numUnstableIncs += unstable;
9763 unstable = conn.unstableCount + unstable;
9765 throw new IllegalStateException("unstableCount < 0: " + unstable);
9768 if ((stable+unstable) <= 0) {
9769 throw new IllegalStateException("ref counts can't go to zero here: stable="
9770 + stable + " unstable=" + unstable);
9772 conn.stableCount = stable;
9773 conn.unstableCount = unstable;
9778 public void unstableProviderDied(IBinder connection) {
9779 ContentProviderConnection conn;
9781 conn = (ContentProviderConnection)connection;
9782 } catch (ClassCastException e) {
9783 String msg ="refContentProvider: " + connection
9784 + " not a ContentProviderConnection";
9786 throw new IllegalArgumentException(msg);
9789 throw new NullPointerException("connection is null");
9792 // Safely retrieve the content provider associated with the connection.
9793 IContentProvider provider;
9794 synchronized (this) {
9795 provider = conn.provider.provider;
9798 if (provider == null) {
9799 // Um, yeah, we're way ahead of you.
9803 // Make sure the caller is being honest with us.
9804 if (provider.asBinder().pingBinder()) {
9805 // Er, no, still looks good to us.
9806 synchronized (this) {
9807 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9808 + " says " + conn + " died, but we don't agree");
9813 // Well look at that! It's dead!
9814 synchronized (this) {
9815 if (conn.provider.provider != provider) {
9816 // But something changed... good enough.
9820 ProcessRecord proc = conn.provider.proc;
9821 if (proc == null || proc.thread == null) {
9822 // Seems like the process is already cleaned up.
9826 // As far as we're concerned, this is just like receiving a
9827 // death notification... just a bit prematurely.
9828 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9829 + ") early provider death");
9830 final long ident = Binder.clearCallingIdentity();
9832 appDiedLocked(proc);
9834 Binder.restoreCallingIdentity(ident);
9840 public void appNotRespondingViaProvider(IBinder connection) {
9841 enforceCallingPermission(
9842 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9844 final ContentProviderConnection conn = (ContentProviderConnection) connection;
9846 Slog.w(TAG, "ContentProviderConnection is null");
9850 final ProcessRecord host = conn.provider.proc;
9852 Slog.w(TAG, "Failed to find hosting ProcessRecord");
9856 final long token = Binder.clearCallingIdentity();
9858 appNotResponding(host, null, null, false, "ContentProvider not responding");
9860 Binder.restoreCallingIdentity(token);
9864 public final void installSystemProviders() {
9865 List<ProviderInfo> providers;
9866 synchronized (this) {
9867 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9868 providers = generateApplicationProvidersLocked(app);
9869 if (providers != null) {
9870 for (int i=providers.size()-1; i>=0; i--) {
9871 ProviderInfo pi = (ProviderInfo)providers.get(i);
9872 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9873 Slog.w(TAG, "Not installing system proc provider " + pi.name
9874 + ": not system .apk");
9875 providers.remove(i);
9880 if (providers != null) {
9881 mSystemThread.installSystemProviders(providers);
9884 mCoreSettingsObserver = new CoreSettingsObserver(this);
9886 //mUsageStatsService.monitorPackages();
9890 * Allows apps to retrieve the MIME type of a URI.
9891 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9892 * users, then it does not need permission to access the ContentProvider.
9893 * Either, it needs cross-user uri grants.
9895 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9897 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9898 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9900 public String getProviderMimeType(Uri uri, int userId) {
9901 enforceNotIsolatedCaller("getProviderMimeType");
9902 final String name = uri.getAuthority();
9903 int callingUid = Binder.getCallingUid();
9904 int callingPid = Binder.getCallingPid();
9906 boolean clearedIdentity = false;
9907 userId = unsafeConvertIncomingUser(userId);
9908 if (canClearIdentity(callingPid, callingUid, userId)) {
9909 clearedIdentity = true;
9910 ident = Binder.clearCallingIdentity();
9912 ContentProviderHolder holder = null;
9914 holder = getContentProviderExternalUnchecked(name, null, userId);
9915 if (holder != null) {
9916 return holder.provider.getType(uri);
9918 } catch (RemoteException e) {
9919 Log.w(TAG, "Content provider dead retrieving " + uri, e);
9922 // We need to clear the identity to call removeContentProviderExternalUnchecked
9923 if (!clearedIdentity) {
9924 ident = Binder.clearCallingIdentity();
9927 if (holder != null) {
9928 removeContentProviderExternalUnchecked(name, null, userId);
9931 Binder.restoreCallingIdentity(ident);
9938 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9939 if (UserHandle.getUserId(callingUid) == userId) {
9942 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9943 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9944 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9945 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9951 // =========================================================
9952 // GLOBAL MANAGEMENT
9953 // =========================================================
9955 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9956 boolean isolated, int isolatedUid) {
9957 String proc = customProcess != null ? customProcess : info.processName;
9958 BatteryStatsImpl.Uid.Proc ps = null;
9959 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9960 final int userId = UserHandle.getUserId(info.uid);
9963 if (isolatedUid == 0) {
9964 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9966 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9967 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9968 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9970 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9971 mNextIsolatedProcessUid++;
9972 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9973 // No process for this uid, use it.
9977 if (stepsLeft <= 0) {
9982 // Special case for startIsolatedProcess (internal only), where
9983 // the uid of the isolated process is specified by the caller.
9987 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
9988 if (!mBooted && !mBooting
9989 && userId == UserHandle.USER_OWNER
9990 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
9991 r.persistent = true;
9996 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9997 String abiOverride) {
10000 app = getProcessRecordLocked(info.processName, info.uid, true);
10006 app = newProcessRecordLocked(info, null, isolated, 0);
10007 mProcessNames.put(info.processName, app.uid, app);
10009 mIsolatedProcesses.put(app.uid, app);
10011 updateLruProcessLocked(app, false, null);
10012 updateOomAdjLocked();
10015 // This package really, really can not be stopped.
10017 AppGlobals.getPackageManager().setPackageStoppedState(
10018 info.packageName, false, UserHandle.getUserId(app.uid));
10019 } catch (RemoteException e) {
10020 } catch (IllegalArgumentException e) {
10021 Slog.w(TAG, "Failed trying to unstop package "
10022 + info.packageName + ": " + e);
10025 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10026 app.persistent = true;
10027 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10029 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10030 mPersistentStartingProcesses.add(app);
10031 startProcessLocked(app, "added application", app.processName, abiOverride,
10032 null /* entryPoint */, null /* entryPointArgs */);
10038 public void unhandledBack() {
10039 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10040 "unhandledBack()");
10042 synchronized(this) {
10043 final long origId = Binder.clearCallingIdentity();
10045 getFocusedStack().unhandledBackLocked();
10047 Binder.restoreCallingIdentity(origId);
10052 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10053 enforceNotIsolatedCaller("openContentUri");
10054 final int userId = UserHandle.getCallingUserId();
10055 String name = uri.getAuthority();
10056 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10057 ParcelFileDescriptor pfd = null;
10059 // We record the binder invoker's uid in thread-local storage before
10060 // going to the content provider to open the file. Later, in the code
10061 // that handles all permissions checks, we look for this uid and use
10062 // that rather than the Activity Manager's own uid. The effect is that
10063 // we do the check against the caller's permissions even though it looks
10064 // to the content provider like the Activity Manager itself is making
10066 Binder token = new Binder();
10067 sCallerIdentity.set(new Identity(
10068 token, Binder.getCallingPid(), Binder.getCallingUid()));
10070 pfd = cph.provider.openFile(null, uri, "r", null, token);
10071 } catch (FileNotFoundException e) {
10072 // do nothing; pfd will be returned null
10074 // Ensure that whatever happens, we clean up the identity state
10075 sCallerIdentity.remove();
10076 // Ensure we're done with the provider.
10077 removeContentProviderExternalUnchecked(name, null, userId);
10080 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10085 // Actually is sleeping or shutting down or whatever else in the future
10086 // is an inactive state.
10087 public boolean isSleepingOrShuttingDown() {
10088 return isSleeping() || mShuttingDown;
10091 public boolean isSleeping() {
10095 void onWakefulnessChanged(int wakefulness) {
10096 synchronized(this) {
10097 mWakefulness = wakefulness;
10098 updateSleepIfNeededLocked();
10102 void finishRunningVoiceLocked() {
10103 if (mRunningVoice) {
10104 mRunningVoice = false;
10105 updateSleepIfNeededLocked();
10109 void updateSleepIfNeededLocked() {
10110 if (mSleeping && !shouldSleepLocked()) {
10112 mStackSupervisor.comeOutOfSleepIfNeededLocked();
10113 } else if (!mSleeping && shouldSleepLocked()) {
10115 mStackSupervisor.goingToSleepLocked();
10117 // Initialize the wake times of all processes.
10118 checkExcessivePowerUsageLocked(false);
10119 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10120 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10121 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10125 private boolean shouldSleepLocked() {
10126 // Resume applications while running a voice interactor.
10127 if (mRunningVoice) {
10131 switch (mWakefulness) {
10132 case PowerManagerInternal.WAKEFULNESS_AWAKE:
10133 case PowerManagerInternal.WAKEFULNESS_DREAMING:
10134 // If we're interactive but applications are already paused then defer
10135 // resuming them until the lock screen is hidden.
10136 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10137 case PowerManagerInternal.WAKEFULNESS_DOZING:
10138 // If we're dozing then pause applications whenever the lock screen is shown.
10139 return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10140 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10142 // If we're asleep then pause applications unconditionally.
10147 /** Pokes the task persister. */
10148 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10149 if (task != null && task.stack != null && task.stack.isHomeStack()) {
10150 // Never persist the home stack.
10153 mTaskPersister.wakeup(task, flush);
10156 /** Notifies all listeners when the task stack has changed. */
10157 void notifyTaskStackChangedLocked() {
10158 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10159 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10160 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10164 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10165 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10169 public boolean shutdown(int timeout) {
10170 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10171 != PackageManager.PERMISSION_GRANTED) {
10172 throw new SecurityException("Requires permission "
10173 + android.Manifest.permission.SHUTDOWN);
10176 boolean timedout = false;
10178 synchronized(this) {
10179 mShuttingDown = true;
10180 updateEventDispatchingLocked();
10181 timedout = mStackSupervisor.shutdownLocked(timeout);
10184 mAppOpsService.shutdown();
10185 if (mUsageStatsService != null) {
10186 mUsageStatsService.prepareShutdown();
10188 mBatteryStatsService.shutdown();
10189 synchronized (this) {
10190 mProcessStats.shutdownLocked();
10191 notifyTaskPersisterLocked(null, true);
10197 public final void activitySlept(IBinder token) {
10198 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10200 final long origId = Binder.clearCallingIdentity();
10202 synchronized (this) {
10203 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10205 mStackSupervisor.activitySleptLocked(r);
10209 Binder.restoreCallingIdentity(origId);
10212 private String lockScreenShownToString() {
10213 switch (mLockScreenShown) {
10214 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10215 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10216 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10217 default: return "Unknown=" + mLockScreenShown;
10221 void logLockScreen(String msg) {
10222 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10223 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10224 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10225 + " mSleeping=" + mSleeping);
10228 void startRunningVoiceLocked() {
10229 if (!mRunningVoice) {
10230 mRunningVoice = true;
10231 updateSleepIfNeededLocked();
10235 private void updateEventDispatchingLocked() {
10236 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10239 public void setLockScreenShown(boolean shown) {
10240 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10241 != PackageManager.PERMISSION_GRANTED) {
10242 throw new SecurityException("Requires permission "
10243 + android.Manifest.permission.DEVICE_POWER);
10246 synchronized(this) {
10247 long ident = Binder.clearCallingIdentity();
10249 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10250 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10251 updateSleepIfNeededLocked();
10253 Binder.restoreCallingIdentity(ident);
10259 public void stopAppSwitches() {
10260 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10261 != PackageManager.PERMISSION_GRANTED) {
10262 throw new SecurityException("Requires permission "
10263 + android.Manifest.permission.STOP_APP_SWITCHES);
10266 synchronized(this) {
10267 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10268 + APP_SWITCH_DELAY_TIME;
10269 mDidAppSwitch = false;
10270 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10271 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10272 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10276 public void resumeAppSwitches() {
10277 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10278 != PackageManager.PERMISSION_GRANTED) {
10279 throw new SecurityException("Requires permission "
10280 + android.Manifest.permission.STOP_APP_SWITCHES);
10283 synchronized(this) {
10284 // Note that we don't execute any pending app switches... we will
10285 // let those wait until either the timeout, or the next start
10286 // activity request.
10287 mAppSwitchesAllowedTime = 0;
10291 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10292 int callingPid, int callingUid, String name) {
10293 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10297 int perm = checkComponentPermission(
10298 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10299 sourceUid, -1, true);
10300 if (perm == PackageManager.PERMISSION_GRANTED) {
10304 // If the actual IPC caller is different from the logical source, then
10305 // also see if they are allowed to control app switches.
10306 if (callingUid != -1 && callingUid != sourceUid) {
10307 perm = checkComponentPermission(
10308 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10309 callingUid, -1, true);
10310 if (perm == PackageManager.PERMISSION_GRANTED) {
10315 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10319 public void setDebugApp(String packageName, boolean waitForDebugger,
10320 boolean persistent) {
10321 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10324 long ident = Binder.clearCallingIdentity();
10326 // Note that this is not really thread safe if there are multiple
10327 // callers into it at the same time, but that's not a situation we
10330 final ContentResolver resolver = mContext.getContentResolver();
10331 Settings.Global.putString(
10332 resolver, Settings.Global.DEBUG_APP,
10334 Settings.Global.putInt(
10335 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10336 waitForDebugger ? 1 : 0);
10339 synchronized (this) {
10341 mOrigDebugApp = mDebugApp;
10342 mOrigWaitForDebugger = mWaitForDebugger;
10344 mDebugApp = packageName;
10345 mWaitForDebugger = waitForDebugger;
10346 mDebugTransient = !persistent;
10347 if (packageName != null) {
10348 forceStopPackageLocked(packageName, -1, false, false, true, true,
10349 false, UserHandle.USER_ALL, "set debug app");
10353 Binder.restoreCallingIdentity(ident);
10357 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10358 synchronized (this) {
10359 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10360 if (!isDebuggable) {
10361 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10362 throw new SecurityException("Process not debuggable: " + app.packageName);
10366 mOpenGlTraceApp = processName;
10370 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10371 synchronized (this) {
10372 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10373 if (!isDebuggable) {
10374 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10375 throw new SecurityException("Process not debuggable: " + app.packageName);
10378 mProfileApp = processName;
10379 mProfileFile = profilerInfo.profileFile;
10380 if (mProfileFd != null) {
10382 mProfileFd.close();
10383 } catch (IOException e) {
10387 mProfileFd = profilerInfo.profileFd;
10388 mSamplingInterval = profilerInfo.samplingInterval;
10389 mAutoStopProfiler = profilerInfo.autoStopProfiler;
10395 public void setAlwaysFinish(boolean enabled) {
10396 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10397 "setAlwaysFinish()");
10399 Settings.Global.putInt(
10400 mContext.getContentResolver(),
10401 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10403 synchronized (this) {
10404 mAlwaysFinishActivities = enabled;
10409 public void setActivityController(IActivityController controller) {
10410 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10411 "setActivityController()");
10412 synchronized (this) {
10413 mController = controller;
10414 Watchdog.getInstance().setActivityController(controller);
10419 public void setUserIsMonkey(boolean userIsMonkey) {
10420 synchronized (this) {
10421 synchronized (mPidsSelfLocked) {
10422 final int callingPid = Binder.getCallingPid();
10423 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10424 if (precessRecord == null) {
10425 throw new SecurityException("Unknown process: " + callingPid);
10427 if (precessRecord.instrumentationUiAutomationConnection == null) {
10428 throw new SecurityException("Only an instrumentation process "
10429 + "with a UiAutomation can call setUserIsMonkey");
10432 mUserIsMonkey = userIsMonkey;
10437 public boolean isUserAMonkey() {
10438 synchronized (this) {
10439 // If there is a controller also implies the user is a monkey.
10440 return (mUserIsMonkey || mController != null);
10444 public void requestBugReport() {
10445 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10446 SystemProperties.set("ctl.start", "bugreport");
10449 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10450 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10453 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10454 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10455 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10457 return KEY_DISPATCHING_TIMEOUT;
10461 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10462 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10463 != PackageManager.PERMISSION_GRANTED) {
10464 throw new SecurityException("Requires permission "
10465 + android.Manifest.permission.FILTER_EVENTS);
10467 ProcessRecord proc;
10469 synchronized (this) {
10470 synchronized (mPidsSelfLocked) {
10471 proc = mPidsSelfLocked.get(pid);
10473 timeout = getInputDispatchingTimeoutLocked(proc);
10476 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10484 * Handle input dispatching timeouts.
10485 * Returns whether input dispatching should be aborted or not.
10487 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10488 final ActivityRecord activity, final ActivityRecord parent,
10489 final boolean aboveSystem, String reason) {
10490 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10491 != PackageManager.PERMISSION_GRANTED) {
10492 throw new SecurityException("Requires permission "
10493 + android.Manifest.permission.FILTER_EVENTS);
10496 final String annotation;
10497 if (reason == null) {
10498 annotation = "Input dispatching timed out";
10500 annotation = "Input dispatching timed out (" + reason + ")";
10503 if (proc != null) {
10504 synchronized (this) {
10505 if (proc.debugging) {
10510 // Give more time since we were dexopting.
10511 mDidDexOpt = false;
10515 if (proc.instrumentationClass != null) {
10516 Bundle info = new Bundle();
10517 info.putString("shortMsg", "keyDispatchingTimedOut");
10518 info.putString("longMsg", annotation);
10519 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10523 mHandler.post(new Runnable() {
10525 public void run() {
10526 appNotResponding(proc, activity, parent, aboveSystem, annotation);
10534 public Bundle getAssistContextExtras(int requestType) {
10535 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10536 UserHandle.getCallingUserId());
10540 synchronized (pae) {
10541 while (!pae.haveResult) {
10544 } catch (InterruptedException e) {
10547 if (pae.result != null) {
10548 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10551 synchronized (this) {
10552 mPendingAssistExtras.remove(pae);
10553 mHandler.removeCallbacks(pae);
10558 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10560 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10561 "getAssistContextExtras()");
10562 PendingAssistExtras pae;
10563 Bundle extras = new Bundle();
10564 synchronized (this) {
10565 ActivityRecord activity = getFocusedStack().mResumedActivity;
10566 if (activity == null) {
10567 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10570 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10571 if (activity.app == null || activity.app.thread == null) {
10572 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10575 if (activity.app.pid == Binder.getCallingPid()) {
10576 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10579 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10581 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10583 mPendingAssistExtras.add(pae);
10584 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10585 } catch (RemoteException e) {
10586 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10593 public void reportAssistContextExtras(IBinder token, Bundle extras) {
10594 PendingAssistExtras pae = (PendingAssistExtras)token;
10595 synchronized (pae) {
10596 pae.result = extras;
10597 pae.haveResult = true;
10599 if (pae.intent == null) {
10600 // Caller is just waiting for the result.
10605 // We are now ready to launch the assist activity.
10606 synchronized (this) {
10607 boolean exists = mPendingAssistExtras.remove(pae);
10608 mHandler.removeCallbacks(pae);
10614 pae.intent.replaceExtras(extras);
10615 if (pae.hint != null) {
10616 pae.intent.putExtra(pae.hint, true);
10618 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10619 | Intent.FLAG_ACTIVITY_SINGLE_TOP
10620 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10621 closeSystemDialogs("assist");
10623 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10624 } catch (ActivityNotFoundException e) {
10625 Slog.w(TAG, "No activity to handle assist action.", e);
10629 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10630 return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10633 public void registerProcessObserver(IProcessObserver observer) {
10634 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10635 "registerProcessObserver()");
10636 synchronized (this) {
10637 mProcessObservers.register(observer);
10642 public void unregisterProcessObserver(IProcessObserver observer) {
10643 synchronized (this) {
10644 mProcessObservers.unregister(observer);
10649 public boolean convertFromTranslucent(IBinder token) {
10650 final long origId = Binder.clearCallingIdentity();
10652 synchronized (this) {
10653 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10657 final boolean translucentChanged = r.changeWindowTranslucency(true);
10658 if (translucentChanged) {
10659 r.task.stack.releaseBackgroundResources();
10660 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10662 mWindowManager.setAppFullscreen(token, true);
10663 return translucentChanged;
10666 Binder.restoreCallingIdentity(origId);
10671 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10672 final long origId = Binder.clearCallingIdentity();
10674 synchronized (this) {
10675 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10679 int index = r.task.mActivities.lastIndexOf(r);
10681 ActivityRecord under = r.task.mActivities.get(index - 1);
10682 under.returningOptions = options;
10684 final boolean translucentChanged = r.changeWindowTranslucency(false);
10685 if (translucentChanged) {
10686 r.task.stack.convertToTranslucent(r);
10688 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10689 mWindowManager.setAppFullscreen(token, false);
10690 return translucentChanged;
10693 Binder.restoreCallingIdentity(origId);
10698 public boolean requestVisibleBehind(IBinder token, boolean visible) {
10699 final long origId = Binder.clearCallingIdentity();
10701 synchronized (this) {
10702 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10704 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10709 Binder.restoreCallingIdentity(origId);
10714 public boolean isBackgroundVisibleBehind(IBinder token) {
10715 final long origId = Binder.clearCallingIdentity();
10717 synchronized (this) {
10718 final ActivityStack stack = ActivityRecord.getStackLocked(token);
10719 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10720 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10721 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10725 Binder.restoreCallingIdentity(origId);
10730 public ActivityOptions getActivityOptions(IBinder token) {
10731 final long origId = Binder.clearCallingIdentity();
10733 synchronized (this) {
10734 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10736 final ActivityOptions activityOptions = r.pendingOptions;
10737 r.pendingOptions = null;
10738 return activityOptions;
10743 Binder.restoreCallingIdentity(origId);
10748 public void setImmersive(IBinder token, boolean immersive) {
10749 synchronized(this) {
10750 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10752 throw new IllegalArgumentException();
10754 r.immersive = immersive;
10756 // update associated state if we're frontmost
10757 if (r == mFocusedActivity) {
10758 if (DEBUG_IMMERSIVE) {
10759 Slog.d(TAG, "Frontmost changed immersion: "+ r);
10761 applyUpdateLockStateLocked(r);
10767 public boolean isImmersive(IBinder token) {
10768 synchronized (this) {
10769 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10771 throw new IllegalArgumentException();
10773 return r.immersive;
10777 public boolean isTopActivityImmersive() {
10778 enforceNotIsolatedCaller("startActivity");
10779 synchronized (this) {
10780 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10781 return (r != null) ? r.immersive : false;
10786 public boolean isTopOfTask(IBinder token) {
10787 synchronized (this) {
10788 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10790 throw new IllegalArgumentException();
10792 return r.task.getTopActivity() == r;
10796 public final void enterSafeMode() {
10797 synchronized(this) {
10798 // It only makes sense to do this before the system is ready
10799 // and started launching other packages.
10800 if (!mSystemReady) {
10802 AppGlobals.getPackageManager().enterSafeMode();
10803 } catch (RemoteException e) {
10811 public final void showSafeModeOverlay() {
10812 View v = LayoutInflater.from(mContext).inflate(
10813 com.android.internal.R.layout.safe_mode, null);
10814 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10815 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10816 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10817 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10818 lp.gravity = Gravity.BOTTOM | Gravity.START;
10819 lp.format = v.getBackground().getOpacity();
10820 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10821 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10822 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10823 ((WindowManager)mContext.getSystemService(
10824 Context.WINDOW_SERVICE)).addView(v, lp);
10827 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10828 if (!(sender instanceof PendingIntentRecord)) {
10831 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10832 synchronized (stats) {
10833 if (mBatteryStatsService.isOnBattery()) {
10834 mBatteryStatsService.enforceCallingPermission();
10835 PendingIntentRecord rec = (PendingIntentRecord)sender;
10836 int MY_UID = Binder.getCallingUid();
10837 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10838 BatteryStatsImpl.Uid.Pkg pkg =
10839 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10840 sourcePkg != null ? sourcePkg : rec.key.packageName);
10841 pkg.incWakeupsLocked();
10846 public boolean killPids(int[] pids, String pReason, boolean secure) {
10847 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10848 throw new SecurityException("killPids only available to the system");
10850 String reason = (pReason == null) ? "Unknown" : pReason;
10851 // XXX Note: don't acquire main activity lock here, because the window
10852 // manager calls in with its locks held.
10854 boolean killed = false;
10855 synchronized (mPidsSelfLocked) {
10856 int[] types = new int[pids.length];
10858 for (int i=0; i<pids.length; i++) {
10859 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10860 if (proc != null) {
10861 int type = proc.setAdj;
10863 if (type > worstType) {
10869 // If the worst oom_adj is somewhere in the cached proc LRU range,
10870 // then constrain it so we will kill all cached procs.
10871 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10872 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10873 worstType = ProcessList.CACHED_APP_MIN_ADJ;
10876 // If this is not a secure call, don't let it kill processes that
10878 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10879 worstType = ProcessList.SERVICE_ADJ;
10882 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10883 for (int i=0; i<pids.length; i++) {
10884 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10885 if (proc == null) {
10888 int adj = proc.setAdj;
10889 if (adj >= worstType && !proc.killedByAm) {
10890 proc.kill(reason, true);
10899 public void killUid(int uid, String reason) {
10900 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10901 throw new SecurityException("killUid only available to the system");
10903 synchronized (this) {
10904 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10905 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10906 reason != null ? reason : "kill uid");
10911 public boolean killProcessesBelowForeground(String reason) {
10912 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10913 throw new SecurityException("killProcessesBelowForeground() only available to system");
10916 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10919 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10920 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10921 throw new SecurityException("killProcessesBelowAdj() only available to system");
10924 boolean killed = false;
10925 synchronized (mPidsSelfLocked) {
10926 final int size = mPidsSelfLocked.size();
10927 for (int i = 0; i < size; i++) {
10928 final int pid = mPidsSelfLocked.keyAt(i);
10929 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10930 if (proc == null) continue;
10932 final int adj = proc.setAdj;
10933 if (adj > belowAdj && !proc.killedByAm) {
10934 proc.kill(reason, true);
10943 public void hang(final IBinder who, boolean allowRestart) {
10944 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10945 != PackageManager.PERMISSION_GRANTED) {
10946 throw new SecurityException("Requires permission "
10947 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10950 final IBinder.DeathRecipient death = new DeathRecipient() {
10952 public void binderDied() {
10953 synchronized (this) {
10960 who.linkToDeath(death, 0);
10961 } catch (RemoteException e) {
10962 Slog.w(TAG, "hang: given caller IBinder is already dead.");
10966 synchronized (this) {
10967 Watchdog.getInstance().setAllowRestart(allowRestart);
10968 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10969 synchronized (death) {
10970 while (who.isBinderAlive()) {
10973 } catch (InterruptedException e) {
10977 Watchdog.getInstance().setAllowRestart(true);
10982 public void restart() {
10983 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10984 != PackageManager.PERMISSION_GRANTED) {
10985 throw new SecurityException("Requires permission "
10986 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10989 Log.i(TAG, "Sending shutdown broadcast...");
10991 BroadcastReceiver br = new BroadcastReceiver() {
10992 @Override public void onReceive(Context context, Intent intent) {
10993 // Now the broadcast is done, finish up the low-level shutdown.
10994 Log.i(TAG, "Shutting down activity manager...");
10996 Log.i(TAG, "Shutdown complete, restarting!");
10997 Process.killProcess(Process.myPid());
11002 // First send the high-level shut down broadcast.
11003 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11004 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11005 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11006 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11007 mContext.sendOrderedBroadcastAsUser(intent,
11008 UserHandle.ALL, null, br, mHandler, 0, null, null);
11010 br.onReceive(mContext, intent);
11013 private long getLowRamTimeSinceIdle(long now) {
11014 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11018 public void performIdleMaintenance() {
11019 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11020 != PackageManager.PERMISSION_GRANTED) {
11021 throw new SecurityException("Requires permission "
11022 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11025 synchronized (this) {
11026 final long now = SystemClock.uptimeMillis();
11027 final long timeSinceLastIdle = now - mLastIdleTime;
11028 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11029 mLastIdleTime = now;
11030 mLowRamTimeSinceLastIdle = 0;
11031 if (mLowRamStartTime != 0) {
11032 mLowRamStartTime = now;
11035 StringBuilder sb = new StringBuilder(128);
11036 sb.append("Idle maintenance over ");
11037 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11038 sb.append(" low RAM for ");
11039 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11040 Slog.i(TAG, sb.toString());
11042 // If at least 1/3 of our time since the last idle period has been spent
11043 // with RAM low, then we want to kill processes.
11044 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11046 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11047 ProcessRecord proc = mLruProcesses.get(i);
11048 if (proc.notCachedSinceIdle) {
11049 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
11050 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11051 if (doKilling && proc.initialIdlePss != 0
11052 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11053 sb = new StringBuilder(128);
11055 sb.append(proc.processName);
11056 sb.append(" in idle maint: pss=");
11057 sb.append(proc.lastPss);
11058 sb.append(", initialPss=");
11059 sb.append(proc.initialIdlePss);
11060 sb.append(", period=");
11061 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11062 sb.append(", lowRamPeriod=");
11063 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11064 Slog.wtfQuiet(TAG, sb.toString());
11065 proc.kill("idle maint (pss " + proc.lastPss
11066 + " from " + proc.initialIdlePss + ")", true);
11069 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11070 proc.notCachedSinceIdle = true;
11071 proc.initialIdlePss = 0;
11072 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11073 mTestPssMode, isSleeping(), now);
11077 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11078 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11082 private void retrieveSettings() {
11083 final ContentResolver resolver = mContext.getContentResolver();
11084 String debugApp = Settings.Global.getString(
11085 resolver, Settings.Global.DEBUG_APP);
11086 boolean waitForDebugger = Settings.Global.getInt(
11087 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11088 boolean alwaysFinishActivities = Settings.Global.getInt(
11089 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11090 boolean forceRtl = Settings.Global.getInt(
11091 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11092 // Transfer any global setting for forcing RTL layout, into a System Property
11093 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11095 Configuration configuration = new Configuration();
11096 Settings.System.getConfiguration(resolver, configuration);
11098 // This will take care of setting the correct layout direction flags
11099 configuration.setLayoutDirection(configuration.locale);
11102 synchronized (this) {
11103 mDebugApp = mOrigDebugApp = debugApp;
11104 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11105 mAlwaysFinishActivities = alwaysFinishActivities;
11106 // This happens before any activities are started, so we can
11107 // change mConfiguration in-place.
11108 updateConfigurationLocked(configuration, null, false, true);
11109 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11113 /** Loads resources after the current configuration has been set. */
11114 private void loadResourcesOnSystemReady() {
11115 final Resources res = mContext.getResources();
11116 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11117 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11118 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11121 public boolean testIsSystemReady() {
11122 // no need to synchronize(this) just to read & return the value
11123 return mSystemReady;
11126 private static File getCalledPreBootReceiversFile() {
11127 File dataDir = Environment.getDataDirectory();
11128 File systemDir = new File(dataDir, "system");
11129 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11133 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11134 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11135 File file = getCalledPreBootReceiversFile();
11136 FileInputStream fis = null;
11138 fis = new FileInputStream(file);
11139 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11140 int fvers = dis.readInt();
11141 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11142 String vers = dis.readUTF();
11143 String codename = dis.readUTF();
11144 String build = dis.readUTF();
11145 if (android.os.Build.VERSION.RELEASE.equals(vers)
11146 && android.os.Build.VERSION.CODENAME.equals(codename)
11147 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11148 int num = dis.readInt();
11151 String pkg = dis.readUTF();
11152 String cls = dis.readUTF();
11153 lastDoneReceivers.add(new ComponentName(pkg, cls));
11157 } catch (FileNotFoundException e) {
11158 } catch (IOException e) {
11159 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11164 } catch (IOException e) {
11168 return lastDoneReceivers;
11171 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11172 File file = getCalledPreBootReceiversFile();
11173 FileOutputStream fos = null;
11174 DataOutputStream dos = null;
11176 fos = new FileOutputStream(file);
11177 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11178 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11179 dos.writeUTF(android.os.Build.VERSION.RELEASE);
11180 dos.writeUTF(android.os.Build.VERSION.CODENAME);
11181 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11182 dos.writeInt(list.size());
11183 for (int i=0; i<list.size(); i++) {
11184 dos.writeUTF(list.get(i).getPackageName());
11185 dos.writeUTF(list.get(i).getClassName());
11187 } catch (IOException e) {
11188 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11191 FileUtils.sync(fos);
11195 } catch (IOException e) {
11196 // TODO Auto-generated catch block
11197 e.printStackTrace();
11203 private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11204 ArrayList<ComponentName> doneReceivers, int userId) {
11205 boolean waitingUpdate = false;
11206 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11207 List<ResolveInfo> ris = null;
11209 ris = AppGlobals.getPackageManager().queryIntentReceivers(
11210 intent, null, 0, userId);
11211 } catch (RemoteException e) {
11214 for (int i=ris.size()-1; i>=0; i--) {
11215 if ((ris.get(i).activityInfo.applicationInfo.flags
11216 &ApplicationInfo.FLAG_SYSTEM) == 0) {
11220 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11222 // For User 0, load the version number. When delivering to a new user, deliver
11223 // to all receivers.
11224 if (userId == UserHandle.USER_OWNER) {
11225 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11226 for (int i=0; i<ris.size(); i++) {
11227 ActivityInfo ai = ris.get(i).activityInfo;
11228 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11229 if (lastDoneReceivers.contains(comp)) {
11230 // We already did the pre boot receiver for this app with the current
11231 // platform version, so don't do it again...
11234 // ...however, do keep it as one that has been done, so we don't
11235 // forget about it when rewriting the file of last done receivers.
11236 doneReceivers.add(comp);
11241 // If primary user, send broadcast to all available users, else just to userId
11242 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11243 : new int[] { userId };
11244 for (int i = 0; i < ris.size(); i++) {
11245 ActivityInfo ai = ris.get(i).activityInfo;
11246 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11247 doneReceivers.add(comp);
11248 intent.setComponent(comp);
11249 for (int j=0; j<users.length; j++) {
11250 IIntentReceiver finisher = null;
11251 // On last receiver and user, set up a completion callback
11252 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11253 finisher = new IIntentReceiver.Stub() {
11254 public void performReceive(Intent intent, int resultCode,
11255 String data, Bundle extras, boolean ordered,
11256 boolean sticky, int sendingUser) {
11257 // The raw IIntentReceiver interface is called
11258 // with the AM lock held, so redispatch to
11259 // execute our code without the lock.
11260 mHandler.post(onFinishCallback);
11264 Slog.i(TAG, "Sending system update to " + intent.getComponent()
11265 + " for user " + users[j]);
11266 broadcastIntentLocked(null, null, intent, null, finisher,
11267 0, null, null, null, AppOpsManager.OP_NONE,
11268 true, false, MY_PID, Process.SYSTEM_UID,
11270 if (finisher != null) {
11271 waitingUpdate = true;
11277 return waitingUpdate;
11280 public void systemReady(final Runnable goingCallback) {
11281 synchronized(this) {
11282 if (mSystemReady) {
11283 // If we're done calling all the receivers, run the next "boot phase" passed in
11284 // by the SystemServer
11285 if (goingCallback != null) {
11286 goingCallback.run();
11291 // Make sure we have the current profile info, since it is needed for
11292 // security checks.
11293 updateCurrentProfileIdsLocked();
11295 if (mRecentTasks == null) {
11296 mRecentTasks = mTaskPersister.restoreTasksLocked();
11297 mTaskPersister.restoreTasksFromOtherDeviceLocked();
11298 cleanupRecentTasksLocked(UserHandle.USER_ALL);
11299 mTaskPersister.startPersisting();
11302 // Check to see if there are any update receivers to run.
11304 if (mWaitingUpdate) {
11307 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11308 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11309 public void run() {
11310 synchronized (ActivityManagerService.this) {
11313 writeLastDonePreBootReceivers(doneReceivers);
11314 showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11316 systemReady(goingCallback);
11318 }, doneReceivers, UserHandle.USER_OWNER);
11320 if (mWaitingUpdate) {
11326 mAppOpsService.systemReady();
11327 mSystemReady = true;
11330 ArrayList<ProcessRecord> procsToKill = null;
11331 synchronized(mPidsSelfLocked) {
11332 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11333 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11334 if (!isAllowedWhileBooting(proc.info)){
11335 if (procsToKill == null) {
11336 procsToKill = new ArrayList<ProcessRecord>();
11338 procsToKill.add(proc);
11343 synchronized(this) {
11344 if (procsToKill != null) {
11345 for (int i=procsToKill.size()-1; i>=0; i--) {
11346 ProcessRecord proc = procsToKill.get(i);
11347 Slog.i(TAG, "Removing system update proc: " + proc);
11348 removeProcessLocked(proc, true, false, "system update done");
11352 // Now that we have cleaned up any update processes, we
11353 // are ready to start launching real processes and know that
11354 // we won't trample on them any more.
11355 mProcessesReady = true;
11358 Slog.i(TAG, "System now ready");
11359 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11360 SystemClock.uptimeMillis());
11362 synchronized(this) {
11363 // Make sure we have no pre-ready processes sitting around.
11365 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11366 ResolveInfo ri = mContext.getPackageManager()
11367 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11369 CharSequence errorMsg = null;
11371 ActivityInfo ai = ri.activityInfo;
11372 ApplicationInfo app = ai.applicationInfo;
11373 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11374 mTopAction = Intent.ACTION_FACTORY_TEST;
11376 mTopComponent = new ComponentName(app.packageName,
11379 errorMsg = mContext.getResources().getText(
11380 com.android.internal.R.string.factorytest_not_system);
11383 errorMsg = mContext.getResources().getText(
11384 com.android.internal.R.string.factorytest_no_action);
11386 if (errorMsg != null) {
11389 mTopComponent = null;
11390 Message msg = Message.obtain();
11391 msg.what = SHOW_FACTORY_ERROR_MSG;
11392 msg.getData().putCharSequence("msg", errorMsg);
11393 mUiHandler.sendMessage(msg);
11398 retrieveSettings();
11399 loadResourcesOnSystemReady();
11401 synchronized (this) {
11402 readGrantedUriPermissionsLocked();
11405 if (goingCallback != null) goingCallback.run();
11407 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11408 Integer.toString(mCurrentUserId), mCurrentUserId);
11409 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11410 Integer.toString(mCurrentUserId), mCurrentUserId);
11411 mSystemServiceManager.startUser(mCurrentUserId);
11413 synchronized (this) {
11414 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11416 List apps = AppGlobals.getPackageManager().
11417 getPersistentApplications(STOCK_PM_FLAGS);
11418 if (apps != null) {
11419 int N = apps.size();
11421 for (i=0; i<N; i++) {
11422 ApplicationInfo info
11423 = (ApplicationInfo)apps.get(i);
11424 if (info != null &&
11425 !info.packageName.equals("android")) {
11426 addAppLocked(info, false, null /* ABI override */);
11430 } catch (RemoteException ex) {
11431 // pm is in same process, this will never happen.
11435 // Start up initial activity.
11437 startHomeActivityLocked(mCurrentUserId, "systemReady");
11440 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11441 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11442 + " data partition or your device will be unstable.");
11443 mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11445 } catch (RemoteException e) {
11448 if (!Build.isFingerprintConsistent()) {
11449 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11450 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11453 long ident = Binder.clearCallingIdentity();
11455 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11456 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11457 | Intent.FLAG_RECEIVER_FOREGROUND);
11458 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11459 broadcastIntentLocked(null, null, intent,
11460 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11461 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11462 intent = new Intent(Intent.ACTION_USER_STARTING);
11463 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11464 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11465 broadcastIntentLocked(null, null, intent,
11466 null, new IIntentReceiver.Stub() {
11468 public void performReceive(Intent intent, int resultCode, String data,
11469 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11470 throws RemoteException {
11473 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11474 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11475 } catch (Throwable t) {
11476 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11478 Binder.restoreCallingIdentity(ident);
11480 mStackSupervisor.resumeTopActivitiesLocked();
11481 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11485 private boolean makeAppCrashingLocked(ProcessRecord app,
11486 String shortMsg, String longMsg, String stackTrace) {
11487 app.crashing = true;
11488 app.crashingReport = generateProcessError(app,
11489 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11490 startAppProblemLocked(app);
11491 app.stopFreezingAllLocked();
11492 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11495 private void makeAppNotRespondingLocked(ProcessRecord app,
11496 String activity, String shortMsg, String longMsg) {
11497 app.notResponding = true;
11498 app.notRespondingReport = generateProcessError(app,
11499 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11500 activity, shortMsg, longMsg, null);
11501 startAppProblemLocked(app);
11502 app.stopFreezingAllLocked();
11506 * Generate a process error record, suitable for attachment to a ProcessRecord.
11508 * @param app The ProcessRecord in which the error occurred.
11509 * @param condition Crashing, Application Not Responding, etc. Values are defined in
11510 * ActivityManager.AppErrorStateInfo
11511 * @param activity The activity associated with the crash, if known.
11512 * @param shortMsg Short message describing the crash.
11513 * @param longMsg Long message describing the crash.
11514 * @param stackTrace Full crash stack trace, may be null.
11516 * @return Returns a fully-formed AppErrorStateInfo record.
11518 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11519 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11520 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11522 report.condition = condition;
11523 report.processName = app.processName;
11524 report.pid = app.pid;
11525 report.uid = app.info.uid;
11526 report.tag = activity;
11527 report.shortMsg = shortMsg;
11528 report.longMsg = longMsg;
11529 report.stackTrace = stackTrace;
11534 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11535 synchronized (this) {
11536 app.crashing = false;
11537 app.crashingReport = null;
11538 app.notResponding = false;
11539 app.notRespondingReport = null;
11540 if (app.anrDialog == fromDialog) {
11541 app.anrDialog = null;
11543 if (app.waitDialog == fromDialog) {
11544 app.waitDialog = null;
11546 if (app.pid > 0 && app.pid != MY_PID) {
11547 handleAppCrashLocked(app, null, null, null);
11548 app.kill("user request after error", true);
11553 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11554 String stackTrace) {
11555 long now = SystemClock.uptimeMillis();
11558 if (!app.isolated) {
11559 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11563 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11564 // This process loses!
11565 Slog.w(TAG, "Process " + app.info.processName
11566 + " has crashed too many times: killing!");
11567 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11568 app.userId, app.info.processName, app.uid);
11569 mStackSupervisor.handleAppCrashLocked(app);
11570 if (!app.persistent) {
11571 // We don't want to start this process again until the user
11572 // explicitly does so... but for persistent process, we really
11573 // need to keep it running. If a persistent process is actually
11574 // repeatedly crashing, then badness for everyone.
11575 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11576 app.info.processName);
11577 if (!app.isolated) {
11578 // XXX We don't have a way to mark isolated processes
11579 // as bad, since they don't have a peristent identity.
11580 mBadProcesses.put(app.info.processName, app.uid,
11581 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11582 mProcessCrashTimes.remove(app.info.processName, app.uid);
11585 app.removed = true;
11586 // Don't let services in this process be restarted and potentially
11587 // annoy the user repeatedly. Unless it is persistent, since those
11588 // processes run critical code.
11589 removeProcessLocked(app, false, false, "crash");
11590 mStackSupervisor.resumeTopActivitiesLocked();
11593 mStackSupervisor.resumeTopActivitiesLocked();
11595 mStackSupervisor.finishTopRunningActivityLocked(app);
11598 // Bump up the crash count of any services currently running in the proc.
11599 for (int i=app.services.size()-1; i>=0; i--) {
11600 // Any services running in the application need to be placed
11601 // back in the pending list.
11602 ServiceRecord sr = app.services.valueAt(i);
11606 // If the crashing process is what we consider to be the "home process" and it has been
11607 // replaced by a third-party app, clear the package preferred activities from packages
11608 // with a home activity running in the process to prevent a repeatedly crashing app
11609 // from blocking the user to manually clear the list.
11610 final ArrayList<ActivityRecord> activities = app.activities;
11611 if (app == mHomeProcess && activities.size() > 0
11612 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11613 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11614 final ActivityRecord r = activities.get(activityNdx);
11615 if (r.isHomeActivity()) {
11616 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11618 ActivityThread.getPackageManager()
11619 .clearPackagePreferredActivities(r.packageName);
11620 } catch (RemoteException c) {
11621 // pm is in same process, this will never happen.
11627 if (!app.isolated) {
11628 // XXX Can't keep track of crash times for isolated processes,
11629 // because they don't have a perisistent identity.
11630 mProcessCrashTimes.put(app.info.processName, app.uid, now);
11633 if (app.crashHandler != null) mHandler.post(app.crashHandler);
11637 void startAppProblemLocked(ProcessRecord app) {
11638 // If this app is not running under the current user, then we
11639 // can't give it a report button because that would require
11640 // launching the report UI under a different user.
11641 app.errorReportReceiver = null;
11643 for (int userId : mCurrentProfileIds) {
11644 if (app.userId == userId) {
11645 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11646 mContext, app.info.packageName, app.info.flags);
11649 skipCurrentReceiverLocked(app);
11652 void skipCurrentReceiverLocked(ProcessRecord app) {
11653 for (BroadcastQueue queue : mBroadcastQueues) {
11654 queue.skipCurrentReceiverLocked(app);
11659 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11660 * The application process will exit immediately after this call returns.
11661 * @param app object of the crashing app, null for the system server
11662 * @param crashInfo describing the exception
11664 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11665 ProcessRecord r = findAppProcess(app, "Crash");
11666 final String processName = app == null ? "system_server"
11667 : (r == null ? "unknown" : r.processName);
11669 handleApplicationCrashInner("crash", r, processName, crashInfo);
11672 /* Native crash reporting uses this inner version because it needs to be somewhat
11673 * decoupled from the AM-managed cleanup lifecycle
11675 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11676 ApplicationErrorReport.CrashInfo crashInfo) {
11677 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11678 UserHandle.getUserId(Binder.getCallingUid()), processName,
11679 r == null ? -1 : r.info.flags,
11680 crashInfo.exceptionClassName,
11681 crashInfo.exceptionMessage,
11682 crashInfo.throwFileName,
11683 crashInfo.throwLineNumber);
11685 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11687 crashApplication(r, crashInfo);
11690 public void handleApplicationStrictModeViolation(
11693 StrictMode.ViolationInfo info) {
11694 ProcessRecord r = findAppProcess(app, "StrictMode");
11699 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11700 Integer stackFingerprint = info.hashCode();
11701 boolean logIt = true;
11702 synchronized (mAlreadyLoggedViolatedStacks) {
11703 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11705 // TODO: sub-sample into EventLog for these, with
11706 // the info.durationMillis? Then we'd get
11707 // the relative pain numbers, without logging all
11708 // the stack traces repeatedly. We'd want to do
11709 // likewise in the client code, which also does
11710 // dup suppression, before the Binder call.
11712 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11713 mAlreadyLoggedViolatedStacks.clear();
11715 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11719 logStrictModeViolationToDropBox(r, info);
11723 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11724 AppErrorResult result = new AppErrorResult();
11725 synchronized (this) {
11726 final long origId = Binder.clearCallingIdentity();
11728 Message msg = Message.obtain();
11729 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11730 HashMap<String, Object> data = new HashMap<String, Object>();
11731 data.put("result", result);
11732 data.put("app", r);
11733 data.put("violationMask", violationMask);
11734 data.put("info", info);
11736 mUiHandler.sendMessage(msg);
11738 Binder.restoreCallingIdentity(origId);
11740 int res = result.get();
11741 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11745 // Depending on the policy in effect, there could be a bunch of
11746 // these in quick succession so we try to batch these together to
11747 // minimize disk writes, number of dropbox entries, and maximize
11748 // compression, by having more fewer, larger records.
11749 private void logStrictModeViolationToDropBox(
11750 ProcessRecord process,
11751 StrictMode.ViolationInfo info) {
11752 if (info == null) {
11755 final boolean isSystemApp = process == null ||
11756 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11757 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11758 final String processName = process == null ? "unknown" : process.processName;
11759 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11760 final DropBoxManager dbox = (DropBoxManager)
11761 mContext.getSystemService(Context.DROPBOX_SERVICE);
11763 // Exit early if the dropbox isn't configured to accept this report type.
11764 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11766 boolean bufferWasEmpty;
11767 boolean needsFlush;
11768 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11769 synchronized (sb) {
11770 bufferWasEmpty = sb.length() == 0;
11771 appendDropBoxProcessHeaders(process, processName, sb);
11772 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11773 sb.append("System-App: ").append(isSystemApp).append("\n");
11774 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11775 if (info.violationNumThisLoop != 0) {
11776 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11778 if (info.numAnimationsRunning != 0) {
11779 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11781 if (info.broadcastIntentAction != null) {
11782 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11784 if (info.durationMillis != -1) {
11785 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11787 if (info.numInstances != -1) {
11788 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11790 if (info.tags != null) {
11791 for (String tag : info.tags) {
11792 sb.append("Span-Tag: ").append(tag).append("\n");
11796 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11797 sb.append(info.crashInfo.stackTrace);
11800 if (info.message != null) {
11801 sb.append(info.message);
11805 // Only buffer up to ~64k. Various logging bits truncate
11807 needsFlush = (sb.length() > 64 * 1024);
11810 // Flush immediately if the buffer's grown too large, or this
11811 // is a non-system app. Non-system apps are isolated with a
11812 // different tag & policy and not batched.
11814 // Batching is useful during internal testing with
11815 // StrictMode settings turned up high. Without batching,
11816 // thousands of separate files could be created on boot.
11817 if (!isSystemApp || needsFlush) {
11818 new Thread("Error dump: " + dropboxTag) {
11820 public void run() {
11822 synchronized (sb) {
11823 report = sb.toString();
11824 sb.delete(0, sb.length());
11827 if (report.length() != 0) {
11828 dbox.addText(dropboxTag, report);
11835 // System app batching:
11836 if (!bufferWasEmpty) {
11837 // An existing dropbox-writing thread is outstanding, so
11838 // we don't need to start it up. The existing thread will
11839 // catch the buffer appends we just did.
11843 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11844 // (After this point, we shouldn't access AMS internal data structures.)
11845 new Thread("Error dump: " + dropboxTag) {
11847 public void run() {
11848 // 5 second sleep to let stacks arrive and be batched together
11850 Thread.sleep(5000); // 5 seconds
11851 } catch (InterruptedException e) {}
11853 String errorReport;
11854 synchronized (mStrictModeBuffer) {
11855 errorReport = mStrictModeBuffer.toString();
11856 if (errorReport.length() == 0) {
11859 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11860 mStrictModeBuffer.trimToSize();
11862 dbox.addText(dropboxTag, errorReport);
11868 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11869 * @param app object of the crashing app, null for the system server
11870 * @param tag reported by the caller
11871 * @param system whether this wtf is coming from the system
11872 * @param crashInfo describing the context of the error
11873 * @return true if the process should exit immediately (WTF is fatal)
11875 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11876 final ApplicationErrorReport.CrashInfo crashInfo) {
11877 final int callingUid = Binder.getCallingUid();
11878 final int callingPid = Binder.getCallingPid();
11881 // If this is coming from the system, we could very well have low-level
11882 // system locks held, so we want to do this all asynchronously. And we
11883 // never want this to become fatal, so there is that too.
11884 mHandler.post(new Runnable() {
11885 @Override public void run() {
11886 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11892 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11895 if (r != null && r.pid != Process.myPid() &&
11896 Settings.Global.getInt(mContext.getContentResolver(),
11897 Settings.Global.WTF_IS_FATAL, 0) != 0) {
11898 crashApplication(r, crashInfo);
11905 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11906 final ApplicationErrorReport.CrashInfo crashInfo) {
11907 final ProcessRecord r = findAppProcess(app, "WTF");
11908 final String processName = app == null ? "system_server"
11909 : (r == null ? "unknown" : r.processName);
11911 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11912 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11914 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11920 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11921 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11923 private ProcessRecord findAppProcess(IBinder app, String reason) {
11928 synchronized (this) {
11929 final int NP = mProcessNames.getMap().size();
11930 for (int ip=0; ip<NP; ip++) {
11931 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11932 final int NA = apps.size();
11933 for (int ia=0; ia<NA; ia++) {
11934 ProcessRecord p = apps.valueAt(ia);
11935 if (p.thread != null && p.thread.asBinder() == app) {
11941 Slog.w(TAG, "Can't find mystery application for " + reason
11942 + " from pid=" + Binder.getCallingPid()
11943 + " uid=" + Binder.getCallingUid() + ": " + app);
11949 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11950 * to append various headers to the dropbox log text.
11952 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11953 StringBuilder sb) {
11954 // Watchdog thread ends up invoking this function (with
11955 // a null ProcessRecord) to add the stack file to dropbox.
11956 // Do not acquire a lock on this (am) in such cases, as it
11957 // could cause a potential deadlock, if and when watchdog
11958 // is invoked due to unavailability of lock on am and it
11959 // would prevent watchdog from killing system_server.
11960 if (process == null) {
11961 sb.append("Process: ").append(processName).append("\n");
11964 // Note: ProcessRecord 'process' is guarded by the service
11965 // instance. (notably process.pkgList, which could otherwise change
11966 // concurrently during execution of this method)
11967 synchronized (this) {
11968 sb.append("Process: ").append(processName).append("\n");
11969 int flags = process.info.flags;
11970 IPackageManager pm = AppGlobals.getPackageManager();
11971 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11972 for (int ip=0; ip<process.pkgList.size(); ip++) {
11973 String pkg = process.pkgList.keyAt(ip);
11974 sb.append("Package: ").append(pkg);
11976 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11978 sb.append(" v").append(pi.versionCode);
11979 if (pi.versionName != null) {
11980 sb.append(" (").append(pi.versionName).append(")");
11983 } catch (RemoteException e) {
11984 Slog.e(TAG, "Error getting package info: " + pkg, e);
11991 private static String processClass(ProcessRecord process) {
11992 if (process == null || process.pid == MY_PID) {
11993 return "system_server";
11994 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11995 return "system_app";
12002 * Write a description of an error (crash, WTF, ANR) to the drop box.
12003 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12004 * @param process which caused the error, null means the system server
12005 * @param activity which triggered the error, null if unknown
12006 * @param parent activity related to the error, null if unknown
12007 * @param subject line related to the error, null if absent
12008 * @param report in long form describing the error, null if absent
12009 * @param logFile to include in the report, null if none
12010 * @param crashInfo giving an application stack trace, null if absent
12012 public void addErrorToDropBox(String eventType,
12013 ProcessRecord process, String processName, ActivityRecord activity,
12014 ActivityRecord parent, String subject,
12015 final String report, final File logFile,
12016 final ApplicationErrorReport.CrashInfo crashInfo) {
12017 // NOTE -- this must never acquire the ActivityManagerService lock,
12018 // otherwise the watchdog may be prevented from resetting the system.
12020 final String dropboxTag = processClass(process) + "_" + eventType;
12021 final DropBoxManager dbox = (DropBoxManager)
12022 mContext.getSystemService(Context.DROPBOX_SERVICE);
12024 // Exit early if the dropbox isn't configured to accept this report type.
12025 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12027 final StringBuilder sb = new StringBuilder(1024);
12028 appendDropBoxProcessHeaders(process, processName, sb);
12029 if (activity != null) {
12030 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12032 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12033 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12035 if (parent != null && parent != activity) {
12036 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12038 if (subject != null) {
12039 sb.append("Subject: ").append(subject).append("\n");
12041 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12042 if (Debug.isDebuggerConnected()) {
12043 sb.append("Debugger: Connected\n");
12047 // Do the rest in a worker thread to avoid blocking the caller on I/O
12048 // (After this point, we shouldn't access AMS internal data structures.)
12049 Thread worker = new Thread("Error dump: " + dropboxTag) {
12051 public void run() {
12052 if (report != null) {
12055 if (logFile != null) {
12057 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12058 "\n\n[[TRUNCATED]]"));
12059 } catch (IOException e) {
12060 Slog.e(TAG, "Error reading " + logFile, e);
12063 if (crashInfo != null && crashInfo.stackTrace != null) {
12064 sb.append(crashInfo.stackTrace);
12067 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12068 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12072 // Merge several logcat streams, and take the last N lines
12073 InputStreamReader input = null;
12075 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12076 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12078 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12080 try { logcat.getOutputStream().close(); } catch (IOException e) {}
12081 try { logcat.getErrorStream().close(); } catch (IOException e) {}
12082 input = new InputStreamReader(logcat.getInputStream());
12085 char[] buf = new char[8192];
12086 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12087 } catch (IOException e) {
12088 Slog.e(TAG, "Error running logcat", e);
12090 if (input != null) try { input.close(); } catch (IOException e) {}
12094 dbox.addText(dropboxTag, sb.toString());
12098 if (process == null) {
12099 // If process is null, we are being called from some internal code
12100 // and may be about to die -- run this synchronously.
12108 * Bring up the "unexpected error" dialog box for a crashing app.
12109 * Deal with edge cases (intercepts from instrumented applications,
12110 * ActivityController, error intent receivers, that sort of thing).
12111 * @param r the application crashing
12112 * @param crashInfo describing the failure
12114 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12115 long timeMillis = System.currentTimeMillis();
12116 String shortMsg = crashInfo.exceptionClassName;
12117 String longMsg = crashInfo.exceptionMessage;
12118 String stackTrace = crashInfo.stackTrace;
12119 if (shortMsg != null && longMsg != null) {
12120 longMsg = shortMsg + ": " + longMsg;
12121 } else if (shortMsg != null) {
12122 longMsg = shortMsg;
12125 AppErrorResult result = new AppErrorResult();
12126 synchronized (this) {
12127 if (mController != null) {
12129 String name = r != null ? r.processName : null;
12130 int pid = r != null ? r.pid : Binder.getCallingPid();
12131 int uid = r != null ? r.info.uid : Binder.getCallingUid();
12132 if (!mController.appCrashed(name, pid,
12133 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12134 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12135 && "Native crash".equals(crashInfo.exceptionClassName)) {
12136 Slog.w(TAG, "Skip killing native crashed app " + name
12137 + "(" + pid + ") during testing");
12139 Slog.w(TAG, "Force-killing crashed app " + name
12140 + " at watcher's request");
12142 r.kill("crash", true);
12145 Process.killProcess(pid);
12146 Process.killProcessGroup(uid, pid);
12151 } catch (RemoteException e) {
12152 mController = null;
12153 Watchdog.getInstance().setActivityController(null);
12157 final long origId = Binder.clearCallingIdentity();
12159 // If this process is running instrumentation, finish it.
12160 if (r != null && r.instrumentationClass != null) {
12161 Slog.w(TAG, "Error in app " + r.processName
12162 + " running instrumentation " + r.instrumentationClass + ":");
12163 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
12164 if (longMsg != null) Slog.w(TAG, " " + longMsg);
12165 Bundle info = new Bundle();
12166 info.putString("shortMsg", shortMsg);
12167 info.putString("longMsg", longMsg);
12168 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12169 Binder.restoreCallingIdentity(origId);
12173 // Log crash in battery stats.
12175 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12178 // If we can't identify the process or it's already exceeded its crash quota,
12179 // quit right away without showing a crash dialog.
12180 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12181 Binder.restoreCallingIdentity(origId);
12185 Message msg = Message.obtain();
12186 msg.what = SHOW_ERROR_MSG;
12187 HashMap data = new HashMap();
12188 data.put("result", result);
12189 data.put("app", r);
12191 mUiHandler.sendMessage(msg);
12193 Binder.restoreCallingIdentity(origId);
12196 int res = result.get();
12198 Intent appErrorIntent = null;
12199 synchronized (this) {
12200 if (r != null && !r.isolated) {
12201 // XXX Can't keep track of crash time for isolated processes,
12202 // since they don't have a persistent identity.
12203 mProcessCrashTimes.put(r.info.processName, r.uid,
12204 SystemClock.uptimeMillis());
12206 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12207 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12211 if (appErrorIntent != null) {
12213 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12214 } catch (ActivityNotFoundException e) {
12215 Slog.w(TAG, "bug report receiver dissappeared", e);
12220 Intent createAppErrorIntentLocked(ProcessRecord r,
12221 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12222 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12223 if (report == null) {
12226 Intent result = new Intent(Intent.ACTION_APP_ERROR);
12227 result.setComponent(r.errorReportReceiver);
12228 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12229 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12233 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12234 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12235 if (r.errorReportReceiver == null) {
12239 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12243 ApplicationErrorReport report = new ApplicationErrorReport();
12244 report.packageName = r.info.packageName;
12245 report.installerPackageName = r.errorReportReceiver.getPackageName();
12246 report.processName = r.processName;
12247 report.time = timeMillis;
12248 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12250 if (r.crashing || r.forceCrashReport) {
12251 report.type = ApplicationErrorReport.TYPE_CRASH;
12252 report.crashInfo = crashInfo;
12253 } else if (r.notResponding) {
12254 report.type = ApplicationErrorReport.TYPE_ANR;
12255 report.anrInfo = new ApplicationErrorReport.AnrInfo();
12257 report.anrInfo.activity = r.notRespondingReport.tag;
12258 report.anrInfo.cause = r.notRespondingReport.shortMsg;
12259 report.anrInfo.info = r.notRespondingReport.longMsg;
12265 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12266 enforceNotIsolatedCaller("getProcessesInErrorState");
12267 // assume our apps are happy - lazy create the list
12268 List<ActivityManager.ProcessErrorStateInfo> errList = null;
12270 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12271 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12272 int userId = UserHandle.getUserId(Binder.getCallingUid());
12274 synchronized (this) {
12276 // iterate across all processes
12277 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12278 ProcessRecord app = mLruProcesses.get(i);
12279 if (!allUsers && app.userId != userId) {
12282 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12283 // This one's in trouble, so we'll generate a report for it
12284 // crashes are higher priority (in case there's a crash *and* an anr)
12285 ActivityManager.ProcessErrorStateInfo report = null;
12286 if (app.crashing) {
12287 report = app.crashingReport;
12288 } else if (app.notResponding) {
12289 report = app.notRespondingReport;
12292 if (report != null) {
12293 if (errList == null) {
12294 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12296 errList.add(report);
12298 Slog.w(TAG, "Missing app error report, app = " + app.processName +
12299 " crashing = " + app.crashing +
12300 " notResponding = " + app.notResponding);
12309 static int procStateToImportance(int procState, int memAdj,
12310 ActivityManager.RunningAppProcessInfo currApp) {
12311 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12312 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12313 currApp.lru = memAdj;
12320 private void fillInProcMemInfo(ProcessRecord app,
12321 ActivityManager.RunningAppProcessInfo outInfo) {
12322 outInfo.pid = app.pid;
12323 outInfo.uid = app.info.uid;
12324 if (mHeavyWeightProcess == app) {
12325 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12327 if (app.persistent) {
12328 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12330 if (app.activities.size() > 0) {
12331 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12333 outInfo.lastTrimLevel = app.trimMemoryLevel;
12334 int adj = app.curAdj;
12335 int procState = app.curProcState;
12336 outInfo.importance = procStateToImportance(procState, adj, outInfo);
12337 outInfo.importanceReasonCode = app.adjTypeCode;
12338 outInfo.processState = app.curProcState;
12341 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12342 enforceNotIsolatedCaller("getRunningAppProcesses");
12344 final int callingUid = Binder.getCallingUid();
12346 // Lazy instantiation of list
12347 List<ActivityManager.RunningAppProcessInfo> runList = null;
12348 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12349 callingUid) == PackageManager.PERMISSION_GRANTED;
12350 final int userId = UserHandle.getUserId(callingUid);
12351 final boolean allUids = isGetTasksAllowed(
12352 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12354 synchronized (this) {
12355 // Iterate across all processes
12356 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12357 ProcessRecord app = mLruProcesses.get(i);
12358 if ((!allUsers && app.userId != userId)
12359 || (!allUids && app.uid != callingUid)) {
12362 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12363 // Generate process state info for running application
12364 ActivityManager.RunningAppProcessInfo currApp =
12365 new ActivityManager.RunningAppProcessInfo(app.processName,
12366 app.pid, app.getPackageList());
12367 fillInProcMemInfo(app, currApp);
12368 if (app.adjSource instanceof ProcessRecord) {
12369 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12370 currApp.importanceReasonImportance =
12371 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12372 app.adjSourceProcState);
12373 } else if (app.adjSource instanceof ActivityRecord) {
12374 ActivityRecord r = (ActivityRecord)app.adjSource;
12375 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12377 if (app.adjTarget instanceof ComponentName) {
12378 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12380 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12381 // + " lru=" + currApp.lru);
12382 if (runList == null) {
12383 runList = new ArrayList<>();
12385 runList.add(currApp);
12392 public List<ApplicationInfo> getRunningExternalApplications() {
12393 enforceNotIsolatedCaller("getRunningExternalApplications");
12394 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12395 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12396 if (runningApps != null && runningApps.size() > 0) {
12397 Set<String> extList = new HashSet<String>();
12398 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12399 if (app.pkgList != null) {
12400 for (String pkg : app.pkgList) {
12405 IPackageManager pm = AppGlobals.getPackageManager();
12406 for (String pkg : extList) {
12408 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12409 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12412 } catch (RemoteException e) {
12420 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12421 enforceNotIsolatedCaller("getMyMemoryState");
12422 synchronized (this) {
12423 ProcessRecord proc;
12424 synchronized (mPidsSelfLocked) {
12425 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12427 fillInProcMemInfo(proc, outInfo);
12432 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12433 if (checkCallingPermission(android.Manifest.permission.DUMP)
12434 != PackageManager.PERMISSION_GRANTED) {
12435 pw.println("Permission Denial: can't dump ActivityManager from from pid="
12436 + Binder.getCallingPid()
12437 + ", uid=" + Binder.getCallingUid()
12438 + " without permission "
12439 + android.Manifest.permission.DUMP);
12443 boolean dumpAll = false;
12444 boolean dumpClient = false;
12445 String dumpPackage = null;
12448 while (opti < args.length) {
12449 String opt = args[opti];
12450 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12454 if ("-a".equals(opt)) {
12456 } else if ("-c".equals(opt)) {
12458 } else if ("-p".equals(opt)) {
12459 if (opti < args.length) {
12460 dumpPackage = args[opti];
12463 pw.println("Error: -p option requires package argument");
12467 } else if ("-h".equals(opt)) {
12468 pw.println("Activity manager dump options:");
12469 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ...");
12470 pw.println(" cmd may be one of:");
12471 pw.println(" a[ctivities]: activity stack state");
12472 pw.println(" r[recents]: recent activities state");
12473 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12474 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
12475 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
12476 pw.println(" o[om]: out of memory management");
12477 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
12478 pw.println(" provider [COMP_SPEC]: provider client-side state");
12479 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
12480 pw.println(" as[sociations]: tracked app associations");
12481 pw.println(" service [COMP_SPEC]: service client-side state");
12482 pw.println(" package [PACKAGE_NAME]: all state related to given package");
12483 pw.println(" all: dump all activities");
12484 pw.println(" top: dump the top activity");
12485 pw.println(" write: write all pending state to storage");
12486 pw.println(" track-associations: enable association tracking");
12487 pw.println(" untrack-associations: disable and clear association tracking");
12488 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
12489 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
12490 pw.println(" a partial substring in a component name, a");
12491 pw.println(" hex object identifier.");
12492 pw.println(" -a: include all available server state.");
12493 pw.println(" -c: include client state.");
12494 pw.println(" -p: limit output to given package.");
12497 pw.println("Unknown argument: " + opt + "; use -h for help");
12501 long origId = Binder.clearCallingIdentity();
12502 boolean more = false;
12503 // Is the caller requesting to dump a particular piece of data?
12504 if (opti < args.length) {
12505 String cmd = args[opti];
12507 if ("activities".equals(cmd) || "a".equals(cmd)) {
12508 synchronized (this) {
12509 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12511 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12512 synchronized (this) {
12513 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12515 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12518 if (opti >= args.length) {
12520 newArgs = EMPTY_STRING_ARRAY;
12522 dumpPackage = args[opti];
12524 newArgs = new String[args.length - opti];
12525 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12526 args.length - opti);
12528 synchronized (this) {
12529 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12531 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12534 if (opti >= args.length) {
12536 newArgs = EMPTY_STRING_ARRAY;
12538 dumpPackage = args[opti];
12540 newArgs = new String[args.length - opti];
12541 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12542 args.length - opti);
12544 synchronized (this) {
12545 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12547 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12550 if (opti >= args.length) {
12552 newArgs = EMPTY_STRING_ARRAY;
12554 dumpPackage = args[opti];
12556 newArgs = new String[args.length - opti];
12557 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12558 args.length - opti);
12560 synchronized (this) {
12561 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12563 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12564 synchronized (this) {
12565 dumpOomLocked(fd, pw, args, opti, true);
12567 } else if ("provider".equals(cmd)) {
12570 if (opti >= args.length) {
12572 newArgs = EMPTY_STRING_ARRAY;
12576 newArgs = new String[args.length - opti];
12577 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12579 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12580 pw.println("No providers match: " + name);
12581 pw.println("Use -h for help.");
12583 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12584 synchronized (this) {
12585 dumpProvidersLocked(fd, pw, args, opti, true, null);
12587 } else if ("service".equals(cmd)) {
12590 if (opti >= args.length) {
12592 newArgs = EMPTY_STRING_ARRAY;
12596 newArgs = new String[args.length - opti];
12597 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12598 args.length - opti);
12600 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12601 pw.println("No services match: " + name);
12602 pw.println("Use -h for help.");
12604 } else if ("package".equals(cmd)) {
12606 if (opti >= args.length) {
12607 pw.println("package: no package name specified");
12608 pw.println("Use -h for help.");
12610 dumpPackage = args[opti];
12612 newArgs = new String[args.length - opti];
12613 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12614 args.length - opti);
12619 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12620 synchronized (this) {
12621 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12623 } else if ("services".equals(cmd) || "s".equals(cmd)) {
12624 synchronized (this) {
12625 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12627 } else if ("write".equals(cmd)) {
12628 mTaskPersister.flush();
12629 pw.println("All tasks persisted.");
12631 } else if ("track-associations".equals(cmd)) {
12632 synchronized (this) {
12633 if (!mTrackingAssociations) {
12634 mTrackingAssociations = true;
12635 pw.println("Association tracking started.");
12637 pw.println("Association tracking already enabled.");
12641 } else if ("untrack-associations".equals(cmd)) {
12642 synchronized (this) {
12643 if (mTrackingAssociations) {
12644 mTrackingAssociations = false;
12645 mAssociations.clear();
12646 pw.println("Association tracking stopped.");
12648 pw.println("Association tracking not running.");
12653 // Dumping a single activity?
12654 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12655 pw.println("Bad activity command, or no activities match: " + cmd);
12656 pw.println("Use -h for help.");
12660 Binder.restoreCallingIdentity(origId);
12665 // No piece of data specified, dump everything.
12666 synchronized (this) {
12667 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12670 pw.println("-------------------------------------------------------------------------------");
12672 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12675 pw.println("-------------------------------------------------------------------------------");
12677 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12680 pw.println("-------------------------------------------------------------------------------");
12682 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12685 pw.println("-------------------------------------------------------------------------------");
12687 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12690 pw.println("-------------------------------------------------------------------------------");
12692 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12693 if (mAssociations.size() > 0) {
12696 pw.println("-------------------------------------------------------------------------------");
12698 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12702 pw.println("-------------------------------------------------------------------------------");
12704 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12706 Binder.restoreCallingIdentity(origId);
12709 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12710 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12711 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12713 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12715 boolean needSep = printedAnything;
12717 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12718 dumpPackage, needSep, " mFocusedActivity: ");
12720 printedAnything = true;
12724 if (dumpPackage == null) {
12729 printedAnything = true;
12730 mStackSupervisor.dump(pw, " ");
12733 if (!printedAnything) {
12734 pw.println(" (nothing)");
12738 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12739 int opti, boolean dumpAll, String dumpPackage) {
12740 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12742 boolean printedAnything = false;
12744 if (mRecentTasks != null && mRecentTasks.size() > 0) {
12745 boolean printedHeader = false;
12747 final int N = mRecentTasks.size();
12748 for (int i=0; i<N; i++) {
12749 TaskRecord tr = mRecentTasks.get(i);
12750 if (dumpPackage != null) {
12751 if (tr.realActivity == null ||
12752 !dumpPackage.equals(tr.realActivity)) {
12756 if (!printedHeader) {
12757 pw.println(" Recent tasks:");
12758 printedHeader = true;
12759 printedAnything = true;
12761 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
12764 mRecentTasks.get(i).dump(pw, " ");
12769 if (!printedAnything) {
12770 pw.println(" (nothing)");
12774 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12775 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12776 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12779 if (dumpPackage != null) {
12780 IPackageManager pm = AppGlobals.getPackageManager();
12782 dumpUid = pm.getPackageUid(dumpPackage, 0);
12783 } catch (RemoteException e) {
12787 boolean printedAnything = false;
12789 final long now = SystemClock.uptimeMillis();
12791 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12792 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12793 = mAssociations.valueAt(i1);
12794 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12795 SparseArray<ArrayMap<String, Association>> sourceUids
12796 = targetComponents.valueAt(i2);
12797 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12798 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12799 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12800 Association ass = sourceProcesses.valueAt(i4);
12801 if (dumpPackage != null) {
12802 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12803 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12807 printedAnything = true;
12809 pw.print(ass.mTargetProcess);
12811 UserHandle.formatUid(pw, ass.mTargetUid);
12813 pw.print(ass.mSourceProcess);
12815 UserHandle.formatUid(pw, ass.mSourceUid);
12818 pw.print(ass.mTargetComponent.flattenToShortString());
12821 long dur = ass.mTime;
12822 if (ass.mNesting > 0) {
12823 dur += now - ass.mStartTime;
12825 TimeUtils.formatDuration(dur, pw);
12827 pw.print(ass.mCount);
12828 pw.println(" times)");
12829 if (ass.mNesting > 0) {
12831 pw.print(" Currently active: ");
12832 TimeUtils.formatDuration(now - ass.mStartTime, pw);
12841 if (!printedAnything) {
12842 pw.println(" (nothing)");
12846 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12847 int opti, boolean dumpAll, String dumpPackage) {
12848 boolean needSep = false;
12849 boolean printedAnything = false;
12852 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12855 final int NP = mProcessNames.getMap().size();
12856 for (int ip=0; ip<NP; ip++) {
12857 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12858 final int NA = procs.size();
12859 for (int ia=0; ia<NA; ia++) {
12860 ProcessRecord r = procs.valueAt(ia);
12861 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12865 pw.println(" All known processes:");
12867 printedAnything = true;
12869 pw.print(r.persistent ? " *PERS*" : " *APP*");
12870 pw.print(" UID "); pw.print(procs.keyAt(ia));
12871 pw.print(" "); pw.println(r);
12873 if (r.persistent) {
12880 if (mIsolatedProcesses.size() > 0) {
12881 boolean printed = false;
12882 for (int i=0; i<mIsolatedProcesses.size(); i++) {
12883 ProcessRecord r = mIsolatedProcesses.valueAt(i);
12884 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12891 pw.println(" Isolated process list (sorted by uid):");
12892 printedAnything = true;
12896 pw.println(String.format("%sIsolated #%2d: %s",
12897 " ", i, r.toString()));
12901 if (mLruProcesses.size() > 0) {
12905 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12906 pw.print(" total, non-act at ");
12907 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12908 pw.print(", non-svc at ");
12909 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12911 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
12913 printedAnything = true;
12916 if (dumpAll || dumpPackage != null) {
12917 synchronized (mPidsSelfLocked) {
12918 boolean printed = false;
12919 for (int i=0; i<mPidsSelfLocked.size(); i++) {
12920 ProcessRecord r = mPidsSelfLocked.valueAt(i);
12921 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12925 if (needSep) pw.println();
12927 pw.println(" PID mappings:");
12929 printedAnything = true;
12931 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12932 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12937 if (mForegroundProcesses.size() > 0) {
12938 synchronized (mPidsSelfLocked) {
12939 boolean printed = false;
12940 for (int i=0; i<mForegroundProcesses.size(); i++) {
12941 ProcessRecord r = mPidsSelfLocked.get(
12942 mForegroundProcesses.valueAt(i).pid);
12943 if (dumpPackage != null && (r == null
12944 || !r.pkgList.containsKey(dumpPackage))) {
12948 if (needSep) pw.println();
12950 pw.println(" Foreground Processes:");
12952 printedAnything = true;
12954 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
12955 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12960 if (mPersistentStartingProcesses.size() > 0) {
12961 if (needSep) pw.println();
12963 printedAnything = true;
12964 pw.println(" Persisent processes that are starting:");
12965 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
12966 "Starting Norm", "Restarting PERS", dumpPackage);
12969 if (mRemovedProcesses.size() > 0) {
12970 if (needSep) pw.println();
12972 printedAnything = true;
12973 pw.println(" Processes that are being removed:");
12974 dumpProcessList(pw, this, mRemovedProcesses, " ",
12975 "Removed Norm", "Removed PERS", dumpPackage);
12978 if (mProcessesOnHold.size() > 0) {
12979 if (needSep) pw.println();
12981 printedAnything = true;
12982 pw.println(" Processes that are on old until the system is ready:");
12983 dumpProcessList(pw, this, mProcessesOnHold, " ",
12984 "OnHold Norm", "OnHold PERS", dumpPackage);
12987 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12989 if (mProcessCrashTimes.getMap().size() > 0) {
12990 boolean printed = false;
12991 long now = SystemClock.uptimeMillis();
12992 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12993 final int NP = pmap.size();
12994 for (int ip=0; ip<NP; ip++) {
12995 String pname = pmap.keyAt(ip);
12996 SparseArray<Long> uids = pmap.valueAt(ip);
12997 final int N = uids.size();
12998 for (int i=0; i<N; i++) {
12999 int puid = uids.keyAt(i);
13000 ProcessRecord r = mProcessNames.get(pname, puid);
13001 if (dumpPackage != null && (r == null
13002 || !r.pkgList.containsKey(dumpPackage))) {
13006 if (needSep) pw.println();
13008 pw.println(" Time since processes crashed:");
13010 printedAnything = true;
13012 pw.print(" Process "); pw.print(pname);
13013 pw.print(" uid "); pw.print(puid);
13014 pw.print(": last crashed ");
13015 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13016 pw.println(" ago");
13021 if (mBadProcesses.getMap().size() > 0) {
13022 boolean printed = false;
13023 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13024 final int NP = pmap.size();
13025 for (int ip=0; ip<NP; ip++) {
13026 String pname = pmap.keyAt(ip);
13027 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13028 final int N = uids.size();
13029 for (int i=0; i<N; i++) {
13030 int puid = uids.keyAt(i);
13031 ProcessRecord r = mProcessNames.get(pname, puid);
13032 if (dumpPackage != null && (r == null
13033 || !r.pkgList.containsKey(dumpPackage))) {
13037 if (needSep) pw.println();
13039 pw.println(" Bad processes:");
13040 printedAnything = true;
13042 BadProcessInfo info = uids.valueAt(i);
13043 pw.print(" Bad process "); pw.print(pname);
13044 pw.print(" uid "); pw.print(puid);
13045 pw.print(": crashed at time "); pw.println(info.time);
13046 if (info.shortMsg != null) {
13047 pw.print(" Short msg: "); pw.println(info.shortMsg);
13049 if (info.longMsg != null) {
13050 pw.print(" Long msg: "); pw.println(info.longMsg);
13052 if (info.stack != null) {
13053 pw.println(" Stack:");
13055 for (int pos=0; pos<info.stack.length(); pos++) {
13056 if (info.stack.charAt(pos) == '\n') {
13058 pw.write(info.stack, lastPos, pos-lastPos);
13063 if (lastPos < info.stack.length()) {
13065 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13073 if (dumpPackage == null) {
13076 pw.println(" mStartedUsers:");
13077 for (int i=0; i<mStartedUsers.size(); i++) {
13078 UserStartedState uss = mStartedUsers.valueAt(i);
13079 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
13080 pw.print(": "); uss.dump("", pw);
13082 pw.print(" mStartedUserArray: [");
13083 for (int i=0; i<mStartedUserArray.length; i++) {
13084 if (i > 0) pw.print(", ");
13085 pw.print(mStartedUserArray[i]);
13088 pw.print(" mUserLru: [");
13089 for (int i=0; i<mUserLru.size(); i++) {
13090 if (i > 0) pw.print(", ");
13091 pw.print(mUserLru.get(i));
13095 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13097 synchronized (mUserProfileGroupIdsSelfLocked) {
13098 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13099 pw.println(" mUserProfileGroupIds:");
13100 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13101 pw.print(" User #");
13102 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13103 pw.print(" -> profile #");
13104 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13109 if (mHomeProcess != null && (dumpPackage == null
13110 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13115 pw.println(" mHomeProcess: " + mHomeProcess);
13117 if (mPreviousProcess != null && (dumpPackage == null
13118 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13123 pw.println(" mPreviousProcess: " + mPreviousProcess);
13126 StringBuilder sb = new StringBuilder(128);
13127 sb.append(" mPreviousProcessVisibleTime: ");
13128 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13131 if (mHeavyWeightProcess != null && (dumpPackage == null
13132 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13137 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13139 if (dumpPackage == null) {
13140 pw.println(" mConfiguration: " + mConfiguration);
13143 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13144 if (mCompatModePackages.getPackages().size() > 0) {
13145 boolean printed = false;
13146 for (Map.Entry<String, Integer> entry
13147 : mCompatModePackages.getPackages().entrySet()) {
13148 String pkg = entry.getKey();
13149 int mode = entry.getValue();
13150 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13154 pw.println(" mScreenCompatPackages:");
13157 pw.print(" "); pw.print(pkg); pw.print(": ");
13158 pw.print(mode); pw.println();
13162 if (dumpPackage == null) {
13163 pw.println(" mWakefulness="
13164 + PowerManagerInternal.wakefulnessToString(mWakefulness));
13165 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
13166 + lockScreenShownToString());
13167 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
13168 + " mTestPssMode=" + mTestPssMode);
13170 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13171 || mOrigWaitForDebugger) {
13172 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13173 || dumpPackage.equals(mOrigDebugApp)) {
13178 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13179 + " mDebugTransient=" + mDebugTransient
13180 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13183 if (mOpenGlTraceApp != null) {
13184 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13189 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
13192 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13193 || mProfileFd != null) {
13194 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13199 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13200 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13201 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13202 + mAutoStopProfiler);
13203 pw.println(" mProfileType=" + mProfileType);
13206 if (dumpPackage == null) {
13207 if (mAlwaysFinishActivities || mController != null) {
13208 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
13209 + " mController=" + mController);
13212 pw.println(" Total persistent processes: " + numPers);
13213 pw.println(" mProcessesReady=" + mProcessesReady
13214 + " mSystemReady=" + mSystemReady
13215 + " mBooted=" + mBooted
13216 + " mFactoryTest=" + mFactoryTest);
13217 pw.println(" mBooting=" + mBooting
13218 + " mCallFinishBooting=" + mCallFinishBooting
13219 + " mBootAnimationComplete=" + mBootAnimationComplete);
13220 pw.print(" mLastPowerCheckRealtime=");
13221 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13223 pw.print(" mLastPowerCheckUptime=");
13224 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13226 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13227 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13228 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13229 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
13230 + " (" + mLruProcesses.size() + " total)"
13231 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13232 + " mNumServiceProcs=" + mNumServiceProcs
13233 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13234 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
13235 + " mLastMemoryLevel" + mLastMemoryLevel
13236 + " mLastNumProcesses" + mLastNumProcesses);
13237 long now = SystemClock.uptimeMillis();
13238 pw.print(" mLastIdleTime=");
13239 TimeUtils.formatDuration(now, mLastIdleTime, pw);
13240 pw.print(" mLowRamSinceLastIdle=");
13241 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13246 if (!printedAnything) {
13247 pw.println(" (nothing)");
13251 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13252 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13253 if (mProcessesToGc.size() > 0) {
13254 boolean printed = false;
13255 long now = SystemClock.uptimeMillis();
13256 for (int i=0; i<mProcessesToGc.size(); i++) {
13257 ProcessRecord proc = mProcessesToGc.get(i);
13258 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13262 if (needSep) pw.println();
13264 pw.println(" Processes that are waiting to GC:");
13267 pw.print(" Process "); pw.println(proc);
13268 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
13269 pw.print(", last gced=");
13270 pw.print(now-proc.lastRequestedGc);
13271 pw.print(" ms ago, last lowMem=");
13272 pw.print(now-proc.lastLowMemory);
13273 pw.println(" ms ago");
13280 void printOomLevel(PrintWriter pw, String name, int adj) {
13284 if (adj < 10) pw.print(' ');
13286 if (adj > -10) pw.print(' ');
13292 pw.print(mProcessList.getMemLevel(adj)/1024);
13293 pw.println(" kB)");
13296 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13297 int opti, boolean dumpAll) {
13298 boolean needSep = false;
13300 if (mLruProcesses.size() > 0) {
13301 if (needSep) pw.println();
13303 pw.println(" OOM levels:");
13304 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13305 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13306 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13307 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13308 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13309 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13310 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13311 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13312 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13313 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13314 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13315 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13316 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13317 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13319 if (needSep) pw.println();
13320 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
13321 pw.print(" total, non-act at ");
13322 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13323 pw.print(", non-svc at ");
13324 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13326 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
13330 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13333 pw.println(" mHomeProcess: " + mHomeProcess);
13334 pw.println(" mPreviousProcess: " + mPreviousProcess);
13335 if (mHeavyWeightProcess != null) {
13336 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13343 * There are three ways to call this:
13344 * - no provider specified: dump all the providers
13345 * - a flattened component name that matched an existing provider was specified as the
13346 * first arg: dump that one provider
13347 * - the first arg isn't the flattened component name of an existing provider:
13348 * dump all providers whose component contains the first arg as a substring
13350 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13351 int opti, boolean dumpAll) {
13352 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13355 static class ItemMatcher {
13356 ArrayList<ComponentName> components;
13357 ArrayList<String> strings;
13358 ArrayList<Integer> objects;
13365 void build(String name) {
13366 ComponentName componentName = ComponentName.unflattenFromString(name);
13367 if (componentName != null) {
13368 if (components == null) {
13369 components = new ArrayList<ComponentName>();
13371 components.add(componentName);
13375 // Not a '/' separated full component name; maybe an object ID?
13377 objectId = Integer.parseInt(name, 16);
13378 if (objects == null) {
13379 objects = new ArrayList<Integer>();
13381 objects.add(objectId);
13383 } catch (RuntimeException e) {
13384 // Not an integer; just do string match.
13385 if (strings == null) {
13386 strings = new ArrayList<String>();
13394 int build(String[] args, int opti) {
13395 for (; opti<args.length; opti++) {
13396 String name = args[opti];
13397 if ("--".equals(name)) {
13405 boolean match(Object object, ComponentName comp) {
13409 if (components != null) {
13410 for (int i=0; i<components.size(); i++) {
13411 if (components.get(i).equals(comp)) {
13416 if (objects != null) {
13417 for (int i=0; i<objects.size(); i++) {
13418 if (System.identityHashCode(object) == objects.get(i)) {
13423 if (strings != null) {
13424 String flat = comp.flattenToString();
13425 for (int i=0; i<strings.size(); i++) {
13426 if (flat.contains(strings.get(i))) {
13436 * There are three things that cmd can be:
13437 * - a flattened component name that matches an existing activity
13438 * - the cmd arg isn't the flattened component name of an existing activity:
13439 * dump all activity whose component contains the cmd as a substring
13440 * - A hex number of the ActivityRecord object instance.
13442 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13443 int opti, boolean dumpAll) {
13444 ArrayList<ActivityRecord> activities;
13446 synchronized (this) {
13447 activities = mStackSupervisor.getDumpActivitiesLocked(name);
13450 if (activities.size() <= 0) {
13454 String[] newArgs = new String[args.length - opti];
13455 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13457 TaskRecord lastTask = null;
13458 boolean needSep = false;
13459 for (int i=activities.size()-1; i>=0; i--) {
13460 ActivityRecord r = activities.get(i);
13465 synchronized (this) {
13466 if (lastTask != r.task) {
13468 pw.print("TASK "); pw.print(lastTask.affinity);
13469 pw.print(" id="); pw.println(lastTask.taskId);
13471 lastTask.dump(pw, " ");
13475 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
13481 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13482 * there is a thread associated with the activity.
13484 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13485 final ActivityRecord r, String[] args, boolean dumpAll) {
13486 String innerPrefix = prefix + " ";
13487 synchronized (this) {
13488 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13489 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13491 if (r.app != null) pw.println(r.app.pid);
13492 else pw.println("(not running)");
13494 r.dump(pw, innerPrefix);
13497 if (r.app != null && r.app.thread != null) {
13498 // flush anything that is already in the PrintWriter since the thread is going
13499 // to write to the file descriptor directly
13502 TransferPipe tp = new TransferPipe();
13504 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13505 r.appToken, innerPrefix, args);
13510 } catch (IOException e) {
13511 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13512 } catch (RemoteException e) {
13513 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13518 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13519 int opti, boolean dumpAll, String dumpPackage) {
13520 boolean needSep = false;
13521 boolean onlyHistory = false;
13522 boolean printedAnything = false;
13524 if ("history".equals(dumpPackage)) {
13525 if (opti < args.length && "-s".equals(args[opti])) {
13528 onlyHistory = true;
13529 dumpPackage = null;
13532 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13533 if (!onlyHistory && dumpAll) {
13534 if (mRegisteredReceivers.size() > 0) {
13535 boolean printed = false;
13536 Iterator it = mRegisteredReceivers.values().iterator();
13537 while (it.hasNext()) {
13538 ReceiverList r = (ReceiverList)it.next();
13539 if (dumpPackage != null && (r.app == null ||
13540 !dumpPackage.equals(r.app.info.packageName))) {
13544 pw.println(" Registered Receivers:");
13547 printedAnything = true;
13549 pw.print(" * "); pw.println(r);
13554 if (mReceiverResolver.dump(pw, needSep ?
13555 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
13556 " ", dumpPackage, false, false)) {
13558 printedAnything = true;
13562 for (BroadcastQueue q : mBroadcastQueues) {
13563 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13564 printedAnything |= needSep;
13569 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13570 for (int user=0; user<mStickyBroadcasts.size(); user++) {
13575 printedAnything = true;
13576 pw.print(" Sticky broadcasts for user ");
13577 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13578 StringBuilder sb = new StringBuilder(128);
13579 for (Map.Entry<String, ArrayList<Intent>> ent
13580 : mStickyBroadcasts.valueAt(user).entrySet()) {
13581 pw.print(" * Sticky action "); pw.print(ent.getKey());
13584 ArrayList<Intent> intents = ent.getValue();
13585 final int N = intents.size();
13586 for (int i=0; i<N; i++) {
13588 sb.append(" Intent: ");
13589 intents.get(i).toShortString(sb, false, true, false, false);
13590 pw.println(sb.toString());
13591 Bundle bundle = intents.get(i).getExtras();
13592 if (bundle != null) {
13594 pw.println(bundle.toString());
13604 if (!onlyHistory && dumpAll) {
13606 for (BroadcastQueue queue : mBroadcastQueues) {
13607 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
13608 + queue.mBroadcastsScheduled);
13610 pw.println(" mHandler:");
13611 mHandler.dump(new PrintWriterPrinter(pw), " ");
13613 printedAnything = true;
13616 if (!printedAnything) {
13617 pw.println(" (nothing)");
13621 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13622 int opti, boolean dumpAll, String dumpPackage) {
13624 boolean printedAnything = false;
13626 ItemMatcher matcher = new ItemMatcher();
13627 matcher.build(args, opti);
13629 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13631 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13632 printedAnything |= needSep;
13634 if (mLaunchingProviders.size() > 0) {
13635 boolean printed = false;
13636 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13637 ContentProviderRecord r = mLaunchingProviders.get(i);
13638 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13642 if (needSep) pw.println();
13644 pw.println(" Launching content providers:");
13646 printedAnything = true;
13648 pw.print(" Launching #"); pw.print(i); pw.print(": ");
13653 if (mGrantedUriPermissions.size() > 0) {
13654 boolean printed = false;
13656 if (dumpPackage != null) {
13658 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13659 } catch (NameNotFoundException e) {
13663 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13664 int uid = mGrantedUriPermissions.keyAt(i);
13665 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13668 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13670 if (needSep) pw.println();
13672 pw.println(" Granted Uri Permissions:");
13674 printedAnything = true;
13676 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
13677 for (UriPermission perm : perms.values()) {
13678 pw.print(" "); pw.println(perm);
13680 perm.dump(pw, " ");
13686 if (!printedAnything) {
13687 pw.println(" (nothing)");
13691 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13692 int opti, boolean dumpAll, String dumpPackage) {
13693 boolean printed = false;
13695 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13697 if (mIntentSenderRecords.size() > 0) {
13698 Iterator<WeakReference<PendingIntentRecord>> it
13699 = mIntentSenderRecords.values().iterator();
13700 while (it.hasNext()) {
13701 WeakReference<PendingIntentRecord> ref = it.next();
13702 PendingIntentRecord rec = ref != null ? ref.get(): null;
13703 if (dumpPackage != null && (rec == null
13704 || !dumpPackage.equals(rec.key.packageName))) {
13709 pw.print(" * "); pw.println(rec);
13714 pw.print(" * "); pw.println(ref);
13720 pw.println(" (nothing)");
13724 private static final int dumpProcessList(PrintWriter pw,
13725 ActivityManagerService service, List list,
13726 String prefix, String normalLabel, String persistentLabel,
13727 String dumpPackage) {
13729 final int N = list.size()-1;
13730 for (int i=N; i>=0; i--) {
13731 ProcessRecord r = (ProcessRecord)list.get(i);
13732 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13735 pw.println(String.format("%s%s #%2d: %s",
13736 prefix, (r.persistent ? persistentLabel : normalLabel),
13738 if (r.persistent) {
13745 private static final boolean dumpProcessOomList(PrintWriter pw,
13746 ActivityManagerService service, List<ProcessRecord> origList,
13747 String prefix, String normalLabel, String persistentLabel,
13748 boolean inclDetails, String dumpPackage) {
13750 ArrayList<Pair<ProcessRecord, Integer>> list
13751 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13752 for (int i=0; i<origList.size(); i++) {
13753 ProcessRecord r = origList.get(i);
13754 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13757 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13760 if (list.size() <= 0) {
13764 Comparator<Pair<ProcessRecord, Integer>> comparator
13765 = new Comparator<Pair<ProcessRecord, Integer>>() {
13767 public int compare(Pair<ProcessRecord, Integer> object1,
13768 Pair<ProcessRecord, Integer> object2) {
13769 if (object1.first.setAdj != object2.first.setAdj) {
13770 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13772 if (object1.second.intValue() != object2.second.intValue()) {
13773 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13779 Collections.sort(list, comparator);
13781 final long curRealtime = SystemClock.elapsedRealtime();
13782 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13783 final long curUptime = SystemClock.uptimeMillis();
13784 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13786 for (int i=list.size()-1; i>=0; i--) {
13787 ProcessRecord r = list.get(i).first;
13788 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13790 switch (r.setSchedGroup) {
13791 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13794 case Process.THREAD_GROUP_DEFAULT:
13802 if (r.foregroundActivities) {
13804 } else if (r.foregroundServices) {
13809 String procState = ProcessList.makeProcStateString(r.curProcState);
13811 pw.print(r.persistent ? persistentLabel : normalLabel);
13813 int num = (origList.size()-1)-list.get(i).second;
13814 if (num < 10) pw.print(' ');
13819 pw.print(schedGroup);
13821 pw.print(foreground);
13823 pw.print(procState);
13825 if (r.trimMemoryLevel < 10) pw.print(' ');
13826 pw.print(r.trimMemoryLevel);
13828 pw.print(r.toShortString());
13830 pw.print(r.adjType);
13832 if (r.adjSource != null || r.adjTarget != null) {
13835 if (r.adjTarget instanceof ComponentName) {
13836 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13837 } else if (r.adjTarget != null) {
13838 pw.print(r.adjTarget.toString());
13840 pw.print("{null}");
13843 if (r.adjSource instanceof ProcessRecord) {
13845 pw.print(((ProcessRecord)r.adjSource).toShortString());
13847 } else if (r.adjSource != null) {
13848 pw.println(r.adjSource.toString());
13850 pw.println("{null}");
13856 pw.print("oom: max="); pw.print(r.maxAdj);
13857 pw.print(" curRaw="); pw.print(r.curRawAdj);
13858 pw.print(" setRaw="); pw.print(r.setRawAdj);
13859 pw.print(" cur="); pw.print(r.curAdj);
13860 pw.print(" set="); pw.println(r.setAdj);
13863 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13864 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13865 pw.print(" lastPss="); pw.print(r.lastPss);
13866 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13869 pw.print("cached="); pw.print(r.cached);
13870 pw.print(" empty="); pw.print(r.empty);
13871 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13873 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13874 if (r.lastWakeTime != 0) {
13876 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13877 synchronized (stats) {
13878 wtime = stats.getProcessWakeTime(r.info.uid,
13879 r.pid, curRealtime);
13881 long timeUsed = wtime - r.lastWakeTime;
13884 pw.print("keep awake over ");
13885 TimeUtils.formatDuration(realtimeSince, pw);
13886 pw.print(" used ");
13887 TimeUtils.formatDuration(timeUsed, pw);
13889 pw.print((timeUsed*100)/realtimeSince);
13892 if (r.lastCpuTime != 0) {
13893 long timeUsed = r.curCpuTime - r.lastCpuTime;
13896 pw.print("run cpu over ");
13897 TimeUtils.formatDuration(uptimeSince, pw);
13898 pw.print(" used ");
13899 TimeUtils.formatDuration(timeUsed, pw);
13901 pw.print((timeUsed*100)/uptimeSince);
13910 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13912 ArrayList<ProcessRecord> procs;
13913 synchronized (this) {
13914 if (args != null && args.length > start
13915 && args[start].charAt(0) != '-') {
13916 procs = new ArrayList<ProcessRecord>();
13919 pid = Integer.parseInt(args[start]);
13920 } catch (NumberFormatException e) {
13922 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13923 ProcessRecord proc = mLruProcesses.get(i);
13924 if (proc.pid == pid) {
13926 } else if (allPkgs && proc.pkgList != null
13927 && proc.pkgList.containsKey(args[start])) {
13929 } else if (proc.processName.equals(args[start])) {
13933 if (procs.size() <= 0) {
13937 procs = new ArrayList<ProcessRecord>(mLruProcesses);
13943 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13944 PrintWriter pw, String[] args) {
13945 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13946 if (procs == null) {
13947 pw.println("No process found for: " + args[0]);
13951 long uptime = SystemClock.uptimeMillis();
13952 long realtime = SystemClock.elapsedRealtime();
13953 pw.println("Applications Graphics Acceleration Info:");
13954 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13956 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13957 ProcessRecord r = procs.get(i);
13958 if (r.thread != null) {
13959 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13962 TransferPipe tp = new TransferPipe();
13964 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13969 } catch (IOException e) {
13970 pw.println("Failure while dumping the app: " + r);
13972 } catch (RemoteException e) {
13973 pw.println("Got a RemoteException while dumping the app " + r);
13980 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13981 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13982 if (procs == null) {
13983 pw.println("No process found for: " + args[0]);
13987 pw.println("Applications Database Info:");
13989 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13990 ProcessRecord r = procs.get(i);
13991 if (r.thread != null) {
13992 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13995 TransferPipe tp = new TransferPipe();
13997 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14002 } catch (IOException e) {
14003 pw.println("Failure while dumping the app: " + r);
14005 } catch (RemoteException e) {
14006 pw.println("Got a RemoteException while dumping the app " + r);
14013 final static class MemItem {
14014 final boolean isProc;
14015 final String label;
14016 final String shortLabel;
14019 final boolean hasActivities;
14020 ArrayList<MemItem> subitems;
14022 public MemItem(String _label, String _shortLabel, long _pss, int _id,
14023 boolean _hasActivities) {
14026 shortLabel = _shortLabel;
14029 hasActivities = _hasActivities;
14032 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14035 shortLabel = _shortLabel;
14038 hasActivities = false;
14042 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14043 ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14044 if (sort && !isCompact) {
14045 Collections.sort(items, new Comparator<MemItem>() {
14047 public int compare(MemItem lhs, MemItem rhs) {
14048 if (lhs.pss < rhs.pss) {
14050 } else if (lhs.pss > rhs.pss) {
14058 for (int i=0; i<items.size(); i++) {
14059 MemItem mi = items.get(i);
14061 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14062 } else if (mi.isProc) {
14063 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14064 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14065 pw.println(mi.hasActivities ? ",a" : ",e");
14067 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14068 pw.println(mi.pss);
14070 if (mi.subitems != null) {
14071 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
14077 // These are in KB.
14078 static final long[] DUMP_MEM_BUCKETS = new long[] {
14079 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14080 120*1024, 160*1024, 200*1024,
14081 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14082 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14085 static final void appendMemBucket(StringBuilder out, long memKB, String label,
14086 boolean stackLike) {
14087 int start = label.lastIndexOf('.');
14088 if (start >= 0) start++;
14090 int end = label.length();
14091 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14092 if (DUMP_MEM_BUCKETS[i] >= memKB) {
14093 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14094 out.append(bucket);
14095 out.append(stackLike ? "MB." : "MB ");
14096 out.append(label, start, end);
14100 out.append(memKB/1024);
14101 out.append(stackLike ? "MB." : "MB ");
14102 out.append(label, start, end);
14105 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14106 ProcessList.NATIVE_ADJ,
14107 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14108 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14109 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14110 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14111 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14112 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14114 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14116 "System", "Persistent", "Persistent Service", "Foreground",
14117 "Visible", "Perceptible",
14118 "Heavy Weight", "Backup",
14119 "A Services", "Home",
14120 "Previous", "B Services", "Cached"
14122 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14124 "sys", "pers", "persvc", "fore",
14127 "servicea", "home",
14128 "prev", "serviceb", "cached"
14131 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14132 long realtime, boolean isCheckinRequest, boolean isCompact) {
14133 if (isCheckinRequest || isCompact) {
14134 // short checkin version
14135 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14137 pw.println("Applications Memory Usage (kB):");
14138 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14142 private static final int KSM_SHARED = 0;
14143 private static final int KSM_SHARING = 1;
14144 private static final int KSM_UNSHARED = 2;
14145 private static final int KSM_VOLATILE = 3;
14147 private final long[] getKsmInfo() {
14148 long[] longOut = new long[4];
14149 final int[] SINGLE_LONG_FORMAT = new int[] {
14150 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14152 long[] longTmp = new long[1];
14153 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14154 SINGLE_LONG_FORMAT, null, longTmp, null);
14155 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14157 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14158 SINGLE_LONG_FORMAT, null, longTmp, null);
14159 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14161 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14162 SINGLE_LONG_FORMAT, null, longTmp, null);
14163 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14165 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14166 SINGLE_LONG_FORMAT, null, longTmp, null);
14167 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14171 final void dumpApplicationMemoryUsage(FileDescriptor fd,
14172 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14173 boolean dumpDetails = false;
14174 boolean dumpFullDetails = false;
14175 boolean dumpDalvik = false;
14176 boolean oomOnly = false;
14177 boolean isCompact = false;
14178 boolean localOnly = false;
14179 boolean packages = false;
14182 while (opti < args.length) {
14183 String opt = args[opti];
14184 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14188 if ("-a".equals(opt)) {
14189 dumpDetails = true;
14190 dumpFullDetails = true;
14192 } else if ("-d".equals(opt)) {
14194 } else if ("-c".equals(opt)) {
14196 } else if ("--oom".equals(opt)) {
14198 } else if ("--local".equals(opt)) {
14200 } else if ("--package".equals(opt)) {
14202 } else if ("-h".equals(opt)) {
14203 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14204 pw.println(" -a: include all available information for each process.");
14205 pw.println(" -d: include dalvik details.");
14206 pw.println(" -c: dump in a compact machine-parseable representation.");
14207 pw.println(" --oom: only show processes organized by oom adj.");
14208 pw.println(" --local: only collect details locally, don't call process.");
14209 pw.println(" --package: interpret process arg as package, dumping all");
14210 pw.println(" processes that have loaded that package.");
14211 pw.println("If [process] is specified it can be the name or ");
14212 pw.println("pid of a specific process to dump.");
14215 pw.println("Unknown argument: " + opt + "; use -h for help");
14219 final boolean isCheckinRequest = scanArgs(args, "--checkin");
14220 long uptime = SystemClock.uptimeMillis();
14221 long realtime = SystemClock.elapsedRealtime();
14222 final long[] tmpLong = new long[1];
14224 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14225 if (procs == null) {
14226 // No Java processes. Maybe they want to print a native process.
14227 if (args != null && args.length > opti
14228 && args[opti].charAt(0) != '-') {
14229 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14230 = new ArrayList<ProcessCpuTracker.Stats>();
14231 updateCpuStatsNow();
14234 findPid = Integer.parseInt(args[opti]);
14235 } catch (NumberFormatException e) {
14237 synchronized (mProcessCpuTracker) {
14238 final int N = mProcessCpuTracker.countStats();
14239 for (int i=0; i<N; i++) {
14240 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14241 if (st.pid == findPid || (st.baseName != null
14242 && st.baseName.equals(args[opti]))) {
14243 nativeProcs.add(st);
14247 if (nativeProcs.size() > 0) {
14248 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14250 Debug.MemoryInfo mi = null;
14251 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14252 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14253 final int pid = r.pid;
14254 if (!isCheckinRequest && dumpDetails) {
14255 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14258 mi = new Debug.MemoryInfo();
14260 if (dumpDetails || (!brief && !oomOnly)) {
14261 Debug.getMemoryInfo(pid, mi);
14263 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14264 mi.dalvikPrivateDirty = (int)tmpLong[0];
14266 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14267 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14268 if (isCheckinRequest) {
14275 pw.println("No process found for: " + args[opti]);
14279 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14280 dumpDetails = true;
14283 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14285 String[] innerArgs = new String[args.length-opti];
14286 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14288 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14289 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14290 long nativePss = 0;
14291 long dalvikPss = 0;
14292 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14295 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14297 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14298 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14299 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14302 long cachedPss = 0;
14304 Debug.MemoryInfo mi = null;
14305 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14306 final ProcessRecord r = procs.get(i);
14307 final IApplicationThread thread;
14310 final boolean hasActivities;
14311 synchronized (this) {
14314 oomAdj = r.getSetAdjWithServices();
14315 hasActivities = r.activities.size() > 0;
14317 if (thread != null) {
14318 if (!isCheckinRequest && dumpDetails) {
14319 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14322 mi = new Debug.MemoryInfo();
14324 if (dumpDetails || (!brief && !oomOnly)) {
14325 Debug.getMemoryInfo(pid, mi);
14327 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14328 mi.dalvikPrivateDirty = (int)tmpLong[0];
14332 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14333 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14334 if (isCheckinRequest) {
14340 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14341 dumpDalvik, innerArgs);
14342 } catch (RemoteException e) {
14343 if (!isCheckinRequest) {
14344 pw.println("Got RemoteException!");
14351 final long myTotalPss = mi.getTotalPss();
14352 final long myTotalUss = mi.getTotalUss();
14354 synchronized (this) {
14355 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14356 // Record this for posterity if the process has been stable.
14357 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14361 if (!isCheckinRequest && mi != null) {
14362 totalPss += myTotalPss;
14363 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14364 (hasActivities ? " / activities)" : ")"),
14365 r.processName, myTotalPss, pid, hasActivities);
14366 procMems.add(pssItem);
14367 procMemsMap.put(pid, pssItem);
14369 nativePss += mi.nativePss;
14370 dalvikPss += mi.dalvikPss;
14371 for (int j=0; j<dalvikSubitemPss.length; j++) {
14372 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14374 otherPss += mi.otherPss;
14375 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14376 long mem = mi.getOtherPss(j);
14381 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14382 cachedPss += myTotalPss;
14385 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14386 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14387 || oomIndex == (oomPss.length-1)) {
14388 oomPss[oomIndex] += myTotalPss;
14389 if (oomProcs[oomIndex] == null) {
14390 oomProcs[oomIndex] = new ArrayList<MemItem>();
14392 oomProcs[oomIndex].add(pssItem);
14400 long nativeProcTotalPss = 0;
14402 if (!isCheckinRequest && procs.size() > 1 && !packages) {
14403 // If we are showing aggregations, also look for native processes to
14404 // include so that our aggregations are more accurate.
14405 updateCpuStatsNow();
14407 synchronized (mProcessCpuTracker) {
14408 final int N = mProcessCpuTracker.countStats();
14409 for (int i=0; i<N; i++) {
14410 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14411 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14413 mi = new Debug.MemoryInfo();
14415 if (!brief && !oomOnly) {
14416 Debug.getMemoryInfo(st.pid, mi);
14418 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14419 mi.nativePrivateDirty = (int)tmpLong[0];
14422 final long myTotalPss = mi.getTotalPss();
14423 totalPss += myTotalPss;
14424 nativeProcTotalPss += myTotalPss;
14426 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14427 st.name, myTotalPss, st.pid, false);
14428 procMems.add(pssItem);
14430 nativePss += mi.nativePss;
14431 dalvikPss += mi.dalvikPss;
14432 for (int j=0; j<dalvikSubitemPss.length; j++) {
14433 dalvikSubitemPss[j] += mi.getOtherPss(
14434 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14436 otherPss += mi.otherPss;
14437 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14438 long mem = mi.getOtherPss(j);
14442 oomPss[0] += myTotalPss;
14443 if (oomProcs[0] == null) {
14444 oomProcs[0] = new ArrayList<MemItem>();
14446 oomProcs[0].add(pssItem);
14451 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14453 catMems.add(new MemItem("Native", "Native", nativePss, -1));
14454 final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14455 if (dalvikSubitemPss.length > 0) {
14456 dalvikItem.subitems = new ArrayList<MemItem>();
14457 for (int j=0; j<dalvikSubitemPss.length; j++) {
14458 final String name = Debug.MemoryInfo.getOtherLabel(
14459 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14460 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14463 catMems.add(dalvikItem);
14464 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14465 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14466 String label = Debug.MemoryInfo.getOtherLabel(j);
14467 catMems.add(new MemItem(label, label, miscPss[j], j));
14470 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14471 for (int j=0; j<oomPss.length; j++) {
14472 if (oomPss[j] != 0) {
14473 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14474 : DUMP_MEM_OOM_LABEL[j];
14475 MemItem item = new MemItem(label, label, oomPss[j],
14476 DUMP_MEM_OOM_ADJ[j]);
14477 item.subitems = oomProcs[j];
14482 if (!brief && !oomOnly && !isCompact) {
14484 pw.println("Total PSS by process:");
14485 dumpMemItems(pw, " ", "proc", procMems, true, isCompact);
14489 pw.println("Total PSS by OOM adjustment:");
14491 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact);
14492 if (!brief && !oomOnly) {
14493 PrintWriter out = categoryPw != null ? categoryPw : pw;
14496 out.println("Total PSS by category:");
14498 dumpMemItems(out, " ", "cat", catMems, true, isCompact);
14503 MemInfoReader memInfo = new MemInfoReader();
14504 memInfo.readMemInfo();
14505 if (nativeProcTotalPss > 0) {
14506 synchronized (this) {
14507 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14508 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14509 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14514 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14515 pw.print(" kB (status ");
14516 switch (mLastMemoryLevel) {
14517 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14518 pw.println("normal)");
14520 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14521 pw.println("moderate)");
14523 case ProcessStats.ADJ_MEM_FACTOR_LOW:
14524 pw.println("low)");
14526 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14527 pw.println("critical)");
14530 pw.print(mLastMemoryLevel);
14534 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14535 + memInfo.getFreeSizeKb()); pw.print(" kB (");
14536 pw.print(cachedPss); pw.print(" cached pss + ");
14537 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14538 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14540 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14541 pw.print(cachedPss + memInfo.getCachedSizeKb()
14542 + memInfo.getFreeSizeKb()); pw.print(",");
14543 pw.println(totalPss - cachedPss);
14547 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14548 + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14549 pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14550 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14551 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14552 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14553 - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14556 if (memInfo.getZramTotalSizeKb() != 0) {
14558 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14559 pw.print(" kB physical used for ");
14560 pw.print(memInfo.getSwapTotalSizeKb()
14561 - memInfo.getSwapFreeSizeKb());
14562 pw.print(" kB in swap (");
14563 pw.print(memInfo.getSwapTotalSizeKb());
14564 pw.println(" kB total swap)");
14566 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14567 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14568 pw.println(memInfo.getSwapFreeSizeKb());
14571 final long[] ksm = getKsmInfo();
14573 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14574 || ksm[KSM_VOLATILE] != 0) {
14575 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]);
14576 pw.print(" kB saved from shared ");
14577 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14578 pw.print(" "); pw.print(ksm[KSM_UNSHARED]);
14579 pw.print(" kB unshared; ");
14580 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14582 pw.print(" Tuning: ");
14583 pw.print(ActivityManager.staticGetMemoryClass());
14584 pw.print(" (large ");
14585 pw.print(ActivityManager.staticGetLargeMemoryClass());
14586 pw.print("), oom ");
14587 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14589 pw.print(", restore limit ");
14590 pw.print(mProcessList.getCachedRestoreThresholdKb());
14592 if (ActivityManager.isLowRamDeviceStatic()) {
14593 pw.print(" (low-ram)");
14595 if (ActivityManager.isHighEndGfx()) {
14596 pw.print(" (high-end-gfx)");
14600 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14601 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14602 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14603 pw.print("tuning,");
14604 pw.print(ActivityManager.staticGetMemoryClass());
14606 pw.print(ActivityManager.staticGetLargeMemoryClass());
14608 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14609 if (ActivityManager.isLowRamDeviceStatic()) {
14610 pw.print(",low-ram");
14612 if (ActivityManager.isHighEndGfx()) {
14613 pw.print(",high-end-gfx");
14621 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14622 long memtrack, String name) {
14624 sb.append(ProcessList.makeOomAdjString(oomAdj));
14626 sb.append(ProcessList.makeProcStateString(procState));
14628 ProcessList.appendRamKb(sb, pss);
14629 sb.append(" kB: ");
14631 if (memtrack > 0) {
14633 sb.append(memtrack);
14634 sb.append(" kB memtrack)");
14638 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14639 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14640 sb.append(" (pid ");
14643 sb.append(mi.adjType);
14645 if (mi.adjReason != null) {
14647 sb.append(mi.adjReason);
14652 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14653 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14654 for (int i=0, N=memInfos.size(); i<N; i++) {
14655 ProcessMemInfo mi = memInfos.get(i);
14656 infoMap.put(mi.pid, mi);
14658 updateCpuStatsNow();
14659 long[] memtrackTmp = new long[1];
14660 synchronized (mProcessCpuTracker) {
14661 final int N = mProcessCpuTracker.countStats();
14662 for (int i=0; i<N; i++) {
14663 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14664 if (st.vsize > 0) {
14665 long pss = Debug.getPss(st.pid, null, memtrackTmp);
14667 if (infoMap.indexOfKey(st.pid) < 0) {
14668 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14669 ProcessList.NATIVE_ADJ, -1, "native", null);
14671 mi.memtrack = memtrackTmp[0];
14680 long totalMemtrack = 0;
14681 for (int i=0, N=memInfos.size(); i<N; i++) {
14682 ProcessMemInfo mi = memInfos.get(i);
14684 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14685 mi.memtrack = memtrackTmp[0];
14687 totalPss += mi.pss;
14688 totalMemtrack += mi.memtrack;
14690 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14691 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14692 if (lhs.oomAdj != rhs.oomAdj) {
14693 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14695 if (lhs.pss != rhs.pss) {
14696 return lhs.pss < rhs.pss ? 1 : -1;
14702 StringBuilder tag = new StringBuilder(128);
14703 StringBuilder stack = new StringBuilder(128);
14704 tag.append("Low on memory -- ");
14705 appendMemBucket(tag, totalPss, "total", false);
14706 appendMemBucket(stack, totalPss, "total", true);
14708 StringBuilder fullNativeBuilder = new StringBuilder(1024);
14709 StringBuilder shortNativeBuilder = new StringBuilder(1024);
14710 StringBuilder fullJavaBuilder = new StringBuilder(1024);
14712 boolean firstLine = true;
14713 int lastOomAdj = Integer.MIN_VALUE;
14714 long extraNativeRam = 0;
14715 long extraNativeMemtrack = 0;
14716 long cachedPss = 0;
14717 for (int i=0, N=memInfos.size(); i<N; i++) {
14718 ProcessMemInfo mi = memInfos.get(i);
14720 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14721 cachedPss += mi.pss;
14724 if (mi.oomAdj != ProcessList.NATIVE_ADJ
14725 && (mi.oomAdj < ProcessList.SERVICE_ADJ
14726 || mi.oomAdj == ProcessList.HOME_APP_ADJ
14727 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14728 if (lastOomAdj != mi.oomAdj) {
14729 lastOomAdj = mi.oomAdj;
14730 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14733 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14738 stack.append("\n\t at ");
14746 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14747 appendMemBucket(tag, mi.pss, mi.name, false);
14749 appendMemBucket(stack, mi.pss, mi.name, true);
14750 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14751 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14753 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14754 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14755 stack.append(DUMP_MEM_OOM_LABEL[k]);
14757 stack.append(DUMP_MEM_OOM_ADJ[k]);
14764 appendMemInfo(fullNativeBuilder, mi);
14765 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14766 // The short form only has native processes that are >= 512K.
14767 if (mi.pss >= 512) {
14768 appendMemInfo(shortNativeBuilder, mi);
14770 extraNativeRam += mi.pss;
14771 extraNativeMemtrack += mi.memtrack;
14774 // Short form has all other details, but if we have collected RAM
14775 // from smaller native processes let's dump a summary of that.
14776 if (extraNativeRam > 0) {
14777 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14778 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14779 shortNativeBuilder.append('\n');
14780 extraNativeRam = 0;
14782 appendMemInfo(fullJavaBuilder, mi);
14786 fullJavaBuilder.append(" ");
14787 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14788 fullJavaBuilder.append(" kB: TOTAL");
14789 if (totalMemtrack > 0) {
14790 fullJavaBuilder.append(" (");
14791 fullJavaBuilder.append(totalMemtrack);
14792 fullJavaBuilder.append(" kB memtrack)");
14795 fullJavaBuilder.append("\n");
14797 MemInfoReader memInfo = new MemInfoReader();
14798 memInfo.readMemInfo();
14799 final long[] infos = memInfo.getRawInfo();
14801 StringBuilder memInfoBuilder = new StringBuilder(1024);
14802 Debug.getMemInfo(infos);
14803 memInfoBuilder.append(" MemInfo: ");
14804 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14805 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14806 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14807 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14808 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14809 memInfoBuilder.append(" ");
14810 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14811 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14812 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14813 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14814 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14815 memInfoBuilder.append(" ZRAM: ");
14816 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14817 memInfoBuilder.append(" kB RAM, ");
14818 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14819 memInfoBuilder.append(" kB swap total, ");
14820 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14821 memInfoBuilder.append(" kB swap free\n");
14823 final long[] ksm = getKsmInfo();
14824 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14825 || ksm[KSM_VOLATILE] != 0) {
14826 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14827 memInfoBuilder.append(" kB saved from shared ");
14828 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14829 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14830 memInfoBuilder.append(" kB unshared; ");
14831 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14833 memInfoBuilder.append(" Free RAM: ");
14834 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14835 + memInfo.getFreeSizeKb());
14836 memInfoBuilder.append(" kB\n");
14837 memInfoBuilder.append(" Used RAM: ");
14838 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14839 memInfoBuilder.append(" kB\n");
14840 memInfoBuilder.append(" Lost RAM: ");
14841 memInfoBuilder.append(memInfo.getTotalSizeKb()
14842 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14843 - memInfo.getKernelUsedSizeKb());
14844 memInfoBuilder.append(" kB\n");
14845 Slog.i(TAG, "Low on memory:");
14846 Slog.i(TAG, shortNativeBuilder.toString());
14847 Slog.i(TAG, fullJavaBuilder.toString());
14848 Slog.i(TAG, memInfoBuilder.toString());
14850 StringBuilder dropBuilder = new StringBuilder(1024);
14852 StringWriter oomSw = new StringWriter();
14853 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14854 StringWriter catSw = new StringWriter();
14855 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14856 String[] emptyArgs = new String[] { };
14857 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
14859 String oomString = oomSw.toString();
14861 dropBuilder.append("Low on memory:");
14862 dropBuilder.append(stack);
14863 dropBuilder.append('\n');
14864 dropBuilder.append(fullNativeBuilder);
14865 dropBuilder.append(fullJavaBuilder);
14866 dropBuilder.append('\n');
14867 dropBuilder.append(memInfoBuilder);
14868 dropBuilder.append('\n');
14870 dropBuilder.append(oomString);
14871 dropBuilder.append('\n');
14873 StringWriter catSw = new StringWriter();
14874 synchronized (ActivityManagerService.this) {
14875 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14876 String[] emptyArgs = new String[] { };
14878 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14880 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14881 false, false, null);
14883 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14886 dropBuilder.append(catSw.toString());
14887 addErrorToDropBox("lowmem", null, "system_server", null,
14888 null, tag.toString(), dropBuilder.toString(), null, null);
14889 //Slog.i(TAG, "Sent to dropbox:");
14890 //Slog.i(TAG, dropBuilder.toString());
14891 synchronized (ActivityManagerService.this) {
14892 long now = SystemClock.uptimeMillis();
14893 if (mLastMemUsageReportTime < now) {
14894 mLastMemUsageReportTime = now;
14900 * Searches array of arguments for the specified string
14901 * @param args array of argument strings
14902 * @param value value to search for
14903 * @return true if the value is contained in the array
14905 private static boolean scanArgs(String[] args, String value) {
14906 if (args != null) {
14907 for (String arg : args) {
14908 if (value.equals(arg)) {
14916 private final boolean removeDyingProviderLocked(ProcessRecord proc,
14917 ContentProviderRecord cpr, boolean always) {
14918 final boolean inLaunching = mLaunchingProviders.contains(cpr);
14920 if (!inLaunching || always) {
14921 synchronized (cpr) {
14922 cpr.launchingApp = null;
14925 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14926 String names[] = cpr.info.authority.split(";");
14927 for (int j = 0; j < names.length; j++) {
14928 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14932 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
14933 ContentProviderConnection conn = cpr.connections.get(i);
14934 if (conn.waiting) {
14935 // If this connection is waiting for the provider, then we don't
14936 // need to mess with its process unless we are always removing
14937 // or for some reason the provider is not currently launching.
14938 if (inLaunching && !always) {
14942 ProcessRecord capp = conn.client;
14944 if (conn.stableCount > 0) {
14945 if (!capp.persistent && capp.thread != null
14947 && capp.pid != MY_PID) {
14948 capp.kill("depends on provider "
14949 + cpr.name.flattenToShortString()
14950 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14952 } else if (capp.thread != null && conn.provider.provider != null) {
14954 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14955 } catch (RemoteException e) {
14957 // In the protocol here, we don't expect the client to correctly
14958 // clean up this connection, we'll just remove it.
14959 cpr.connections.remove(i);
14960 if (conn.client.conProviders.remove(conn)) {
14961 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14966 if (inLaunching && always) {
14967 mLaunchingProviders.remove(cpr);
14969 return inLaunching;
14973 * Main code for cleaning up a process when it has gone away. This is
14974 * called both as a result of the process dying, or directly when stopping
14975 * a process when running in single process mode.
14977 * @return Returns true if the given process has been restarted, so the
14978 * app that was passed in must remain on the process lists.
14980 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14981 boolean restarting, boolean allowRestart, int index) {
14983 removeLruProcessLocked(app);
14984 ProcessList.remove(app.pid);
14987 mProcessesToGc.remove(app);
14988 mPendingPssProcesses.remove(app);
14990 // Dismiss any open dialogs.
14991 if (app.crashDialog != null && !app.forceCrashReport) {
14992 app.crashDialog.dismiss();
14993 app.crashDialog = null;
14995 if (app.anrDialog != null) {
14996 app.anrDialog.dismiss();
14997 app.anrDialog = null;
14999 if (app.waitDialog != null) {
15000 app.waitDialog.dismiss();
15001 app.waitDialog = null;
15004 app.crashing = false;
15005 app.notResponding = false;
15007 app.resetPackageList(mProcessStats);
15008 app.unlinkDeathRecipient();
15009 app.makeInactive(mProcessStats);
15010 app.waitingToKill = null;
15011 app.forcingToForeground = null;
15012 updateProcessForegroundLocked(app, false, false);
15013 app.foregroundActivities = false;
15014 app.hasShownUi = false;
15015 app.treatLikeActivity = false;
15016 app.hasAboveClient = false;
15017 app.hasClientActivities = false;
15019 mServices.killServicesLocked(app, allowRestart);
15021 boolean restart = false;
15023 // Remove published content providers.
15024 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15025 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15026 final boolean always = app.bad || !allowRestart;
15027 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15028 if ((inLaunching || always) && !cpr.connections.isEmpty()) {
15029 // We left the provider in the launching list, need to
15034 cpr.provider = null;
15037 app.pubProviders.clear();
15039 // Take care of any launching providers waiting for this process.
15040 if (checkAppInLaunchingProvidersLocked(app, false)) {
15044 // Unregister from connected content providers.
15045 if (!app.conProviders.isEmpty()) {
15046 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15047 ContentProviderConnection conn = app.conProviders.get(i);
15048 conn.provider.connections.remove(conn);
15049 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15050 conn.provider.name);
15052 app.conProviders.clear();
15055 // At this point there may be remaining entries in mLaunchingProviders
15056 // where we were the only one waiting, so they are no longer of use.
15057 // Look for these and clean up if found.
15058 // XXX Commented out for now. Trying to figure out a way to reproduce
15059 // the actual situation to identify what is actually going on.
15061 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15062 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15063 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15064 synchronized (cpr) {
15065 cpr.launchingApp = null;
15072 skipCurrentReceiverLocked(app);
15074 // Unregister any receivers.
15075 for (int i = app.receivers.size() - 1; i >= 0; i--) {
15076 removeReceiverLocked(app.receivers.valueAt(i));
15078 app.receivers.clear();
15080 // If the app is undergoing backup, tell the backup manager about it
15081 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15082 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
15083 + mBackupTarget.appInfo + " died during backup");
15085 IBackupManager bm = IBackupManager.Stub.asInterface(
15086 ServiceManager.getService(Context.BACKUP_SERVICE));
15087 bm.agentDisconnected(app.info.packageName);
15088 } catch (RemoteException e) {
15089 // can't happen; backup manager is local
15093 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15094 ProcessChangeItem item = mPendingProcessChanges.get(i);
15095 if (item.pid == app.pid) {
15096 mPendingProcessChanges.remove(i);
15097 mAvailProcessChanges.add(item);
15100 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15102 // If the caller is restarting this app, then leave it in its
15103 // current lists and let the caller take care of it.
15108 if (!app.persistent || app.isolated) {
15109 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
15110 "Removing non-persistent process during cleanup: " + app);
15111 mProcessNames.remove(app.processName, app.uid);
15112 mIsolatedProcesses.remove(app.uid);
15113 if (mHeavyWeightProcess == app) {
15114 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15115 mHeavyWeightProcess.userId, 0));
15116 mHeavyWeightProcess = null;
15118 } else if (!app.removed) {
15119 // This app is persistent, so we need to keep its record around.
15120 // If it is not already on the pending app list, add it there
15121 // and start a new process for it.
15122 if (mPersistentStartingProcesses.indexOf(app) < 0) {
15123 mPersistentStartingProcesses.add(app);
15127 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
15128 "Clean-up removing on hold: " + app);
15129 mProcessesOnHold.remove(app);
15131 if (app == mHomeProcess) {
15132 mHomeProcess = null;
15134 if (app == mPreviousProcess) {
15135 mPreviousProcess = null;
15138 if (restart && !app.isolated) {
15139 // We have components that still need to be running in the
15140 // process, so re-launch it.
15142 ProcessList.remove(app.pid);
15144 mProcessNames.put(app.processName, app.uid, app);
15145 startProcessLocked(app, "restart", app.processName);
15147 } else if (app.pid > 0 && app.pid != MY_PID) {
15150 synchronized (mPidsSelfLocked) {
15151 mPidsSelfLocked.remove(app.pid);
15152 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15154 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15155 if (app.isolated) {
15156 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15163 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15164 // Look through the content providers we are waiting to have launched,
15165 // and if any run in this process then either schedule a restart of
15166 // the process or kill the client waiting for it if this process has
15168 boolean restart = false;
15169 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15170 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15171 if (cpr.launchingApp == app) {
15172 if (!alwaysBad && !app.bad && !cpr.connections.isEmpty()) {
15175 removeDyingProviderLocked(app, cpr, true);
15182 // =========================================================
15184 // =========================================================
15187 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15189 enforceNotIsolatedCaller("getServices");
15190 synchronized (this) {
15191 return mServices.getRunningServiceInfoLocked(maxNum, flags);
15196 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15197 enforceNotIsolatedCaller("getRunningServiceControlPanel");
15198 synchronized (this) {
15199 return mServices.getRunningServiceControlPanelLocked(name);
15204 public ComponentName startService(IApplicationThread caller, Intent service,
15205 String resolvedType, int userId) {
15206 enforceNotIsolatedCaller("startService");
15207 // Refuse possible leaked file descriptors
15208 if (service != null && service.hasFileDescriptors() == true) {
15209 throw new IllegalArgumentException("File descriptors passed in Intent");
15213 Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
15214 synchronized(this) {
15215 final int callingPid = Binder.getCallingPid();
15216 final int callingUid = Binder.getCallingUid();
15217 final long origId = Binder.clearCallingIdentity();
15218 ComponentName res = mServices.startServiceLocked(caller, service,
15219 resolvedType, callingPid, callingUid, userId);
15220 Binder.restoreCallingIdentity(origId);
15225 ComponentName startServiceInPackage(int uid,
15226 Intent service, String resolvedType, int userId) {
15227 synchronized(this) {
15229 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
15230 final long origId = Binder.clearCallingIdentity();
15231 ComponentName res = mServices.startServiceLocked(null, service,
15232 resolvedType, -1, uid, userId);
15233 Binder.restoreCallingIdentity(origId);
15239 public int stopService(IApplicationThread caller, Intent service,
15240 String resolvedType, int userId) {
15241 enforceNotIsolatedCaller("stopService");
15242 // Refuse possible leaked file descriptors
15243 if (service != null && service.hasFileDescriptors() == true) {
15244 throw new IllegalArgumentException("File descriptors passed in Intent");
15247 synchronized(this) {
15248 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15253 public IBinder peekService(Intent service, String resolvedType) {
15254 enforceNotIsolatedCaller("peekService");
15255 // Refuse possible leaked file descriptors
15256 if (service != null && service.hasFileDescriptors() == true) {
15257 throw new IllegalArgumentException("File descriptors passed in Intent");
15259 synchronized(this) {
15260 return mServices.peekServiceLocked(service, resolvedType);
15265 public boolean stopServiceToken(ComponentName className, IBinder token,
15267 synchronized(this) {
15268 return mServices.stopServiceTokenLocked(className, token, startId);
15273 public void setServiceForeground(ComponentName className, IBinder token,
15274 int id, Notification notification, boolean removeNotification) {
15275 synchronized(this) {
15276 mServices.setServiceForegroundLocked(className, token, id, notification,
15277 removeNotification);
15282 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15283 boolean requireFull, String name, String callerPackage) {
15284 return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15285 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15288 int unsafeConvertIncomingUser(int userId) {
15289 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15290 ? mCurrentUserId : userId;
15293 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15294 int allowMode, String name, String callerPackage) {
15295 final int callingUserId = UserHandle.getUserId(callingUid);
15296 if (callingUserId == userId) {
15300 // Note that we may be accessing mCurrentUserId outside of a lock...
15301 // shouldn't be a big deal, if this is being called outside
15302 // of a locked context there is intrinsically a race with
15303 // the value the caller will receive and someone else changing it.
15304 // We assume that USER_CURRENT_OR_SELF will use the current user; later
15305 // we will switch to the calling user if access to the current user fails.
15306 int targetUserId = unsafeConvertIncomingUser(userId);
15308 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15309 final boolean allow;
15310 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15311 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15312 // If the caller has this permission, they always pass go. And collect $200.
15314 } else if (allowMode == ALLOW_FULL_ONLY) {
15315 // We require full access, sucks to be you.
15317 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15318 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15319 // If the caller does not have either permission, they are always doomed.
15321 } else if (allowMode == ALLOW_NON_FULL) {
15322 // We are blanket allowing non-full access, you lucky caller!
15324 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15325 // We may or may not allow this depending on whether the two users are
15326 // in the same profile.
15327 synchronized (mUserProfileGroupIdsSelfLocked) {
15328 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15329 UserInfo.NO_PROFILE_GROUP_ID);
15330 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15331 UserInfo.NO_PROFILE_GROUP_ID);
15332 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15333 && callingProfile == targetProfile;
15336 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15339 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15340 // In this case, they would like to just execute as their
15341 // owner user instead of failing.
15342 targetUserId = callingUserId;
15344 StringBuilder builder = new StringBuilder(128);
15345 builder.append("Permission Denial: ");
15346 builder.append(name);
15347 if (callerPackage != null) {
15348 builder.append(" from ");
15349 builder.append(callerPackage);
15351 builder.append(" asks to run as user ");
15352 builder.append(userId);
15353 builder.append(" but is calling from user ");
15354 builder.append(UserHandle.getUserId(callingUid));
15355 builder.append("; this requires ");
15356 builder.append(INTERACT_ACROSS_USERS_FULL);
15357 if (allowMode != ALLOW_FULL_ONLY) {
15358 builder.append(" or ");
15359 builder.append(INTERACT_ACROSS_USERS);
15361 String msg = builder.toString();
15363 throw new SecurityException(msg);
15367 if (!allowAll && targetUserId < 0) {
15368 throw new IllegalArgumentException(
15369 "Call does not support special user #" + targetUserId);
15371 // Check shell permission
15372 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15373 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15375 throw new SecurityException("Shell does not have permission to access user "
15376 + targetUserId + "\n " + Debug.getCallers(3));
15379 return targetUserId;
15382 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15383 String className, int flags) {
15384 boolean result = false;
15385 // For apps that don't have pre-defined UIDs, check for permission
15386 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15387 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15388 if (ActivityManager.checkUidPermission(
15389 INTERACT_ACROSS_USERS,
15390 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15391 ComponentName comp = new ComponentName(aInfo.packageName, className);
15392 String msg = "Permission Denial: Component " + comp.flattenToShortString()
15393 + " requests FLAG_SINGLE_USER, but app does not hold "
15394 + INTERACT_ACROSS_USERS;
15396 throw new SecurityException(msg);
15398 // Permission passed
15401 } else if ("system".equals(componentProcessName)) {
15403 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15404 // Phone app and persistent apps are allowed to export singleuser providers.
15405 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15406 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15409 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15410 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15416 * Checks to see if the caller is in the same app as the singleton
15417 * component, or the component is in a special app. It allows special apps
15418 * to export singleton components but prevents exporting singleton
15419 * components for regular apps.
15421 boolean isValidSingletonCall(int callingUid, int componentUid) {
15422 int componentAppId = UserHandle.getAppId(componentUid);
15423 return UserHandle.isSameApp(callingUid, componentUid)
15424 || componentAppId == Process.SYSTEM_UID
15425 || componentAppId == Process.PHONE_UID
15426 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15427 == PackageManager.PERMISSION_GRANTED;
15430 public int bindService(IApplicationThread caller, IBinder token,
15431 Intent service, String resolvedType,
15432 IServiceConnection connection, int flags, int userId) {
15433 enforceNotIsolatedCaller("bindService");
15435 // Refuse possible leaked file descriptors
15436 if (service != null && service.hasFileDescriptors() == true) {
15437 throw new IllegalArgumentException("File descriptors passed in Intent");
15440 synchronized(this) {
15441 return mServices.bindServiceLocked(caller, token, service, resolvedType,
15442 connection, flags, userId);
15446 public boolean unbindService(IServiceConnection connection) {
15447 synchronized (this) {
15448 return mServices.unbindServiceLocked(connection);
15452 public void publishService(IBinder token, Intent intent, IBinder service) {
15453 // Refuse possible leaked file descriptors
15454 if (intent != null && intent.hasFileDescriptors() == true) {
15455 throw new IllegalArgumentException("File descriptors passed in Intent");
15458 synchronized(this) {
15459 if (!(token instanceof ServiceRecord)) {
15460 throw new IllegalArgumentException("Invalid service token");
15462 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15466 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15467 // Refuse possible leaked file descriptors
15468 if (intent != null && intent.hasFileDescriptors() == true) {
15469 throw new IllegalArgumentException("File descriptors passed in Intent");
15472 synchronized(this) {
15473 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15477 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15478 synchronized(this) {
15479 if (!(token instanceof ServiceRecord)) {
15480 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15481 throw new IllegalArgumentException("Invalid service token");
15483 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15487 // =========================================================
15488 // BACKUP AND RESTORE
15489 // =========================================================
15491 // Cause the target app to be launched if necessary and its backup agent
15492 // instantiated. The backup agent will invoke backupAgentCreated() on the
15493 // activity manager to announce its creation.
15494 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
15495 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
15496 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15498 synchronized(this) {
15499 // !!! TODO: currently no check here that we're already bound
15500 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15501 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15502 synchronized (stats) {
15503 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15506 // Backup agent is now in use, its package can't be stopped.
15508 AppGlobals.getPackageManager().setPackageStoppedState(
15509 app.packageName, false, UserHandle.getUserId(app.uid));
15510 } catch (RemoteException e) {
15511 } catch (IllegalArgumentException e) {
15512 Slog.w(TAG, "Failed trying to unstop package "
15513 + app.packageName + ": " + e);
15516 BackupRecord r = new BackupRecord(ss, app, backupMode);
15517 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15518 ? new ComponentName(app.packageName, app.backupAgentName)
15519 : new ComponentName("android", "FullBackupAgent");
15520 // startProcessLocked() returns existing proc's record if it's already running
15521 ProcessRecord proc = startProcessLocked(app.processName, app,
15522 false, 0, "backup", hostingName, false, false, false);
15523 if (proc == null) {
15524 Slog.e(TAG, "Unable to start backup agent process " + r);
15530 mBackupAppName = app.packageName;
15532 // Try not to kill the process during backup
15533 updateOomAdjLocked(proc);
15535 // If the process is already attached, schedule the creation of the backup agent now.
15536 // If it is not yet live, this will be done when it attaches to the framework.
15537 if (proc.thread != null) {
15538 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15540 proc.thread.scheduleCreateBackupAgent(app,
15541 compatibilityInfoForPackageLocked(app), backupMode);
15542 } catch (RemoteException e) {
15543 // Will time out on the backup manager side
15546 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15548 // Invariants: at this point, the target app process exists and the application
15549 // is either already running or in the process of coming up. mBackupTarget and
15550 // mBackupAppName describe the app, so that when it binds back to the AM we
15551 // know that it's scheduled for a backup-agent operation.
15558 public void clearPendingBackup() {
15559 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15560 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15562 synchronized (this) {
15563 mBackupTarget = null;
15564 mBackupAppName = null;
15568 // A backup agent has just come up
15569 public void backupAgentCreated(String agentPackageName, IBinder agent) {
15570 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15573 synchronized(this) {
15574 if (!agentPackageName.equals(mBackupAppName)) {
15575 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15580 long oldIdent = Binder.clearCallingIdentity();
15582 IBackupManager bm = IBackupManager.Stub.asInterface(
15583 ServiceManager.getService(Context.BACKUP_SERVICE));
15584 bm.agentConnected(agentPackageName, agent);
15585 } catch (RemoteException e) {
15586 // can't happen; the backup manager service is local
15587 } catch (Exception e) {
15588 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15589 e.printStackTrace();
15591 Binder.restoreCallingIdentity(oldIdent);
15595 // done with this agent
15596 public void unbindBackupAgent(ApplicationInfo appInfo) {
15597 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15598 if (appInfo == null) {
15599 Slog.w(TAG, "unbind backup agent for null app");
15603 synchronized(this) {
15605 if (mBackupAppName == null) {
15606 Slog.w(TAG, "Unbinding backup agent with no active backup");
15610 if (!mBackupAppName.equals(appInfo.packageName)) {
15611 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15615 // Not backing this app up any more; reset its OOM adjustment
15616 final ProcessRecord proc = mBackupTarget.app;
15617 updateOomAdjLocked(proc);
15619 // If the app crashed during backup, 'thread' will be null here
15620 if (proc.thread != null) {
15622 proc.thread.scheduleDestroyBackupAgent(appInfo,
15623 compatibilityInfoForPackageLocked(appInfo));
15624 } catch (Exception e) {
15625 Slog.e(TAG, "Exception when unbinding backup agent:");
15626 e.printStackTrace();
15630 mBackupTarget = null;
15631 mBackupAppName = null;
15635 // =========================================================
15637 // =========================================================
15639 boolean isPendingBroadcastProcessLocked(int pid) {
15640 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15641 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15644 void skipPendingBroadcastLocked(int pid) {
15645 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15646 for (BroadcastQueue queue : mBroadcastQueues) {
15647 queue.skipPendingBroadcastLocked(pid);
15651 // The app just attached; send any pending broadcasts that it should receive
15652 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15653 boolean didSomething = false;
15654 for (BroadcastQueue queue : mBroadcastQueues) {
15655 didSomething |= queue.sendPendingBroadcastsLocked(app);
15657 return didSomething;
15660 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15661 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15662 enforceNotIsolatedCaller("registerReceiver");
15663 ArrayList<Intent> stickyIntents = null;
15664 ProcessRecord callerApp = null;
15667 synchronized(this) {
15668 if (caller != null) {
15669 callerApp = getRecordForAppLocked(caller);
15670 if (callerApp == null) {
15671 throw new SecurityException(
15672 "Unable to find app for caller " + caller
15673 + " (pid=" + Binder.getCallingPid()
15674 + ") when registering receiver " + receiver);
15676 if (callerApp.info.uid != Process.SYSTEM_UID &&
15677 !callerApp.pkgList.containsKey(callerPackage) &&
15678 !"android".equals(callerPackage)) {
15679 throw new SecurityException("Given caller package " + callerPackage
15680 + " is not running in process " + callerApp);
15682 callingUid = callerApp.info.uid;
15683 callingPid = callerApp.pid;
15685 callerPackage = null;
15686 callingUid = Binder.getCallingUid();
15687 callingPid = Binder.getCallingPid();
15690 userId = handleIncomingUser(callingPid, callingUid, userId,
15691 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15693 Iterator<String> actions = filter.actionsIterator();
15694 if (actions == null) {
15695 ArrayList<String> noAction = new ArrayList<String>(1);
15696 noAction.add(null);
15697 actions = noAction.iterator();
15700 // Collect stickies of users
15701 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
15702 while (actions.hasNext()) {
15703 String action = actions.next();
15704 for (int id : userIds) {
15705 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
15706 if (stickies != null) {
15707 ArrayList<Intent> intents = stickies.get(action);
15708 if (intents != null) {
15709 if (stickyIntents == null) {
15710 stickyIntents = new ArrayList<Intent>();
15712 stickyIntents.addAll(intents);
15719 ArrayList<Intent> allSticky = null;
15720 if (stickyIntents != null) {
15721 final ContentResolver resolver = mContext.getContentResolver();
15722 // Look for any matching sticky broadcasts...
15723 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
15724 Intent intent = stickyIntents.get(i);
15725 // If intent has scheme "content", it will need to acccess
15726 // provider that needs to lock mProviderMap in ActivityThread
15727 // and also it may need to wait application response, so we
15728 // cannot lock ActivityManagerService here.
15729 if (filter.match(resolver, intent, true, TAG) >= 0) {
15730 if (allSticky == null) {
15731 allSticky = new ArrayList<Intent>();
15733 allSticky.add(intent);
15738 // The first sticky in the list is returned directly back to the client.
15739 Intent sticky = allSticky != null ? allSticky.get(0) : null;
15740 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter + ": " + sticky);
15741 if (receiver == null) {
15745 synchronized (this) {
15746 if (callerApp != null && (callerApp.thread == null
15747 || callerApp.thread.asBinder() != caller.asBinder())) {
15748 // Original caller already died
15752 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15754 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15756 if (rl.app != null) {
15757 rl.app.receivers.add(rl);
15760 receiver.asBinder().linkToDeath(rl, 0);
15761 } catch (RemoteException e) {
15764 rl.linkedToDeath = true;
15766 mRegisteredReceivers.put(receiver.asBinder(), rl);
15767 } else if (rl.uid != callingUid) {
15768 throw new IllegalArgumentException(
15769 "Receiver requested to register for uid " + callingUid
15770 + " was previously registered for uid " + rl.uid);
15771 } else if (rl.pid != callingPid) {
15772 throw new IllegalArgumentException(
15773 "Receiver requested to register for pid " + callingPid
15774 + " was previously registered for pid " + rl.pid);
15775 } else if (rl.userId != userId) {
15776 throw new IllegalArgumentException(
15777 "Receiver requested to register for user " + userId
15778 + " was previously registered for user " + rl.userId);
15780 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15781 permission, callingUid, userId);
15783 if (!bf.debugCheck()) {
15784 Slog.w(TAG, "==> For Dynamic broadast");
15786 mReceiverResolver.addFilter(bf);
15788 // Enqueue broadcasts for all existing stickies that match
15790 if (allSticky != null) {
15791 ArrayList receivers = new ArrayList();
15794 int N = allSticky.size();
15795 for (int i=0; i<N; i++) {
15796 Intent intent = (Intent)allSticky.get(i);
15797 BroadcastQueue queue = broadcastQueueForIntent(intent);
15798 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15799 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15800 null, null, false, true, true, -1);
15801 queue.enqueueParallelBroadcastLocked(r);
15802 queue.scheduleBroadcastsLocked();
15810 public void unregisterReceiver(IIntentReceiver receiver) {
15811 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15813 final long origId = Binder.clearCallingIdentity();
15815 boolean doTrim = false;
15817 synchronized(this) {
15818 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15820 final BroadcastRecord r = rl.curBroadcast;
15821 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
15822 final boolean doNext = r.queue.finishReceiverLocked(
15823 r, r.resultCode, r.resultData, r.resultExtras,
15824 r.resultAbort, false);
15827 r.queue.processNextBroadcast(false);
15831 if (rl.app != null) {
15832 rl.app.receivers.remove(rl);
15834 removeReceiverLocked(rl);
15835 if (rl.linkedToDeath) {
15836 rl.linkedToDeath = false;
15837 rl.receiver.asBinder().unlinkToDeath(rl, 0);
15842 // If we actually concluded any broadcasts, we might now be able
15843 // to trim the recipients' apps from our working set
15845 trimApplications();
15850 Binder.restoreCallingIdentity(origId);
15854 void removeReceiverLocked(ReceiverList rl) {
15855 mRegisteredReceivers.remove(rl.receiver.asBinder());
15857 for (int i=0; i<N; i++) {
15858 mReceiverResolver.removeFilter(rl.get(i));
15862 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15863 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15864 ProcessRecord r = mLruProcesses.get(i);
15865 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15867 r.thread.dispatchPackageBroadcast(cmd, packages);
15868 } catch (RemoteException ex) {
15874 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15875 int callingUid, int[] users) {
15876 List<ResolveInfo> receivers = null;
15878 HashSet<ComponentName> singleUserReceivers = null;
15879 boolean scannedFirstReceivers = false;
15880 for (int user : users) {
15881 // Skip users that have Shell restrictions
15882 if (callingUid == Process.SHELL_UID
15883 && getUserManagerLocked().hasUserRestriction(
15884 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15887 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15888 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15889 if (user != 0 && newReceivers != null) {
15890 // If this is not the primary user, we need to check for
15891 // any receivers that should be filtered out.
15892 for (int i=0; i<newReceivers.size(); i++) {
15893 ResolveInfo ri = newReceivers.get(i);
15894 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15895 newReceivers.remove(i);
15900 if (newReceivers != null && newReceivers.size() == 0) {
15901 newReceivers = null;
15903 if (receivers == null) {
15904 receivers = newReceivers;
15905 } else if (newReceivers != null) {
15906 // We need to concatenate the additional receivers
15907 // found with what we have do far. This would be easy,
15908 // but we also need to de-dup any receivers that are
15910 if (!scannedFirstReceivers) {
15911 // Collect any single user receivers we had already retrieved.
15912 scannedFirstReceivers = true;
15913 for (int i=0; i<receivers.size(); i++) {
15914 ResolveInfo ri = receivers.get(i);
15915 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15916 ComponentName cn = new ComponentName(
15917 ri.activityInfo.packageName, ri.activityInfo.name);
15918 if (singleUserReceivers == null) {
15919 singleUserReceivers = new HashSet<ComponentName>();
15921 singleUserReceivers.add(cn);
15925 // Add the new results to the existing results, tracking
15926 // and de-dupping single user receivers.
15927 for (int i=0; i<newReceivers.size(); i++) {
15928 ResolveInfo ri = newReceivers.get(i);
15929 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15930 ComponentName cn = new ComponentName(
15931 ri.activityInfo.packageName, ri.activityInfo.name);
15932 if (singleUserReceivers == null) {
15933 singleUserReceivers = new HashSet<ComponentName>();
15935 if (!singleUserReceivers.contains(cn)) {
15936 singleUserReceivers.add(cn);
15945 } catch (RemoteException ex) {
15946 // pm is in same process, this will never happen.
15951 private final int broadcastIntentLocked(ProcessRecord callerApp,
15952 String callerPackage, Intent intent, String resolvedType,
15953 IIntentReceiver resultTo, int resultCode, String resultData,
15954 Bundle map, String requiredPermission, int appOp,
15955 boolean ordered, boolean sticky, int callingPid, int callingUid,
15957 intent = new Intent(intent);
15959 // By default broadcasts do not go to stopped apps.
15960 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15962 if (DEBUG_BROADCAST_LIGHT) Slog.v(
15963 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15964 + " ordered=" + ordered + " userid=" + userId);
15965 if ((resultTo != null) && !ordered) {
15966 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15969 userId = handleIncomingUser(callingPid, callingUid, userId,
15970 true, ALLOW_NON_FULL, "broadcast", callerPackage);
15972 // Make sure that the user who is receiving this broadcast is running.
15973 // If not, we will just skip it. Make an exception for shutdown broadcasts
15974 // and upgrade steps.
15976 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15977 if ((callingUid != Process.SYSTEM_UID
15978 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15979 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15980 Slog.w(TAG, "Skipping broadcast of " + intent
15981 + ": user " + userId + " is stopped");
15982 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15987 * Prevent non-system code (defined here to be non-persistent
15988 * processes) from sending protected broadcasts.
15990 int callingAppId = UserHandle.getAppId(callingUid);
15991 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15992 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15993 || callingAppId == Process.NFC_UID || callingUid == 0) {
15995 } else if (callerApp == null || !callerApp.persistent) {
15997 if (AppGlobals.getPackageManager().isProtectedBroadcast(
15998 intent.getAction())) {
15999 String msg = "Permission Denial: not allowed to send broadcast "
16000 + intent.getAction() + " from pid="
16001 + callingPid + ", uid=" + callingUid;
16003 throw new SecurityException(msg);
16004 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16005 // Special case for compatibility: we don't want apps to send this,
16006 // but historically it has not been protected and apps may be using it
16007 // to poke their own app widget. So, instead of making it protected,
16008 // just limit it to the caller.
16009 if (callerApp == null) {
16010 String msg = "Permission Denial: not allowed to send broadcast "
16011 + intent.getAction() + " from unknown caller.";
16013 throw new SecurityException(msg);
16014 } else if (intent.getComponent() != null) {
16015 // They are good enough to send to an explicit component... verify
16016 // it is being sent to the calling app.
16017 if (!intent.getComponent().getPackageName().equals(
16018 callerApp.info.packageName)) {
16019 String msg = "Permission Denial: not allowed to send broadcast "
16020 + intent.getAction() + " to "
16021 + intent.getComponent().getPackageName() + " from "
16022 + callerApp.info.packageName;
16024 throw new SecurityException(msg);
16027 // Limit broadcast to their own package.
16028 intent.setPackage(callerApp.info.packageName);
16031 } catch (RemoteException e) {
16032 Slog.w(TAG, "Remote exception", e);
16033 return ActivityManager.BROADCAST_SUCCESS;
16037 final String action = intent.getAction();
16038 if (action != null) {
16040 case Intent.ACTION_UID_REMOVED:
16041 case Intent.ACTION_PACKAGE_REMOVED:
16042 case Intent.ACTION_PACKAGE_CHANGED:
16043 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16044 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16045 // Handle special intents: if this broadcast is from the package
16046 // manager about a package being removed, we need to remove all of
16047 // its activities from the history stack.
16048 if (checkComponentPermission(
16049 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16050 callingPid, callingUid, -1, true)
16051 != PackageManager.PERMISSION_GRANTED) {
16052 String msg = "Permission Denial: " + intent.getAction()
16053 + " broadcast from " + callerPackage + " (pid=" + callingPid
16054 + ", uid=" + callingUid + ")"
16056 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16058 throw new SecurityException(msg);
16061 case Intent.ACTION_UID_REMOVED:
16062 final Bundle intentExtras = intent.getExtras();
16063 final int uid = intentExtras != null
16064 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16066 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
16067 synchronized (bs) {
16068 bs.removeUidStatsLocked(uid);
16070 mAppOpsService.uidRemoved(uid);
16073 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16074 // If resources are unavailable just force stop all those packages
16075 // and flush the attribute cache as well.
16077 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16078 if (list != null && list.length > 0) {
16079 for (int i = 0; i < list.length; i++) {
16080 forceStopPackageLocked(list[i], -1, false, true, true,
16081 false, false, userId, "storage unmount");
16083 cleanupRecentTasksLocked(UserHandle.USER_ALL);
16084 sendPackageBroadcastLocked(
16085 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16089 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16090 cleanupRecentTasksLocked(UserHandle.USER_ALL);
16092 case Intent.ACTION_PACKAGE_REMOVED:
16093 case Intent.ACTION_PACKAGE_CHANGED:
16094 Uri data = intent.getData();
16096 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16097 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16098 boolean fullUninstall = removed &&
16099 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16100 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16101 forceStopPackageLocked(ssp, UserHandle.getAppId(
16102 intent.getIntExtra(Intent.EXTRA_UID, -1)),
16103 false, true, true, false, fullUninstall, userId,
16104 removed ? "pkg removed" : "pkg changed");
16107 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16108 new String[] {ssp}, userId);
16109 if (fullUninstall) {
16110 mAppOpsService.packageRemoved(
16111 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16113 // Remove all permissions granted from/to this package
16114 removeUriPermissionsForPackageLocked(ssp, userId, true);
16116 removeTasksByPackageNameLocked(ssp, userId);
16117 if (userId == UserHandle.USER_OWNER) {
16118 mTaskPersister.removeFromPackageCache(ssp);
16122 removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16123 if (userId == UserHandle.USER_OWNER) {
16124 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16131 case Intent.ACTION_PACKAGE_ADDED:
16132 // Special case for adding a package: by default turn on compatibility mode.
16133 Uri data = intent.getData();
16135 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16136 final boolean replacing =
16137 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16138 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16141 removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16143 if (userId == UserHandle.USER_OWNER) {
16144 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16148 case Intent.ACTION_TIMEZONE_CHANGED:
16149 // If this is the time zone changed action, queue up a message that will reset
16150 // the timezone of all currently running processes. This message will get
16151 // queued up before the broadcast happens.
16152 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16154 case Intent.ACTION_TIME_CHANGED:
16155 // If the user set the time, let all running processes know.
16156 final int is24Hour =
16157 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16159 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16160 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16161 synchronized (stats) {
16162 stats.noteCurrentTimeChangedLocked();
16165 case Intent.ACTION_CLEAR_DNS_CACHE:
16166 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16168 case Proxy.PROXY_CHANGE_ACTION:
16169 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16170 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16175 // Add to the sticky list if requested.
16177 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16178 callingPid, callingUid)
16179 != PackageManager.PERMISSION_GRANTED) {
16180 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16181 + callingPid + ", uid=" + callingUid
16182 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16184 throw new SecurityException(msg);
16186 if (requiredPermission != null) {
16187 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16188 + " and enforce permission " + requiredPermission);
16189 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16191 if (intent.getComponent() != null) {
16192 throw new SecurityException(
16193 "Sticky broadcasts can't target a specific component");
16195 // We use userId directly here, since the "all" target is maintained
16196 // as a separate set of sticky broadcasts.
16197 if (userId != UserHandle.USER_ALL) {
16198 // But first, if this is not a broadcast to all users, then
16199 // make sure it doesn't conflict with an existing broadcast to
16201 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16202 UserHandle.USER_ALL);
16203 if (stickies != null) {
16204 ArrayList<Intent> list = stickies.get(intent.getAction());
16205 if (list != null) {
16206 int N = list.size();
16208 for (i=0; i<N; i++) {
16209 if (intent.filterEquals(list.get(i))) {
16210 throw new IllegalArgumentException(
16211 "Sticky broadcast " + intent + " for user "
16212 + userId + " conflicts with existing global broadcast");
16218 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16219 if (stickies == null) {
16220 stickies = new ArrayMap<String, ArrayList<Intent>>();
16221 mStickyBroadcasts.put(userId, stickies);
16223 ArrayList<Intent> list = stickies.get(intent.getAction());
16224 if (list == null) {
16225 list = new ArrayList<Intent>();
16226 stickies.put(intent.getAction(), list);
16228 int N = list.size();
16230 for (i=0; i<N; i++) {
16231 if (intent.filterEquals(list.get(i))) {
16232 // This sticky already exists, replace it.
16233 list.set(i, new Intent(intent));
16238 list.add(new Intent(intent));
16243 if (userId == UserHandle.USER_ALL) {
16244 // Caller wants broadcast to go to all started users.
16245 users = mStartedUserArray;
16247 // Caller wants broadcast to go to one specific user.
16248 users = new int[] {userId};
16251 // Figure out who all will receive this broadcast.
16252 List receivers = null;
16253 List<BroadcastFilter> registeredReceivers = null;
16254 // Need to resolve the intent to interested receivers...
16255 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16257 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16259 if (intent.getComponent() == null) {
16260 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16261 // Query one target user at a time, excluding shell-restricted users
16262 UserManagerService ums = getUserManagerLocked();
16263 for (int i = 0; i < users.length; i++) {
16264 if (ums.hasUserRestriction(
16265 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16268 List<BroadcastFilter> registeredReceiversForUser =
16269 mReceiverResolver.queryIntent(intent,
16270 resolvedType, false, users[i]);
16271 if (registeredReceivers == null) {
16272 registeredReceivers = registeredReceiversForUser;
16273 } else if (registeredReceiversForUser != null) {
16274 registeredReceivers.addAll(registeredReceiversForUser);
16278 registeredReceivers = mReceiverResolver.queryIntent(intent,
16279 resolvedType, false, userId);
16283 final boolean replacePending =
16284 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16286 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16287 + " replacePending=" + replacePending);
16289 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16290 if (!ordered && NR > 0) {
16291 // If we are not serializing this broadcast, then send the
16292 // registered receivers separately so they don't wait for the
16293 // components to be launched.
16294 final BroadcastQueue queue = broadcastQueueForIntent(intent);
16295 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16296 callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16297 appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16298 ordered, sticky, false, userId);
16299 if (DEBUG_BROADCAST) Slog.v(
16300 TAG, "Enqueueing parallel broadcast " + r);
16301 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16303 queue.enqueueParallelBroadcastLocked(r);
16304 queue.scheduleBroadcastsLocked();
16306 registeredReceivers = null;
16310 // Merge into one list.
16312 if (receivers != null) {
16313 // A special case for PACKAGE_ADDED: do not allow the package
16314 // being added to see this broadcast. This prevents them from
16315 // using this as a back door to get run as soon as they are
16316 // installed. Maybe in the future we want to have a special install
16317 // broadcast or such for apps, but we'd like to deliberately make
16319 String skipPackages[] = null;
16320 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16321 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16322 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16323 Uri data = intent.getData();
16324 if (data != null) {
16325 String pkgName = data.getSchemeSpecificPart();
16326 if (pkgName != null) {
16327 skipPackages = new String[] { pkgName };
16330 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16331 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16333 if (skipPackages != null && (skipPackages.length > 0)) {
16334 for (String skipPackage : skipPackages) {
16335 if (skipPackage != null) {
16336 int NT = receivers.size();
16337 for (int it=0; it<NT; it++) {
16338 ResolveInfo curt = (ResolveInfo)receivers.get(it);
16339 if (curt.activityInfo.packageName.equals(skipPackage)) {
16340 receivers.remove(it);
16349 int NT = receivers != null ? receivers.size() : 0;
16351 ResolveInfo curt = null;
16352 BroadcastFilter curr = null;
16353 while (it < NT && ir < NR) {
16354 if (curt == null) {
16355 curt = (ResolveInfo)receivers.get(it);
16357 if (curr == null) {
16358 curr = registeredReceivers.get(ir);
16360 if (curr.getPriority() >= curt.priority) {
16361 // Insert this broadcast record into the final list.
16362 receivers.add(it, curr);
16368 // Skip to the next ResolveInfo in the final list.
16375 if (receivers == null) {
16376 receivers = new ArrayList();
16378 receivers.add(registeredReceivers.get(ir));
16382 if ((receivers != null && receivers.size() > 0)
16383 || resultTo != null) {
16384 BroadcastQueue queue = broadcastQueueForIntent(intent);
16385 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16386 callerPackage, callingPid, callingUid, resolvedType,
16387 requiredPermission, appOp, receivers, resultTo, resultCode,
16388 resultData, map, ordered, sticky, false, userId);
16389 if (DEBUG_BROADCAST) Slog.v(
16390 TAG, "Enqueueing ordered broadcast " + r
16391 + ": prev had " + queue.mOrderedBroadcasts.size());
16392 if (DEBUG_BROADCAST) {
16393 int seq = r.intent.getIntExtra("seq", -1);
16394 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16396 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16398 queue.enqueueOrderedBroadcastLocked(r);
16399 queue.scheduleBroadcastsLocked();
16403 return ActivityManager.BROADCAST_SUCCESS;
16406 final Intent verifyBroadcastLocked(Intent intent) {
16407 // Refuse possible leaked file descriptors
16408 if (intent != null && intent.hasFileDescriptors() == true) {
16409 throw new IllegalArgumentException("File descriptors passed in Intent");
16412 int flags = intent.getFlags();
16414 if (!mProcessesReady) {
16415 // if the caller really truly claims to know what they're doing, go
16416 // ahead and allow the broadcast without launching any receivers
16417 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16418 intent = new Intent(intent);
16419 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16420 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16421 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16422 + " before boot completion");
16423 throw new IllegalStateException("Cannot broadcast before boot completed");
16427 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16428 throw new IllegalArgumentException(
16429 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16435 public final int broadcastIntent(IApplicationThread caller,
16436 Intent intent, String resolvedType, IIntentReceiver resultTo,
16437 int resultCode, String resultData, Bundle map,
16438 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16439 enforceNotIsolatedCaller("broadcastIntent");
16440 synchronized(this) {
16441 intent = verifyBroadcastLocked(intent);
16443 final ProcessRecord callerApp = getRecordForAppLocked(caller);
16444 final int callingPid = Binder.getCallingPid();
16445 final int callingUid = Binder.getCallingUid();
16446 final long origId = Binder.clearCallingIdentity();
16447 int res = broadcastIntentLocked(callerApp,
16448 callerApp != null ? callerApp.info.packageName : null,
16449 intent, resolvedType, resultTo,
16450 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16451 callingPid, callingUid, userId);
16452 Binder.restoreCallingIdentity(origId);
16457 int broadcastIntentInPackage(String packageName, int uid,
16458 Intent intent, String resolvedType, IIntentReceiver resultTo,
16459 int resultCode, String resultData, Bundle map,
16460 String requiredPermission, boolean serialized, boolean sticky, int userId) {
16461 synchronized(this) {
16462 intent = verifyBroadcastLocked(intent);
16464 final long origId = Binder.clearCallingIdentity();
16465 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16466 resultTo, resultCode, resultData, map, requiredPermission,
16467 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16468 Binder.restoreCallingIdentity(origId);
16473 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16474 // Refuse possible leaked file descriptors
16475 if (intent != null && intent.hasFileDescriptors() == true) {
16476 throw new IllegalArgumentException("File descriptors passed in Intent");
16479 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16480 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16482 synchronized(this) {
16483 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16484 != PackageManager.PERMISSION_GRANTED) {
16485 String msg = "Permission Denial: unbroadcastIntent() from pid="
16486 + Binder.getCallingPid()
16487 + ", uid=" + Binder.getCallingUid()
16488 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16490 throw new SecurityException(msg);
16492 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16493 if (stickies != null) {
16494 ArrayList<Intent> list = stickies.get(intent.getAction());
16495 if (list != null) {
16496 int N = list.size();
16498 for (i=0; i<N; i++) {
16499 if (intent.filterEquals(list.get(i))) {
16504 if (list.size() <= 0) {
16505 stickies.remove(intent.getAction());
16508 if (stickies.size() <= 0) {
16509 mStickyBroadcasts.remove(userId);
16515 void backgroundServicesFinishedLocked(int userId) {
16516 for (BroadcastQueue queue : mBroadcastQueues) {
16517 queue.backgroundServicesFinishedLocked(userId);
16521 public void finishReceiver(IBinder who, int resultCode, String resultData,
16522 Bundle resultExtras, boolean resultAbort, int flags) {
16523 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16525 // Refuse possible leaked file descriptors
16526 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16527 throw new IllegalArgumentException("File descriptors passed in Bundle");
16530 final long origId = Binder.clearCallingIdentity();
16532 boolean doNext = false;
16535 synchronized(this) {
16536 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
16537 ? mFgBroadcastQueue : mBgBroadcastQueue;
16538 r = queue.getMatchingOrderedReceiver(who);
16540 doNext = r.queue.finishReceiverLocked(r, resultCode,
16541 resultData, resultExtras, resultAbort, true);
16546 r.queue.processNextBroadcast(false);
16548 trimApplications();
16550 Binder.restoreCallingIdentity(origId);
16554 // =========================================================
16556 // =========================================================
16558 public boolean startInstrumentation(ComponentName className,
16559 String profileFile, int flags, Bundle arguments,
16560 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16561 int userId, String abiOverride) {
16562 enforceNotIsolatedCaller("startInstrumentation");
16563 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16564 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16565 // Refuse possible leaked file descriptors
16566 if (arguments != null && arguments.hasFileDescriptors()) {
16567 throw new IllegalArgumentException("File descriptors passed in Bundle");
16570 synchronized(this) {
16571 InstrumentationInfo ii = null;
16572 ApplicationInfo ai = null;
16574 ii = mContext.getPackageManager().getInstrumentationInfo(
16575 className, STOCK_PM_FLAGS);
16576 ai = AppGlobals.getPackageManager().getApplicationInfo(
16577 ii.targetPackage, STOCK_PM_FLAGS, userId);
16578 } catch (PackageManager.NameNotFoundException e) {
16579 } catch (RemoteException e) {
16582 reportStartInstrumentationFailure(watcher, className,
16583 "Unable to find instrumentation info for: " + className);
16587 reportStartInstrumentationFailure(watcher, className,
16588 "Unable to find instrumentation target package: " + ii.targetPackage);
16592 int match = mContext.getPackageManager().checkSignatures(
16593 ii.targetPackage, ii.packageName);
16594 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16595 String msg = "Permission Denial: starting instrumentation "
16596 + className + " from pid="
16597 + Binder.getCallingPid()
16598 + ", uid=" + Binder.getCallingPid()
16599 + " not allowed because package " + ii.packageName
16600 + " does not have a signature matching the target "
16601 + ii.targetPackage;
16602 reportStartInstrumentationFailure(watcher, className, msg);
16603 throw new SecurityException(msg);
16606 final long origId = Binder.clearCallingIdentity();
16607 // Instrumentation can kill and relaunch even persistent processes
16608 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16610 ProcessRecord app = addAppLocked(ai, false, abiOverride);
16611 app.instrumentationClass = className;
16612 app.instrumentationInfo = ai;
16613 app.instrumentationProfileFile = profileFile;
16614 app.instrumentationArguments = arguments;
16615 app.instrumentationWatcher = watcher;
16616 app.instrumentationUiAutomationConnection = uiAutomationConnection;
16617 app.instrumentationResultClass = className;
16618 Binder.restoreCallingIdentity(origId);
16625 * Report errors that occur while attempting to start Instrumentation. Always writes the
16626 * error to the logs, but if somebody is watching, send the report there too. This enables
16627 * the "am" command to report errors with more information.
16629 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
16630 * @param cn The component name of the instrumentation.
16631 * @param report The error report.
16633 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16634 ComponentName cn, String report) {
16635 Slog.w(TAG, report);
16637 if (watcher != null) {
16638 Bundle results = new Bundle();
16639 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16640 results.putString("Error", report);
16641 watcher.instrumentationStatus(cn, -1, results);
16643 } catch (RemoteException e) {
16648 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16649 if (app.instrumentationWatcher != null) {
16651 // NOTE: IInstrumentationWatcher *must* be oneway here
16652 app.instrumentationWatcher.instrumentationFinished(
16653 app.instrumentationClass,
16656 } catch (RemoteException e) {
16659 if (app.instrumentationUiAutomationConnection != null) {
16661 app.instrumentationUiAutomationConnection.shutdown();
16662 } catch (RemoteException re) {
16665 // Only a UiAutomation can set this flag and now that
16666 // it is finished we make sure it is reset to its default.
16667 mUserIsMonkey = false;
16669 app.instrumentationWatcher = null;
16670 app.instrumentationUiAutomationConnection = null;
16671 app.instrumentationClass = null;
16672 app.instrumentationInfo = null;
16673 app.instrumentationProfileFile = null;
16674 app.instrumentationArguments = null;
16676 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16680 public void finishInstrumentation(IApplicationThread target,
16681 int resultCode, Bundle results) {
16682 int userId = UserHandle.getCallingUserId();
16683 // Refuse possible leaked file descriptors
16684 if (results != null && results.hasFileDescriptors()) {
16685 throw new IllegalArgumentException("File descriptors passed in Intent");
16688 synchronized(this) {
16689 ProcessRecord app = getRecordForAppLocked(target);
16691 Slog.w(TAG, "finishInstrumentation: no app for " + target);
16694 final long origId = Binder.clearCallingIdentity();
16695 finishInstrumentationLocked(app, resultCode, results);
16696 Binder.restoreCallingIdentity(origId);
16700 // =========================================================
16702 // =========================================================
16704 public ConfigurationInfo getDeviceConfigurationInfo() {
16705 ConfigurationInfo config = new ConfigurationInfo();
16706 synchronized (this) {
16707 config.reqTouchScreen = mConfiguration.touchscreen;
16708 config.reqKeyboardType = mConfiguration.keyboard;
16709 config.reqNavigation = mConfiguration.navigation;
16710 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16711 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16712 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16714 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16715 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16716 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16718 config.reqGlEsVersion = GL_ES_VERSION;
16723 ActivityStack getFocusedStack() {
16724 return mStackSupervisor.getFocusedStack();
16727 public Configuration getConfiguration() {
16729 synchronized(this) {
16730 ci = new Configuration(mConfiguration);
16731 ci.userSetLocale = false;
16736 public void updatePersistentConfiguration(Configuration values) {
16737 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16738 "updateConfiguration()");
16739 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16740 "updateConfiguration()");
16741 if (values == null) {
16742 throw new NullPointerException("Configuration must not be null");
16745 synchronized(this) {
16746 final long origId = Binder.clearCallingIdentity();
16747 updateConfigurationLocked(values, null, true, false);
16748 Binder.restoreCallingIdentity(origId);
16752 public void updateConfiguration(Configuration values) {
16753 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16754 "updateConfiguration()");
16756 synchronized(this) {
16757 if (values == null && mWindowManager != null) {
16758 // sentinel: fetch the current configuration from the window manager
16759 values = mWindowManager.computeNewConfiguration();
16762 if (mWindowManager != null) {
16763 mProcessList.applyDisplaySize(mWindowManager);
16766 final long origId = Binder.clearCallingIdentity();
16767 if (values != null) {
16768 Settings.System.clearConfiguration(values);
16770 updateConfigurationLocked(values, null, false, false);
16771 Binder.restoreCallingIdentity(origId);
16776 * Do either or both things: (1) change the current configuration, and (2)
16777 * make sure the given activity is running with the (now) current
16778 * configuration. Returns true if the activity has been left running, or
16779 * false if <var>starting</var> is being destroyed to match the new
16781 * @param persistent TODO
16783 boolean updateConfigurationLocked(Configuration values,
16784 ActivityRecord starting, boolean persistent, boolean initLocale) {
16787 if (values != null) {
16788 Configuration newConfig = new Configuration(mConfiguration);
16789 changes = newConfig.updateFrom(values);
16790 if (changes != 0) {
16791 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16792 Slog.i(TAG, "Updating configuration to: " + values);
16795 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16797 if (!initLocale && values.locale != null && values.userSetLocale) {
16798 final String languageTag = values.locale.toLanguageTag();
16799 SystemProperties.set("persist.sys.locale", languageTag);
16800 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
16804 mConfigurationSeq++;
16805 if (mConfigurationSeq <= 0) {
16806 mConfigurationSeq = 1;
16808 newConfig.seq = mConfigurationSeq;
16809 mConfiguration = newConfig;
16810 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16811 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16812 //mUsageStatsService.noteStartConfig(newConfig);
16814 final Configuration configCopy = new Configuration(mConfiguration);
16816 // TODO: If our config changes, should we auto dismiss any currently
16817 // showing dialogs?
16818 mShowDialogs = shouldShowDialogs(newConfig);
16820 AttributeCache ac = AttributeCache.instance();
16822 ac.updateConfiguration(configCopy);
16825 // Make sure all resources in our process are updated
16826 // right now, so that anyone who is going to retrieve
16827 // resource values after we return will be sure to get
16828 // the new ones. This is especially important during
16829 // boot, where the first config change needs to guarantee
16830 // all resources have that config before following boot
16831 // code is executed.
16832 mSystemThread.applyConfigurationToResources(configCopy);
16834 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16835 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16836 msg.obj = new Configuration(configCopy);
16837 mHandler.sendMessage(msg);
16840 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16841 ProcessRecord app = mLruProcesses.get(i);
16843 if (app.thread != null) {
16844 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16845 + app.processName + " new config " + mConfiguration);
16846 app.thread.scheduleConfigurationChanged(configCopy);
16848 } catch (Exception e) {
16851 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16852 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16853 | Intent.FLAG_RECEIVER_REPLACE_PENDING
16854 | Intent.FLAG_RECEIVER_FOREGROUND);
16855 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16856 null, AppOpsManager.OP_NONE, false, false, MY_PID,
16857 Process.SYSTEM_UID, UserHandle.USER_ALL);
16858 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16859 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16860 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16861 if (!mProcessesReady) {
16862 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16864 broadcastIntentLocked(null, null, intent,
16865 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16866 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16871 boolean kept = true;
16872 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16873 // mainStack is null during startup.
16874 if (mainStack != null) {
16875 if (changes != 0 && starting == null) {
16876 // If the configuration changed, and the caller is not already
16877 // in the process of starting an activity, then find the top
16878 // activity to check if its configuration needs to change.
16879 starting = mainStack.topRunningActivityLocked(null);
16882 if (starting != null) {
16883 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16884 // And we need to make sure at this point that all other activities
16885 // are made visible with the correct configuration.
16886 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16890 if (values != null && mWindowManager != null) {
16891 mWindowManager.setNewConfiguration(mConfiguration);
16898 * Decide based on the configuration whether we should shouw the ANR,
16899 * crash, etc dialogs. The idea is that if there is no affordnace to
16900 * press the on-screen buttons, we shouldn't show the dialog.
16902 * A thought: SystemUI might also want to get told about this, the Power
16903 * dialog / global actions also might want different behaviors.
16905 private static final boolean shouldShowDialogs(Configuration config) {
16906 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16907 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16911 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16912 synchronized (this) {
16913 ActivityRecord srec = ActivityRecord.forToken(token);
16914 if (srec.task != null && srec.task.stack != null) {
16915 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16921 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16922 Intent resultData) {
16924 synchronized (this) {
16925 final ActivityStack stack = ActivityRecord.getStackLocked(token);
16926 if (stack != null) {
16927 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16933 public int getLaunchedFromUid(IBinder activityToken) {
16934 ActivityRecord srec = ActivityRecord.forToken(activityToken);
16935 if (srec == null) {
16938 return srec.launchedFromUid;
16941 public String getLaunchedFromPackage(IBinder activityToken) {
16942 ActivityRecord srec = ActivityRecord.forToken(activityToken);
16943 if (srec == null) {
16946 return srec.launchedFromPackage;
16949 // =========================================================
16950 // LIFETIME MANAGEMENT
16951 // =========================================================
16953 // Returns which broadcast queue the app is the current [or imminent] receiver
16954 // on, or 'null' if the app is not an active broadcast recipient.
16955 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16956 BroadcastRecord r = app.curReceiver;
16961 // It's not the current receiver, but it might be starting up to become one
16962 synchronized (this) {
16963 for (BroadcastQueue queue : mBroadcastQueues) {
16964 r = queue.mPendingBroadcast;
16965 if (r != null && r.curApp == app) {
16966 // found it; report which queue it's in
16975 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16976 ComponentName targetComponent, String targetProcess) {
16977 if (!mTrackingAssociations) {
16980 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16981 = mAssociations.get(targetUid);
16982 if (components == null) {
16983 components = new ArrayMap<>();
16984 mAssociations.put(targetUid, components);
16986 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16987 if (sourceUids == null) {
16988 sourceUids = new SparseArray<>();
16989 components.put(targetComponent, sourceUids);
16991 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16992 if (sourceProcesses == null) {
16993 sourceProcesses = new ArrayMap<>();
16994 sourceUids.put(sourceUid, sourceProcesses);
16996 Association ass = sourceProcesses.get(sourceProcess);
16998 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17000 sourceProcesses.put(sourceProcess, ass);
17004 if (ass.mNesting == 1) {
17005 ass.mStartTime = SystemClock.uptimeMillis();
17010 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17011 ComponentName targetComponent) {
17012 if (!mTrackingAssociations) {
17015 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17016 = mAssociations.get(targetUid);
17017 if (components == null) {
17020 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17021 if (sourceUids == null) {
17024 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17025 if (sourceProcesses == null) {
17028 Association ass = sourceProcesses.get(sourceProcess);
17029 if (ass == null || ass.mNesting <= 0) {
17033 if (ass.mNesting == 0) {
17034 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17038 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17039 boolean doingAll, long now) {
17040 if (mAdjSeq == app.adjSeq) {
17041 // This adjustment has already been computed.
17042 return app.curRawAdj;
17045 if (app.thread == null) {
17046 app.adjSeq = mAdjSeq;
17047 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17048 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17049 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17052 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17053 app.adjSource = null;
17054 app.adjTarget = null;
17056 app.cached = false;
17058 final int activitiesSize = app.activities.size();
17060 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17061 // The max adjustment doesn't allow this app to be anything
17062 // below foreground, so it is not worth doing work for it.
17063 app.adjType = "fixed";
17064 app.adjSeq = mAdjSeq;
17065 app.curRawAdj = app.maxAdj;
17066 app.foregroundActivities = false;
17067 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17068 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17069 // System processes can do UI, and when they do we want to have
17070 // them trim their memory after the user leaves the UI. To
17071 // facilitate this, here we need to determine whether or not it
17072 // is currently showing UI.
17073 app.systemNoUi = true;
17074 if (app == TOP_APP) {
17075 app.systemNoUi = false;
17076 } else if (activitiesSize > 0) {
17077 for (int j = 0; j < activitiesSize; j++) {
17078 final ActivityRecord r = app.activities.get(j);
17080 app.systemNoUi = false;
17084 if (!app.systemNoUi) {
17085 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17087 return (app.curAdj=app.maxAdj);
17090 app.systemNoUi = false;
17092 // Determine the importance of the process, starting with most
17093 // important to least, and assign an appropriate OOM adjustment.
17097 boolean foregroundActivities = false;
17098 BroadcastQueue queue;
17099 if (app == TOP_APP) {
17100 // The last app on the list is the foreground app.
17101 adj = ProcessList.FOREGROUND_APP_ADJ;
17102 schedGroup = Process.THREAD_GROUP_DEFAULT;
17103 app.adjType = "top-activity";
17104 foregroundActivities = true;
17105 procState = ActivityManager.PROCESS_STATE_TOP;
17106 } else if (app.instrumentationClass != null) {
17107 // Don't want to kill running instrumentation.
17108 adj = ProcessList.FOREGROUND_APP_ADJ;
17109 schedGroup = Process.THREAD_GROUP_DEFAULT;
17110 app.adjType = "instrumentation";
17111 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17112 } else if ((queue = isReceivingBroadcast(app)) != null) {
17113 // An app that is currently receiving a broadcast also
17114 // counts as being in the foreground for OOM killer purposes.
17115 // It's placed in a sched group based on the nature of the
17116 // broadcast as reflected by which queue it's active in.
17117 adj = ProcessList.FOREGROUND_APP_ADJ;
17118 schedGroup = (queue == mFgBroadcastQueue)
17119 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17120 app.adjType = "broadcast";
17121 procState = ActivityManager.PROCESS_STATE_RECEIVER;
17122 } else if (app.executingServices.size() > 0) {
17123 // An app that is currently executing a service callback also
17124 // counts as being in the foreground.
17125 adj = ProcessList.FOREGROUND_APP_ADJ;
17126 schedGroup = app.execServicesFg ?
17127 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17128 app.adjType = "exec-service";
17129 procState = ActivityManager.PROCESS_STATE_SERVICE;
17130 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17132 // As far as we know the process is empty. We may change our mind later.
17133 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17134 // At this point we don't actually know the adjustment. Use the cached adj
17135 // value that the caller wants us to.
17137 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17140 app.adjType = "cch-empty";
17143 // Examine all activities if not already foreground.
17144 if (!foregroundActivities && activitiesSize > 0) {
17145 for (int j = 0; j < activitiesSize; j++) {
17146 final ActivityRecord r = app.activities.get(j);
17147 if (r.app != app) {
17148 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17153 // App has a visible activity; only upgrade adjustment.
17154 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17155 adj = ProcessList.VISIBLE_APP_ADJ;
17156 app.adjType = "visible";
17158 if (procState > ActivityManager.PROCESS_STATE_TOP) {
17159 procState = ActivityManager.PROCESS_STATE_TOP;
17161 schedGroup = Process.THREAD_GROUP_DEFAULT;
17162 app.cached = false;
17164 foregroundActivities = true;
17166 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17167 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17168 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17169 app.adjType = "pausing";
17171 if (procState > ActivityManager.PROCESS_STATE_TOP) {
17172 procState = ActivityManager.PROCESS_STATE_TOP;
17174 schedGroup = Process.THREAD_GROUP_DEFAULT;
17175 app.cached = false;
17177 foregroundActivities = true;
17178 } else if (r.state == ActivityState.STOPPING) {
17179 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17180 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17181 app.adjType = "stopping";
17183 // For the process state, we will at this point consider the
17184 // process to be cached. It will be cached either as an activity
17185 // or empty depending on whether the activity is finishing. We do
17186 // this so that we can treat the process as cached for purposes of
17187 // memory trimming (determing current memory level, trim command to
17188 // send to process) since there can be an arbitrary number of stopping
17189 // processes and they should soon all go into the cached state.
17190 if (!r.finishing) {
17191 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17192 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17195 app.cached = false;
17197 foregroundActivities = true;
17199 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17200 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17201 app.adjType = "cch-act";
17207 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17208 if (app.foregroundServices) {
17209 // The user is aware of this app, so make it visible.
17210 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17211 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17212 app.cached = false;
17213 app.adjType = "fg-service";
17214 schedGroup = Process.THREAD_GROUP_DEFAULT;
17215 } else if (app.forcingToForeground != null) {
17216 // The user is aware of this app, so make it visible.
17217 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17218 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17219 app.cached = false;
17220 app.adjType = "force-fg";
17221 app.adjSource = app.forcingToForeground;
17222 schedGroup = Process.THREAD_GROUP_DEFAULT;
17226 if (app == mHeavyWeightProcess) {
17227 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17228 // We don't want to kill the current heavy-weight process.
17229 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17230 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17231 app.cached = false;
17232 app.adjType = "heavy";
17234 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17235 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17239 if (app == mHomeProcess) {
17240 if (adj > ProcessList.HOME_APP_ADJ) {
17241 // This process is hosting what we currently consider to be the
17242 // home app, so we don't want to let it go into the background.
17243 adj = ProcessList.HOME_APP_ADJ;
17244 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17245 app.cached = false;
17246 app.adjType = "home";
17248 if (procState > ActivityManager.PROCESS_STATE_HOME) {
17249 procState = ActivityManager.PROCESS_STATE_HOME;
17253 if (app == mPreviousProcess && app.activities.size() > 0) {
17254 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17255 // This was the previous process that showed UI to the user.
17256 // We want to try to keep it around more aggressively, to give
17257 // a good experience around switching between two apps.
17258 adj = ProcessList.PREVIOUS_APP_ADJ;
17259 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17260 app.cached = false;
17261 app.adjType = "previous";
17263 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17264 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17268 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17269 + " reason=" + app.adjType);
17271 // By default, we use the computed adjustment. It may be changed if
17272 // there are applications dependent on our services or providers, but
17273 // this gives us a baseline and makes sure we don't get into an
17274 // infinite recursion.
17275 app.adjSeq = mAdjSeq;
17276 app.curRawAdj = adj;
17277 app.hasStartedServices = false;
17279 if (mBackupTarget != null && app == mBackupTarget.app) {
17280 // If possible we want to avoid killing apps while they're being backed up
17281 if (adj > ProcessList.BACKUP_APP_ADJ) {
17282 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
17283 adj = ProcessList.BACKUP_APP_ADJ;
17284 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17285 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17287 app.adjType = "backup";
17288 app.cached = false;
17290 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17291 procState = ActivityManager.PROCESS_STATE_BACKUP;
17295 boolean mayBeTop = false;
17297 for (int is = app.services.size()-1;
17298 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17299 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17300 || procState > ActivityManager.PROCESS_STATE_TOP);
17302 ServiceRecord s = app.services.valueAt(is);
17303 if (s.startRequested) {
17304 app.hasStartedServices = true;
17305 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17306 procState = ActivityManager.PROCESS_STATE_SERVICE;
17308 if (app.hasShownUi && app != mHomeProcess) {
17309 // If this process has shown some UI, let it immediately
17310 // go to the LRU list because it may be pretty heavy with
17311 // UI stuff. We'll tag it with a label just to help
17312 // debug and understand what is going on.
17313 if (adj > ProcessList.SERVICE_ADJ) {
17314 app.adjType = "cch-started-ui-services";
17317 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17318 // This service has seen some activity within
17319 // recent memory, so we will keep its process ahead
17320 // of the background processes.
17321 if (adj > ProcessList.SERVICE_ADJ) {
17322 adj = ProcessList.SERVICE_ADJ;
17323 app.adjType = "started-services";
17324 app.cached = false;
17327 // If we have let the service slide into the background
17328 // state, still have some text describing what it is doing
17329 // even though the service no longer has an impact.
17330 if (adj > ProcessList.SERVICE_ADJ) {
17331 app.adjType = "cch-started-services";
17335 for (int conni = s.connections.size()-1;
17336 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17337 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17338 || procState > ActivityManager.PROCESS_STATE_TOP);
17340 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17342 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17343 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17344 || procState > ActivityManager.PROCESS_STATE_TOP);
17346 // XXX should compute this based on the max of
17347 // all connected clients.
17348 ConnectionRecord cr = clist.get(i);
17349 if (cr.binding.client == app) {
17350 // Binding to ourself is not interesting.
17353 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17354 ProcessRecord client = cr.binding.client;
17355 int clientAdj = computeOomAdjLocked(client, cachedAdj,
17356 TOP_APP, doingAll, now);
17357 int clientProcState = client.curProcState;
17358 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17359 // If the other app is cached for any reason, for purposes here
17360 // we are going to consider it empty. The specific cached state
17361 // doesn't propagate except under certain conditions.
17362 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17364 String adjType = null;
17365 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17366 // Not doing bind OOM management, so treat
17367 // this guy more like a started service.
17368 if (app.hasShownUi && app != mHomeProcess) {
17369 // If this process has shown some UI, let it immediately
17370 // go to the LRU list because it may be pretty heavy with
17371 // UI stuff. We'll tag it with a label just to help
17372 // debug and understand what is going on.
17373 if (adj > clientAdj) {
17374 adjType = "cch-bound-ui-services";
17376 app.cached = false;
17378 clientProcState = procState;
17380 if (now >= (s.lastActivity
17381 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17382 // This service has not seen activity within
17383 // recent memory, so allow it to drop to the
17384 // LRU list if there is no other reason to keep
17385 // it around. We'll also tag it with a label just
17386 // to help debug and undertand what is going on.
17387 if (adj > clientAdj) {
17388 adjType = "cch-bound-services";
17394 if (adj > clientAdj) {
17395 // If this process has recently shown UI, and
17396 // the process that is binding to it is less
17397 // important than being visible, then we don't
17398 // care about the binding as much as we care
17399 // about letting this process get into the LRU
17400 // list to be killed and restarted if needed for
17402 if (app.hasShownUi && app != mHomeProcess
17403 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17404 adjType = "cch-bound-ui-services";
17406 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17407 |Context.BIND_IMPORTANT)) != 0) {
17408 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17409 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17410 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17411 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17412 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17413 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17414 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17417 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17418 adj = ProcessList.VISIBLE_APP_ADJ;
17421 if (!client.cached) {
17422 app.cached = false;
17424 adjType = "service";
17427 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17428 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17429 schedGroup = Process.THREAD_GROUP_DEFAULT;
17431 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17432 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17433 // Special handling of clients who are in the top state.
17434 // We *may* want to consider this process to be in the
17435 // top state as well, but only if there is not another
17436 // reason for it to be running. Being on the top is a
17437 // special state, meaning you are specifically running
17438 // for the current top app. If the process is already
17439 // running in the background for some other reason, it
17440 // is more important to continue considering it to be
17441 // in the background state.
17443 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17445 // Special handling for above-top states (persistent
17446 // processes). These should not bring the current process
17447 // into the top state, since they are not on top. Instead
17448 // give them the best state after that.
17450 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17454 if (clientProcState <
17455 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17457 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17460 if (procState > clientProcState) {
17461 procState = clientProcState;
17463 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17464 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17465 app.pendingUiClean = true;
17467 if (adjType != null) {
17468 app.adjType = adjType;
17469 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17470 .REASON_SERVICE_IN_USE;
17471 app.adjSource = cr.binding.client;
17472 app.adjSourceProcState = clientProcState;
17473 app.adjTarget = s.name;
17476 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17477 app.treatLikeActivity = true;
17479 final ActivityRecord a = cr.activity;
17480 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17481 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17482 (a.visible || a.state == ActivityState.RESUMED
17483 || a.state == ActivityState.PAUSING)) {
17484 adj = ProcessList.FOREGROUND_APP_ADJ;
17485 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17486 schedGroup = Process.THREAD_GROUP_DEFAULT;
17488 app.cached = false;
17489 app.adjType = "service";
17490 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17491 .REASON_SERVICE_IN_USE;
17493 app.adjSourceProcState = procState;
17494 app.adjTarget = s.name;
17501 for (int provi = app.pubProviders.size()-1;
17502 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17503 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17504 || procState > ActivityManager.PROCESS_STATE_TOP);
17506 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17507 for (int i = cpr.connections.size()-1;
17508 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17509 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17510 || procState > ActivityManager.PROCESS_STATE_TOP);
17512 ContentProviderConnection conn = cpr.connections.get(i);
17513 ProcessRecord client = conn.client;
17514 if (client == app) {
17515 // Being our own client is not interesting.
17518 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17519 int clientProcState = client.curProcState;
17520 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17521 // If the other app is cached for any reason, for purposes here
17522 // we are going to consider it empty.
17523 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17525 if (adj > clientAdj) {
17526 if (app.hasShownUi && app != mHomeProcess
17527 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17528 app.adjType = "cch-ui-provider";
17530 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17531 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17532 app.adjType = "provider";
17534 app.cached &= client.cached;
17535 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17536 .REASON_PROVIDER_IN_USE;
17537 app.adjSource = client;
17538 app.adjSourceProcState = clientProcState;
17539 app.adjTarget = cpr.name;
17541 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17542 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17543 // Special handling of clients who are in the top state.
17544 // We *may* want to consider this process to be in the
17545 // top state as well, but only if there is not another
17546 // reason for it to be running. Being on the top is a
17547 // special state, meaning you are specifically running
17548 // for the current top app. If the process is already
17549 // running in the background for some other reason, it
17550 // is more important to continue considering it to be
17551 // in the background state.
17553 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17555 // Special handling for above-top states (persistent
17556 // processes). These should not bring the current process
17557 // into the top state, since they are not on top. Instead
17558 // give them the best state after that.
17560 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17563 if (procState > clientProcState) {
17564 procState = clientProcState;
17566 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17567 schedGroup = Process.THREAD_GROUP_DEFAULT;
17570 // If the provider has external (non-framework) process
17571 // dependencies, ensure that its adjustment is at least
17572 // FOREGROUND_APP_ADJ.
17573 if (cpr.hasExternalProcessHandles()) {
17574 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17575 adj = ProcessList.FOREGROUND_APP_ADJ;
17576 schedGroup = Process.THREAD_GROUP_DEFAULT;
17577 app.cached = false;
17578 app.adjType = "provider";
17579 app.adjTarget = cpr.name;
17581 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17582 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17587 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17588 // A client of one of our services or providers is in the top state. We
17589 // *may* want to be in the top state, but not if we are already running in
17590 // the background for some other reason. For the decision here, we are going
17591 // to pick out a few specific states that we want to remain in when a client
17592 // is top (states that tend to be longer-term) and otherwise allow it to go
17593 // to the top state.
17594 switch (procState) {
17595 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17596 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17597 case ActivityManager.PROCESS_STATE_SERVICE:
17598 // These all are longer-term states, so pull them up to the top
17599 // of the background states, but not all the way to the top state.
17600 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17603 // Otherwise, top is a better choice, so take it.
17604 procState = ActivityManager.PROCESS_STATE_TOP;
17609 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17610 if (app.hasClientActivities) {
17611 // This is a cached process, but with client activities. Mark it so.
17612 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17613 app.adjType = "cch-client-act";
17614 } else if (app.treatLikeActivity) {
17615 // This is a cached process, but somebody wants us to treat it like it has
17616 // an activity, okay!
17617 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17618 app.adjType = "cch-as-act";
17622 if (adj == ProcessList.SERVICE_ADJ) {
17624 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17625 mNewNumServiceProcs++;
17626 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17627 if (!app.serviceb) {
17628 // This service isn't far enough down on the LRU list to
17629 // normally be a B service, but if we are low on RAM and it
17630 // is large we want to force it down since we would prefer to
17631 // keep launcher over it.
17632 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17633 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17634 app.serviceHighRam = true;
17635 app.serviceb = true;
17636 //Slog.i(TAG, "ADJ " + app + " high ram!");
17638 mNewNumAServiceProcs++;
17639 //Slog.i(TAG, "ADJ " + app + " not high ram!");
17642 app.serviceHighRam = false;
17645 if (app.serviceb) {
17646 adj = ProcessList.SERVICE_B_ADJ;
17650 app.curRawAdj = adj;
17652 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17653 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17654 if (adj > app.maxAdj) {
17656 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17657 schedGroup = Process.THREAD_GROUP_DEFAULT;
17661 // Do final modification to adj. Everything we do between here and applying
17662 // the final setAdj must be done in this function, because we will also use
17663 // it when computing the final cached adj later. Note that we don't need to
17664 // worry about this for max adj above, since max adj will always be used to
17665 // keep it out of the cached vaues.
17666 app.curAdj = app.modifyRawOomAdj(adj);
17667 app.curSchedGroup = schedGroup;
17668 app.curProcState = procState;
17669 app.foregroundActivities = foregroundActivities;
17671 return app.curRawAdj;
17675 * Record new PSS sample for a process.
17677 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17678 proc.lastPssTime = now;
17679 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17680 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17681 + ": " + pss + " lastPss=" + proc.lastPss
17682 + " state=" + ProcessList.makeProcStateString(procState));
17683 if (proc.initialIdlePss == 0) {
17684 proc.initialIdlePss = pss;
17686 proc.lastPss = pss;
17687 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17688 proc.lastCachedPss = pss;
17693 * Schedule PSS collection of a process.
17695 void requestPssLocked(ProcessRecord proc, int procState) {
17696 if (mPendingPssProcesses.contains(proc)) {
17699 if (mPendingPssProcesses.size() == 0) {
17700 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17702 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17703 proc.pssProcState = procState;
17704 mPendingPssProcesses.add(proc);
17708 * Schedule PSS collection of all processes.
17710 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17712 if (now < (mLastFullPssTime +
17713 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17717 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered);
17718 mLastFullPssTime = now;
17719 mFullPssPending = true;
17720 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17721 mPendingPssProcesses.clear();
17722 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17723 ProcessRecord app = mLruProcesses.get(i);
17724 if (app.thread == null
17725 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
17728 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17729 app.pssProcState = app.setProcState;
17730 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17731 mTestPssMode, isSleeping(), now);
17732 mPendingPssProcesses.add(app);
17735 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17738 public void setTestPssMode(boolean enabled) {
17739 synchronized (this) {
17740 mTestPssMode = enabled;
17742 // Whenever we enable the mode, we want to take a snapshot all of current
17743 // process mem use.
17744 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17750 * Ask a given process to GC right now.
17752 final void performAppGcLocked(ProcessRecord app) {
17754 app.lastRequestedGc = SystemClock.uptimeMillis();
17755 if (app.thread != null) {
17756 if (app.reportLowMemory) {
17757 app.reportLowMemory = false;
17758 app.thread.scheduleLowMemory();
17760 app.thread.processInBackground();
17763 } catch (Exception e) {
17769 * Returns true if things are idle enough to perform GCs.
17771 private final boolean canGcNowLocked() {
17772 boolean processingBroadcasts = false;
17773 for (BroadcastQueue q : mBroadcastQueues) {
17774 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17775 processingBroadcasts = true;
17778 return !processingBroadcasts
17779 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17783 * Perform GCs on all processes that are waiting for it, but only
17784 * if things are idle.
17786 final void performAppGcsLocked() {
17787 final int N = mProcessesToGc.size();
17791 if (canGcNowLocked()) {
17792 while (mProcessesToGc.size() > 0) {
17793 ProcessRecord proc = mProcessesToGc.remove(0);
17794 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17795 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17796 <= SystemClock.uptimeMillis()) {
17797 // To avoid spamming the system, we will GC processes one
17798 // at a time, waiting a few seconds between each.
17799 performAppGcLocked(proc);
17800 scheduleAppGcsLocked();
17803 // It hasn't been long enough since we last GCed this
17804 // process... put it in the list to wait for its time.
17805 addProcessToGcListLocked(proc);
17811 scheduleAppGcsLocked();
17816 * If all looks good, perform GCs on all processes waiting for them.
17818 final void performAppGcsIfAppropriateLocked() {
17819 if (canGcNowLocked()) {
17820 performAppGcsLocked();
17823 // Still not idle, wait some more.
17824 scheduleAppGcsLocked();
17828 * Schedule the execution of all pending app GCs.
17830 final void scheduleAppGcsLocked() {
17831 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17833 if (mProcessesToGc.size() > 0) {
17834 // Schedule a GC for the time to the next process.
17835 ProcessRecord proc = mProcessesToGc.get(0);
17836 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17838 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17839 long now = SystemClock.uptimeMillis();
17840 if (when < (now+GC_TIMEOUT)) {
17841 when = now + GC_TIMEOUT;
17843 mHandler.sendMessageAtTime(msg, when);
17848 * Add a process to the array of processes waiting to be GCed. Keeps the
17849 * list in sorted order by the last GC time. The process can't already be
17852 final void addProcessToGcListLocked(ProcessRecord proc) {
17853 boolean added = false;
17854 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17855 if (mProcessesToGc.get(i).lastRequestedGc <
17856 proc.lastRequestedGc) {
17858 mProcessesToGc.add(i+1, proc);
17863 mProcessesToGc.add(0, proc);
17868 * Set up to ask a process to GC itself. This will either do it
17869 * immediately, or put it on the list of processes to gc the next
17870 * time things are idle.
17872 final void scheduleAppGcLocked(ProcessRecord app) {
17873 long now = SystemClock.uptimeMillis();
17874 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17877 if (!mProcessesToGc.contains(app)) {
17878 addProcessToGcListLocked(app);
17879 scheduleAppGcsLocked();
17883 final void checkExcessivePowerUsageLocked(boolean doKills) {
17884 updateCpuStatsNow();
17886 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17887 boolean doWakeKills = doKills;
17888 boolean doCpuKills = doKills;
17889 if (mLastPowerCheckRealtime == 0) {
17890 doWakeKills = false;
17892 if (mLastPowerCheckUptime == 0) {
17893 doCpuKills = false;
17895 if (stats.isScreenOn()) {
17896 doWakeKills = false;
17898 final long curRealtime = SystemClock.elapsedRealtime();
17899 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17900 final long curUptime = SystemClock.uptimeMillis();
17901 final long uptimeSince = curUptime - mLastPowerCheckUptime;
17902 mLastPowerCheckRealtime = curRealtime;
17903 mLastPowerCheckUptime = curUptime;
17904 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17905 doWakeKills = false;
17907 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17908 doCpuKills = false;
17910 int i = mLruProcesses.size();
17913 ProcessRecord app = mLruProcesses.get(i);
17914 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17916 synchronized (stats) {
17917 wtime = stats.getProcessWakeTime(app.info.uid,
17918 app.pid, curRealtime);
17920 long wtimeUsed = wtime - app.lastWakeTime;
17921 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17923 StringBuilder sb = new StringBuilder(128);
17924 sb.append("Wake for ");
17925 app.toShortString(sb);
17926 sb.append(": over ");
17927 TimeUtils.formatDuration(realtimeSince, sb);
17928 sb.append(" used ");
17929 TimeUtils.formatDuration(wtimeUsed, sb);
17931 sb.append((wtimeUsed*100)/realtimeSince);
17933 Slog.i(TAG, sb.toString());
17935 sb.append("CPU for ");
17936 app.toShortString(sb);
17937 sb.append(": over ");
17938 TimeUtils.formatDuration(uptimeSince, sb);
17939 sb.append(" used ");
17940 TimeUtils.formatDuration(cputimeUsed, sb);
17942 sb.append((cputimeUsed*100)/uptimeSince);
17944 Slog.i(TAG, sb.toString());
17946 // If a process has held a wake lock for more
17947 // than 50% of the time during this period,
17948 // that sounds bad. Kill!
17949 if (doWakeKills && realtimeSince > 0
17950 && ((wtimeUsed*100)/realtimeSince) >= 50) {
17951 synchronized (stats) {
17952 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17953 realtimeSince, wtimeUsed);
17955 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17956 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17957 } else if (doCpuKills && uptimeSince > 0
17958 && ((cputimeUsed*100)/uptimeSince) >= 25) {
17959 synchronized (stats) {
17960 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17961 uptimeSince, cputimeUsed);
17963 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17964 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17966 app.lastWakeTime = wtime;
17967 app.lastCpuTime = app.curCpuTime;
17973 private final boolean applyOomAdjLocked(ProcessRecord app,
17974 ProcessRecord TOP_APP, boolean doingAll, long now) {
17975 boolean success = true;
17977 if (app.curRawAdj != app.setRawAdj) {
17978 app.setRawAdj = app.curRawAdj;
17983 if (app.curAdj != app.setAdj) {
17984 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17985 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17986 TAG, "Set " + app.pid + " " + app.processName +
17987 " adj " + app.curAdj + ": " + app.adjType);
17988 app.setAdj = app.curAdj;
17991 if (app.setSchedGroup != app.curSchedGroup) {
17992 app.setSchedGroup = app.curSchedGroup;
17993 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17994 "Setting process group of " + app.processName
17995 + " to " + app.curSchedGroup);
17996 if (app.waitingToKill != null &&
17997 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17998 app.kill(app.waitingToKill, true);
18002 long oldId = Binder.clearCallingIdentity();
18004 Process.setProcessGroup(app.pid, app.curSchedGroup);
18005 } catch (Exception e) {
18006 Slog.w(TAG, "Failed setting process group of " + app.pid
18007 + " to " + app.curSchedGroup);
18008 e.printStackTrace();
18010 Binder.restoreCallingIdentity(oldId);
18013 if (app.thread != null) {
18015 app.thread.setSchedulingGroup(app.curSchedGroup);
18016 } catch (RemoteException e) {
18020 Process.setSwappiness(app.pid,
18021 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18024 if (app.repForegroundActivities != app.foregroundActivities) {
18025 app.repForegroundActivities = app.foregroundActivities;
18026 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18028 if (app.repProcState != app.curProcState) {
18029 app.repProcState = app.curProcState;
18030 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18031 if (app.thread != null) {
18034 //RuntimeException h = new RuntimeException("here");
18035 Slog.i(TAG, "Sending new process state " + app.repProcState
18036 + " to " + app /*, h*/);
18038 app.thread.setProcessState(app.repProcState);
18039 } catch (RemoteException e) {
18043 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18044 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18045 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18046 // Experimental code to more aggressively collect pss while
18047 // running test... the problem is that this tends to collect
18048 // the data right when a process is transitioning between process
18049 // states, which well tend to give noisy data.
18050 long start = SystemClock.uptimeMillis();
18051 long pss = Debug.getPss(app.pid, mTmpLong, null);
18052 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
18053 mPendingPssProcesses.remove(app);
18054 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18055 + " to " + app.curProcState + ": "
18056 + (SystemClock.uptimeMillis()-start) + "ms");
18058 app.lastStateTime = now;
18059 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18060 mTestPssMode, isSleeping(), now);
18061 if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
18062 + ProcessList.makeProcStateString(app.setProcState) + " to "
18063 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18064 + (app.nextPssTime-now) + ": " + app);
18066 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18067 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18069 requestPssLocked(app, app.setProcState);
18070 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18071 mTestPssMode, isSleeping(), now);
18072 } else if (false && DEBUG_PSS) {
18073 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18076 if (app.setProcState != app.curProcState) {
18077 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18078 "Proc state change of " + app.processName
18079 + " to " + app.curProcState);
18080 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18081 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18082 if (setImportant && !curImportant) {
18083 // This app is no longer something we consider important enough to allow to
18084 // use arbitrary amounts of battery power. Note
18085 // its current wake lock time to later know to kill it if
18086 // it is not behaving well.
18087 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18088 synchronized (stats) {
18089 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18090 app.pid, SystemClock.elapsedRealtime());
18092 app.lastCpuTime = app.curCpuTime;
18095 app.setProcState = app.curProcState;
18096 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18097 app.notCachedSinceIdle = false;
18100 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18102 app.procStateChanged = true;
18106 if (changes != 0) {
18107 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
18108 int i = mPendingProcessChanges.size()-1;
18109 ProcessChangeItem item = null;
18111 item = mPendingProcessChanges.get(i);
18112 if (item.pid == app.pid) {
18113 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
18119 // No existing item in pending changes; need a new one.
18120 final int NA = mAvailProcessChanges.size();
18122 item = mAvailProcessChanges.remove(NA-1);
18123 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
18125 item = new ProcessChangeItem();
18126 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
18129 item.pid = app.pid;
18130 item.uid = app.info.uid;
18131 if (mPendingProcessChanges.size() == 0) {
18132 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
18133 "*** Enqueueing dispatch processes changed!");
18134 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18136 mPendingProcessChanges.add(item);
18138 item.changes |= changes;
18139 item.processState = app.repProcState;
18140 item.foregroundActivities = app.repForegroundActivities;
18141 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
18142 + Integer.toHexString(System.identityHashCode(item))
18143 + " " + app.toShortString() + ": changes=" + item.changes
18144 + " procState=" + item.processState
18145 + " foreground=" + item.foregroundActivities
18146 + " type=" + app.adjType + " source=" + app.adjSource
18147 + " target=" + app.adjTarget);
18153 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18154 if (proc.thread != null) {
18155 if (proc.baseProcessTracker != null) {
18156 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18158 if (proc.repProcState >= 0) {
18159 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18160 proc.repProcState);
18165 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18166 ProcessRecord TOP_APP, boolean doingAll, long now) {
18167 if (app.thread == null) {
18171 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18173 return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18176 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18178 if (isForeground != proc.foregroundServices) {
18179 proc.foregroundServices = isForeground;
18180 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18182 if (isForeground) {
18183 if (curProcs == null) {
18184 curProcs = new ArrayList<ProcessRecord>();
18185 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18187 if (!curProcs.contains(proc)) {
18188 curProcs.add(proc);
18189 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18190 proc.info.packageName, proc.info.uid);
18193 if (curProcs != null) {
18194 if (curProcs.remove(proc)) {
18195 mBatteryStatsService.noteEvent(
18196 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18197 proc.info.packageName, proc.info.uid);
18198 if (curProcs.size() <= 0) {
18199 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18205 updateOomAdjLocked();
18210 private final ActivityRecord resumedAppLocked() {
18211 ActivityRecord act = mStackSupervisor.resumedAppLocked();
18215 pkg = act.packageName;
18216 uid = act.info.applicationInfo.uid;
18221 // Has the UID or resumed package name changed?
18222 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18223 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18224 if (mCurResumedPackage != null) {
18225 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18226 mCurResumedPackage, mCurResumedUid);
18228 mCurResumedPackage = pkg;
18229 mCurResumedUid = uid;
18230 if (mCurResumedPackage != null) {
18231 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18232 mCurResumedPackage, mCurResumedUid);
18238 final boolean updateOomAdjLocked(ProcessRecord app) {
18239 final ActivityRecord TOP_ACT = resumedAppLocked();
18240 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18241 final boolean wasCached = app.cached;
18245 // This is the desired cached adjusment we want to tell it to use.
18246 // If our app is currently cached, we know it, and that is it. Otherwise,
18247 // we don't know it yet, and it needs to now be cached we will then
18248 // need to do a complete oom adj.
18249 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18250 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18251 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18252 SystemClock.uptimeMillis());
18253 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18254 // Changed to/from cached state, so apps after it in the LRU
18255 // list may also be changed.
18256 updateOomAdjLocked();
18261 final void updateOomAdjLocked() {
18262 final ActivityRecord TOP_ACT = resumedAppLocked();
18263 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18264 final long now = SystemClock.uptimeMillis();
18265 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18266 final int N = mLruProcesses.size();
18269 RuntimeException e = new RuntimeException();
18270 e.fillInStackTrace();
18271 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18275 mNewNumServiceProcs = 0;
18276 mNewNumAServiceProcs = 0;
18278 final int emptyProcessLimit;
18279 final int cachedProcessLimit;
18280 if (mProcessLimit <= 0) {
18281 emptyProcessLimit = cachedProcessLimit = 0;
18282 } else if (mProcessLimit == 1) {
18283 emptyProcessLimit = 1;
18284 cachedProcessLimit = 0;
18286 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18287 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18290 // Let's determine how many processes we have running vs.
18291 // how many slots we have for background processes; we may want
18292 // to put multiple processes in a slot of there are enough of
18294 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18295 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18296 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18297 if (numEmptyProcs > cachedProcessLimit) {
18298 // If there are more empty processes than our limit on cached
18299 // processes, then use the cached process limit for the factor.
18300 // This ensures that the really old empty processes get pushed
18301 // down to the bottom, so if we are running low on memory we will
18302 // have a better chance at keeping around more cached processes
18303 // instead of a gazillion empty processes.
18304 numEmptyProcs = cachedProcessLimit;
18306 int emptyFactor = numEmptyProcs/numSlots;
18307 if (emptyFactor < 1) emptyFactor = 1;
18308 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18309 if (cachedFactor < 1) cachedFactor = 1;
18310 int stepCached = 0;
18314 int numTrimming = 0;
18316 mNumNonCachedProcs = 0;
18317 mNumCachedHiddenProcs = 0;
18319 // First update the OOM adjustment for each of the
18320 // application processes based on their current state.
18321 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18322 int nextCachedAdj = curCachedAdj+1;
18323 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18324 int nextEmptyAdj = curEmptyAdj+2;
18325 for (int i=N-1; i>=0; i--) {
18326 ProcessRecord app = mLruProcesses.get(i);
18327 if (!app.killedByAm && app.thread != null) {
18328 app.procStateChanged = false;
18329 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18331 // If we haven't yet assigned the final cached adj
18332 // to the process, do that now.
18333 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18334 switch (app.curProcState) {
18335 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18336 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18337 // This process is a cached process holding activities...
18338 // assign it the next cached value for that type, and then
18339 // step that cached level.
18340 app.curRawAdj = curCachedAdj;
18341 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18342 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18343 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18345 if (curCachedAdj != nextCachedAdj) {
18347 if (stepCached >= cachedFactor) {
18349 curCachedAdj = nextCachedAdj;
18350 nextCachedAdj += 2;
18351 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18352 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18358 // For everything else, assign next empty cached process
18359 // level and bump that up. Note that this means that
18360 // long-running services that have dropped down to the
18361 // cached level will be treated as empty (since their process
18362 // state is still as a service), which is what we want.
18363 app.curRawAdj = curEmptyAdj;
18364 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18365 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18366 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18368 if (curEmptyAdj != nextEmptyAdj) {
18370 if (stepEmpty >= emptyFactor) {
18372 curEmptyAdj = nextEmptyAdj;
18374 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18375 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18383 applyOomAdjLocked(app, TOP_APP, true, now);
18385 // Count the number of process types.
18386 switch (app.curProcState) {
18387 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18388 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18389 mNumCachedHiddenProcs++;
18391 if (numCached > cachedProcessLimit) {
18392 app.kill("cached #" + numCached, true);
18395 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18396 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18397 && app.lastActivityTime < oldTime) {
18398 app.kill("empty for "
18399 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18400 / 1000) + "s", true);
18403 if (numEmpty > emptyProcessLimit) {
18404 app.kill("empty #" + numEmpty, true);
18409 mNumNonCachedProcs++;
18413 if (app.isolated && app.services.size() <= 0) {
18414 // If this is an isolated process, and there are no
18415 // services running in it, then the process is no longer
18416 // needed. We agressively kill these because we can by
18417 // definition not re-use the same process again, and it is
18418 // good to avoid having whatever code was running in them
18419 // left sitting around after no longer needed.
18420 app.kill("isolated not needed", true);
18423 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18424 && !app.killedByAm) {
18430 mNumServiceProcs = mNewNumServiceProcs;
18432 // Now determine the memory trimming level of background processes.
18433 // Unfortunately we need to start at the back of the list to do this
18434 // properly. We only do this if the number of background apps we
18435 // are managing to keep around is less than half the maximum we desire;
18436 // if we are keeping a good number around, we'll let them use whatever
18437 // memory they want.
18438 final int numCachedAndEmpty = numCached + numEmpty;
18440 if (numCached <= ProcessList.TRIM_CACHED_APPS
18441 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18442 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18443 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18444 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18445 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18447 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18450 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18452 // We always allow the memory level to go up (better). We only allow it to go
18453 // down if we are in a state where that is allowed, *and* the total number of processes
18454 // has gone down since last time.
18455 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18456 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18457 + " last=" + mLastNumProcesses);
18458 if (memFactor > mLastMemoryLevel) {
18459 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18460 memFactor = mLastMemoryLevel;
18461 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18464 mLastMemoryLevel = memFactor;
18465 mLastNumProcesses = mLruProcesses.size();
18466 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18467 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18468 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18469 if (mLowRamStartTime == 0) {
18470 mLowRamStartTime = now;
18474 switch (memFactor) {
18475 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18476 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18478 case ProcessStats.ADJ_MEM_FACTOR_LOW:
18479 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18482 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18485 int factor = numTrimming/3;
18487 if (mHomeProcess != null) minFactor++;
18488 if (mPreviousProcess != null) minFactor++;
18489 if (factor < minFactor) factor = minFactor;
18490 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18491 for (int i=N-1; i>=0; i--) {
18492 ProcessRecord app = mLruProcesses.get(i);
18493 if (allChanged || app.procStateChanged) {
18494 setProcessTrackerStateLocked(app, trackerMemFactor, now);
18495 app.procStateChanged = false;
18497 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18498 && !app.killedByAm) {
18499 if (app.trimMemoryLevel < curLevel && app.thread != null) {
18501 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18502 "Trimming memory of " + app.processName
18503 + " to " + curLevel);
18504 app.thread.scheduleTrimMemory(curLevel);
18505 } catch (RemoteException e) {
18508 // For now we won't do this; our memory trimming seems
18509 // to be good enough at this point that destroying
18510 // activities causes more harm than good.
18511 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18512 && app != mHomeProcess && app != mPreviousProcess) {
18513 // Need to do this on its own message because the stack may not
18514 // be in a consistent state at this point.
18515 // For these apps we will also finish their activities
18516 // to help them free memory.
18517 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18521 app.trimMemoryLevel = curLevel;
18523 if (step >= factor) {
18525 switch (curLevel) {
18526 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18527 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18529 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18530 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18534 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18535 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18536 && app.thread != null) {
18538 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18539 "Trimming memory of heavy-weight " + app.processName
18540 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18541 app.thread.scheduleTrimMemory(
18542 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18543 } catch (RemoteException e) {
18546 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18548 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18549 || app.systemNoUi) && app.pendingUiClean) {
18550 // If this application is now in the background and it
18551 // had done UI, then give it the special trim level to
18552 // have it free UI resources.
18553 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18554 if (app.trimMemoryLevel < level && app.thread != null) {
18556 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18557 "Trimming memory of bg-ui " + app.processName
18559 app.thread.scheduleTrimMemory(level);
18560 } catch (RemoteException e) {
18563 app.pendingUiClean = false;
18565 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18567 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18568 "Trimming memory of fg " + app.processName
18569 + " to " + fgTrimLevel);
18570 app.thread.scheduleTrimMemory(fgTrimLevel);
18571 } catch (RemoteException e) {
18574 app.trimMemoryLevel = fgTrimLevel;
18578 if (mLowRamStartTime != 0) {
18579 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18580 mLowRamStartTime = 0;
18582 for (int i=N-1; i>=0; i--) {
18583 ProcessRecord app = mLruProcesses.get(i);
18584 if (allChanged || app.procStateChanged) {
18585 setProcessTrackerStateLocked(app, trackerMemFactor, now);
18586 app.procStateChanged = false;
18588 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18589 || app.systemNoUi) && app.pendingUiClean) {
18590 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18591 && app.thread != null) {
18593 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18594 "Trimming memory of ui hidden " + app.processName
18595 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18596 app.thread.scheduleTrimMemory(
18597 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18598 } catch (RemoteException e) {
18601 app.pendingUiClean = false;
18603 app.trimMemoryLevel = 0;
18607 if (mAlwaysFinishActivities) {
18608 // Need to do this on its own message because the stack may not
18609 // be in a consistent state at this point.
18610 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18614 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18617 if (mProcessStats.shouldWriteNowLocked(now)) {
18618 mHandler.post(new Runnable() {
18619 @Override public void run() {
18620 synchronized (ActivityManagerService.this) {
18621 mProcessStats.writeStateAsyncLocked();
18627 if (DEBUG_OOM_ADJ) {
18629 RuntimeException here = new RuntimeException("here");
18630 here.fillInStackTrace();
18631 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18633 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18638 final void trimApplications() {
18639 synchronized (this) {
18642 // First remove any unused application processes whose package
18643 // has been removed.
18644 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18645 final ProcessRecord app = mRemovedProcesses.get(i);
18646 if (app.activities.size() == 0
18647 && app.curReceiver == null && app.services.size() == 0) {
18649 TAG, "Exiting empty application process "
18650 + app.processName + " ("
18651 + (app.thread != null ? app.thread.asBinder() : null)
18653 if (app.pid > 0 && app.pid != MY_PID) {
18654 app.kill("empty", false);
18657 app.thread.scheduleExit();
18658 } catch (Exception e) {
18659 // Ignore exceptions.
18662 cleanUpApplicationRecordLocked(app, false, true, -1);
18663 mRemovedProcesses.remove(i);
18665 if (app.persistent) {
18666 addAppLocked(app.info, false, null /* ABI override */);
18671 // Now update the oom adj for all processes.
18672 updateOomAdjLocked();
18676 /** This method sends the specified signal to each of the persistent apps */
18677 public void signalPersistentProcesses(int sig) throws RemoteException {
18678 if (sig != Process.SIGNAL_USR1) {
18679 throw new SecurityException("Only SIGNAL_USR1 is allowed");
18682 synchronized (this) {
18683 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18684 != PackageManager.PERMISSION_GRANTED) {
18685 throw new SecurityException("Requires permission "
18686 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18689 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18690 ProcessRecord r = mLruProcesses.get(i);
18691 if (r.thread != null && r.persistent) {
18692 Process.sendSignal(r.pid, sig);
18698 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18699 if (proc == null || proc == mProfileProc) {
18700 proc = mProfileProc;
18701 profileType = mProfileType;
18702 clearProfilerLocked();
18704 if (proc == null) {
18708 proc.thread.profilerControl(false, null, profileType);
18709 } catch (RemoteException e) {
18710 throw new IllegalStateException("Process disappeared");
18714 private void clearProfilerLocked() {
18715 if (mProfileFd != null) {
18717 mProfileFd.close();
18718 } catch (IOException e) {
18721 mProfileApp = null;
18722 mProfileProc = null;
18723 mProfileFile = null;
18725 mAutoStopProfiler = false;
18726 mSamplingInterval = 0;
18729 public boolean profileControl(String process, int userId, boolean start,
18730 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18733 synchronized (this) {
18734 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18735 // its own permission.
18736 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18737 != PackageManager.PERMISSION_GRANTED) {
18738 throw new SecurityException("Requires permission "
18739 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18742 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18743 throw new IllegalArgumentException("null profile info or fd");
18746 ProcessRecord proc = null;
18747 if (process != null) {
18748 proc = findProcessLocked(process, userId, "profileControl");
18751 if (start && (proc == null || proc.thread == null)) {
18752 throw new IllegalArgumentException("Unknown process: " + process);
18756 stopProfilerLocked(null, 0);
18757 setProfileApp(proc.info, proc.processName, profilerInfo);
18758 mProfileProc = proc;
18759 mProfileType = profileType;
18760 ParcelFileDescriptor fd = profilerInfo.profileFd;
18763 } catch (IOException e) {
18766 profilerInfo.profileFd = fd;
18767 proc.thread.profilerControl(start, profilerInfo, profileType);
18771 stopProfilerLocked(proc, profileType);
18772 if (profilerInfo != null && profilerInfo.profileFd != null) {
18774 profilerInfo.profileFd.close();
18775 } catch (IOException e) {
18782 } catch (RemoteException e) {
18783 throw new IllegalStateException("Process disappeared");
18785 if (profilerInfo != null && profilerInfo.profileFd != null) {
18787 profilerInfo.profileFd.close();
18788 } catch (IOException e) {
18794 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18795 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18796 userId, true, ALLOW_FULL_ONLY, callName, null);
18797 ProcessRecord proc = null;
18799 int pid = Integer.parseInt(process);
18800 synchronized (mPidsSelfLocked) {
18801 proc = mPidsSelfLocked.get(pid);
18803 } catch (NumberFormatException e) {
18806 if (proc == null) {
18807 ArrayMap<String, SparseArray<ProcessRecord>> all
18808 = mProcessNames.getMap();
18809 SparseArray<ProcessRecord> procs = all.get(process);
18810 if (procs != null && procs.size() > 0) {
18811 proc = procs.valueAt(0);
18812 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18813 for (int i=1; i<procs.size(); i++) {
18814 ProcessRecord thisProc = procs.valueAt(i);
18815 if (thisProc.userId == userId) {
18827 public boolean dumpHeap(String process, int userId, boolean managed,
18828 String path, ParcelFileDescriptor fd) throws RemoteException {
18831 synchronized (this) {
18832 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18833 // its own permission (same as profileControl).
18834 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18835 != PackageManager.PERMISSION_GRANTED) {
18836 throw new SecurityException("Requires permission "
18837 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18841 throw new IllegalArgumentException("null fd");
18844 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18845 if (proc == null || proc.thread == null) {
18846 throw new IllegalArgumentException("Unknown process: " + process);
18849 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18850 if (!isDebuggable) {
18851 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18852 throw new SecurityException("Process not debuggable: " + proc);
18856 proc.thread.dumpHeap(managed, path, fd);
18860 } catch (RemoteException e) {
18861 throw new IllegalStateException("Process disappeared");
18866 } catch (IOException e) {
18872 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18873 public void monitor() {
18874 synchronized (this) { }
18877 void onCoreSettingsChange(Bundle settings) {
18878 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18879 ProcessRecord processRecord = mLruProcesses.get(i);
18881 if (processRecord.thread != null) {
18882 processRecord.thread.setCoreSettings(settings);
18884 } catch (RemoteException re) {
18890 // Multi-user methods
18893 * Start user, if its not already running, but don't bring it to foreground.
18896 public boolean startUserInBackground(final int userId) {
18897 return startUser(userId, /* foreground */ false);
18901 * Start user, if its not already running, and bring it to foreground.
18903 boolean startUserInForeground(final int userId, Dialog dlg) {
18904 boolean result = startUser(userId, /* foreground */ true);
18910 * Refreshes the list of users related to the current user when either a
18911 * user switch happens or when a new related user is started in the
18914 private void updateCurrentProfileIdsLocked() {
18915 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18916 mCurrentUserId, false /* enabledOnly */);
18917 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18918 for (int i = 0; i < currentProfileIds.length; i++) {
18919 currentProfileIds[i] = profiles.get(i).id;
18921 mCurrentProfileIds = currentProfileIds;
18923 synchronized (mUserProfileGroupIdsSelfLocked) {
18924 mUserProfileGroupIdsSelfLocked.clear();
18925 final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18926 for (int i = 0; i < users.size(); i++) {
18927 UserInfo user = users.get(i);
18928 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18929 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18935 private Set getProfileIdsLocked(int userId) {
18936 Set userIds = new HashSet<Integer>();
18937 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18938 userId, false /* enabledOnly */);
18939 for (UserInfo user : profiles) {
18940 userIds.add(Integer.valueOf(user.id));
18946 public boolean switchUser(final int userId) {
18947 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18949 synchronized (this) {
18950 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18951 if (userInfo == null) {
18952 Slog.w(TAG, "No user info for user #" + userId);
18955 if (userInfo.isManagedProfile()) {
18956 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18959 userName = userInfo.name;
18960 mTargetUserId = userId;
18962 mUiHandler.removeMessages(START_USER_SWITCH_MSG);
18963 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18967 private void showUserSwitchDialog(int userId, String userName) {
18968 // The dialog will show and then initiate the user switch by calling startUserInForeground
18969 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18970 true /* above system */);
18974 private boolean startUser(final int userId, final boolean foreground) {
18975 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18976 != PackageManager.PERMISSION_GRANTED) {
18977 String msg = "Permission Denial: switchUser() from pid="
18978 + Binder.getCallingPid()
18979 + ", uid=" + Binder.getCallingUid()
18980 + " requires " + INTERACT_ACROSS_USERS_FULL;
18982 throw new SecurityException(msg);
18985 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18987 final long ident = Binder.clearCallingIdentity();
18989 synchronized (this) {
18990 final int oldUserId = mCurrentUserId;
18991 if (oldUserId == userId) {
18995 mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
18997 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18998 if (userInfo == null) {
18999 Slog.w(TAG, "No user info for user #" + userId);
19002 if (foreground && userInfo.isManagedProfile()) {
19003 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19008 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19009 R.anim.screen_user_enter);
19012 boolean needStart = false;
19014 // If the user we are switching to is not currently started, then
19015 // we need to start it now.
19016 if (mStartedUsers.get(userId) == null) {
19017 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
19018 updateStartedUserArrayLocked();
19022 final Integer userIdInt = Integer.valueOf(userId);
19023 mUserLru.remove(userIdInt);
19024 mUserLru.add(userIdInt);
19027 mCurrentUserId = userId;
19028 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19029 updateCurrentProfileIdsLocked();
19030 mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19031 // Once the internal notion of the active user has switched, we lock the device
19032 // with the option to show the user switcher on the keyguard.
19033 mWindowManager.lockNow(null);
19035 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19036 updateCurrentProfileIdsLocked();
19037 mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19038 mUserLru.remove(currentUserIdInt);
19039 mUserLru.add(currentUserIdInt);
19042 final UserStartedState uss = mStartedUsers.get(userId);
19044 // Make sure user is in the started state. If it is currently
19045 // stopping, we need to knock that off.
19046 if (uss.mState == UserStartedState.STATE_STOPPING) {
19047 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19048 // so we can just fairly silently bring the user back from
19049 // the almost-dead.
19050 uss.mState = UserStartedState.STATE_RUNNING;
19051 updateStartedUserArrayLocked();
19053 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
19054 // This means ACTION_SHUTDOWN has been sent, so we will
19055 // need to treat this as a new boot of the user.
19056 uss.mState = UserStartedState.STATE_BOOTING;
19057 updateStartedUserArrayLocked();
19061 if (uss.mState == UserStartedState.STATE_BOOTING) {
19062 // Booting up a new user, need to tell system services about it.
19063 // Note that this is on the same handler as scheduling of broadcasts,
19064 // which is important because it needs to go first.
19065 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19069 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19071 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19072 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19073 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19074 oldUserId, userId, uss));
19075 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19076 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19080 // Send USER_STARTED broadcast
19081 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19082 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19083 | Intent.FLAG_RECEIVER_FOREGROUND);
19084 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19085 broadcastIntentLocked(null, null, intent,
19086 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19087 false, false, MY_PID, Process.SYSTEM_UID, userId);
19090 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19091 if (userId != UserHandle.USER_OWNER) {
19092 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19093 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19094 broadcastIntentLocked(null, null, intent, null,
19095 new IIntentReceiver.Stub() {
19096 public void performReceive(Intent intent, int resultCode,
19097 String data, Bundle extras, boolean ordered,
19098 boolean sticky, int sendingUser) {
19099 onUserInitialized(uss, foreground, oldUserId, userId);
19101 }, 0, null, null, null, AppOpsManager.OP_NONE,
19102 true, false, MY_PID, Process.SYSTEM_UID,
19104 uss.initializing = true;
19106 getUserManagerLocked().makeInitialized(userInfo.id);
19111 if (!uss.initializing) {
19112 moveUserToForeground(uss, oldUserId, userId);
19115 mStackSupervisor.startBackgroundUserLocked(userId, uss);
19119 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19120 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19121 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19122 broadcastIntentLocked(null, null, intent,
19123 null, new IIntentReceiver.Stub() {
19125 public void performReceive(Intent intent, int resultCode, String data,
19126 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19127 throws RemoteException {
19130 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19131 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19135 Binder.restoreCallingIdentity(ident);
19141 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19142 long ident = Binder.clearCallingIdentity();
19145 if (oldUserId >= 0) {
19146 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19147 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19148 int count = profiles.size();
19149 for (int i = 0; i < count; i++) {
19150 int profileUserId = profiles.get(i).id;
19151 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19152 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19153 | Intent.FLAG_RECEIVER_FOREGROUND);
19154 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19155 broadcastIntentLocked(null, null, intent,
19156 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19157 false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19160 if (newUserId >= 0) {
19161 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19162 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19163 int count = profiles.size();
19164 for (int i = 0; i < count; i++) {
19165 int profileUserId = profiles.get(i).id;
19166 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19167 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19168 | Intent.FLAG_RECEIVER_FOREGROUND);
19169 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19170 broadcastIntentLocked(null, null, intent,
19171 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19172 false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19174 intent = new Intent(Intent.ACTION_USER_SWITCHED);
19175 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19176 | Intent.FLAG_RECEIVER_FOREGROUND);
19177 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19178 broadcastIntentLocked(null, null, intent,
19179 null, null, 0, null, null,
19180 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19181 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19184 Binder.restoreCallingIdentity(ident);
19188 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19189 final int newUserId) {
19190 final int N = mUserSwitchObservers.beginBroadcast();
19192 final IRemoteCallback callback = new IRemoteCallback.Stub() {
19195 public void sendResult(Bundle data) throws RemoteException {
19196 synchronized (ActivityManagerService.this) {
19197 if (mCurUserSwitchCallback == this) {
19200 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19206 synchronized (this) {
19207 uss.switching = true;
19208 mCurUserSwitchCallback = callback;
19210 for (int i=0; i<N; i++) {
19212 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19213 newUserId, callback);
19214 } catch (RemoteException e) {
19218 synchronized (this) {
19219 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19222 mUserSwitchObservers.finishBroadcast();
19225 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19226 synchronized (this) {
19227 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19228 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19232 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19233 mCurUserSwitchCallback = null;
19234 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19235 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19236 oldUserId, newUserId, uss));
19239 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19240 synchronized (this) {
19242 moveUserToForeground(uss, oldUserId, newUserId);
19246 completeSwitchAndInitalize(uss, newUserId, true, false);
19249 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19250 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19252 startHomeActivityLocked(newUserId, "moveUserToFroreground");
19254 mStackSupervisor.resumeTopActivitiesLocked();
19256 EventLogTags.writeAmSwitchUser(newUserId);
19257 getUserManagerLocked().userForeground(newUserId);
19258 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19261 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19262 completeSwitchAndInitalize(uss, newUserId, false, true);
19265 void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19266 boolean clearInitializing, boolean clearSwitching) {
19267 boolean unfrozen = false;
19268 synchronized (this) {
19269 if (clearInitializing) {
19270 uss.initializing = false;
19271 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19273 if (clearSwitching) {
19274 uss.switching = false;
19276 if (!uss.switching && !uss.initializing) {
19277 mWindowManager.stopFreezingScreen();
19282 final int N = mUserSwitchObservers.beginBroadcast();
19283 for (int i=0; i<N; i++) {
19285 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19286 } catch (RemoteException e) {
19289 mUserSwitchObservers.finishBroadcast();
19291 stopGuestUserIfBackground();
19295 * Stops the guest user if it has gone to the background.
19297 private void stopGuestUserIfBackground() {
19298 synchronized (this) {
19299 final int num = mUserLru.size();
19300 for (int i = 0; i < num; i++) {
19301 Integer oldUserId = mUserLru.get(i);
19302 UserStartedState oldUss = mStartedUsers.get(oldUserId);
19303 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19304 || oldUss.mState == UserStartedState.STATE_STOPPING
19305 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19308 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19309 if (userInfo.isGuest()) {
19310 // This is a user to be stopped.
19311 stopUserLocked(oldUserId, null);
19318 void scheduleStartProfilesLocked() {
19319 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19320 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19321 DateUtils.SECOND_IN_MILLIS);
19325 void startProfilesLocked() {
19326 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19327 List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19328 mCurrentUserId, false /* enabledOnly */);
19329 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19330 for (UserInfo user : profiles) {
19331 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19332 && user.id != mCurrentUserId) {
19336 final int n = toStart.size();
19338 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19339 startUserInBackground(toStart.get(i).id);
19342 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19346 void finishUserBoot(UserStartedState uss) {
19347 synchronized (this) {
19348 if (uss.mState == UserStartedState.STATE_BOOTING
19349 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19350 uss.mState = UserStartedState.STATE_RUNNING;
19351 final int userId = uss.mHandle.getIdentifier();
19352 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19353 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19354 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19355 broadcastIntentLocked(null, null, intent,
19356 null, null, 0, null, null,
19357 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19358 true, false, MY_PID, Process.SYSTEM_UID, userId);
19363 void finishUserSwitch(UserStartedState uss) {
19364 synchronized (this) {
19365 finishUserBoot(uss);
19367 startProfilesLocked();
19369 int num = mUserLru.size();
19371 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19372 Integer oldUserId = mUserLru.get(i);
19373 UserStartedState oldUss = mStartedUsers.get(oldUserId);
19374 if (oldUss == null) {
19375 // Shouldn't happen, but be sane if it does.
19376 mUserLru.remove(i);
19380 if (oldUss.mState == UserStartedState.STATE_STOPPING
19381 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19382 // This user is already stopping, doesn't count.
19387 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19388 // Owner and current can't be stopped, but count as running.
19392 // This is a user to be stopped.
19393 stopUserLocked(oldUserId, null);
19401 public int stopUser(final int userId, final IStopUserCallback callback) {
19402 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19403 != PackageManager.PERMISSION_GRANTED) {
19404 String msg = "Permission Denial: switchUser() from pid="
19405 + Binder.getCallingPid()
19406 + ", uid=" + Binder.getCallingUid()
19407 + " requires " + INTERACT_ACROSS_USERS_FULL;
19409 throw new SecurityException(msg);
19412 throw new IllegalArgumentException("Can't stop primary user " + userId);
19414 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19415 synchronized (this) {
19416 return stopUserLocked(userId, callback);
19420 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19421 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19422 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19423 return ActivityManager.USER_OP_IS_CURRENT;
19426 final UserStartedState uss = mStartedUsers.get(userId);
19428 // User is not started, nothing to do... but we do need to
19429 // callback if requested.
19430 if (callback != null) {
19431 mHandler.post(new Runnable() {
19433 public void run() {
19435 callback.userStopped(userId);
19436 } catch (RemoteException e) {
19441 return ActivityManager.USER_OP_SUCCESS;
19444 if (callback != null) {
19445 uss.mStopCallbacks.add(callback);
19448 if (uss.mState != UserStartedState.STATE_STOPPING
19449 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19450 uss.mState = UserStartedState.STATE_STOPPING;
19451 updateStartedUserArrayLocked();
19453 long ident = Binder.clearCallingIdentity();
19455 // We are going to broadcast ACTION_USER_STOPPING and then
19456 // once that is done send a final ACTION_SHUTDOWN and then
19458 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19459 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19460 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19461 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19462 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19463 // This is the result receiver for the final shutdown broadcast.
19464 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19466 public void performReceive(Intent intent, int resultCode, String data,
19467 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19468 finishUserStop(uss);
19471 // This is the result receiver for the initial stopping broadcast.
19472 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19474 public void performReceive(Intent intent, int resultCode, String data,
19475 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19477 synchronized (ActivityManagerService.this) {
19478 if (uss.mState != UserStartedState.STATE_STOPPING) {
19479 // Whoops, we are being started back up. Abort, abort!
19482 uss.mState = UserStartedState.STATE_SHUTDOWN;
19484 mBatteryStatsService.noteEvent(
19485 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19486 Integer.toString(userId), userId);
19487 mSystemServiceManager.stopUser(userId);
19488 broadcastIntentLocked(null, null, shutdownIntent,
19489 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19490 true, false, MY_PID, Process.SYSTEM_UID, userId);
19493 // Kick things off.
19494 broadcastIntentLocked(null, null, stoppingIntent,
19495 null, stoppingReceiver, 0, null, null,
19496 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19497 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19499 Binder.restoreCallingIdentity(ident);
19503 return ActivityManager.USER_OP_SUCCESS;
19506 void finishUserStop(UserStartedState uss) {
19507 final int userId = uss.mHandle.getIdentifier();
19509 ArrayList<IStopUserCallback> callbacks;
19510 synchronized (this) {
19511 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19512 if (mStartedUsers.get(userId) != uss) {
19514 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19518 // User can no longer run.
19519 mStartedUsers.remove(userId);
19520 mUserLru.remove(Integer.valueOf(userId));
19521 updateStartedUserArrayLocked();
19523 // Clean up all state and processes associated with the user.
19524 // Kill all the processes for the user.
19525 forceStopUserLocked(userId, "finish user");
19528 // Explicitly remove the old information in mRecentTasks.
19529 removeRecentTasksForUserLocked(userId);
19532 for (int i=0; i<callbacks.size(); i++) {
19534 if (stopped) callbacks.get(i).userStopped(userId);
19535 else callbacks.get(i).userStopAborted(userId);
19536 } catch (RemoteException e) {
19541 mSystemServiceManager.cleanupUser(userId);
19542 synchronized (this) {
19543 mStackSupervisor.removeUserLocked(userId);
19549 public UserInfo getCurrentUser() {
19550 if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19551 != PackageManager.PERMISSION_GRANTED) && (
19552 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19553 != PackageManager.PERMISSION_GRANTED)) {
19554 String msg = "Permission Denial: getCurrentUser() from pid="
19555 + Binder.getCallingPid()
19556 + ", uid=" + Binder.getCallingUid()
19557 + " requires " + INTERACT_ACROSS_USERS;
19559 throw new SecurityException(msg);
19561 synchronized (this) {
19562 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19563 return getUserManagerLocked().getUserInfo(userId);
19567 int getCurrentUserIdLocked() {
19568 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19572 public boolean isUserRunning(int userId, boolean orStopped) {
19573 if (checkCallingPermission(INTERACT_ACROSS_USERS)
19574 != PackageManager.PERMISSION_GRANTED) {
19575 String msg = "Permission Denial: isUserRunning() from pid="
19576 + Binder.getCallingPid()
19577 + ", uid=" + Binder.getCallingUid()
19578 + " requires " + INTERACT_ACROSS_USERS;
19580 throw new SecurityException(msg);
19582 synchronized (this) {
19583 return isUserRunningLocked(userId, orStopped);
19587 boolean isUserRunningLocked(int userId, boolean orStopped) {
19588 UserStartedState state = mStartedUsers.get(userId);
19589 if (state == null) {
19595 return state.mState != UserStartedState.STATE_STOPPING
19596 && state.mState != UserStartedState.STATE_SHUTDOWN;
19600 public int[] getRunningUserIds() {
19601 if (checkCallingPermission(INTERACT_ACROSS_USERS)
19602 != PackageManager.PERMISSION_GRANTED) {
19603 String msg = "Permission Denial: isUserRunning() from pid="
19604 + Binder.getCallingPid()
19605 + ", uid=" + Binder.getCallingUid()
19606 + " requires " + INTERACT_ACROSS_USERS;
19608 throw new SecurityException(msg);
19610 synchronized (this) {
19611 return mStartedUserArray;
19615 private void updateStartedUserArrayLocked() {
19617 for (int i=0; i<mStartedUsers.size(); i++) {
19618 UserStartedState uss = mStartedUsers.valueAt(i);
19619 // This list does not include stopping users.
19620 if (uss.mState != UserStartedState.STATE_STOPPING
19621 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19625 mStartedUserArray = new int[num];
19627 for (int i=0; i<mStartedUsers.size(); i++) {
19628 UserStartedState uss = mStartedUsers.valueAt(i);
19629 if (uss.mState != UserStartedState.STATE_STOPPING
19630 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19631 mStartedUserArray[num] = mStartedUsers.keyAt(i);
19638 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19639 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19640 != PackageManager.PERMISSION_GRANTED) {
19641 String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19642 + Binder.getCallingPid()
19643 + ", uid=" + Binder.getCallingUid()
19644 + " requires " + INTERACT_ACROSS_USERS_FULL;
19646 throw new SecurityException(msg);
19649 mUserSwitchObservers.register(observer);
19653 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19654 mUserSwitchObservers.unregister(observer);
19657 private boolean userExists(int userId) {
19661 UserManagerService ums = getUserManagerLocked();
19662 return ums != null ? (ums.getUserInfo(userId) != null) : false;
19665 int[] getUsersLocked() {
19666 UserManagerService ums = getUserManagerLocked();
19667 return ums != null ? ums.getUserIds() : new int[] { 0 };
19670 UserManagerService getUserManagerLocked() {
19671 if (mUserManager == null) {
19672 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19673 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19675 return mUserManager;
19678 private int applyUserId(int uid, int userId) {
19679 return UserHandle.getUid(userId, uid);
19682 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19683 if (info == null) return null;
19684 ApplicationInfo newInfo = new ApplicationInfo(info);
19685 newInfo.uid = applyUserId(info.uid, userId);
19686 newInfo.dataDir = USER_DATA_DIR + userId + "/"
19687 + info.packageName;
19691 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19693 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19697 ActivityInfo info = new ActivityInfo(aInfo);
19698 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19702 private final class LocalService extends ActivityManagerInternal {
19704 public void onWakefulnessChanged(int wakefulness) {
19705 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19709 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19710 String processName, String abiOverride, int uid, Runnable crashHandler) {
19711 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19712 processName, abiOverride, uid, crashHandler);
19717 * An implementation of IAppTask, that allows an app to manage its own tasks via
19718 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
19719 * only the process that calls getAppTasks() can call the AppTask methods.
19721 class AppTaskImpl extends IAppTask.Stub {
19722 private int mTaskId;
19723 private int mCallingUid;
19725 public AppTaskImpl(int taskId, int callingUid) {
19727 mCallingUid = callingUid;
19730 private void checkCaller() {
19731 if (mCallingUid != Binder.getCallingUid()) {
19732 throw new SecurityException("Caller " + mCallingUid
19733 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19738 public void finishAndRemoveTask() {
19741 synchronized (ActivityManagerService.this) {
19742 long origId = Binder.clearCallingIdentity();
19744 if (!removeTaskByIdLocked(mTaskId, false)) {
19745 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19748 Binder.restoreCallingIdentity(origId);
19754 public ActivityManager.RecentTaskInfo getTaskInfo() {
19757 synchronized (ActivityManagerService.this) {
19758 long origId = Binder.clearCallingIdentity();
19760 TaskRecord tr = recentTaskForIdLocked(mTaskId);
19762 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19764 return createRecentTaskInfoFromTaskRecord(tr);
19766 Binder.restoreCallingIdentity(origId);
19772 public void moveToFront() {
19774 // Will bring task to front if it already has a root activity.
19775 startActivityFromRecentsInner(mTaskId, null);
19779 public int startActivity(IBinder whoThread, String callingPackage,
19780 Intent intent, String resolvedType, Bundle options) {
19783 int callingUser = UserHandle.getCallingUserId();
19785 IApplicationThread appThread;
19786 synchronized (ActivityManagerService.this) {
19787 tr = recentTaskForIdLocked(mTaskId);
19789 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19791 appThread = ApplicationThreadNative.asInterface(whoThread);
19792 if (appThread == null) {
19793 throw new IllegalArgumentException("Bad app thread " + appThread);
19796 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19797 resolvedType, null, null, null, null, 0, 0, null, null,
19798 null, options, callingUser, null, tr);
19802 public void setExcludeFromRecents(boolean exclude) {
19805 synchronized (ActivityManagerService.this) {
19806 long origId = Binder.clearCallingIdentity();
19808 TaskRecord tr = recentTaskForIdLocked(mTaskId);
19810 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19812 Intent intent = tr.getBaseIntent();
19814 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19816 intent.setFlags(intent.getFlags()
19817 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19820 Binder.restoreCallingIdentity(origId);