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;
96 import org.xmlpull.v1.XmlPullParser;
97 import org.xmlpull.v1.XmlPullParserException;
98 import org.xmlpull.v1.XmlSerializer;
100 import android.app.Activity;
101 import android.app.ActivityManager;
102 import android.app.ActivityManager.RunningTaskInfo;
103 import android.app.ActivityManager.StackInfo;
104 import android.app.ActivityManagerInternal;
105 import android.app.ActivityManagerNative;
106 import android.app.ActivityOptions;
107 import android.app.ActivityThread;
108 import android.app.AlertDialog;
109 import android.app.AppGlobals;
110 import android.app.ApplicationErrorReport;
111 import android.app.Dialog;
112 import android.app.IActivityController;
113 import android.app.IApplicationThread;
114 import android.app.IInstrumentationWatcher;
115 import android.app.INotificationManager;
116 import android.app.IProcessObserver;
117 import android.app.IServiceConnection;
118 import android.app.IStopUserCallback;
119 import android.app.IUiAutomationConnection;
120 import android.app.IUserSwitchObserver;
121 import android.app.Instrumentation;
122 import android.app.Notification;
123 import android.app.NotificationManager;
124 import android.app.PendingIntent;
125 import android.app.backup.IBackupManager;
126 import android.content.ActivityNotFoundException;
127 import android.content.BroadcastReceiver;
128 import android.content.ClipData;
129 import android.content.ComponentCallbacks2;
130 import android.content.ComponentName;
131 import android.content.ContentProvider;
132 import android.content.ContentResolver;
133 import android.content.Context;
134 import android.content.DialogInterface;
135 import android.content.IContentProvider;
136 import android.content.IIntentReceiver;
137 import android.content.IIntentSender;
138 import android.content.Intent;
139 import android.content.IntentFilter;
140 import android.content.IntentSender;
141 import android.content.pm.ActivityInfo;
142 import android.content.pm.ApplicationInfo;
143 import android.content.pm.ConfigurationInfo;
144 import android.content.pm.IPackageDataObserver;
145 import android.content.pm.IPackageManager;
146 import android.content.pm.InstrumentationInfo;
147 import android.content.pm.PackageInfo;
148 import android.content.pm.PackageManager;
149 import android.content.pm.ParceledListSlice;
150 import android.content.pm.UserInfo;
151 import android.content.pm.PackageManager.NameNotFoundException;
152 import android.content.pm.PathPermission;
153 import android.content.pm.ProviderInfo;
154 import android.content.pm.ResolveInfo;
155 import android.content.pm.ServiceInfo;
156 import android.content.res.CompatibilityInfo;
157 import android.content.res.Configuration;
158 import android.net.Proxy;
159 import android.net.ProxyInfo;
160 import android.net.Uri;
161 import android.os.Binder;
162 import android.os.Build;
163 import android.os.Bundle;
164 import android.os.Debug;
165 import android.os.DropBoxManager;
166 import android.os.Environment;
167 import android.os.FactoryTest;
168 import android.os.FileObserver;
169 import android.os.FileUtils;
170 import android.os.Handler;
171 import android.os.IBinder;
172 import android.os.IPermissionController;
173 import android.os.IRemoteCallback;
174 import android.os.IUserManager;
175 import android.os.Looper;
176 import android.os.Message;
177 import android.os.Parcel;
178 import android.os.ParcelFileDescriptor;
179 import android.os.PowerManagerInternal;
180 import android.os.Process;
181 import android.os.RemoteCallbackList;
182 import android.os.RemoteException;
183 import android.os.SELinux;
184 import android.os.ServiceManager;
185 import android.os.StrictMode;
186 import android.os.SystemClock;
187 import android.os.SystemProperties;
188 import android.os.UpdateLock;
189 import android.os.UserHandle;
190 import android.os.UserManager;
191 import android.provider.Downloads;
192 import android.provider.Settings;
193 import android.text.format.DateUtils;
194 import android.text.format.Time;
195 import android.util.AtomicFile;
196 import android.util.EventLog;
197 import android.util.Log;
198 import android.util.Pair;
199 import android.util.PrintWriterPrinter;
200 import android.util.Slog;
201 import android.util.SparseArray;
202 import android.util.TimeUtils;
203 import android.util.Xml;
204 import android.view.Gravity;
205 import android.view.LayoutInflater;
206 import android.view.View;
207 import android.view.WindowManager;
209 import dalvik.system.VMRuntime;
211 import java.io.BufferedInputStream;
212 import java.io.BufferedOutputStream;
213 import java.io.DataInputStream;
214 import java.io.DataOutputStream;
216 import java.io.FileDescriptor;
217 import java.io.FileInputStream;
218 import java.io.FileNotFoundException;
219 import java.io.FileOutputStream;
220 import java.io.IOException;
221 import java.io.InputStreamReader;
222 import java.io.PrintWriter;
223 import java.io.StringWriter;
224 import java.lang.ref.WeakReference;
225 import java.util.ArrayList;
226 import java.util.Arrays;
227 import java.util.Collections;
228 import java.util.Comparator;
229 import java.util.HashMap;
230 import java.util.HashSet;
231 import java.util.Iterator;
232 import java.util.List;
233 import java.util.Locale;
234 import java.util.Map;
235 import java.util.Set;
236 import java.util.concurrent.atomic.AtomicBoolean;
237 import java.util.concurrent.atomic.AtomicLong;
239 public final class ActivityManagerService extends ActivityManagerNative
240 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
242 private static final String USER_DATA_DIR = "/data/user/";
243 // File that stores last updated system version and called preboot receivers
244 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
246 static final String TAG = "ActivityManager";
247 static final String TAG_MU = "ActivityManagerServiceMU";
248 static final boolean DEBUG = false;
249 static final boolean localLOGV = DEBUG;
250 static final boolean DEBUG_BACKUP = localLOGV || false;
251 static final boolean DEBUG_BROADCAST = localLOGV || false;
252 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
253 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
254 static final boolean DEBUG_CLEANUP = localLOGV || false;
255 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
256 static final boolean DEBUG_FOCUS = false;
257 static final boolean DEBUG_IMMERSIVE = localLOGV || false;
258 static final boolean DEBUG_MU = localLOGV || false;
259 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
260 static final boolean DEBUG_LRU = localLOGV || false;
261 static final boolean DEBUG_PAUSE = localLOGV || false;
262 static final boolean DEBUG_POWER = localLOGV || false;
263 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
264 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
265 static final boolean DEBUG_PROCESSES = localLOGV || false;
266 static final boolean DEBUG_PROVIDER = localLOGV || false;
267 static final boolean DEBUG_RESULTS = localLOGV || false;
268 static final boolean DEBUG_SERVICE = localLOGV || false;
269 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
270 static final boolean DEBUG_STACK = localLOGV || false;
271 static final boolean DEBUG_SWITCH = localLOGV || false;
272 static final boolean DEBUG_TASKS = localLOGV || false;
273 static final boolean DEBUG_THUMBNAILS = localLOGV || false;
274 static final boolean DEBUG_TRANSITION = localLOGV || false;
275 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
276 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
277 static final boolean DEBUG_VISBILITY = localLOGV || false;
278 static final boolean DEBUG_PSS = localLOGV || false;
279 static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
280 static final boolean DEBUG_RECENTS = localLOGV || false;
281 static final boolean VALIDATE_TOKENS = false;
282 static final boolean SHOW_ACTIVITY_START_TIME = true;
284 // Control over CPU and battery monitoring.
285 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
286 static final boolean MONITOR_CPU_USAGE = true;
287 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
288 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
289 static final boolean MONITOR_THREAD_CPU_USAGE = false;
291 // The flags that are set for all calls we make to the package manager.
292 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
294 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
296 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
298 // Maximum number recent bitmaps to keep in memory.
299 static final int MAX_RECENT_BITMAPS = 3;
301 // Amount of time after a call to stopAppSwitches() during which we will
302 // prevent further untrusted switches from happening.
303 static final long APP_SWITCH_DELAY_TIME = 5*1000;
305 // How long we wait for a launched process to attach to the activity manager
306 // before we decide it's never going to come up for real.
307 static final int PROC_START_TIMEOUT = 10*1000;
309 // How long we wait for a launched process to attach to the activity manager
310 // before we decide it's never going to come up for real, when the process was
311 // started with a wrapper for instrumentation (such as Valgrind) because it
312 // could take much longer than usual.
313 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
315 // How long to wait after going idle before forcing apps to GC.
316 static final int GC_TIMEOUT = 5*1000;
318 // The minimum amount of time between successive GC requests for a process.
319 static final int GC_MIN_INTERVAL = 60*1000;
321 // The minimum amount of time between successive PSS requests for a process.
322 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
324 // The minimum amount of time between successive PSS requests for a process
325 // when the request is due to the memory state being lowered.
326 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
328 // The rate at which we check for apps using excessive power -- 15 mins.
329 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
331 // The minimum sample duration we will allow before deciding we have
332 // enough data on wake locks to start killing things.
333 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
335 // The minimum sample duration we will allow before deciding we have
336 // enough data on CPU usage to start killing things.
337 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
339 // How long we allow a receiver to run before giving up on it.
340 static final int BROADCAST_FG_TIMEOUT = 10*1000;
341 static final int BROADCAST_BG_TIMEOUT = 60*1000;
343 // How long we wait until we timeout on key dispatching.
344 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
346 // How long we wait until we timeout on key dispatching during instrumentation.
347 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
349 // Amount of time we wait for observers to handle a user switch before
350 // giving up on them and unfreezing the screen.
351 static final int USER_SWITCH_TIMEOUT = 2*1000;
353 // Maximum number of users we allow to be running at a time.
354 static final int MAX_RUNNING_USERS = 3;
356 // How long to wait in getAssistContextExtras for the activity and foreground services
357 // to respond with the result.
358 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
360 // Maximum number of persisted Uri grants a package is allowed
361 static final int MAX_PERSISTED_URI_GRANTS = 128;
363 static final int MY_PID = Process.myPid();
365 static final String[] EMPTY_STRING_ARRAY = new String[0];
367 // How many bytes to write into the dropbox log before truncating
368 static final int DROPBOX_MAX_SIZE = 256 * 1024;
370 // Access modes for handleIncomingUser.
371 static final int ALLOW_NON_FULL = 0;
372 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
373 static final int ALLOW_FULL_ONLY = 2;
375 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
377 // Delay in notifying task stack change listeners (in millis)
378 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
380 // Necessary ApplicationInfo flags to mark an app as persistent
381 private static final int PERSISTENT_MASK =
382 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
384 /** All system services */
385 SystemServiceManager mSystemServiceManager;
387 private Installer mInstaller;
389 /** Run all ActivityStacks through this */
390 ActivityStackSupervisor mStackSupervisor;
392 /** Task stack change listeners. */
393 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
394 new RemoteCallbackList<ITaskStackListener>();
396 public IntentFirewall mIntentFirewall;
398 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
399 // default actuion automatically. Important for devices without direct input
401 private boolean mShowDialogs = true;
403 BroadcastQueue mFgBroadcastQueue;
404 BroadcastQueue mBgBroadcastQueue;
405 // Convenient for easy iteration over the queues. Foreground is first
406 // so that dispatch of foreground broadcasts gets precedence.
407 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
409 BroadcastQueue broadcastQueueForIntent(Intent intent) {
410 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
411 if (DEBUG_BACKGROUND_BROADCAST) {
412 Slog.i(TAG, "Broadcast intent " + intent + " on "
413 + (isFg ? "foreground" : "background")
416 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
419 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
420 for (BroadcastQueue queue : mBroadcastQueues) {
421 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
430 * Activity we have told the window manager to have key focus.
432 ActivityRecord mFocusedActivity = null;
435 * List of intents that were used to start the most recent tasks.
437 ArrayList<TaskRecord> mRecentTasks;
438 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
441 * For addAppTask: cached of the last activity component that was added.
443 ComponentName mLastAddedTaskComponent;
446 * For addAppTask: cached of the last activity uid that was added.
448 int mLastAddedTaskUid;
451 * For addAppTask: cached of the last ActivityInfo that was added.
453 ActivityInfo mLastAddedTaskActivity;
455 public class PendingAssistExtras extends Binder implements Runnable {
456 public final ActivityRecord activity;
457 public final Bundle extras;
458 public final Intent intent;
459 public final String hint;
460 public final int userHandle;
461 public boolean haveResult = false;
462 public Bundle result = null;
463 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
464 String _hint, int _userHandle) {
465 activity = _activity;
469 userHandle = _userHandle;
473 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
474 synchronized (this) {
481 final ArrayList<PendingAssistExtras> mPendingAssistExtras
482 = new ArrayList<PendingAssistExtras>();
485 * Process management.
487 final ProcessList mProcessList = new ProcessList();
490 * All of the applications we currently have running organized by name.
491 * The keys are strings of the application package name (as
492 * returned by the package manager), and the keys are ApplicationRecord
495 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
498 * Tracking long-term execution of processes to look for abuse and other
501 final ProcessStatsService mProcessStats;
504 * The currently running isolated processes.
506 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
509 * Counter for assigning isolated process uids, to avoid frequently reusing the
512 int mNextIsolatedProcessUid = 0;
515 * The currently running heavy-weight process, if any.
517 ProcessRecord mHeavyWeightProcess = null;
520 * The last time that various processes have crashed.
522 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
525 * Information about a process that is currently marked as bad.
527 static final class BadProcessInfo {
528 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
530 this.shortMsg = shortMsg;
531 this.longMsg = longMsg;
536 final String shortMsg;
537 final String longMsg;
542 * Set of applications that we consider to be bad, and will reject
543 * incoming broadcasts from (which the user has no control over).
544 * Processes are added to this set when they have crashed twice within
545 * a minimum amount of time; they are removed from it when they are
546 * later restarted (hopefully due to some user action). The value is the
547 * time it was added to the list.
549 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
552 * All of the processes we currently have running organized by pid.
553 * The keys are the pid running the application.
555 * <p>NOTE: This object is protected by its own lock, NOT the global
556 * activity manager lock!
558 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
561 * All of the processes that have been forced to be foreground. The key
562 * is the pid of the caller who requested it (we hold a death
565 abstract class ForegroundToken implements IBinder.DeathRecipient {
569 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
572 * List of records for processes that someone had tried to start before the
573 * system was ready. We don't start them at that point, but ensure they
574 * are started by the time booting is complete.
576 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
579 * List of persistent applications that are in the process
582 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
585 * Processes that are being forcibly torn down.
587 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
590 * List of running applications, sorted by recent usage.
591 * The first entry in the list is the least recently used.
593 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
596 * Where in mLruProcesses that the processes hosting activities start.
598 int mLruProcessActivityStart = 0;
601 * Where in mLruProcesses that the processes hosting services start.
602 * This is after (lower index) than mLruProcessesActivityStart.
604 int mLruProcessServiceStart = 0;
607 * List of processes that should gc as soon as things are idle.
609 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
612 * Processes we want to collect PSS data from.
614 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
617 * Last time we requested PSS data of all processes.
619 long mLastFullPssTime = SystemClock.uptimeMillis();
622 * If set, the next time we collect PSS data we should do a full collection
623 * with data from native processes and the kernel.
625 boolean mFullPssPending = false;
628 * This is the process holding what we currently consider to be
629 * the "home" activity.
631 ProcessRecord mHomeProcess;
634 * This is the process holding the activity the user last visited that
635 * is in a different process from the one they are currently in.
637 ProcessRecord mPreviousProcess;
640 * The time at which the previous process was last visible.
642 long mPreviousProcessVisibleTime;
645 * Which uses have been started, so are allowed to run code.
647 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
650 * LRU list of history of current users. Most recently current is at the end.
652 final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
655 * Constant array of the users that are currently started.
657 int[] mStartedUserArray = new int[] { 0 };
660 * Registered observers of the user switching mechanics.
662 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
663 = new RemoteCallbackList<IUserSwitchObserver>();
666 * Currently active user switch.
668 Object mCurUserSwitchCallback;
671 * Packages that the user has asked to have run in screen size
672 * compatibility mode instead of filling the screen.
674 final CompatModePackages mCompatModePackages;
677 * Set of IntentSenderRecord objects that are currently active.
679 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
680 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
683 * Fingerprints (hashCode()) of stack traces that we've
684 * already logged DropBox entries for. Guarded by itself. If
685 * something (rogue user app) forces this over
686 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
688 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
689 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
692 * Strict Mode background batched logging state.
694 * The string buffer is guarded by itself, and its lock is also
695 * used to determine if another batched write is already
698 private final StringBuilder mStrictModeBuffer = new StringBuilder();
701 * Keeps track of all IIntentReceivers that have been registered for
702 * broadcasts. Hash keys are the receiver IBinder, hash value is
705 final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
706 new HashMap<IBinder, ReceiverList>();
709 * Resolver for broadcast intents to registered receivers.
710 * Holds BroadcastFilter (subclass of IntentFilter).
712 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
713 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
715 protected boolean allowFilterResult(
716 BroadcastFilter filter, List<BroadcastFilter> dest) {
717 IBinder target = filter.receiverList.receiver.asBinder();
718 for (int i=dest.size()-1; i>=0; i--) {
719 if (dest.get(i).receiverList.receiver.asBinder() == target) {
727 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
728 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
729 || userId == filter.owningUserId) {
730 return super.newResult(filter, match, userId);
736 protected BroadcastFilter[] newArray(int size) {
737 return new BroadcastFilter[size];
741 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
742 return packageName.equals(filter.packageName);
747 * State of all active sticky broadcasts per user. Keys are the action of the
748 * sticky Intent, values are an ArrayList of all broadcasted intents with
749 * that action (which should usually be one). The SparseArray is keyed
750 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
751 * for stickies that are sent to all users.
753 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
754 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
756 final ActiveServices mServices;
758 final static class Association {
759 final int mSourceUid;
760 final String mSourceProcess;
761 final int mTargetUid;
762 final ComponentName mTargetComponent;
763 final String mTargetProcess;
771 Association(int sourceUid, String sourceProcess, int targetUid,
772 ComponentName targetComponent, String targetProcess) {
773 mSourceUid = sourceUid;
774 mSourceProcess = sourceProcess;
775 mTargetUid = targetUid;
776 mTargetComponent = targetComponent;
777 mTargetProcess = targetProcess;
782 * When service association tracking is enabled, this is all of the associations we
783 * have seen. Mapping is target uid -> target component -> source uid -> source process name
784 * -> association data.
786 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
787 mAssociations = new SparseArray<>();
788 boolean mTrackingAssociations;
791 * Backup/restore process management
793 String mBackupAppName = null;
794 BackupRecord mBackupTarget = null;
796 final ProviderMap mProviderMap;
799 * List of content providers who have clients waiting for them. The
800 * application is currently being launched and the provider will be
801 * removed from this list once it is published.
803 final ArrayList<ContentProviderRecord> mLaunchingProviders
804 = new ArrayList<ContentProviderRecord>();
807 * File storing persisted {@link #mGrantedUriPermissions}.
809 private final AtomicFile mGrantFile;
811 /** XML constants used in {@link #mGrantFile} */
812 private static final String TAG_URI_GRANTS = "uri-grants";
813 private static final String TAG_URI_GRANT = "uri-grant";
814 private static final String ATTR_USER_HANDLE = "userHandle";
815 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
816 private static final String ATTR_TARGET_USER_ID = "targetUserId";
817 private static final String ATTR_SOURCE_PKG = "sourcePkg";
818 private static final String ATTR_TARGET_PKG = "targetPkg";
819 private static final String ATTR_URI = "uri";
820 private static final String ATTR_MODE_FLAGS = "modeFlags";
821 private static final String ATTR_CREATED_TIME = "createdTime";
822 private static final String ATTR_PREFIX = "prefix";
825 * Global set of specific {@link Uri} permissions that have been granted.
826 * This optimized lookup structure maps from {@link UriPermission#targetUid}
827 * to {@link UriPermission#uri} to {@link UriPermission}.
830 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
831 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
833 public static class GrantUri {
834 public final int sourceUserId;
835 public final Uri uri;
836 public boolean prefix;
838 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
839 this.sourceUserId = sourceUserId;
841 this.prefix = prefix;
845 public int hashCode() {
847 hashCode = 31 * hashCode + sourceUserId;
848 hashCode = 31 * hashCode + uri.hashCode();
849 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
854 public boolean equals(Object o) {
855 if (o instanceof GrantUri) {
856 GrantUri other = (GrantUri) o;
857 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
858 && prefix == other.prefix;
864 public String toString() {
865 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
866 if (prefix) result += " [prefix]";
870 public String toSafeString() {
871 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
872 if (prefix) result += " [prefix]";
876 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
877 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
878 ContentProvider.getUriWithoutUserId(uri), false);
882 CoreSettingsObserver mCoreSettingsObserver;
885 * Thread-local storage used to carry caller permissions over through
886 * indirect content-provider access.
888 private class Identity {
889 public final IBinder token;
890 public final int pid;
891 public final int uid;
893 Identity(IBinder _token, int _pid, int _uid) {
900 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
903 * All information we have collected about the runtime performance of
904 * any user id that can impact battery performance.
906 final BatteryStatsService mBatteryStatsService;
909 * Information about component usage
911 UsageStatsManagerInternal mUsageStatsService;
914 * Information about and control over application operations
916 final AppOpsService mAppOpsService;
919 * Save recent tasks information across reboots.
921 final TaskPersister mTaskPersister;
924 * Current configuration information. HistoryRecord objects are given
925 * a reference to this object to indicate which configuration they are
926 * currently running in, so this object must be kept immutable.
928 Configuration mConfiguration = new Configuration();
931 * Current sequencing integer of the configuration, for skipping old
934 int mConfigurationSeq = 0;
937 * Hardware-reported OpenGLES version.
939 final int GL_ES_VERSION;
942 * List of initialization arguments to pass to all processes when binding applications to them.
943 * For example, references to the commonly used services.
945 HashMap<String, IBinder> mAppBindArgs;
946 HashMap<String, IBinder> mIsolatedAppBindArgs;
949 * Temporary to avoid allocations. Protected by main lock.
951 final StringBuilder mStringBuilder = new StringBuilder(256);
954 * Used to control how we initialize the service.
956 ComponentName mTopComponent;
957 String mTopAction = Intent.ACTION_MAIN;
959 boolean mProcessesReady = false;
960 boolean mSystemReady = false;
961 boolean mBooting = false;
962 boolean mCallFinishBooting = false;
963 boolean mBootAnimationComplete = false;
964 boolean mWaitingUpdate = false;
965 boolean mDidUpdate = false;
966 boolean mOnBattery = false;
967 boolean mLaunchWarningShown = false;
973 boolean mCheckedForSetup;
976 * The time at which we will allow normal application switches again,
977 * after a call to {@link #stopAppSwitches()}.
979 long mAppSwitchesAllowedTime;
982 * This is set to true after the first switch after mAppSwitchesAllowedTime
983 * is set; any switches after that will clear the time.
985 boolean mDidAppSwitch;
988 * Last time (in realtime) at which we checked for power usage.
990 long mLastPowerCheckRealtime;
993 * Last time (in uptime) at which we checked for power usage.
995 long mLastPowerCheckUptime;
998 * Set while we are wanting to sleep, to prevent any
999 * activities from being started/resumed.
1001 private boolean mSleeping = false;
1004 * Set while we are running a voice interaction. This overrides
1005 * sleeping while it is active.
1007 private boolean mRunningVoice = false;
1010 * State of external calls telling us if the device is awake or asleep.
1012 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1014 static final int LOCK_SCREEN_HIDDEN = 0;
1015 static final int LOCK_SCREEN_LEAVING = 1;
1016 static final int LOCK_SCREEN_SHOWN = 2;
1018 * State of external call telling us if the lock screen is shown.
1020 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1023 * Set if we are shutting down the system, similar to sleeping.
1025 boolean mShuttingDown = false;
1028 * Current sequence id for oom_adj computation traversal.
1033 * Current sequence id for process LRU updating.
1038 * Keep track of the non-cached/empty process we last found, to help
1039 * determine how to distribute cached/empty processes next time.
1041 int mNumNonCachedProcs = 0;
1044 * Keep track of the number of cached hidden procs, to balance oom adj
1045 * distribution between those and empty procs.
1047 int mNumCachedHiddenProcs = 0;
1050 * Keep track of the number of service processes we last found, to
1051 * determine on the next iteration which should be B services.
1053 int mNumServiceProcs = 0;
1054 int mNewNumAServiceProcs = 0;
1055 int mNewNumServiceProcs = 0;
1058 * Allow the current computed overall memory level of the system to go down?
1059 * This is set to false when we are killing processes for reasons other than
1060 * memory management, so that the now smaller process list will not be taken as
1061 * an indication that memory is tighter.
1063 boolean mAllowLowerMemLevel = false;
1066 * The last computed memory level, for holding when we are in a state that
1067 * processes are going away for other reasons.
1069 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1072 * The last total number of process we have, to determine if changes actually look
1073 * like a shrinking number of process due to lower RAM.
1075 int mLastNumProcesses;
1078 * The uptime of the last time we performed idle maintenance.
1080 long mLastIdleTime = SystemClock.uptimeMillis();
1083 * Total time spent with RAM that has been added in the past since the last idle time.
1085 long mLowRamTimeSinceLastIdle = 0;
1088 * If RAM is currently low, when that horrible situation started.
1090 long mLowRamStartTime = 0;
1093 * For reporting to battery stats the current top application.
1095 private String mCurResumedPackage = null;
1096 private int mCurResumedUid = -1;
1099 * For reporting to battery stats the apps currently running foreground
1100 * service. The ProcessMap is package/uid tuples; each of these contain
1101 * an array of the currently foreground processes.
1103 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1104 = new ProcessMap<ArrayList<ProcessRecord>>();
1107 * This is set if we had to do a delayed dexopt of an app before launching
1108 * it, to increase the ANR timeouts in that case.
1113 * Set if the systemServer made a call to enterSafeMode.
1118 * If true, we are running under a test environment so will sample PSS from processes
1119 * much more rapidly to try to collect better data when the tests are rapidly
1120 * running through apps.
1122 boolean mTestPssMode = false;
1124 String mDebugApp = null;
1125 boolean mWaitForDebugger = false;
1126 boolean mDebugTransient = false;
1127 String mOrigDebugApp = null;
1128 boolean mOrigWaitForDebugger = false;
1129 boolean mAlwaysFinishActivities = false;
1130 IActivityController mController = null;
1131 String mProfileApp = null;
1132 ProcessRecord mProfileProc = null;
1133 String mProfileFile;
1134 ParcelFileDescriptor mProfileFd;
1135 int mSamplingInterval = 0;
1136 boolean mAutoStopProfiler = false;
1137 int mProfileType = 0;
1138 String mOpenGlTraceApp = null;
1140 final long[] mTmpLong = new long[1];
1142 static class ProcessChangeItem {
1143 static final int CHANGE_ACTIVITIES = 1<<0;
1144 static final int CHANGE_PROCESS_STATE = 1<<1;
1149 boolean foregroundActivities;
1152 final RemoteCallbackList<IProcessObserver> mProcessObservers
1153 = new RemoteCallbackList<IProcessObserver>();
1154 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1156 final ArrayList<ProcessChangeItem> mPendingProcessChanges
1157 = new ArrayList<ProcessChangeItem>();
1158 final ArrayList<ProcessChangeItem> mAvailProcessChanges
1159 = new ArrayList<ProcessChangeItem>();
1162 * Runtime CPU use collection thread. This object's lock is used to
1163 * perform synchronization with the thread (notifying it to run).
1165 final Thread mProcessCpuThread;
1168 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1169 * Must acquire this object's lock when accessing it.
1170 * NOTE: this lock will be held while doing long operations (trawling
1171 * through all processes in /proc), so it should never be acquired by
1172 * any critical paths such as when holding the main activity manager lock.
1174 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1175 MONITOR_THREAD_CPU_USAGE);
1176 final AtomicLong mLastCpuTime = new AtomicLong(0);
1177 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1179 long mLastWriteTime = 0;
1182 * Used to retain an update lock when the foreground activity is in
1185 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1188 * Set to true after the system has finished booting.
1190 boolean mBooted = false;
1192 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1193 int mProcessLimitOverride = -1;
1195 WindowManagerService mWindowManager;
1197 final ActivityThread mSystemThread;
1199 // Holds the current foreground user's id
1200 int mCurrentUserId = 0;
1201 // Holds the target user's id during a user switch
1202 int mTargetUserId = UserHandle.USER_NULL;
1203 // If there are multiple profiles for the current user, their ids are here
1204 // Currently only the primary user can have managed profiles
1205 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1208 * Mapping from each known user ID to the profile group ID it is associated with.
1210 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1212 private UserManagerService mUserManager;
1214 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1215 final ProcessRecord mApp;
1217 final IApplicationThread mAppThread;
1219 AppDeathRecipient(ProcessRecord app, int pid,
1220 IApplicationThread thread) {
1221 if (localLOGV) Slog.v(
1222 TAG, "New death recipient " + this
1223 + " for thread " + thread.asBinder());
1226 mAppThread = thread;
1230 public void binderDied() {
1231 if (localLOGV) Slog.v(
1232 TAG, "Death received in " + this
1233 + " for thread " + mAppThread.asBinder());
1234 synchronized(ActivityManagerService.this) {
1235 appDiedLocked(mApp, mPid, mAppThread);
1240 static final int SHOW_ERROR_MSG = 1;
1241 static final int SHOW_NOT_RESPONDING_MSG = 2;
1242 static final int SHOW_FACTORY_ERROR_MSG = 3;
1243 static final int UPDATE_CONFIGURATION_MSG = 4;
1244 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1245 static final int WAIT_FOR_DEBUGGER_MSG = 6;
1246 static final int SERVICE_TIMEOUT_MSG = 12;
1247 static final int UPDATE_TIME_ZONE = 13;
1248 static final int SHOW_UID_ERROR_MSG = 14;
1249 static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1250 static final int PROC_START_TIMEOUT_MSG = 20;
1251 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1252 static final int KILL_APPLICATION_MSG = 22;
1253 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1254 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1255 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1256 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1257 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1258 static final int CLEAR_DNS_CACHE_MSG = 28;
1259 static final int UPDATE_HTTP_PROXY_MSG = 29;
1260 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1261 static final int DISPATCH_PROCESSES_CHANGED = 31;
1262 static final int DISPATCH_PROCESS_DIED = 32;
1263 static final int REPORT_MEM_USAGE_MSG = 33;
1264 static final int REPORT_USER_SWITCH_MSG = 34;
1265 static final int CONTINUE_USER_SWITCH_MSG = 35;
1266 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1267 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1268 static final int PERSIST_URI_GRANTS_MSG = 38;
1269 static final int REQUEST_ALL_PSS_MSG = 39;
1270 static final int START_PROFILES_MSG = 40;
1271 static final int UPDATE_TIME = 41;
1272 static final int SYSTEM_USER_START_MSG = 42;
1273 static final int SYSTEM_USER_CURRENT_MSG = 43;
1274 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1275 static final int FINISH_BOOTING_MSG = 45;
1276 static final int START_USER_SWITCH_MSG = 46;
1277 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1278 static final int DISMISS_DIALOG_MSG = 48;
1279 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1281 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1282 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1283 static final int FIRST_COMPAT_MODE_MSG = 300;
1284 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1286 CompatModeDialog mCompatModeDialog;
1287 long mLastMemUsageReportTime = 0;
1290 * Flag whether the current user is a "monkey", i.e. whether
1291 * the UI is driven by a UI automation tool.
1293 private boolean mUserIsMonkey;
1295 /** Flag whether the device has a Recents UI */
1296 boolean mHasRecents;
1298 /** The dimensions of the thumbnails in the Recents UI. */
1299 int mThumbnailWidth;
1300 int mThumbnailHeight;
1302 final ServiceThread mHandlerThread;
1303 final MainHandler mHandler;
1305 final class MainHandler extends Handler {
1306 public MainHandler(Looper looper) {
1307 super(looper, null, true);
1311 public void handleMessage(Message msg) {
1313 case SHOW_ERROR_MSG: {
1314 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1315 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1316 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1317 synchronized (ActivityManagerService.this) {
1318 ProcessRecord proc = (ProcessRecord)data.get("app");
1319 AppErrorResult res = (AppErrorResult) data.get("result");
1320 if (proc != null && proc.crashDialog != null) {
1321 Slog.e(TAG, "App already has crash dialog: " + proc);
1327 boolean isBackground = (UserHandle.getAppId(proc.uid)
1328 >= Process.FIRST_APPLICATION_UID
1329 && proc.pid != MY_PID);
1330 for (int userId : mCurrentProfileIds) {
1331 isBackground &= (proc.userId != userId);
1333 if (isBackground && !showBackground) {
1334 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1340 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1341 Dialog d = new AppErrorDialog(mContext,
1342 ActivityManagerService.this, res, proc);
1344 proc.crashDialog = d;
1346 // The device is asleep, so just pretend that the user
1347 // saw a crash dialog and hit "force quit".
1354 ensureBootCompleted();
1356 case SHOW_NOT_RESPONDING_MSG: {
1357 synchronized (ActivityManagerService.this) {
1358 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1359 ProcessRecord proc = (ProcessRecord)data.get("app");
1360 if (proc != null && proc.anrDialog != null) {
1361 Slog.e(TAG, "App already has anr dialog: " + proc);
1365 Intent intent = new Intent("android.intent.action.ANR");
1366 if (!mProcessesReady) {
1367 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1368 | Intent.FLAG_RECEIVER_FOREGROUND);
1370 broadcastIntentLocked(null, null, intent,
1371 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1372 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1375 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1376 mContext, proc, (ActivityRecord)data.get("activity"),
1381 // Just kill the app if there is no dialog to be shown.
1382 killAppAtUsersRequest(proc, null);
1386 ensureBootCompleted();
1388 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1389 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1390 synchronized (ActivityManagerService.this) {
1391 ProcessRecord proc = (ProcessRecord) data.get("app");
1393 Slog.e(TAG, "App not found when showing strict mode dialog.");
1396 if (proc.crashDialog != null) {
1397 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1400 AppErrorResult res = (AppErrorResult) data.get("result");
1401 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1402 Dialog d = new StrictModeViolationDialog(mContext,
1403 ActivityManagerService.this, res, proc);
1405 proc.crashDialog = d;
1407 // The device is asleep, so just pretend that the user
1408 // saw a crash dialog and hit "force quit".
1412 ensureBootCompleted();
1414 case SHOW_FACTORY_ERROR_MSG: {
1415 Dialog d = new FactoryErrorDialog(
1416 mContext, msg.getData().getCharSequence("msg"));
1418 ensureBootCompleted();
1420 case UPDATE_CONFIGURATION_MSG: {
1421 final ContentResolver resolver = mContext.getContentResolver();
1422 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1424 case GC_BACKGROUND_PROCESSES_MSG: {
1425 synchronized (ActivityManagerService.this) {
1426 performAppGcsIfAppropriateLocked();
1429 case WAIT_FOR_DEBUGGER_MSG: {
1430 synchronized (ActivityManagerService.this) {
1431 ProcessRecord app = (ProcessRecord)msg.obj;
1432 if (msg.arg1 != 0) {
1433 if (!app.waitedForDebugger) {
1434 Dialog d = new AppWaitingForDebuggerDialog(
1435 ActivityManagerService.this,
1438 app.waitedForDebugger = true;
1442 if (app.waitDialog != null) {
1443 app.waitDialog.dismiss();
1444 app.waitDialog = null;
1449 case SERVICE_TIMEOUT_MSG: {
1452 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1454 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1457 mServices.serviceTimeout((ProcessRecord)msg.obj);
1459 case UPDATE_TIME_ZONE: {
1460 synchronized (ActivityManagerService.this) {
1461 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1462 ProcessRecord r = mLruProcesses.get(i);
1463 if (r.thread != null) {
1465 r.thread.updateTimeZone();
1466 } catch (RemoteException ex) {
1467 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1473 case CLEAR_DNS_CACHE_MSG: {
1474 synchronized (ActivityManagerService.this) {
1475 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1476 ProcessRecord r = mLruProcesses.get(i);
1477 if (r.thread != null) {
1479 r.thread.clearDnsCache();
1480 } catch (RemoteException ex) {
1481 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1487 case UPDATE_HTTP_PROXY_MSG: {
1488 ProxyInfo proxy = (ProxyInfo)msg.obj;
1491 String exclList = "";
1492 Uri pacFileUrl = Uri.EMPTY;
1493 if (proxy != null) {
1494 host = proxy.getHost();
1495 port = Integer.toString(proxy.getPort());
1496 exclList = proxy.getExclusionListAsString();
1497 pacFileUrl = proxy.getPacFileUrl();
1499 synchronized (ActivityManagerService.this) {
1500 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1501 ProcessRecord r = mLruProcesses.get(i);
1502 if (r.thread != null) {
1504 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1505 } catch (RemoteException ex) {
1506 Slog.w(TAG, "Failed to update http proxy for: " +
1507 r.info.processName);
1513 case SHOW_UID_ERROR_MSG: {
1515 AlertDialog d = new BaseErrorDialog(mContext);
1516 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1517 d.setCancelable(false);
1518 d.setTitle(mContext.getText(R.string.android_system_label));
1519 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1520 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1521 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1525 case SHOW_FINGERPRINT_ERROR_MSG: {
1527 AlertDialog d = new BaseErrorDialog(mContext);
1528 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1529 d.setCancelable(false);
1530 d.setTitle(mContext.getText(R.string.android_system_label));
1531 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1532 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1533 mHandler.obtainMessage(DISMISS_DIALOG_MSG, d));
1537 case PROC_START_TIMEOUT_MSG: {
1540 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1542 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1545 ProcessRecord app = (ProcessRecord)msg.obj;
1546 synchronized (ActivityManagerService.this) {
1547 processStartTimedOutLocked(app);
1550 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1551 synchronized (ActivityManagerService.this) {
1552 mStackSupervisor.doPendingActivityLaunchesLocked(true);
1555 case KILL_APPLICATION_MSG: {
1556 synchronized (ActivityManagerService.this) {
1557 int appid = msg.arg1;
1558 boolean restart = (msg.arg2 == 1);
1559 Bundle bundle = (Bundle)msg.obj;
1560 String pkg = bundle.getString("pkg");
1561 String reason = bundle.getString("reason");
1562 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1563 false, UserHandle.USER_ALL, reason);
1566 case FINALIZE_PENDING_INTENT_MSG: {
1567 ((PendingIntentRecord)msg.obj).completeFinalize();
1569 case POST_HEAVY_NOTIFICATION_MSG: {
1570 INotificationManager inm = NotificationManager.getService();
1575 ActivityRecord root = (ActivityRecord)msg.obj;
1576 ProcessRecord process = root.app;
1577 if (process == null) {
1582 Context context = mContext.createPackageContext(process.info.packageName, 0);
1583 String text = mContext.getString(R.string.heavy_weight_notification,
1584 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1585 Notification notification = new Notification();
1586 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1587 notification.when = 0;
1588 notification.flags = Notification.FLAG_ONGOING_EVENT;
1589 notification.tickerText = text;
1590 notification.defaults = 0; // please be quiet
1591 notification.sound = null;
1592 notification.vibrate = null;
1593 notification.color = mContext.getResources().getColor(
1594 com.android.internal.R.color.system_notification_accent_color);
1595 notification.setLatestEventInfo(context, text,
1596 mContext.getText(R.string.heavy_weight_notification_detail),
1597 PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1598 PendingIntent.FLAG_CANCEL_CURRENT, null,
1599 new UserHandle(root.userId)));
1602 int[] outId = new int[1];
1603 inm.enqueueNotificationWithTag("android", "android", null,
1604 R.string.heavy_weight_notification,
1605 notification, outId, root.userId);
1606 } catch (RuntimeException e) {
1607 Slog.w(ActivityManagerService.TAG,
1608 "Error showing notification for heavy-weight app", e);
1609 } catch (RemoteException e) {
1611 } catch (NameNotFoundException e) {
1612 Slog.w(TAG, "Unable to create context for heavy notification", e);
1615 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1616 INotificationManager inm = NotificationManager.getService();
1621 inm.cancelNotificationWithTag("android", null,
1622 R.string.heavy_weight_notification, msg.arg1);
1623 } catch (RuntimeException e) {
1624 Slog.w(ActivityManagerService.TAG,
1625 "Error canceling notification for service", e);
1626 } catch (RemoteException e) {
1629 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1630 synchronized (ActivityManagerService.this) {
1631 checkExcessivePowerUsageLocked(true);
1632 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1633 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1634 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1637 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1638 synchronized (ActivityManagerService.this) {
1639 ActivityRecord ar = (ActivityRecord)msg.obj;
1640 if (mCompatModeDialog != null) {
1641 if (mCompatModeDialog.mAppInfo.packageName.equals(
1642 ar.info.applicationInfo.packageName)) {
1645 mCompatModeDialog.dismiss();
1646 mCompatModeDialog = null;
1648 if (ar != null && false) {
1649 if (mCompatModePackages.getPackageAskCompatModeLocked(
1651 int mode = mCompatModePackages.computeCompatModeLocked(
1652 ar.info.applicationInfo);
1653 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1654 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1655 mCompatModeDialog = new CompatModeDialog(
1656 ActivityManagerService.this, mContext,
1657 ar.info.applicationInfo);
1658 mCompatModeDialog.show();
1665 case DISPATCH_PROCESSES_CHANGED: {
1666 dispatchProcessesChanged();
1669 case DISPATCH_PROCESS_DIED: {
1670 final int pid = msg.arg1;
1671 final int uid = msg.arg2;
1672 dispatchProcessDied(pid, uid);
1675 case REPORT_MEM_USAGE_MSG: {
1676 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1677 Thread thread = new Thread() {
1678 @Override public void run() {
1679 reportMemUsage(memInfos);
1685 case START_USER_SWITCH_MSG: {
1686 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1689 case REPORT_USER_SWITCH_MSG: {
1690 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1693 case CONTINUE_USER_SWITCH_MSG: {
1694 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1697 case USER_SWITCH_TIMEOUT_MSG: {
1698 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1701 case IMMERSIVE_MODE_LOCK_MSG: {
1702 final boolean nextState = (msg.arg1 != 0);
1703 if (mUpdateLock.isHeld() != nextState) {
1704 if (DEBUG_IMMERSIVE) {
1705 final ActivityRecord r = (ActivityRecord) msg.obj;
1706 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1709 mUpdateLock.acquire();
1711 mUpdateLock.release();
1716 case PERSIST_URI_GRANTS_MSG: {
1717 writeGrantedUriPermissions();
1720 case REQUEST_ALL_PSS_MSG: {
1721 synchronized (ActivityManagerService.this) {
1722 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1726 case START_PROFILES_MSG: {
1727 synchronized (ActivityManagerService.this) {
1728 startProfilesLocked();
1733 synchronized (ActivityManagerService.this) {
1734 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1735 ProcessRecord r = mLruProcesses.get(i);
1736 if (r.thread != null) {
1738 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1739 } catch (RemoteException ex) {
1740 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1747 case SYSTEM_USER_START_MSG: {
1748 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1749 Integer.toString(msg.arg1), msg.arg1);
1750 mSystemServiceManager.startUser(msg.arg1);
1753 case SYSTEM_USER_CURRENT_MSG: {
1754 mBatteryStatsService.noteEvent(
1755 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1756 Integer.toString(msg.arg2), msg.arg2);
1757 mBatteryStatsService.noteEvent(
1758 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1759 Integer.toString(msg.arg1), msg.arg1);
1760 mSystemServiceManager.switchUser(msg.arg1);
1763 case ENTER_ANIMATION_COMPLETE_MSG: {
1764 synchronized (ActivityManagerService.this) {
1765 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1766 if (r != null && r.app != null && r.app.thread != null) {
1768 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1769 } catch (RemoteException e) {
1775 case FINISH_BOOTING_MSG: {
1776 if (msg.arg1 != 0) {
1779 if (msg.arg2 != 0) {
1780 enableScreenAfterBoot();
1784 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1786 Locale l = (Locale) msg.obj;
1787 IBinder service = ServiceManager.getService("mount");
1788 IMountService mountService = IMountService.Stub.asInterface(service);
1789 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1790 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1791 } catch (RemoteException e) {
1792 Log.e(TAG, "Error storing locale for decryption UI", e);
1796 case DISMISS_DIALOG_MSG: {
1797 final Dialog d = (Dialog) msg.obj;
1801 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1802 synchronized (ActivityManagerService.this) {
1803 int i = mTaskStackListeners.beginBroadcast();
1807 // Make a one-way callback to the listener
1808 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1809 } catch (RemoteException e){
1810 // Handled by the RemoteCallbackList
1813 mTaskStackListeners.finishBroadcast();
1821 static final int COLLECT_PSS_BG_MSG = 1;
1823 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1825 public void handleMessage(Message msg) {
1827 case COLLECT_PSS_BG_MSG: {
1828 long start = SystemClock.uptimeMillis();
1829 MemInfoReader memInfo = null;
1830 synchronized (ActivityManagerService.this) {
1831 if (mFullPssPending) {
1832 mFullPssPending = false;
1833 memInfo = new MemInfoReader();
1836 if (memInfo != null) {
1837 updateCpuStatsNow();
1838 long nativeTotalPss = 0;
1839 synchronized (mProcessCpuTracker) {
1840 final int N = mProcessCpuTracker.countStats();
1841 for (int j=0; j<N; j++) {
1842 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1843 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1844 // This is definitely an application process; skip it.
1847 synchronized (mPidsSelfLocked) {
1848 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1849 // This is one of our own processes; skip it.
1853 nativeTotalPss += Debug.getPss(st.pid, null, null);
1856 memInfo.readMemInfo();
1857 synchronized (ActivityManagerService.this) {
1858 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1859 + (SystemClock.uptimeMillis()-start) + "ms");
1860 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1861 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1862 memInfo.getKernelUsedSizeKb(), nativeTotalPss);
1867 long[] tmp = new long[1];
1873 synchronized (ActivityManagerService.this) {
1874 if (mPendingPssProcesses.size() <= 0) {
1875 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num
1876 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1877 mPendingPssProcesses.clear();
1880 proc = mPendingPssProcesses.remove(0);
1881 procState = proc.pssProcState;
1882 lastPssTime = proc.lastPssTime;
1883 if (proc.thread != null && procState == proc.setProcState
1884 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
1885 < SystemClock.uptimeMillis()) {
1893 long pss = Debug.getPss(pid, tmp, null);
1894 synchronized (ActivityManagerService.this) {
1895 if (pss != 0 && proc.thread != null && proc.setProcState == procState
1896 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
1898 recordPssSample(proc, procState, pss, tmp[0],
1899 SystemClock.uptimeMillis());
1909 public void setSystemProcess() {
1911 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1912 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1913 ServiceManager.addService("meminfo", new MemBinder(this));
1914 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1915 ServiceManager.addService("dbinfo", new DbBinder(this));
1916 if (MONITOR_CPU_USAGE) {
1917 ServiceManager.addService("cpuinfo", new CpuBinder(this));
1919 ServiceManager.addService("permission", new PermissionController(this));
1921 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1922 "android", STOCK_PM_FLAGS);
1923 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
1925 synchronized (this) {
1926 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
1927 app.persistent = true;
1929 app.maxAdj = ProcessList.SYSTEM_ADJ;
1930 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
1931 mProcessNames.put(app.processName, app.uid, app);
1932 synchronized (mPidsSelfLocked) {
1933 mPidsSelfLocked.put(app.pid, app);
1935 updateLruProcessLocked(app, false, null);
1936 updateOomAdjLocked();
1938 } catch (PackageManager.NameNotFoundException e) {
1939 throw new RuntimeException(
1940 "Unable to find android system package", e);
1944 public void setWindowManager(WindowManagerService wm) {
1945 mWindowManager = wm;
1946 mStackSupervisor.setWindowManager(wm);
1949 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
1950 mUsageStatsService = usageStatsManager;
1953 public void startObservingNativeCrashes() {
1954 final NativeCrashListener ncl = new NativeCrashListener(this);
1958 public IAppOpsService getAppOpsService() {
1959 return mAppOpsService;
1962 static class MemBinder extends Binder {
1963 ActivityManagerService mActivityManagerService;
1964 MemBinder(ActivityManagerService activityManagerService) {
1965 mActivityManagerService = activityManagerService;
1969 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1970 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1971 != PackageManager.PERMISSION_GRANTED) {
1972 pw.println("Permission Denial: can't dump meminfo from from pid="
1973 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1974 + " without permission " + android.Manifest.permission.DUMP);
1978 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
1982 static class GraphicsBinder extends Binder {
1983 ActivityManagerService mActivityManagerService;
1984 GraphicsBinder(ActivityManagerService activityManagerService) {
1985 mActivityManagerService = activityManagerService;
1989 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1990 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1991 != PackageManager.PERMISSION_GRANTED) {
1992 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1993 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1994 + " without permission " + android.Manifest.permission.DUMP);
1998 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2002 static class DbBinder extends Binder {
2003 ActivityManagerService mActivityManagerService;
2004 DbBinder(ActivityManagerService activityManagerService) {
2005 mActivityManagerService = activityManagerService;
2009 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2010 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2011 != PackageManager.PERMISSION_GRANTED) {
2012 pw.println("Permission Denial: can't dump dbinfo from from pid="
2013 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2014 + " without permission " + android.Manifest.permission.DUMP);
2018 mActivityManagerService.dumpDbInfo(fd, pw, args);
2022 static class CpuBinder extends Binder {
2023 ActivityManagerService mActivityManagerService;
2024 CpuBinder(ActivityManagerService activityManagerService) {
2025 mActivityManagerService = activityManagerService;
2029 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2030 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2031 != PackageManager.PERMISSION_GRANTED) {
2032 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2033 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2034 + " without permission " + android.Manifest.permission.DUMP);
2038 synchronized (mActivityManagerService.mProcessCpuTracker) {
2039 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2040 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2041 SystemClock.uptimeMillis()));
2046 public static final class Lifecycle extends SystemService {
2047 private final ActivityManagerService mService;
2049 public Lifecycle(Context context) {
2051 mService = new ActivityManagerService(context);
2055 public void onStart() {
2059 public ActivityManagerService getService() {
2064 // Note: This method is invoked on the main thread but may need to attach various
2065 // handlers to other threads. So take care to be explicit about the looper.
2066 public ActivityManagerService(Context systemContext) {
2067 mContext = systemContext;
2068 mFactoryTest = FactoryTest.getMode();
2069 mSystemThread = ActivityThread.currentActivityThread();
2071 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2073 mHandlerThread = new ServiceThread(TAG,
2074 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2075 mHandlerThread.start();
2076 mHandler = new MainHandler(mHandlerThread.getLooper());
2078 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2079 "foreground", BROADCAST_FG_TIMEOUT, false);
2080 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2081 "background", BROADCAST_BG_TIMEOUT, true);
2082 mBroadcastQueues[0] = mFgBroadcastQueue;
2083 mBroadcastQueues[1] = mBgBroadcastQueue;
2085 mServices = new ActiveServices(this);
2086 mProviderMap = new ProviderMap(this);
2088 // TODO: Move creation of battery stats service outside of activity manager service.
2089 File dataDir = Environment.getDataDirectory();
2090 File systemDir = new File(dataDir, "system");
2092 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2093 mBatteryStatsService.getActiveStatistics().readLocked();
2094 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2095 mOnBattery = DEBUG_POWER ? true
2096 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2097 mBatteryStatsService.getActiveStatistics().setCallback(this);
2099 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2101 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2103 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2105 // User 0 is the first and only user that runs at boot.
2106 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2107 mUserLru.add(Integer.valueOf(0));
2108 updateStartedUserArrayLocked();
2110 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2111 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2113 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2115 mConfiguration.setToDefaults();
2116 mConfiguration.locale = Locale.getDefault();
2118 mConfigurationSeq = mConfiguration.seq = 1;
2119 mProcessCpuTracker.init();
2121 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2122 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2123 mStackSupervisor = new ActivityStackSupervisor(this);
2124 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2126 mProcessCpuThread = new Thread("CpuTracker") {
2132 synchronized(this) {
2133 final long now = SystemClock.uptimeMillis();
2134 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2135 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2136 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2137 // + ", write delay=" + nextWriteDelay);
2138 if (nextWriteDelay < nextCpuDelay) {
2139 nextCpuDelay = nextWriteDelay;
2141 if (nextCpuDelay > 0) {
2142 mProcessCpuMutexFree.set(true);
2143 this.wait(nextCpuDelay);
2146 } catch (InterruptedException e) {
2148 updateCpuStatsNow();
2149 } catch (Exception e) {
2150 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2156 Watchdog.getInstance().addMonitor(this);
2157 Watchdog.getInstance().addThread(mHandler);
2160 public void setSystemServiceManager(SystemServiceManager mgr) {
2161 mSystemServiceManager = mgr;
2164 public void setInstaller(Installer installer) {
2165 mInstaller = installer;
2168 private void start() {
2169 Process.removeAllProcessGroups();
2170 mProcessCpuThread.start();
2172 mBatteryStatsService.publish(mContext);
2173 mAppOpsService.publish(mContext);
2174 Slog.d("AppOps", "AppOpsService published");
2175 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2178 public void initPowerManagement() {
2179 mStackSupervisor.initPowerManagement();
2180 mBatteryStatsService.initPowerManagement();
2184 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2185 throws RemoteException {
2186 if (code == SYSPROPS_TRANSACTION) {
2187 // We need to tell all apps about the system property change.
2188 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2189 synchronized(this) {
2190 final int NP = mProcessNames.getMap().size();
2191 for (int ip=0; ip<NP; ip++) {
2192 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2193 final int NA = apps.size();
2194 for (int ia=0; ia<NA; ia++) {
2195 ProcessRecord app = apps.valueAt(ia);
2196 if (app.thread != null) {
2197 procs.add(app.thread.asBinder());
2203 int N = procs.size();
2204 for (int i=0; i<N; i++) {
2205 Parcel data2 = Parcel.obtain();
2207 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2208 } catch (RemoteException e) {
2214 return super.onTransact(code, data, reply, flags);
2215 } catch (RuntimeException e) {
2216 // The activity manager only throws security exceptions, so let's
2218 if (!(e instanceof SecurityException)) {
2219 Slog.wtf(TAG, "Activity Manager Crash", e);
2225 void updateCpuStats() {
2226 final long now = SystemClock.uptimeMillis();
2227 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2230 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2231 synchronized (mProcessCpuThread) {
2232 mProcessCpuThread.notify();
2237 void updateCpuStatsNow() {
2238 synchronized (mProcessCpuTracker) {
2239 mProcessCpuMutexFree.set(false);
2240 final long now = SystemClock.uptimeMillis();
2241 boolean haveNewCpuStats = false;
2243 if (MONITOR_CPU_USAGE &&
2244 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2245 mLastCpuTime.set(now);
2246 haveNewCpuStats = true;
2247 mProcessCpuTracker.update();
2248 //Slog.i(TAG, mProcessCpu.printCurrentState());
2249 //Slog.i(TAG, "Total CPU usage: "
2250 // + mProcessCpu.getTotalCpuPercent() + "%");
2252 // Slog the cpu usage if the property is set.
2253 if ("true".equals(SystemProperties.get("events.cpu"))) {
2254 int user = mProcessCpuTracker.getLastUserTime();
2255 int system = mProcessCpuTracker.getLastSystemTime();
2256 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2257 int irq = mProcessCpuTracker.getLastIrqTime();
2258 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2259 int idle = mProcessCpuTracker.getLastIdleTime();
2261 int total = user + system + iowait + irq + softIrq + idle;
2262 if (total == 0) total = 1;
2264 EventLog.writeEvent(EventLogTags.CPU,
2265 ((user+system+iowait+irq+softIrq) * 100) / total,
2266 (user * 100) / total,
2267 (system * 100) / total,
2268 (iowait * 100) / total,
2269 (irq * 100) / total,
2270 (softIrq * 100) / total);
2274 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2275 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2276 synchronized(bstats) {
2277 synchronized(mPidsSelfLocked) {
2278 if (haveNewCpuStats) {
2280 int perc = bstats.startAddingCpuLocked();
2283 final int N = mProcessCpuTracker.countStats();
2284 for (int i=0; i<N; i++) {
2285 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2289 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2290 int otherUTime = (st.rel_utime*perc)/100;
2291 int otherSTime = (st.rel_stime*perc)/100;
2292 totalUTime += otherUTime;
2293 totalSTime += otherSTime;
2295 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2296 if (ps == null || !ps.isActive()) {
2297 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2298 pr.info.uid, pr.processName);
2300 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2301 st.rel_stime-otherSTime);
2302 ps.addSpeedStepTimes(cpuSpeedTimes);
2303 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2305 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2306 if (ps == null || !ps.isActive()) {
2307 st.batteryStats = ps = bstats.getProcessStatsLocked(
2308 bstats.mapUid(st.uid), st.name);
2310 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2311 st.rel_stime-otherSTime);
2312 ps.addSpeedStepTimes(cpuSpeedTimes);
2315 bstats.finishAddingCpuLocked(perc, totalUTime,
2316 totalSTime, cpuSpeedTimes);
2321 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2322 mLastWriteTime = now;
2323 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2330 public void batteryNeedsCpuUpdate() {
2331 updateCpuStatsNow();
2335 public void batteryPowerChanged(boolean onBattery) {
2336 // When plugging in, update the CPU stats first before changing
2338 updateCpuStatsNow();
2339 synchronized (this) {
2340 synchronized(mPidsSelfLocked) {
2341 mOnBattery = DEBUG_POWER ? true : onBattery;
2347 * Initialize the application bind args. These are passed to each
2348 * process when the bindApplication() IPC is sent to the process. They're
2349 * lazily setup to make sure the services are running when they're asked for.
2351 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2352 // Isolated processes won't get this optimization, so that we don't
2353 // violate the rules about which services they have access to.
2355 if (mIsolatedAppBindArgs == null) {
2356 mIsolatedAppBindArgs = new HashMap<>();
2357 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2359 return mIsolatedAppBindArgs;
2362 if (mAppBindArgs == null) {
2363 mAppBindArgs = new HashMap<>();
2365 // Setup the application init args
2366 mAppBindArgs.put("package", ServiceManager.getService("package"));
2367 mAppBindArgs.put("window", ServiceManager.getService("window"));
2368 mAppBindArgs.put(Context.ALARM_SERVICE,
2369 ServiceManager.getService(Context.ALARM_SERVICE));
2371 return mAppBindArgs;
2374 final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2375 if (mFocusedActivity != r) {
2376 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2377 mFocusedActivity = r;
2378 if (r.task != null && r.task.voiceInteractor != null) {
2379 startRunningVoiceLocked();
2381 finishRunningVoiceLocked();
2383 mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
2385 mWindowManager.setFocusedApp(r.appToken, true);
2387 applyUpdateLockStateLocked(r);
2389 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, mCurrentUserId,
2390 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2393 final void clearFocusedActivity(ActivityRecord r) {
2394 if (mFocusedActivity == r) {
2395 mFocusedActivity = null;
2400 public void setFocusedStack(int stackId) {
2401 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2402 synchronized (ActivityManagerService.this) {
2403 ActivityStack stack = mStackSupervisor.getStack(stackId);
2404 if (stack != null) {
2405 ActivityRecord r = stack.topRunningActivityLocked(null);
2407 setFocusedActivityLocked(r, "setFocusedStack");
2413 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2415 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2416 synchronized (ActivityManagerService.this) {
2417 if (listener != null) {
2418 mTaskStackListeners.register(listener);
2424 public void notifyActivityDrawn(IBinder token) {
2425 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2426 synchronized (this) {
2427 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2429 r.task.stack.notifyActivityDrawnLocked(r);
2434 final void applyUpdateLockStateLocked(ActivityRecord r) {
2435 // Modifications to the UpdateLock state are done on our handler, outside
2436 // the activity manager's locks. The new state is determined based on the
2437 // state *now* of the relevant activity record. The object is passed to
2438 // the handler solely for logging detail, not to be consulted/modified.
2439 final boolean nextState = r != null && r.immersive;
2440 mHandler.sendMessage(
2441 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2444 final void showAskCompatModeDialogLocked(ActivityRecord r) {
2445 Message msg = Message.obtain();
2446 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2447 msg.obj = r.task.askedCompatMode ? null : r;
2448 mHandler.sendMessage(msg);
2451 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2452 String what, Object obj, ProcessRecord srcApp) {
2453 app.lastActivityTime = now;
2455 if (app.activities.size() > 0) {
2456 // Don't want to touch dependent processes that are hosting activities.
2460 int lrui = mLruProcesses.lastIndexOf(app);
2462 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2463 + what + " " + obj + " from " + srcApp);
2467 if (lrui >= index) {
2468 // Don't want to cause this to move dependent processes *back* in the
2469 // list as if they were less frequently used.
2473 if (lrui >= mLruProcessActivityStart) {
2474 // Don't want to touch dependent processes that are hosting activities.
2478 mLruProcesses.remove(lrui);
2482 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2483 + " in LRU list: " + app);
2484 mLruProcesses.add(index, app);
2488 final void removeLruProcessLocked(ProcessRecord app) {
2489 int lrui = mLruProcesses.lastIndexOf(app);
2492 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2493 Process.killProcessQuiet(app.pid);
2494 Process.killProcessGroup(app.uid, app.pid);
2496 if (lrui <= mLruProcessActivityStart) {
2497 mLruProcessActivityStart--;
2499 if (lrui <= mLruProcessServiceStart) {
2500 mLruProcessServiceStart--;
2502 mLruProcesses.remove(lrui);
2506 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2507 ProcessRecord client) {
2508 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2509 || app.treatLikeActivity;
2510 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2511 if (!activityChange && hasActivity) {
2512 // The process has activities, so we are only allowing activity-based adjustments
2513 // to move it. It should be kept in the front of the list with other
2514 // processes that have activities, and we don't want those to change their
2515 // order except due to activity operations.
2520 final long now = SystemClock.uptimeMillis();
2521 app.lastActivityTime = now;
2523 // First a quick reject: if the app is already at the position we will
2524 // put it, then there is nothing to do.
2526 final int N = mLruProcesses.size();
2527 if (N > 0 && mLruProcesses.get(N-1) == app) {
2528 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2532 if (mLruProcessServiceStart > 0
2533 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2534 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2539 int lrui = mLruProcesses.lastIndexOf(app);
2541 if (app.persistent && lrui >= 0) {
2542 // We don't care about the position of persistent processes, as long as
2543 // they are in the list.
2544 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2548 /* In progress: compute new position first, so we can avoid doing work
2549 if the process is not actually going to move. Not yet working.
2552 boolean inActivity = false, inService = false;
2554 // Process has activities, put it at the very tipsy-top.
2555 addIndex = mLruProcesses.size();
2556 nextIndex = mLruProcessServiceStart;
2558 } else if (hasService) {
2559 // Process has services, put it at the top of the service list.
2560 addIndex = mLruProcessActivityStart;
2561 nextIndex = mLruProcessServiceStart;
2565 // Process not otherwise of interest, it goes to the top of the non-service area.
2566 addIndex = mLruProcessServiceStart;
2567 if (client != null) {
2568 int clientIndex = mLruProcesses.lastIndexOf(client);
2569 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2571 if (clientIndex >= 0 && addIndex > clientIndex) {
2572 addIndex = clientIndex;
2575 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2578 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2579 + mLruProcessActivityStart + "): " + app);
2583 if (lrui < mLruProcessActivityStart) {
2584 mLruProcessActivityStart--;
2586 if (lrui < mLruProcessServiceStart) {
2587 mLruProcessServiceStart--;
2590 if (addIndex > lrui) {
2593 if (nextIndex > lrui) {
2597 mLruProcesses.remove(lrui);
2601 mLruProcesses.add(addIndex, app);
2603 mLruProcessActivityStart++;
2606 mLruProcessActivityStart++;
2612 final int N = mLruProcesses.size();
2613 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2614 // Process doesn't have activities, but has clients with
2615 // activities... move it up, but one below the top (the top
2616 // should always have a real activity).
2617 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2618 mLruProcesses.add(N-1, app);
2619 // To keep it from spamming the LRU list (by making a bunch of clients),
2620 // we will push down any other entries owned by the app.
2621 final int uid = app.info.uid;
2622 for (int i=N-2; i>mLruProcessActivityStart; i--) {
2623 ProcessRecord subProc = mLruProcesses.get(i);
2624 if (subProc.info.uid == uid) {
2625 // We want to push this one down the list. If the process after
2626 // it is for the same uid, however, don't do so, because we don't
2627 // want them internally to be re-ordered.
2628 if (mLruProcesses.get(i-1).info.uid != uid) {
2629 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2630 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2631 ProcessRecord tmp = mLruProcesses.get(i);
2632 mLruProcesses.set(i, mLruProcesses.get(i-1));
2633 mLruProcesses.set(i-1, tmp);
2637 // A gap, we can stop here.
2642 // Process has activities, put it at the very tipsy-top.
2643 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2644 mLruProcesses.add(app);
2646 nextIndex = mLruProcessServiceStart;
2647 } else if (hasService) {
2648 // Process has services, put it at the top of the service list.
2649 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2650 mLruProcesses.add(mLruProcessActivityStart, app);
2651 nextIndex = mLruProcessServiceStart;
2652 mLruProcessActivityStart++;
2654 // Process not otherwise of interest, it goes to the top of the non-service area.
2655 int index = mLruProcessServiceStart;
2656 if (client != null) {
2657 // If there is a client, don't allow the process to be moved up higher
2658 // in the list than that client.
2659 int clientIndex = mLruProcesses.lastIndexOf(client);
2660 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2661 + " when updating " + app);
2662 if (clientIndex <= lrui) {
2663 // Don't allow the client index restriction to push it down farther in the
2664 // list than it already is.
2667 if (clientIndex >= 0 && index > clientIndex) {
2668 index = clientIndex;
2671 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2672 mLruProcesses.add(index, app);
2673 nextIndex = index-1;
2674 mLruProcessActivityStart++;
2675 mLruProcessServiceStart++;
2678 // If the app is currently using a content provider or service,
2679 // bump those processes as well.
2680 for (int j=app.connections.size()-1; j>=0; j--) {
2681 ConnectionRecord cr = app.connections.valueAt(j);
2682 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2683 && cr.binding.service.app != null
2684 && cr.binding.service.app.lruSeq != mLruSeq
2685 && !cr.binding.service.app.persistent) {
2686 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2687 "service connection", cr, app);
2690 for (int j=app.conProviders.size()-1; j>=0; j--) {
2691 ContentProviderRecord cpr = app.conProviders.get(j).provider;
2692 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2693 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2694 "provider reference", cpr, app);
2699 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2700 if (uid == Process.SYSTEM_UID) {
2701 // The system gets to run in any process. If there are multiple
2702 // processes with the same uid, just pick the first (this
2703 // should never happen).
2704 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2705 if (procs == null) return null;
2706 final int procCount = procs.size();
2707 for (int i = 0; i < procCount; i++) {
2708 final int procUid = procs.keyAt(i);
2709 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2710 // Don't use an app process or different user process for system component.
2713 return procs.valueAt(i);
2716 ProcessRecord proc = mProcessNames.get(processName, uid);
2717 if (false && proc != null && !keepIfLarge
2718 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2719 && proc.lastCachedPss >= 4000) {
2720 // Turn this condition on to cause killing to happen regularly, for testing.
2721 if (proc.baseProcessTracker != null) {
2722 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2724 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2725 } else if (proc != null && !keepIfLarge
2726 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2727 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2728 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2729 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2730 if (proc.baseProcessTracker != null) {
2731 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2733 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2739 void ensurePackageDexOpt(String packageName) {
2740 IPackageManager pm = AppGlobals.getPackageManager();
2742 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2745 } catch (RemoteException e) {
2749 boolean isNextTransitionForward() {
2750 int transit = mWindowManager.getPendingAppTransition();
2751 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2752 || transit == AppTransition.TRANSIT_TASK_OPEN
2753 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2756 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2757 String processName, String abiOverride, int uid, Runnable crashHandler) {
2758 synchronized(this) {
2759 ApplicationInfo info = new ApplicationInfo();
2760 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2761 // For isolated processes, the former contains the parent's uid and the latter the
2762 // actual uid of the isolated process.
2763 // In the special case introduced by this method (which is, starting an isolated
2764 // process directly from the SystemServer without an actual parent app process) the
2765 // closest thing to a parent's uid is SYSTEM_UID.
2766 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2767 // the |isolated| logic in the ProcessRecord constructor.
2768 info.uid = Process.SYSTEM_UID;
2769 info.processName = processName;
2770 info.className = entryPoint;
2771 info.packageName = "android";
2772 ProcessRecord proc = startProcessLocked(processName, info /* info */,
2773 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
2774 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2775 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2777 return proc != null ? proc.pid : 0;
2781 final ProcessRecord startProcessLocked(String processName,
2782 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2783 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2784 boolean isolated, boolean keepIfLarge) {
2785 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2786 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2787 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2788 null /* crashHandler */);
2791 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2792 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2793 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2794 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2795 long startTime = SystemClock.elapsedRealtime();
2798 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2799 checkTime(startTime, "startProcess: after getProcessRecord");
2801 // If this is an isolated process, it can't re-use an existing process.
2804 // We don't have to do anything more if:
2805 // (1) There is an existing application record; and
2806 // (2) The caller doesn't think it is dead, OR there is no thread
2807 // object attached to it so we know it couldn't have crashed; and
2808 // (3) There is a pid assigned to it, so it is either starting or
2810 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2811 + " app=" + app + " knownToBeDead=" + knownToBeDead
2812 + " thread=" + (app != null ? app.thread : null)
2813 + " pid=" + (app != null ? app.pid : -1));
2814 if (app != null && app.pid > 0) {
2815 if (!knownToBeDead || app.thread == null) {
2816 // We already have the app running, or are waiting for it to
2817 // come up (we have a pid but not yet its thread), so keep it.
2818 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2819 // If this is a new package in the process, add the package to the list
2820 app.addPackage(info.packageName, info.versionCode, mProcessStats);
2821 checkTime(startTime, "startProcess: done, added package to proc");
2825 // An application record is attached to a previous process,
2827 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2828 checkTime(startTime, "startProcess: bad proc running, killing");
2829 Process.killProcessGroup(app.uid, app.pid);
2830 handleAppDiedLocked(app, true, true);
2831 checkTime(startTime, "startProcess: done killing old proc");
2834 String hostingNameStr = hostingName != null
2835 ? hostingName.flattenToShortString() : null;
2838 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2839 // If we are in the background, then check to see if this process
2840 // is bad. If so, we will just silently fail.
2841 if (mBadProcesses.get(info.processName, info.uid) != null) {
2842 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2843 + "/" + info.processName);
2847 // When the user is explicitly starting a process, then clear its
2848 // crash count so that we won't make it bad until they see at
2849 // least one crash dialog again, and make the process good again
2850 // if it had been bad.
2851 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2852 + "/" + info.processName);
2853 mProcessCrashTimes.remove(info.processName, info.uid);
2854 if (mBadProcesses.get(info.processName, info.uid) != null) {
2855 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2856 UserHandle.getUserId(info.uid), info.uid,
2858 mBadProcesses.remove(info.processName, info.uid);
2867 checkTime(startTime, "startProcess: creating new process record");
2868 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2870 Slog.w(TAG, "Failed making new process record for "
2871 + processName + "/" + info.uid + " isolated=" + isolated);
2874 app.crashHandler = crashHandler;
2875 mProcessNames.put(processName, app.uid, app);
2877 mIsolatedProcesses.put(app.uid, app);
2879 checkTime(startTime, "startProcess: done creating new process record");
2881 // If this is a new package in the process, add the package to the list
2882 app.addPackage(info.packageName, info.versionCode, mProcessStats);
2883 checkTime(startTime, "startProcess: added package to existing proc");
2886 // If the system is not ready yet, then hold off on starting this
2887 // process until it is.
2888 if (!mProcessesReady
2889 && !isAllowedWhileBooting(info)
2890 && !allowWhileBooting) {
2891 if (!mProcessesOnHold.contains(app)) {
2892 mProcessesOnHold.add(app);
2894 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2895 checkTime(startTime, "startProcess: returning with proc on hold");
2899 checkTime(startTime, "startProcess: stepping in to startProcess");
2901 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2902 checkTime(startTime, "startProcess: done starting proc!");
2903 return (app.pid != 0) ? app : null;
2906 boolean isAllowedWhileBooting(ApplicationInfo ai) {
2907 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2910 private final void startProcessLocked(ProcessRecord app,
2911 String hostingType, String hostingNameStr) {
2912 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2913 null /* entryPoint */, null /* entryPointArgs */);
2916 private final void startProcessLocked(ProcessRecord app, String hostingType,
2917 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2918 long startTime = SystemClock.elapsedRealtime();
2919 if (app.pid > 0 && app.pid != MY_PID) {
2920 checkTime(startTime, "startProcess: removing from pids map");
2921 synchronized (mPidsSelfLocked) {
2922 mPidsSelfLocked.remove(app.pid);
2923 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2925 checkTime(startTime, "startProcess: done removing from pids map");
2929 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2930 "startProcessLocked removing on hold: " + app);
2931 mProcessesOnHold.remove(app);
2933 checkTime(startTime, "startProcess: starting to update cpu stats");
2935 checkTime(startTime, "startProcess: done updating cpu stats");
2941 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2942 if (!app.isolated) {
2943 int[] permGids = null;
2945 checkTime(startTime, "startProcess: getting gids from package manager");
2946 final PackageManager pm = mContext.getPackageManager();
2947 permGids = pm.getPackageGids(app.info.packageName);
2949 if (Environment.isExternalStorageEmulated()) {
2950 checkTime(startTime, "startProcess: checking external storage perm");
2951 if (pm.checkPermission(
2952 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2953 app.info.packageName) == PERMISSION_GRANTED) {
2954 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2956 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2959 } catch (PackageManager.NameNotFoundException e) {
2960 Slog.w(TAG, "Unable to retrieve gids", e);
2964 * Add shared application and profile GIDs so applications can share some
2965 * resources like shared libraries and access user-wide resources
2967 if (permGids == null) {
2970 gids = new int[permGids.length + 2];
2971 System.arraycopy(permGids, 0, gids, 2, permGids.length);
2973 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2974 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2976 checkTime(startTime, "startProcess: building args");
2977 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2978 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2979 && mTopComponent != null
2980 && app.processName.equals(mTopComponent.getPackageName())) {
2983 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2984 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2989 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2990 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2991 // Also turn on CheckJNI for debuggable apps. It's quite
2992 // awkward to turn on otherwise.
2993 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2995 // Run the app in safe mode if its manifest requests so or the
2996 // system is booted in safe mode.
2997 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2998 mSafeMode == true) {
2999 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3001 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3002 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3004 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3005 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3007 if ("1".equals(SystemProperties.get("debug.assert"))) {
3008 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3011 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3012 if (requiredAbi == null) {
3013 requiredAbi = Build.SUPPORTED_ABIS[0];
3016 String instructionSet = null;
3017 if (app.info.primaryCpuAbi != null) {
3018 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3022 app.requiredAbi = requiredAbi;
3023 app.instructionSet = instructionSet;
3025 // Start the process. It will either succeed and return a result containing
3026 // the PID of the new process, or else throw a RuntimeException.
3027 boolean isActivityProcess = (entryPoint == null);
3028 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3029 checkTime(startTime, "startProcess: asking zygote to start proc");
3030 Process.ProcessStartResult startResult = Process.start(entryPoint,
3031 app.processName, uid, uid, gids, debugFlags, mountExternal,
3032 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3033 app.info.dataDir, entryPointArgs);
3034 checkTime(startTime, "startProcess: returned from zygote!");
3037 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3039 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3040 checkTime(startTime, "startProcess: done updating battery stats");
3042 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3043 UserHandle.getUserId(uid), startResult.pid, uid,
3044 app.processName, hostingType,
3045 hostingNameStr != null ? hostingNameStr : "");
3047 if (app.persistent) {
3048 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3051 checkTime(startTime, "startProcess: building log message");
3052 StringBuilder buf = mStringBuilder;
3054 buf.append("Start proc ");
3055 buf.append(startResult.pid);
3057 buf.append(app.processName);
3059 UserHandle.formatUid(buf, uid);
3060 if (!isActivityProcess) {
3062 buf.append(entryPoint);
3065 buf.append(" for ");
3066 buf.append(hostingType);
3067 if (hostingNameStr != null) {
3069 buf.append(hostingNameStr);
3071 Slog.i(TAG, buf.toString());
3072 app.setPid(startResult.pid);
3073 app.usingWrapper = startResult.usingWrapper;
3074 app.removed = false;
3076 app.killedByAm = false;
3077 checkTime(startTime, "startProcess: starting to update pids map");
3078 ProcessRecord oldApp;
3079 synchronized (mPidsSelfLocked) {
3080 oldApp = mPidsSelfLocked.get(startResult.pid);
3082 // If there is already an app occupying that pid that hasn't been cleaned up
3083 if (oldApp != null && !app.isolated) {
3084 // Clean up anything relating to this pid first
3085 Slog.w(TAG, "Reusing pid " + startResult.pid
3086 + " while app is still mapped to it");
3087 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3088 true /*replacingPid*/);
3090 synchronized (mPidsSelfLocked) {
3091 this.mPidsSelfLocked.put(startResult.pid, app);
3092 if (isActivityProcess) {
3093 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3095 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3096 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3099 checkTime(startTime, "startProcess: done updating pids map");
3100 } catch (RuntimeException e) {
3101 // XXX do better error recovery.
3103 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3105 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3107 Slog.e(TAG, "Failure starting process " + app.processName, e);
3111 void updateUsageStats(ActivityRecord component, boolean resumed) {
3112 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3113 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3115 if (mUsageStatsService != null) {
3116 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3117 UsageEvents.Event.MOVE_TO_FOREGROUND);
3119 synchronized (stats) {
3120 stats.noteActivityResumedLocked(component.app.uid);
3123 if (mUsageStatsService != null) {
3124 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3125 UsageEvents.Event.MOVE_TO_BACKGROUND);
3127 synchronized (stats) {
3128 stats.noteActivityPausedLocked(component.app.uid);
3133 Intent getHomeIntent() {
3134 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3135 intent.setComponent(mTopComponent);
3136 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3137 intent.addCategory(Intent.CATEGORY_HOME);
3142 boolean startHomeActivityLocked(int userId, String reason) {
3143 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3144 && mTopAction == null) {
3145 // We are running in factory test mode, but unable to find
3146 // the factory test app, so just sit around displaying the
3147 // error message and don't try to start anything.
3150 Intent intent = getHomeIntent();
3151 ActivityInfo aInfo =
3152 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3153 if (aInfo != null) {
3154 intent.setComponent(new ComponentName(
3155 aInfo.applicationInfo.packageName, aInfo.name));
3156 // Don't do this if the home app is currently being
3158 aInfo = new ActivityInfo(aInfo);
3159 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3160 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3161 aInfo.applicationInfo.uid, true);
3162 if (app == null || app.instrumentationClass == null) {
3163 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3164 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3171 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3172 ActivityInfo ai = null;
3173 ComponentName comp = intent.getComponent();
3176 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3178 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3180 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3184 ai = info.activityInfo;
3187 } catch (RemoteException e) {
3195 * Starts the "new version setup screen" if appropriate.
3197 void startSetupActivityLocked() {
3198 // Only do this once per boot.
3199 if (mCheckedForSetup) {
3203 // We will show this screen if the current one is a different
3204 // version than the last one shown, and we are not running in
3205 // low-level factory test mode.
3206 final ContentResolver resolver = mContext.getContentResolver();
3207 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3208 Settings.Global.getInt(resolver,
3209 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3210 mCheckedForSetup = true;
3212 // See if we should be showing the platform update setup UI.
3213 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3214 List<ResolveInfo> ris = mContext.getPackageManager()
3215 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3217 // We don't allow third party apps to replace this.
3218 ResolveInfo ri = null;
3219 for (int i=0; ris != null && i<ris.size(); i++) {
3220 if ((ris.get(i).activityInfo.applicationInfo.flags
3221 & ApplicationInfo.FLAG_SYSTEM) != 0) {
3228 String vers = ri.activityInfo.metaData != null
3229 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3231 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3232 vers = ri.activityInfo.applicationInfo.metaData.getString(
3233 Intent.METADATA_SETUP_VERSION);
3235 String lastVers = Settings.Secure.getString(
3236 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3237 if (vers != null && !vers.equals(lastVers)) {
3238 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3239 intent.setComponent(new ComponentName(
3240 ri.activityInfo.packageName, ri.activityInfo.name));
3241 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3242 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3249 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3250 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3253 void enforceNotIsolatedCaller(String caller) {
3254 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3255 throw new SecurityException("Isolated process not allowed to call " + caller);
3259 void enforceShellRestriction(String restriction, int userHandle) {
3260 if (Binder.getCallingUid() == Process.SHELL_UID) {
3262 || mUserManager.hasUserRestriction(restriction, userHandle)) {
3263 throw new SecurityException("Shell does not have permission to access user "
3270 public int getFrontActivityScreenCompatMode() {
3271 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3272 synchronized (this) {
3273 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3278 public void setFrontActivityScreenCompatMode(int mode) {
3279 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3280 "setFrontActivityScreenCompatMode");
3281 synchronized (this) {
3282 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3287 public int getPackageScreenCompatMode(String packageName) {
3288 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3289 synchronized (this) {
3290 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3295 public void setPackageScreenCompatMode(String packageName, int mode) {
3296 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3297 "setPackageScreenCompatMode");
3298 synchronized (this) {
3299 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3304 public boolean getPackageAskScreenCompat(String packageName) {
3305 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3306 synchronized (this) {
3307 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3312 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3313 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3314 "setPackageAskScreenCompat");
3315 synchronized (this) {
3316 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3320 private void dispatchProcessesChanged() {
3322 synchronized (this) {
3323 N = mPendingProcessChanges.size();
3324 if (mActiveProcessChanges.length < N) {
3325 mActiveProcessChanges = new ProcessChangeItem[N];
3327 mPendingProcessChanges.toArray(mActiveProcessChanges);
3328 mAvailProcessChanges.addAll(mPendingProcessChanges);
3329 mPendingProcessChanges.clear();
3330 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3333 int i = mProcessObservers.beginBroadcast();
3336 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3337 if (observer != null) {
3339 for (int j=0; j<N; j++) {
3340 ProcessChangeItem item = mActiveProcessChanges[j];
3341 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3342 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3343 + item.pid + " uid=" + item.uid + ": "
3344 + item.foregroundActivities);
3345 observer.onForegroundActivitiesChanged(item.pid, item.uid,
3346 item.foregroundActivities);
3348 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3349 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3350 + item.pid + " uid=" + item.uid + ": " + item.processState);
3351 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3354 } catch (RemoteException e) {
3358 mProcessObservers.finishBroadcast();
3361 private void dispatchProcessDied(int pid, int uid) {
3362 int i = mProcessObservers.beginBroadcast();
3365 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3366 if (observer != null) {
3368 observer.onProcessDied(pid, uid);
3369 } catch (RemoteException e) {
3373 mProcessObservers.finishBroadcast();
3377 public final int startActivity(IApplicationThread caller, String callingPackage,
3378 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3379 int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3380 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3381 resultWho, requestCode, startFlags, profilerInfo, options,
3382 UserHandle.getCallingUserId());
3386 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3387 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3388 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3389 enforceNotIsolatedCaller("startActivity");
3390 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3391 false, ALLOW_FULL_ONLY, "startActivity", null);
3392 // TODO: Switch to user app stacks here.
3393 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3394 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3395 profilerInfo, null, null, options, userId, null, null);
3399 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3400 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3401 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3403 // This is very dangerous -- it allows you to perform a start activity (including
3404 // permission grants) as any app that may launch one of your own activities. So
3405 // we will only allow this to be done from activities that are part of the core framework,
3406 // and then only when they are running as the system.
3407 final ActivityRecord sourceRecord;
3408 final int targetUid;
3409 final String targetPackage;
3410 synchronized (this) {
3411 if (resultTo == null) {
3412 throw new SecurityException("Must be called from an activity");
3414 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3415 if (sourceRecord == null) {
3416 throw new SecurityException("Called with bad activity token: " + resultTo);
3418 if (!sourceRecord.info.packageName.equals("android")) {
3419 throw new SecurityException(
3420 "Must be called from an activity that is declared in the android package");
3422 if (sourceRecord.app == null) {
3423 throw new SecurityException("Called without a process attached to activity");
3425 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3426 // This is still okay, as long as this activity is running under the
3427 // uid of the original calling activity.
3428 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3429 throw new SecurityException(
3430 "Calling activity in uid " + sourceRecord.app.uid
3431 + " must be system uid or original calling uid "
3432 + sourceRecord.launchedFromUid);
3435 targetUid = sourceRecord.launchedFromUid;
3436 targetPackage = sourceRecord.launchedFromPackage;
3439 if (userId == UserHandle.USER_NULL) {
3440 userId = UserHandle.getUserId(sourceRecord.app.uid);
3443 // TODO: Switch to user app stacks here.
3445 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3446 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3447 null, null, options, userId, null, null);
3449 } catch (SecurityException e) {
3450 // XXX need to figure out how to propagate to original app.
3451 // A SecurityException here is generally actually a fault of the original
3452 // calling activity (such as a fairly granting permissions), so propagate it
3455 StringBuilder msg = new StringBuilder();
3456 msg.append("While launching");
3457 msg.append(intent.toString());
3459 msg.append(e.getMessage());
3466 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3467 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3468 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3469 enforceNotIsolatedCaller("startActivityAndWait");
3470 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3471 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3472 WaitResult res = new WaitResult();
3473 // TODO: Switch to user app stacks here.
3474 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3475 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3476 options, userId, null, null);
3481 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3482 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3483 int startFlags, Configuration config, Bundle options, int userId) {
3484 enforceNotIsolatedCaller("startActivityWithConfig");
3485 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3486 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3487 // TODO: Switch to user app stacks here.
3488 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3489 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3490 null, null, config, options, userId, null, null);
3495 public int startActivityIntentSender(IApplicationThread caller,
3496 IntentSender intent, Intent fillInIntent, String resolvedType,
3497 IBinder resultTo, String resultWho, int requestCode,
3498 int flagsMask, int flagsValues, Bundle options) {
3499 enforceNotIsolatedCaller("startActivityIntentSender");
3500 // Refuse possible leaked file descriptors
3501 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3502 throw new IllegalArgumentException("File descriptors passed in Intent");
3505 IIntentSender sender = intent.getTarget();
3506 if (!(sender instanceof PendingIntentRecord)) {
3507 throw new IllegalArgumentException("Bad PendingIntent object");
3510 PendingIntentRecord pir = (PendingIntentRecord)sender;
3512 synchronized (this) {
3513 // If this is coming from the currently resumed activity, it is
3514 // effectively saying that app switches are allowed at this point.
3515 final ActivityStack stack = getFocusedStack();
3516 if (stack.mResumedActivity != null &&
3517 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3518 mAppSwitchesAllowedTime = 0;
3521 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3522 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3527 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3528 Intent intent, String resolvedType, IVoiceInteractionSession session,
3529 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3530 Bundle options, int userId) {
3531 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3532 != PackageManager.PERMISSION_GRANTED) {
3533 String msg = "Permission Denial: startVoiceActivity() from pid="
3534 + Binder.getCallingPid()
3535 + ", uid=" + Binder.getCallingUid()
3536 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3538 throw new SecurityException(msg);
3540 if (session == null || interactor == null) {
3541 throw new NullPointerException("null session or interactor");
3543 userId = handleIncomingUser(callingPid, callingUid, userId,
3544 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3545 // TODO: Switch to user app stacks here.
3546 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3547 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3548 null, options, userId, null, null);
3552 public boolean startNextMatchingActivity(IBinder callingActivity,
3553 Intent intent, Bundle options) {
3554 // Refuse possible leaked file descriptors
3555 if (intent != null && intent.hasFileDescriptors() == true) {
3556 throw new IllegalArgumentException("File descriptors passed in Intent");
3559 synchronized (this) {
3560 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3562 ActivityOptions.abort(options);
3565 if (r.app == null || r.app.thread == null) {
3566 // The caller is not running... d'oh!
3567 ActivityOptions.abort(options);
3570 intent = new Intent(intent);
3571 // The caller is not allowed to change the data.
3572 intent.setDataAndType(r.intent.getData(), r.intent.getType());
3573 // And we are resetting to find the next component...
3574 intent.setComponent(null);
3576 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3578 ActivityInfo aInfo = null;
3580 List<ResolveInfo> resolves =
3581 AppGlobals.getPackageManager().queryIntentActivities(
3582 intent, r.resolvedType,
3583 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3584 UserHandle.getCallingUserId());
3586 // Look for the original activity in the list...
3587 final int N = resolves != null ? resolves.size() : 0;
3588 for (int i=0; i<N; i++) {
3589 ResolveInfo rInfo = resolves.get(i);
3590 if (rInfo.activityInfo.packageName.equals(r.packageName)
3591 && rInfo.activityInfo.name.equals(r.info.name)) {
3592 // We found the current one... the next matching is
3596 aInfo = resolves.get(i).activityInfo;
3599 Slog.v(TAG, "Next matching activity: found current " + r.packageName
3600 + "/" + r.info.name);
3601 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3602 + "/" + aInfo.name);
3607 } catch (RemoteException e) {
3610 if (aInfo == null) {
3611 // Nobody who is next!
3612 ActivityOptions.abort(options);
3613 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3617 intent.setComponent(new ComponentName(
3618 aInfo.applicationInfo.packageName, aInfo.name));
3619 intent.setFlags(intent.getFlags()&~(
3620 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3621 Intent.FLAG_ACTIVITY_CLEAR_TOP|
3622 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3623 Intent.FLAG_ACTIVITY_NEW_TASK));
3625 // Okay now we need to start the new activity, replacing the
3626 // currently running activity. This is a little tricky because
3627 // we want to start the new one as if the current one is finished,
3628 // but not finish the current one first so that there is no flicker.
3630 final boolean wasFinishing = r.finishing;
3633 // Propagate reply information over to the new activity.
3634 final ActivityRecord resultTo = r.resultTo;
3635 final String resultWho = r.resultWho;
3636 final int requestCode = r.requestCode;
3638 if (resultTo != null) {
3639 resultTo.removeResultsLocked(r, resultWho, requestCode);
3642 final long origId = Binder.clearCallingIdentity();
3643 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3644 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3645 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3646 -1, r.launchedFromUid, 0, options, false, null, null, null);
3647 Binder.restoreCallingIdentity(origId);
3649 r.finishing = wasFinishing;
3650 if (res != ActivityManager.START_SUCCESS) {
3658 public final int startActivityFromRecents(int taskId, Bundle options) {
3659 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3660 String msg = "Permission Denial: startActivityFromRecents called without " +
3661 START_TASKS_FROM_RECENTS;
3663 throw new SecurityException(msg);
3665 return startActivityFromRecentsInner(taskId, options);
3668 final int startActivityFromRecentsInner(int taskId, Bundle options) {
3669 final TaskRecord task;
3670 final int callingUid;
3671 final String callingPackage;
3672 final Intent intent;
3674 synchronized (this) {
3675 task = recentTaskForIdLocked(taskId);
3677 throw new IllegalArgumentException("Task " + taskId + " not found.");
3679 if (task.getRootActivity() != null) {
3680 moveTaskToFrontLocked(task.taskId, 0, null);
3681 return ActivityManager.START_TASK_TO_FRONT;
3683 callingUid = task.mCallingUid;
3684 callingPackage = task.mCallingPackage;
3685 intent = task.intent;
3686 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3687 userId = task.userId;
3689 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3690 options, userId, null, task);
3693 final int startActivityInPackage(int uid, String callingPackage,
3694 Intent intent, String resolvedType, IBinder resultTo,
3695 String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3696 IActivityContainer container, TaskRecord inTask) {
3698 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3699 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3701 // TODO: Switch to user app stacks here.
3702 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3703 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3704 null, null, null, options, userId, container, inTask);
3709 public final int startActivities(IApplicationThread caller, String callingPackage,
3710 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3712 enforceNotIsolatedCaller("startActivities");
3713 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3714 false, ALLOW_FULL_ONLY, "startActivity", null);
3715 // TODO: Switch to user app stacks here.
3716 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3717 resolvedTypes, resultTo, options, userId);
3721 final int startActivitiesInPackage(int uid, String callingPackage,
3722 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3723 Bundle options, int userId) {
3725 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3726 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3727 // TODO: Switch to user app stacks here.
3728 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3729 resultTo, options, userId);
3733 //explicitly remove thd old information in mRecentTasks when removing existing user.
3734 private void removeRecentTasksForUserLocked(int userId) {
3736 Slog.i(TAG, "Can't remove recent task on user " + userId);
3740 for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3741 TaskRecord tr = mRecentTasks.get(i);
3742 if (tr.userId == userId) {
3743 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3744 + " when finishing user" + userId);
3745 mRecentTasks.remove(i);
3746 tr.removedFromRecents();
3750 // Remove tasks from persistent storage.
3751 notifyTaskPersisterLocked(null, true);
3755 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3757 public int compare(TaskRecord lhs, TaskRecord rhs) {
3758 return rhs.taskId - lhs.taskId;
3762 // Extract the affiliates of the chain containing mRecentTasks[start].
3763 private int processNextAffiliateChainLocked(int start) {
3764 final TaskRecord startTask = mRecentTasks.get(start);
3765 final int affiliateId = startTask.mAffiliatedTaskId;
3767 // Quick identification of isolated tasks. I.e. those not launched behind.
3768 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3769 startTask.mNextAffiliate == null) {
3770 // There is still a slim chance that there are other tasks that point to this task
3771 // and that the chain is so messed up that this task no longer points to them but
3772 // the gain of this optimization outweighs the risk.
3773 startTask.inRecents = true;
3777 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3778 mTmpRecents.clear();
3779 for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3780 final TaskRecord task = mRecentTasks.get(i);
3781 if (task.mAffiliatedTaskId == affiliateId) {
3782 mRecentTasks.remove(i);
3783 mTmpRecents.add(task);
3787 // Sort them all by taskId. That is the order they were create in and that order will
3788 // always be correct.
3789 Collections.sort(mTmpRecents, mTaskRecordComparator);
3791 // Go through and fix up the linked list.
3792 // The first one is the end of the chain and has no next.
3793 final TaskRecord first = mTmpRecents.get(0);
3794 first.inRecents = true;
3795 if (first.mNextAffiliate != null) {
3796 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3797 first.setNextAffiliate(null);
3798 notifyTaskPersisterLocked(first, false);
3800 // Everything in the middle is doubly linked from next to prev.
3801 final int tmpSize = mTmpRecents.size();
3802 for (int i = 0; i < tmpSize - 1; ++i) {
3803 final TaskRecord next = mTmpRecents.get(i);
3804 final TaskRecord prev = mTmpRecents.get(i + 1);
3805 if (next.mPrevAffiliate != prev) {
3806 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3807 " setting prev=" + prev);
3808 next.setPrevAffiliate(prev);
3809 notifyTaskPersisterLocked(next, false);
3811 if (prev.mNextAffiliate != next) {
3812 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3813 " setting next=" + next);
3814 prev.setNextAffiliate(next);
3815 notifyTaskPersisterLocked(prev, false);
3817 prev.inRecents = true;
3819 // The last one is the beginning of the list and has no prev.
3820 final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3821 if (last.mPrevAffiliate != null) {
3822 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3823 last.setPrevAffiliate(null);
3824 notifyTaskPersisterLocked(last, false);
3827 // Insert the group back into mRecentTasks at start.
3828 mRecentTasks.addAll(start, mTmpRecents);
3830 // Let the caller know where we left off.
3831 return start + tmpSize;
3835 * Update the recent tasks lists: make sure tasks should still be here (their
3836 * applications / activities still exist), update their availability, fixup ordering
3839 void cleanupRecentTasksLocked(int userId) {
3840 if (mRecentTasks == null) {
3841 // Happens when called from the packagemanager broadcast before boot.
3845 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3846 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3847 final IPackageManager pm = AppGlobals.getPackageManager();
3848 final ActivityInfo dummyAct = new ActivityInfo();
3849 final ApplicationInfo dummyApp = new ApplicationInfo();
3851 int N = mRecentTasks.size();
3853 int[] users = userId == UserHandle.USER_ALL
3854 ? getUsersLocked() : new int[] { userId };
3855 for (int user : users) {
3856 for (int i = 0; i < N; i++) {
3857 TaskRecord task = mRecentTasks.get(i);
3858 if (task.userId != user) {
3859 // Only look at tasks for the user ID of interest.
3862 if (task.autoRemoveRecents && task.getTopActivity() == null) {
3863 // This situation is broken, and we should just get rid of it now.
3864 mRecentTasks.remove(i);
3865 task.removedFromRecents();
3868 Slog.w(TAG, "Removing auto-remove without activity: " + task);
3871 // Check whether this activity is currently available.
3872 if (task.realActivity != null) {
3873 ActivityInfo ai = availActCache.get(task.realActivity);
3876 ai = pm.getActivityInfo(task.realActivity,
3877 PackageManager.GET_UNINSTALLED_PACKAGES
3878 | PackageManager.GET_DISABLED_COMPONENTS, user);
3879 } catch (RemoteException e) {
3880 // Will never happen.
3886 availActCache.put(task.realActivity, ai);
3888 if (ai == dummyAct) {
3889 // This could be either because the activity no longer exists, or the
3890 // app is temporarily gone. For the former we want to remove the recents
3891 // entry; for the latter we want to mark it as unavailable.
3892 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3895 app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3896 PackageManager.GET_UNINSTALLED_PACKAGES
3897 | PackageManager.GET_DISABLED_COMPONENTS, user);
3898 } catch (RemoteException e) {
3899 // Will never happen.
3905 availAppCache.put(task.realActivity.getPackageName(), app);
3907 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3908 // Doesn't exist any more! Good-bye.
3909 mRecentTasks.remove(i);
3910 task.removedFromRecents();
3913 Slog.w(TAG, "Removing no longer valid recent: " + task);
3916 // Otherwise just not available for now.
3917 if (task.isAvailable) {
3918 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3921 task.isAvailable = false;
3924 if (!ai.enabled || !ai.applicationInfo.enabled
3925 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3926 if (task.isAvailable) {
3927 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3928 + task + " (enabled=" + ai.enabled + "/"
3929 + ai.applicationInfo.enabled + " flags="
3930 + Integer.toHexString(ai.applicationInfo.flags) + ")");
3932 task.isAvailable = false;
3934 if (!task.isAvailable) {
3935 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3938 task.isAvailable = true;
3945 // Verify the affiliate chain for each task.
3946 for (int i = 0; i < N; i = processNextAffiliateChainLocked(i)) {
3949 mTmpRecents.clear();
3950 // mRecentTasks is now in sorted, affiliated order.
3953 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3954 int N = mRecentTasks.size();
3955 TaskRecord top = task;
3956 int topIndex = taskIndex;
3957 while (top.mNextAffiliate != null && topIndex > 0) {
3958 top = top.mNextAffiliate;
3961 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3962 + topIndex + " from intial " + taskIndex);
3963 // Find the end of the chain, doing a sanity check along the way.
3964 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3965 int endIndex = topIndex;
3966 TaskRecord prev = top;
3967 while (endIndex < N) {
3968 TaskRecord cur = mRecentTasks.get(endIndex);
3969 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3970 + endIndex + " " + cur);
3972 // Verify start of the chain.
3973 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != INVALID_TASK_ID) {
3974 Slog.wtf(TAG, "Bad chain @" + endIndex
3975 + ": first task has next affiliate: " + prev);
3980 // Verify middle of the chain's next points back to the one before.
3981 if (cur.mNextAffiliate != prev
3982 || cur.mNextAffiliateTaskId != prev.taskId) {
3983 Slog.wtf(TAG, "Bad chain @" + endIndex
3984 + ": middle task " + cur + " @" + endIndex
3985 + " has bad next affiliate "
3986 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
3987 + ", expected " + prev);
3992 if (cur.mPrevAffiliateTaskId == INVALID_TASK_ID) {
3994 if (cur.mPrevAffiliate != null) {
3995 Slog.wtf(TAG, "Bad chain @" + endIndex
3996 + ": last task " + cur + " has previous affiliate "
3997 + cur.mPrevAffiliate);
4000 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4003 // Verify middle of the chain's prev points to a valid item.
4004 if (cur.mPrevAffiliate == null) {
4005 Slog.wtf(TAG, "Bad chain @" + endIndex
4006 + ": task " + cur + " has previous affiliate "
4007 + cur.mPrevAffiliate + " but should be id "
4008 + cur.mPrevAffiliate);
4013 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4014 Slog.wtf(TAG, "Bad chain @" + endIndex
4015 + ": task " + cur + " has affiliated id "
4016 + cur.mAffiliatedTaskId + " but should be "
4017 + task.mAffiliatedTaskId);
4023 if (endIndex >= N) {
4024 Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4025 + ": last task " + prev);
4031 if (endIndex < taskIndex) {
4032 Slog.wtf(TAG, "Bad chain @" + endIndex
4033 + ": did not extend to task " + task + " @" + taskIndex);
4038 // All looks good, we can just move all of the affiliated tasks
4040 for (int i=topIndex; i<=endIndex; i++) {
4041 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4042 + " from " + i + " to " + (i-topIndex));
4043 TaskRecord cur = mRecentTasks.remove(i);
4044 mRecentTasks.add(i-topIndex, cur);
4046 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex
4047 + " to " + endIndex);
4051 // Whoops, couldn't do it.
4055 final void addRecentTaskLocked(TaskRecord task) {
4056 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4057 || task.mNextAffiliateTaskId != INVALID_TASK_ID
4058 || task.mPrevAffiliateTaskId != INVALID_TASK_ID;
4060 int N = mRecentTasks.size();
4061 // Quick case: check if the top-most recent task is the same.
4062 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4063 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4066 // Another quick case: check if this is part of a set of affiliated
4067 // tasks that are at the top.
4068 if (isAffiliated && N > 0 && task.inRecents
4069 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4070 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4071 + " at top when adding " + task);
4074 // Another quick case: never add voice sessions.
4075 if (task.voiceSession != null) {
4076 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4080 boolean needAffiliationFix = false;
4082 // Slightly less quick case: the task is already in recents, so all we need
4083 // to do is move it.
4084 if (task.inRecents) {
4085 int taskIndex = mRecentTasks.indexOf(task);
4086 if (taskIndex >= 0) {
4087 if (!isAffiliated) {
4088 // Simple case: this is not an affiliated task, so we just move it to the front.
4089 mRecentTasks.remove(taskIndex);
4090 mRecentTasks.add(0, task);
4091 notifyTaskPersisterLocked(task, false);
4092 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4093 + " from " + taskIndex);
4096 // More complicated: need to keep all affiliated tasks together.
4097 if (moveAffiliatedTasksToFront(task, taskIndex)) {
4102 // Uh oh... something bad in the affiliation chain, try to rebuild
4103 // everything and then go through our general path of adding a new task.
4104 needAffiliationFix = true;
4107 Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4108 needAffiliationFix = true;
4112 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4113 trimRecentsForTaskLocked(task, true);
4115 N = mRecentTasks.size();
4116 while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4117 final TaskRecord tr = mRecentTasks.remove(N - 1);
4118 tr.removedFromRecents();
4121 task.inRecents = true;
4122 if (!isAffiliated || needAffiliationFix) {
4123 // If this is a simple non-affiliated task, or we had some failure trying to
4124 // handle it as part of an affilated task, then just place it at the top.
4125 mRecentTasks.add(0, task);
4126 } else if (isAffiliated) {
4127 // If this is a new affiliated task, then move all of the affiliated tasks
4128 // to the front and insert this new one.
4129 TaskRecord other = task.mNextAffiliate;
4130 if (other == null) {
4131 other = task.mPrevAffiliate;
4133 if (other != null) {
4134 int otherIndex = mRecentTasks.indexOf(other);
4135 if (otherIndex >= 0) {
4136 // Insert new task at appropriate location.
4138 if (other == task.mNextAffiliate) {
4139 // We found the index of our next affiliation, which is who is
4140 // before us in the list, so add after that point.
4141 taskIndex = otherIndex+1;
4143 // We found the index of our previous affiliation, which is who is
4144 // after us in the list, so add at their position.
4145 taskIndex = otherIndex;
4147 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4148 + taskIndex + ": " + task);
4149 mRecentTasks.add(taskIndex, task);
4151 // Now move everything to the front.
4152 if (moveAffiliatedTasksToFront(task, taskIndex)) {
4157 // Uh oh... something bad in the affiliation chain, try to rebuild
4158 // everything and then go through our general path of adding a new task.
4159 needAffiliationFix = true;
4161 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4163 needAffiliationFix = true;
4166 if (DEBUG_RECENTS) Slog.d(TAG,
4167 "addRecent: adding affiliated task without next/prev:" + task);
4168 needAffiliationFix = true;
4171 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4173 if (needAffiliationFix) {
4174 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4175 cleanupRecentTasksLocked(task.userId);
4180 * If needed, remove oldest existing entries in recents that are for the same kind
4181 * of task as the given one.
4183 int trimRecentsForTaskLocked(TaskRecord task, boolean doTrim) {
4184 int N = mRecentTasks.size();
4185 final Intent intent = task.intent;
4186 final boolean document = intent != null && intent.isDocument();
4188 int maxRecents = task.maxRecents - 1;
4189 for (int i=0; i<N; i++) {
4190 final TaskRecord tr = mRecentTasks.get(i);
4192 if (task.userId != tr.userId) {
4195 if (i > MAX_RECENT_BITMAPS) {
4196 tr.freeLastThumbnail();
4198 final Intent trIntent = tr.intent;
4199 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4200 (intent == null || !intent.filterEquals(trIntent))) {
4203 final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4204 if (document && trIsDocument) {
4205 // These are the same document activity (not necessarily the same doc).
4206 if (maxRecents > 0) {
4210 // Hit the maximum number of documents for this task. Fall through
4211 // and remove this document from recents.
4212 } else if (document || trIsDocument) {
4213 // Only one of these is a document. Not the droid we're looking for.
4219 // If the caller is not actually asking for a trim, just tell them we reached
4220 // a point where the trim would happen.
4224 // Either task and tr are the same or, their affinities match or their intents match
4225 // and neither of them is a document, or they are documents using the same activity
4226 // and their maxRecents has been reached.
4227 tr.disposeThumbnail();
4228 mRecentTasks.remove(i);
4230 tr.removedFromRecents();
4234 if (task.intent == null) {
4235 // If the new recent task we are adding is not fully
4236 // specified, then replace it with the existing recent task.
4239 notifyTaskPersisterLocked(tr, false);
4246 public void reportActivityFullyDrawn(IBinder token) {
4247 synchronized (this) {
4248 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4252 r.reportFullyDrawnLocked();
4257 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4258 synchronized (this) {
4259 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4263 final long origId = Binder.clearCallingIdentity();
4264 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4265 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4266 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4267 if (config != null) {
4268 r.frozenBeforeDestroy = true;
4269 if (!updateConfigurationLocked(config, r, false, false)) {
4270 mStackSupervisor.resumeTopActivitiesLocked();
4273 Binder.restoreCallingIdentity(origId);
4278 public int getRequestedOrientation(IBinder token) {
4279 synchronized (this) {
4280 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4282 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4284 return mWindowManager.getAppOrientation(r.appToken);
4289 * This is the internal entry point for handling Activity.finish().
4291 * @param token The Binder token referencing the Activity we want to finish.
4292 * @param resultCode Result code, if any, from this Activity.
4293 * @param resultData Result data (Intent), if any, from this Activity.
4294 * @param finishTask Whether to finish the task associated with this Activity. Only applies to
4295 * the root Activity in the task.
4297 * @return Returns true if the activity successfully finished, or false if it is still running.
4300 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4301 boolean finishTask) {
4302 // Refuse possible leaked file descriptors
4303 if (resultData != null && resultData.hasFileDescriptors() == true) {
4304 throw new IllegalArgumentException("File descriptors passed in Intent");
4307 synchronized(this) {
4308 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4312 // Keep track of the root activity of the task before we finish it
4313 TaskRecord tr = r.task;
4314 ActivityRecord rootR = tr.getRootActivity();
4315 if (rootR == null) {
4316 Slog.w(TAG, "Finishing task with all activities already finished");
4318 // Do not allow task to finish in Lock Task mode.
4319 if (tr == mStackSupervisor.mLockTaskModeTask) {
4321 Slog.i(TAG, "Not finishing task in lock task mode");
4322 mStackSupervisor.showLockTaskToast();
4326 if (mController != null) {
4327 // Find the first activity that is not finishing.
4328 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4330 // ask watcher if this is allowed
4331 boolean resumeOK = true;
4333 resumeOK = mController.activityResuming(next.packageName);
4334 } catch (RemoteException e) {
4336 Watchdog.getInstance().setActivityController(null);
4340 Slog.i(TAG, "Not finishing activity because controller resumed");
4345 final long origId = Binder.clearCallingIdentity();
4348 if (finishTask && r == rootR) {
4349 // If requested, remove the task that is associated to this activity only if it
4350 // was the root activity in the task. The result code and data is ignored
4351 // because we don't support returning them across task boundaries.
4352 res = removeTaskByIdLocked(tr.taskId, false);
4354 Slog.i(TAG, "Removing task failed to finish activity");
4357 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4358 resultData, "app-request", true);
4360 Slog.i(TAG, "Failed to finish by app-request");
4365 Binder.restoreCallingIdentity(origId);
4371 public final void finishHeavyWeightApp() {
4372 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4373 != PackageManager.PERMISSION_GRANTED) {
4374 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4375 + Binder.getCallingPid()
4376 + ", uid=" + Binder.getCallingUid()
4377 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4379 throw new SecurityException(msg);
4382 synchronized(this) {
4383 if (mHeavyWeightProcess == null) {
4387 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4388 mHeavyWeightProcess.activities);
4389 for (int i=0; i<activities.size(); i++) {
4390 ActivityRecord r = activities.get(i);
4392 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4393 null, "finish-heavy", true);
4397 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4398 mHeavyWeightProcess.userId, 0));
4399 mHeavyWeightProcess = null;
4404 public void crashApplication(int uid, int initialPid, String packageName,
4406 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4407 != PackageManager.PERMISSION_GRANTED) {
4408 String msg = "Permission Denial: crashApplication() from pid="
4409 + Binder.getCallingPid()
4410 + ", uid=" + Binder.getCallingUid()
4411 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4413 throw new SecurityException(msg);
4416 synchronized(this) {
4417 ProcessRecord proc = null;
4419 // Figure out which process to kill. We don't trust that initialPid
4420 // still has any relation to current pids, so must scan through the
4422 synchronized (mPidsSelfLocked) {
4423 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4424 ProcessRecord p = mPidsSelfLocked.valueAt(i);
4428 if (p.pid == initialPid) {
4432 if (p.pkgList.containsKey(packageName)) {
4439 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4440 + " initialPid=" + initialPid
4441 + " packageName=" + packageName);
4445 if (proc.thread != null) {
4446 if (proc.pid == Process.myPid()) {
4447 Log.w(TAG, "crashApplication: trying to crash self!");
4450 long ident = Binder.clearCallingIdentity();
4452 proc.thread.scheduleCrash(message);
4453 } catch (RemoteException e) {
4455 Binder.restoreCallingIdentity(ident);
4461 public final void finishSubActivity(IBinder token, String resultWho,
4463 synchronized(this) {
4464 final long origId = Binder.clearCallingIdentity();
4465 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4467 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4469 Binder.restoreCallingIdentity(origId);
4474 public boolean finishActivityAffinity(IBinder token) {
4475 synchronized(this) {
4476 final long origId = Binder.clearCallingIdentity();
4478 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4480 ActivityRecord rootR = r.task.getRootActivity();
4481 // Do not allow task to finish in Lock Task mode.
4482 if (r.task == mStackSupervisor.mLockTaskModeTask) {
4484 mStackSupervisor.showLockTaskToast();
4488 boolean res = false;
4490 res = r.task.stack.finishActivityAffinityLocked(r);
4494 Binder.restoreCallingIdentity(origId);
4500 public void finishVoiceTask(IVoiceInteractionSession session) {
4501 synchronized(this) {
4502 final long origId = Binder.clearCallingIdentity();
4504 mStackSupervisor.finishVoiceTask(session);
4506 Binder.restoreCallingIdentity(origId);
4513 public boolean releaseActivityInstance(IBinder token) {
4514 synchronized(this) {
4515 final long origId = Binder.clearCallingIdentity();
4517 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4518 if (r.task == null || r.task.stack == null) {
4521 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4523 Binder.restoreCallingIdentity(origId);
4529 public void releaseSomeActivities(IApplicationThread appInt) {
4530 synchronized(this) {
4531 final long origId = Binder.clearCallingIdentity();
4533 ProcessRecord app = getRecordForAppLocked(appInt);
4534 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4536 Binder.restoreCallingIdentity(origId);
4542 public boolean willActivityBeVisible(IBinder token) {
4543 synchronized(this) {
4544 ActivityStack stack = ActivityRecord.getStackLocked(token);
4545 if (stack != null) {
4546 return stack.willActivityBeVisibleLocked(token);
4553 public void overridePendingTransition(IBinder token, String packageName,
4554 int enterAnim, int exitAnim) {
4555 synchronized(this) {
4556 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4561 final long origId = Binder.clearCallingIdentity();
4563 if (self.state == ActivityState.RESUMED
4564 || self.state == ActivityState.PAUSING) {
4565 mWindowManager.overridePendingAppTransition(packageName,
4566 enterAnim, exitAnim, null);
4569 Binder.restoreCallingIdentity(origId);
4574 * Main function for removing an existing process from the activity manager
4575 * as a result of that process going away. Clears out all connections
4578 private final void handleAppDiedLocked(ProcessRecord app,
4579 boolean restarting, boolean allowRestart) {
4581 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
4582 false /*replacingPid*/);
4583 if (!kept && !restarting) {
4584 removeLruProcessLocked(app);
4586 ProcessList.remove(pid);
4590 if (mProfileProc == app) {
4591 clearProfilerLocked();
4594 // Remove this application's activities from active lists.
4595 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4597 app.activities.clear();
4599 if (app.instrumentationClass != null) {
4600 Slog.w(TAG, "Crash of app " + app.processName
4601 + " running instrumentation " + app.instrumentationClass);
4602 Bundle info = new Bundle();
4603 info.putString("shortMsg", "Process crashed.");
4604 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4608 if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4609 // If there was nothing to resume, and we are not already
4610 // restarting this process, but there is a visible activity that
4611 // is hosted by the process... then make sure all visible
4612 // activities are running, taking care of restarting this
4614 if (hasVisibleActivities) {
4615 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4621 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4622 IBinder threadBinder = thread.asBinder();
4623 // Find the application record.
4624 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4625 ProcessRecord rec = mLruProcesses.get(i);
4626 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4633 final ProcessRecord getRecordForAppLocked(
4634 IApplicationThread thread) {
4635 if (thread == null) {
4639 int appIndex = getLRURecordIndexForAppLocked(thread);
4640 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4643 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4644 // If there are no longer any background processes running,
4645 // and the app that died was not running instrumentation,
4646 // then tell everyone we are now low on memory.
4647 boolean haveBg = false;
4648 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4649 ProcessRecord rec = mLruProcesses.get(i);
4650 if (rec.thread != null
4651 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4658 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4660 long now = SystemClock.uptimeMillis();
4661 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4664 mLastMemUsageReportTime = now;
4667 final ArrayList<ProcessMemInfo> memInfos
4668 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4669 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4670 long now = SystemClock.uptimeMillis();
4671 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4672 ProcessRecord rec = mLruProcesses.get(i);
4673 if (rec == dyingProc || rec.thread == null) {
4677 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4678 rec.setProcState, rec.adjType, rec.makeAdjReason()));
4680 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4681 // The low memory report is overriding any current
4682 // state for a GC request. Make sure to do
4683 // heavy/important/visible/foreground processes first.
4684 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4685 rec.lastRequestedGc = 0;
4687 rec.lastRequestedGc = rec.lastLowMemory;
4689 rec.reportLowMemory = true;
4690 rec.lastLowMemory = now;
4691 mProcessesToGc.remove(rec);
4692 addProcessToGcListLocked(rec);
4696 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4697 mHandler.sendMessage(msg);
4699 scheduleAppGcsLocked();
4703 final void appDiedLocked(ProcessRecord app) {
4704 appDiedLocked(app, app.pid, app.thread);
4707 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4708 // First check if this ProcessRecord is actually active for the pid.
4709 synchronized (mPidsSelfLocked) {
4710 ProcessRecord curProc = mPidsSelfLocked.get(pid);
4711 if (curProc != app) {
4712 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4717 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4718 synchronized (stats) {
4719 stats.noteProcessDiedLocked(app.info.uid, pid);
4723 Process.killProcessQuiet(pid);
4724 Process.killProcessGroup(app.uid, pid);
4728 // Clean up already done if the process has been re-started.
4729 if (app.pid == pid && app.thread != null &&
4730 app.thread.asBinder() == thread.asBinder()) {
4731 boolean doLowMem = app.instrumentationClass == null;
4732 boolean doOomAdj = doLowMem;
4733 if (!app.killedByAm) {
4734 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4736 mAllowLowerMemLevel = true;
4738 // Note that we always want to do oom adj to update our state with the
4739 // new number of procs.
4740 mAllowLowerMemLevel = false;
4743 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4744 if (DEBUG_CLEANUP) Slog.v(
4745 TAG, "Dying app: " + app + ", pid: " + pid
4746 + ", thread: " + thread.asBinder());
4747 handleAppDiedLocked(app, false, true);
4750 updateOomAdjLocked();
4753 doLowMemReportIfNeededLocked(app);
4755 } else if (app.pid != pid) {
4756 // A new process has already been started.
4757 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4758 + ") has died and restarted (pid " + app.pid + ").");
4759 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4760 } else if (DEBUG_PROCESSES) {
4761 Slog.d(TAG, "Received spurious death notification for thread "
4762 + thread.asBinder());
4767 * If a stack trace dump file is configured, dump process stack traces.
4768 * @param clearTraces causes the dump file to be erased prior to the new
4769 * traces being written, if true; when false, the new traces will be
4770 * appended to any existing file content.
4771 * @param firstPids of dalvik VM processes to dump stack traces for first
4772 * @param lastPids of dalvik VM processes to dump stack traces for last
4773 * @param nativeProcs optional list of native process names to dump stack crawls
4774 * @return file containing stack traces, or null if no dump file is configured
4776 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4777 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4778 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4779 if (tracesPath == null || tracesPath.length() == 0) {
4783 File tracesFile = new File(tracesPath);
4785 File tracesDir = tracesFile.getParentFile();
4786 if (!tracesDir.exists()) {
4788 if (!SELinux.restorecon(tracesDir)) {
4792 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4794 if (clearTraces && tracesFile.exists()) tracesFile.delete();
4795 tracesFile.createNewFile();
4796 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4797 } catch (IOException e) {
4798 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4802 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4806 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4807 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4808 // Use a FileObserver to detect when traces finish writing.
4809 // The order of traces is considered important to maintain for legibility.
4810 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4812 public synchronized void onEvent(int event, String path) { notify(); }
4816 observer.startWatching();
4818 // First collect all of the stacks of the most important pids.
4819 if (firstPids != null) {
4821 int num = firstPids.size();
4822 for (int i = 0; i < num; i++) {
4823 synchronized (observer) {
4824 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4825 observer.wait(200); // Wait for write-close, give up after 200msec
4828 } catch (InterruptedException e) {
4833 // Next collect the stacks of the native pids
4834 if (nativeProcs != null) {
4835 int[] pids = Process.getPidsForCommands(nativeProcs);
4837 for (int pid : pids) {
4838 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4843 // Lastly, measure CPU usage.
4844 if (processCpuTracker != null) {
4845 processCpuTracker.init();
4847 processCpuTracker.update();
4849 synchronized (processCpuTracker) {
4850 processCpuTracker.wait(500); // measure over 1/2 second.
4852 } catch (InterruptedException e) {
4854 processCpuTracker.update();
4856 // We'll take the stack crawls of just the top apps using CPU.
4857 final int N = processCpuTracker.countWorkingStats();
4859 for (int i=0; i<N && numProcs<5; i++) {
4860 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4861 if (lastPids.indexOfKey(stats.pid) >= 0) {
4864 synchronized (observer) {
4865 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4866 observer.wait(200); // Wait for write-close, give up after 200msec
4868 } catch (InterruptedException e) {
4876 observer.stopWatching();
4880 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4881 if (true || IS_USER_BUILD) {
4884 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4885 if (tracesPath == null || tracesPath.length() == 0) {
4889 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4890 StrictMode.allowThreadDiskWrites();
4892 final File tracesFile = new File(tracesPath);
4893 final File tracesDir = tracesFile.getParentFile();
4894 final File tracesTmp = new File(tracesDir, "__tmp__");
4896 if (!tracesDir.exists()) {
4898 if (!SELinux.restorecon(tracesDir.getPath())) {
4902 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4904 if (tracesFile.exists()) {
4906 tracesFile.renameTo(tracesTmp);
4908 StringBuilder sb = new StringBuilder();
4909 Time tobj = new Time();
4910 tobj.set(System.currentTimeMillis());
4911 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4913 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4914 sb.append(" since ");
4916 FileOutputStream fos = new FileOutputStream(tracesFile);
4917 fos.write(sb.toString().getBytes());
4919 fos.write("\n*** No application process!".getBytes());
4922 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4923 } catch (IOException e) {
4924 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4929 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4930 firstPids.add(app.pid);
4931 dumpStackTraces(tracesPath, firstPids, null, null, null);
4934 File lastTracesFile = null;
4935 File curTracesFile = null;
4936 for (int i=9; i>=0; i--) {
4937 String name = String.format(Locale.US, "slow%02d.txt", i);
4938 curTracesFile = new File(tracesDir, name);
4939 if (curTracesFile.exists()) {
4940 if (lastTracesFile != null) {
4941 curTracesFile.renameTo(lastTracesFile);
4943 curTracesFile.delete();
4946 lastTracesFile = curTracesFile;
4948 tracesFile.renameTo(curTracesFile);
4949 if (tracesTmp.exists()) {
4950 tracesTmp.renameTo(tracesFile);
4953 StrictMode.setThreadPolicy(oldPolicy);
4957 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4958 ActivityRecord parent, boolean aboveSystem, final String annotation) {
4959 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4960 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4962 if (mController != null) {
4964 // 0 == continue, -1 = kill process immediately
4965 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4966 if (res < 0 && app.pid != MY_PID) {
4967 app.kill("anr", true);
4969 } catch (RemoteException e) {
4971 Watchdog.getInstance().setActivityController(null);
4975 long anrTime = SystemClock.uptimeMillis();
4976 if (MONITOR_CPU_USAGE) {
4977 updateCpuStatsNow();
4980 synchronized (this) {
4981 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4982 if (mShuttingDown) {
4983 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4985 } else if (app.notResponding) {
4986 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4988 } else if (app.crashing) {
4989 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4993 // In case we come through here for the same app before completing
4994 // this one, mark as anring now so we will bail out.
4995 app.notResponding = true;
4997 // Log the ANR to the event log.
4998 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4999 app.processName, app.info.flags, annotation);
5001 // Dump thread traces as quickly as we can, starting with "interesting" processes.
5002 firstPids.add(app.pid);
5004 int parentPid = app.pid;
5005 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5006 if (parentPid != app.pid) firstPids.add(parentPid);
5008 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5010 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5011 ProcessRecord r = mLruProcesses.get(i);
5012 if (r != null && r.thread != null) {
5014 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5018 lastPids.put(pid, Boolean.TRUE);
5025 // Log the ANR to the main log.
5026 StringBuilder info = new StringBuilder();
5028 info.append("ANR in ").append(app.processName);
5029 if (activity != null && activity.shortComponentName != null) {
5030 info.append(" (").append(activity.shortComponentName).append(")");
5033 info.append("PID: ").append(app.pid).append("\n");
5034 if (annotation != null) {
5035 info.append("Reason: ").append(annotation).append("\n");
5037 if (parent != null && parent != activity) {
5038 info.append("Parent: ").append(parent.shortComponentName).append("\n");
5041 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5043 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5044 NATIVE_STACKS_OF_INTEREST);
5046 String cpuInfo = null;
5047 if (MONITOR_CPU_USAGE) {
5048 updateCpuStatsNow();
5049 synchronized (mProcessCpuTracker) {
5050 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5052 info.append(processCpuTracker.printCurrentLoad());
5053 info.append(cpuInfo);
5056 info.append(processCpuTracker.printCurrentState(anrTime));
5058 Slog.e(TAG, info.toString());
5059 if (tracesFile == null) {
5060 // There is no trace file, so dump (only) the alleged culprit's threads to the log
5061 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5064 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5065 cpuInfo, tracesFile, null);
5067 if (mController != null) {
5069 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5070 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5072 if (res < 0 && app.pid != MY_PID) {
5073 app.kill("anr", true);
5075 synchronized (this) {
5076 mServices.scheduleServiceTimeoutLocked(app);
5081 } catch (RemoteException e) {
5083 Watchdog.getInstance().setActivityController(null);
5087 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5088 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5089 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5091 synchronized (this) {
5092 mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5094 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5095 app.kill("bg anr", true);
5099 // Set the app's notResponding state, and look up the errorReportReceiver
5100 makeAppNotRespondingLocked(app,
5101 activity != null ? activity.shortComponentName : null,
5102 annotation != null ? "ANR " + annotation : "ANR",
5105 // Bring up the infamous App Not Responding dialog
5106 Message msg = Message.obtain();
5107 HashMap<String, Object> map = new HashMap<String, Object>();
5108 msg.what = SHOW_NOT_RESPONDING_MSG;
5110 msg.arg1 = aboveSystem ? 1 : 0;
5111 map.put("app", app);
5112 if (activity != null) {
5113 map.put("activity", activity);
5116 mHandler.sendMessage(msg);
5120 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5121 if (!mLaunchWarningShown) {
5122 mLaunchWarningShown = true;
5123 mHandler.post(new Runnable() {
5126 synchronized (ActivityManagerService.this) {
5127 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5129 mHandler.postDelayed(new Runnable() {
5132 synchronized (ActivityManagerService.this) {
5134 mLaunchWarningShown = false;
5145 public boolean clearApplicationUserData(final String packageName,
5146 final IPackageDataObserver observer, int userId) {
5147 enforceNotIsolatedCaller("clearApplicationUserData");
5148 int uid = Binder.getCallingUid();
5149 int pid = Binder.getCallingPid();
5150 userId = handleIncomingUser(pid, uid,
5151 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5152 long callingId = Binder.clearCallingIdentity();
5154 IPackageManager pm = AppGlobals.getPackageManager();
5156 synchronized(this) {
5158 pkgUid = pm.getPackageUid(packageName, userId);
5159 } catch (RemoteException e) {
5162 Slog.w(TAG, "Invalid packageName: " + packageName);
5163 if (observer != null) {
5165 observer.onRemoveCompleted(packageName, false);
5166 } catch (RemoteException e) {
5167 Slog.i(TAG, "Observer no longer exists.");
5172 if (uid == pkgUid || checkComponentPermission(
5173 android.Manifest.permission.CLEAR_APP_USER_DATA,
5175 == PackageManager.PERMISSION_GRANTED) {
5176 forceStopPackageLocked(packageName, pkgUid, "clear data");
5178 throw new SecurityException("PID " + pid + " does not have permission "
5179 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5180 + " of package " + packageName);
5183 // Remove all tasks match the cleared application package and user
5184 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5185 final TaskRecord tr = mRecentTasks.get(i);
5186 final String taskPackageName =
5187 tr.getBaseIntent().getComponent().getPackageName();
5188 if (tr.userId != userId) continue;
5189 if (!taskPackageName.equals(packageName)) continue;
5190 removeTaskByIdLocked(tr.taskId, false);
5195 // Clear application user data
5196 pm.clearApplicationUserData(packageName, observer, userId);
5198 synchronized(this) {
5199 // Remove all permissions granted from/to this package
5200 removeUriPermissionsForPackageLocked(packageName, userId, true);
5203 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5204 Uri.fromParts("package", packageName, null));
5205 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5206 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5207 null, null, 0, null, null, null, false, false, userId);
5208 } catch (RemoteException e) {
5211 Binder.restoreCallingIdentity(callingId);
5217 public void killBackgroundProcesses(final String packageName, int userId) {
5218 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5219 != PackageManager.PERMISSION_GRANTED &&
5220 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5221 != PackageManager.PERMISSION_GRANTED) {
5222 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5223 + Binder.getCallingPid()
5224 + ", uid=" + Binder.getCallingUid()
5225 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5227 throw new SecurityException(msg);
5230 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5231 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5232 long callingId = Binder.clearCallingIdentity();
5234 IPackageManager pm = AppGlobals.getPackageManager();
5235 synchronized(this) {
5238 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5239 } catch (RemoteException e) {
5242 Slog.w(TAG, "Invalid packageName: " + packageName);
5245 killPackageProcessesLocked(packageName, appId, userId,
5246 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5249 Binder.restoreCallingIdentity(callingId);
5254 public void killAllBackgroundProcesses() {
5255 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5256 != PackageManager.PERMISSION_GRANTED) {
5257 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5258 + Binder.getCallingPid()
5259 + ", uid=" + Binder.getCallingUid()
5260 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5262 throw new SecurityException(msg);
5265 long callingId = Binder.clearCallingIdentity();
5267 synchronized(this) {
5268 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5269 final int NP = mProcessNames.getMap().size();
5270 for (int ip=0; ip<NP; ip++) {
5271 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5272 final int NA = apps.size();
5273 for (int ia=0; ia<NA; ia++) {
5274 ProcessRecord app = apps.valueAt(ia);
5275 if (app.persistent) {
5276 // we don't kill persistent processes
5281 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5288 int N = procs.size();
5289 for (int i=0; i<N; i++) {
5290 removeProcessLocked(procs.get(i), false, true, "kill all background");
5292 mAllowLowerMemLevel = true;
5293 updateOomAdjLocked();
5294 doLowMemReportIfNeededLocked(null);
5297 Binder.restoreCallingIdentity(callingId);
5302 public void forceStopPackage(final String packageName, int userId) {
5303 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5304 != PackageManager.PERMISSION_GRANTED) {
5305 String msg = "Permission Denial: forceStopPackage() from pid="
5306 + Binder.getCallingPid()
5307 + ", uid=" + Binder.getCallingUid()
5308 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5310 throw new SecurityException(msg);
5312 final int callingPid = Binder.getCallingPid();
5313 userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5314 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5315 long callingId = Binder.clearCallingIdentity();
5317 IPackageManager pm = AppGlobals.getPackageManager();
5318 synchronized(this) {
5319 int[] users = userId == UserHandle.USER_ALL
5320 ? getUsersLocked() : new int[] { userId };
5321 for (int user : users) {
5324 pkgUid = pm.getPackageUid(packageName, user);
5325 } catch (RemoteException e) {
5328 Slog.w(TAG, "Invalid packageName: " + packageName);
5332 pm.setPackageStoppedState(packageName, true, user);
5333 } catch (RemoteException e) {
5334 } catch (IllegalArgumentException e) {
5335 Slog.w(TAG, "Failed trying to unstop package "
5336 + packageName + ": " + e);
5338 if (isUserRunningLocked(user, false)) {
5339 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5344 Binder.restoreCallingIdentity(callingId);
5349 public void addPackageDependency(String packageName) {
5350 synchronized (this) {
5351 int callingPid = Binder.getCallingPid();
5352 if (callingPid == Process.myPid()) {
5357 synchronized (mPidsSelfLocked) {
5358 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5361 if (proc.pkgDeps == null) {
5362 proc.pkgDeps = new ArraySet<String>(1);
5364 proc.pkgDeps.add(packageName);
5370 * The pkg name and app id have to be specified.
5373 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5377 // Make sure the uid is valid.
5379 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5382 int callerUid = Binder.getCallingUid();
5383 // Only the system server can kill an application
5384 if (callerUid == Process.SYSTEM_UID) {
5385 // Post an aysnc message to kill the application
5386 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5389 Bundle bundle = new Bundle();
5390 bundle.putString("pkg", pkg);
5391 bundle.putString("reason", reason);
5393 mHandler.sendMessage(msg);
5395 throw new SecurityException(callerUid + " cannot kill pkg: " +
5401 public void closeSystemDialogs(String reason) {
5402 enforceNotIsolatedCaller("closeSystemDialogs");
5404 final int pid = Binder.getCallingPid();
5405 final int uid = Binder.getCallingUid();
5406 final long origId = Binder.clearCallingIdentity();
5408 synchronized (this) {
5409 // Only allow this from foreground processes, so that background
5410 // applications can't abuse it to prevent system UI from being shown.
5411 if (uid >= Process.FIRST_APPLICATION_UID) {
5413 synchronized (mPidsSelfLocked) {
5414 proc = mPidsSelfLocked.get(pid);
5416 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5417 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5418 + " from background process " + proc);
5422 closeSystemDialogsLocked(reason);
5425 Binder.restoreCallingIdentity(origId);
5429 void closeSystemDialogsLocked(String reason) {
5430 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5431 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5432 | Intent.FLAG_RECEIVER_FOREGROUND);
5433 if (reason != null) {
5434 intent.putExtra("reason", reason);
5436 mWindowManager.closeSystemDialogs(reason);
5438 mStackSupervisor.closeSystemDialogsLocked();
5440 broadcastIntentLocked(null, null, intent, null,
5441 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5442 Process.SYSTEM_UID, UserHandle.USER_ALL);
5446 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5447 enforceNotIsolatedCaller("getProcessMemoryInfo");
5448 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5449 for (int i=pids.length-1; i>=0; i--) {
5452 synchronized (this) {
5453 synchronized (mPidsSelfLocked) {
5454 proc = mPidsSelfLocked.get(pids[i]);
5455 oomAdj = proc != null ? proc.setAdj : 0;
5458 infos[i] = new Debug.MemoryInfo();
5459 Debug.getMemoryInfo(pids[i], infos[i]);
5461 synchronized (this) {
5462 if (proc.thread != null && proc.setAdj == oomAdj) {
5463 // Record this for posterity if the process has been stable.
5464 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5465 infos[i].getTotalUss(), false, proc.pkgList);
5474 public long[] getProcessPss(int[] pids) {
5475 enforceNotIsolatedCaller("getProcessPss");
5476 long[] pss = new long[pids.length];
5477 for (int i=pids.length-1; i>=0; i--) {
5480 synchronized (this) {
5481 synchronized (mPidsSelfLocked) {
5482 proc = mPidsSelfLocked.get(pids[i]);
5483 oomAdj = proc != null ? proc.setAdj : 0;
5486 long[] tmpUss = new long[1];
5487 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5489 synchronized (this) {
5490 if (proc.thread != null && proc.setAdj == oomAdj) {
5491 // Record this for posterity if the process has been stable.
5492 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5501 public void killApplicationProcess(String processName, int uid) {
5502 if (processName == null) {
5506 int callerUid = Binder.getCallingUid();
5507 // Only the system server can kill an application
5508 if (callerUid == Process.SYSTEM_UID) {
5509 synchronized (this) {
5510 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5511 if (app != null && app.thread != null) {
5513 app.thread.scheduleSuicide();
5514 } catch (RemoteException e) {
5515 // If the other end already died, then our work here is done.
5518 Slog.w(TAG, "Process/uid not found attempting kill of "
5519 + processName + " / " + uid);
5523 throw new SecurityException(callerUid + " cannot kill app process: " +
5528 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5529 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5530 false, true, false, false, UserHandle.getUserId(uid), reason);
5531 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5532 Uri.fromParts("package", packageName, null));
5533 if (!mProcessesReady) {
5534 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5535 | Intent.FLAG_RECEIVER_FOREGROUND);
5537 intent.putExtra(Intent.EXTRA_UID, uid);
5538 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5539 broadcastIntentLocked(null, null, intent,
5540 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5542 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5545 private void forceStopUserLocked(int userId, String reason) {
5546 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5547 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5548 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5549 | Intent.FLAG_RECEIVER_FOREGROUND);
5550 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5551 broadcastIntentLocked(null, null, intent,
5552 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5554 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5557 private final boolean killPackageProcessesLocked(String packageName, int appId,
5558 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5559 boolean doit, boolean evenPersistent, String reason) {
5560 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5562 // Remove all processes this package may have touched: all with the
5563 // same UID (except for the system or root user), and all whose name
5564 // matches the package name.
5565 final int NP = mProcessNames.getMap().size();
5566 for (int ip=0; ip<NP; ip++) {
5567 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5568 final int NA = apps.size();
5569 for (int ia=0; ia<NA; ia++) {
5570 ProcessRecord app = apps.valueAt(ia);
5571 if (app.persistent && !evenPersistent) {
5572 // we don't kill persistent processes
5582 // Skip process if it doesn't meet our oom adj requirement.
5583 if (app.setAdj < minOomAdj) {
5587 // If no package is specified, we call all processes under the
5589 if (packageName == null) {
5590 if (app.userId != userId) {
5593 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5596 // Package has been specified, we want to hit all processes
5597 // that match it. We need to qualify this by the processes
5598 // that are running under the specified app and user ID.
5600 final boolean isDep = app.pkgDeps != null
5601 && app.pkgDeps.contains(packageName);
5602 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5605 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5608 if (!app.pkgList.containsKey(packageName) && !isDep) {
5613 // Process has passed all conditions, kill it!
5622 int N = procs.size();
5623 for (int i=0; i<N; i++) {
5624 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5626 updateOomAdjLocked();
5630 private final boolean forceStopPackageLocked(String name, int appId,
5631 boolean callerWillRestart, boolean purgeCache, boolean doit,
5632 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5636 if (userId == UserHandle.USER_ALL && name == null) {
5637 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5640 if (appId < 0 && name != null) {
5642 appId = UserHandle.getAppId(
5643 AppGlobals.getPackageManager().getPackageUid(name, 0));
5644 } catch (RemoteException e) {
5650 Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5651 + " user=" + userId + ": " + reason);
5653 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5656 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5657 for (int ip=pmap.size()-1; ip>=0; ip--) {
5658 SparseArray<Long> ba = pmap.valueAt(ip);
5659 for (i=ba.size()-1; i>=0; i--) {
5660 boolean remove = false;
5661 final int entUid = ba.keyAt(i);
5663 if (userId == UserHandle.USER_ALL) {
5664 if (UserHandle.getAppId(entUid) == appId) {
5668 if (entUid == UserHandle.getUid(userId, appId)) {
5672 } else if (UserHandle.getUserId(entUid) == userId) {
5679 if (ba.size() == 0) {
5685 boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5686 -100, callerWillRestart, true, doit, evenPersistent,
5687 name == null ? ("stop user " + userId) : ("stop " + name));
5689 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5693 didSomething = true;
5696 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5700 didSomething = true;
5704 // Remove all sticky broadcasts from this user.
5705 mStickyBroadcasts.remove(userId);
5708 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5709 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5710 userId, providers)) {
5714 didSomething = true;
5716 N = providers.size();
5717 for (i=0; i<N; i++) {
5718 removeDyingProviderLocked(null, providers.get(i), true);
5721 // Remove transient permissions granted from/to this package/user
5722 removeUriPermissionsForPackageLocked(name, userId, false);
5724 if (name == null || uninstalling) {
5725 // Remove pending intents. For now we only do this when force
5726 // stopping users, because we have some problems when doing this
5727 // for packages -- app widgets are not currently cleaned up for
5728 // such packages, so they can be left with bad pending intents.
5729 if (mIntentSenderRecords.size() > 0) {
5730 Iterator<WeakReference<PendingIntentRecord>> it
5731 = mIntentSenderRecords.values().iterator();
5732 while (it.hasNext()) {
5733 WeakReference<PendingIntentRecord> wpir = it.next();
5738 PendingIntentRecord pir = wpir.get();
5744 // Stopping user, remove all objects for the user.
5745 if (pir.key.userId != userId) {
5746 // Not the same user, skip it.
5750 if (UserHandle.getAppId(pir.uid) != appId) {
5751 // Different app id, skip it.
5754 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5755 // Different user, skip it.
5758 if (!pir.key.packageName.equals(name)) {
5759 // Different package, skip it.
5766 didSomething = true;
5768 pir.canceled = true;
5769 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5770 pir.key.activity.pendingResults.remove(pir.ref);
5777 if (purgeCache && name != null) {
5778 AttributeCache ac = AttributeCache.instance();
5780 ac.removePackage(name);
5784 mStackSupervisor.resumeTopActivitiesLocked();
5785 mStackSupervisor.scheduleIdleLocked();
5789 return didSomething;
5792 private final boolean removeProcessLocked(ProcessRecord app,
5793 boolean callerWillRestart, boolean allowRestart, String reason) {
5794 final String name = app.processName;
5795 final int uid = app.uid;
5796 if (DEBUG_PROCESSES) Slog.d(
5797 TAG, "Force removing proc " + app.toShortString() + " (" + name
5800 mProcessNames.remove(name, uid);
5801 mIsolatedProcesses.remove(app.uid);
5802 if (mHeavyWeightProcess == app) {
5803 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5804 mHeavyWeightProcess.userId, 0));
5805 mHeavyWeightProcess = null;
5807 boolean needRestart = false;
5808 if (app.pid > 0 && app.pid != MY_PID) {
5810 synchronized (mPidsSelfLocked) {
5811 mPidsSelfLocked.remove(pid);
5812 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5814 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5816 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5818 app.kill(reason, true);
5819 handleAppDiedLocked(app, true, allowRestart);
5820 removeLruProcessLocked(app);
5822 if (app.persistent && !app.isolated) {
5823 if (!callerWillRestart) {
5824 addAppLocked(app.info, false, null /* ABI override */);
5830 mRemovedProcesses.add(app);
5836 private final void processStartTimedOutLocked(ProcessRecord app) {
5837 final int pid = app.pid;
5838 boolean gone = false;
5839 synchronized (mPidsSelfLocked) {
5840 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5841 if (knownApp != null && knownApp.thread == null) {
5842 mPidsSelfLocked.remove(pid);
5848 Slog.w(TAG, "Process " + app + " failed to attach");
5849 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5850 pid, app.uid, app.processName);
5851 mProcessNames.remove(app.processName, app.uid);
5852 mIsolatedProcesses.remove(app.uid);
5853 if (mHeavyWeightProcess == app) {
5854 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5855 mHeavyWeightProcess.userId, 0));
5856 mHeavyWeightProcess = null;
5858 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5860 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5862 // Take care of any launching providers waiting for this process.
5863 checkAppInLaunchingProvidersLocked(app, true);
5864 // Take care of any services that are waiting for the process.
5865 mServices.processStartTimedOutLocked(app);
5866 app.kill("start timeout", true);
5867 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5868 Slog.w(TAG, "Unattached app died before backup, skipping");
5870 IBackupManager bm = IBackupManager.Stub.asInterface(
5871 ServiceManager.getService(Context.BACKUP_SERVICE));
5872 bm.agentDisconnected(app.info.packageName);
5873 } catch (RemoteException e) {
5874 // Can't happen; the backup manager is local
5877 if (isPendingBroadcastProcessLocked(pid)) {
5878 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5879 skipPendingBroadcastLocked(pid);
5882 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5886 private final boolean attachApplicationLocked(IApplicationThread thread,
5889 // Find the application record that is being attached... either via
5890 // the pid if we are running in multiple processes, or just pull the
5891 // next app record if we are emulating process with anonymous threads.
5893 if (pid != MY_PID && pid >= 0) {
5894 synchronized (mPidsSelfLocked) {
5895 app = mPidsSelfLocked.get(pid);
5902 Slog.w(TAG, "No pending application record for pid " + pid
5903 + " (IApplicationThread " + thread + "); dropping process");
5904 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5905 if (pid > 0 && pid != MY_PID) {
5906 Process.killProcessQuiet(pid);
5907 //TODO: Process.killProcessGroup(app.info.uid, pid);
5910 thread.scheduleExit();
5911 } catch (Exception e) {
5912 // Ignore exceptions.
5918 // If this application record is still attached to a previous
5919 // process, clean it up now.
5920 if (app.thread != null) {
5921 handleAppDiedLocked(app, true, true);
5924 // Tell the process all about itself.
5926 if (localLOGV) Slog.v(
5927 TAG, "Binding process pid " + pid + " to record " + app);
5929 final String processName = app.processName;
5931 AppDeathRecipient adr = new AppDeathRecipient(
5933 thread.asBinder().linkToDeath(adr, 0);
5934 app.deathRecipient = adr;
5935 } catch (RemoteException e) {
5936 app.resetPackageList(mProcessStats);
5937 startProcessLocked(app, "link fail", processName);
5941 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5943 app.makeActive(thread, mProcessStats);
5944 app.curAdj = app.setAdj = -100;
5945 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5946 app.forcingToForeground = null;
5947 updateProcessForegroundLocked(app, false, false);
5948 app.hasShownUi = false;
5949 app.debugging = false;
5951 app.killedByAm = false;
5953 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5955 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5956 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5959 Slog.i(TAG, "Launching preboot mode app: " + app);
5962 if (localLOGV) Slog.v(
5963 TAG, "New app record " + app
5964 + " thread=" + thread.asBinder() + " pid=" + pid);
5966 int testMode = IApplicationThread.DEBUG_OFF;
5967 if (mDebugApp != null && mDebugApp.equals(processName)) {
5968 testMode = mWaitForDebugger
5969 ? IApplicationThread.DEBUG_WAIT
5970 : IApplicationThread.DEBUG_ON;
5971 app.debugging = true;
5972 if (mDebugTransient) {
5973 mDebugApp = mOrigDebugApp;
5974 mWaitForDebugger = mOrigWaitForDebugger;
5977 String profileFile = app.instrumentationProfileFile;
5978 ParcelFileDescriptor profileFd = null;
5979 int samplingInterval = 0;
5980 boolean profileAutoStop = false;
5981 if (mProfileApp != null && mProfileApp.equals(processName)) {
5983 profileFile = mProfileFile;
5984 profileFd = mProfileFd;
5985 samplingInterval = mSamplingInterval;
5986 profileAutoStop = mAutoStopProfiler;
5988 boolean enableOpenGlTrace = false;
5989 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5990 enableOpenGlTrace = true;
5991 mOpenGlTraceApp = null;
5994 // If the app is being launched for restore or full backup, set it up specially
5995 boolean isRestrictedBackupMode = false;
5996 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5997 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5998 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5999 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6002 ensurePackageDexOpt(app.instrumentationInfo != null
6003 ? app.instrumentationInfo.packageName
6004 : app.info.packageName);
6005 if (app.instrumentationClass != null) {
6006 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6008 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6009 + processName + " with config " + mConfiguration);
6010 ApplicationInfo appInfo = app.instrumentationInfo != null
6011 ? app.instrumentationInfo : app.info;
6012 app.compat = compatibilityInfoForPackageLocked(appInfo);
6013 if (profileFd != null) {
6014 profileFd = profileFd.dup();
6016 ProfilerInfo profilerInfo = profileFile == null ? null
6017 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6018 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6019 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6020 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6021 isRestrictedBackupMode || !normalMode, app.persistent,
6022 new Configuration(mConfiguration), app.compat,
6023 getCommonServicesLocked(app.isolated),
6024 mCoreSettingsObserver.getCoreSettingsLocked());
6025 updateLruProcessLocked(app, false, null);
6026 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6027 } catch (Exception e) {
6028 // todo: Yikes! What should we do? For now we will try to
6029 // start another process, but that could easily get us in
6030 // an infinite loop of restarting processes...
6031 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6033 app.resetPackageList(mProcessStats);
6034 app.unlinkDeathRecipient();
6035 startProcessLocked(app, "bind fail", processName);
6039 // Remove this record from the list of starting applications.
6040 mPersistentStartingProcesses.remove(app);
6041 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6042 "Attach application locked removing on hold: " + app);
6043 mProcessesOnHold.remove(app);
6045 boolean badApp = false;
6046 boolean didSomething = false;
6048 // See if the top visible activity is waiting to run in this process...
6051 if (mStackSupervisor.attachApplicationLocked(app)) {
6052 didSomething = true;
6054 } catch (Exception e) {
6055 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6060 // Find any services that should be running in this process...
6063 didSomething |= mServices.attachApplicationLocked(app, processName);
6064 } catch (Exception e) {
6065 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6070 // Check if a next-broadcast receiver is in this process...
6071 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6073 didSomething |= sendPendingBroadcastsLocked(app);
6074 } catch (Exception e) {
6075 // If the app died trying to launch the receiver we declare it 'bad'
6076 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6081 // Check whether the next backup agent is in this process...
6082 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6083 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6084 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6086 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6087 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6088 mBackupTarget.backupMode);
6089 } catch (Exception e) {
6090 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6096 app.kill("error during init", true);
6097 handleAppDiedLocked(app, false, true);
6101 if (!didSomething) {
6102 updateOomAdjLocked();
6109 public final void attachApplication(IApplicationThread thread) {
6110 synchronized (this) {
6111 int callingPid = Binder.getCallingPid();
6112 final long origId = Binder.clearCallingIdentity();
6113 attachApplicationLocked(thread, callingPid);
6114 Binder.restoreCallingIdentity(origId);
6119 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6120 final long origId = Binder.clearCallingIdentity();
6121 synchronized (this) {
6122 ActivityStack stack = ActivityRecord.getStackLocked(token);
6123 if (stack != null) {
6125 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6126 if (stopProfiling) {
6127 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6130 } catch (IOException e) {
6132 clearProfilerLocked();
6137 Binder.restoreCallingIdentity(origId);
6140 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6141 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6142 finishBooting? 1 : 0, enableScreen ? 1 : 0));
6145 void enableScreenAfterBoot() {
6146 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6147 SystemClock.uptimeMillis());
6148 mWindowManager.enableScreenAfterBoot();
6150 synchronized (this) {
6151 updateEventDispatchingLocked();
6156 public void showBootMessage(final CharSequence msg, final boolean always) {
6157 enforceNotIsolatedCaller("showBootMessage");
6158 mWindowManager.showBootMessage(msg, always);
6162 public void keyguardWaitingForActivityDrawn() {
6163 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6164 final long token = Binder.clearCallingIdentity();
6166 synchronized (this) {
6167 if (DEBUG_LOCKSCREEN) logLockScreen("");
6168 mWindowManager.keyguardWaitingForActivityDrawn();
6169 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6170 mLockScreenShown = LOCK_SCREEN_LEAVING;
6171 updateSleepIfNeededLocked();
6175 Binder.restoreCallingIdentity(token);
6179 final void finishBooting() {
6180 synchronized (this) {
6181 if (!mBootAnimationComplete) {
6182 mCallFinishBooting = true;
6185 mCallFinishBooting = false;
6188 ArraySet<String> completedIsas = new ArraySet<String>();
6189 for (String abi : Build.SUPPORTED_ABIS) {
6190 Process.establishZygoteConnectionForAbi(abi);
6191 final String instructionSet = VMRuntime.getInstructionSet(abi);
6192 if (!completedIsas.contains(instructionSet)) {
6193 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6194 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6196 completedIsas.add(instructionSet);
6200 IntentFilter pkgFilter = new IntentFilter();
6201 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6202 pkgFilter.addDataScheme("package");
6203 mContext.registerReceiver(new BroadcastReceiver() {
6205 public void onReceive(Context context, Intent intent) {
6206 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6208 for (String pkg : pkgs) {
6209 synchronized (ActivityManagerService.this) {
6210 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6211 0, "finished booting")) {
6212 setResultCode(Activity.RESULT_OK);
6221 // Let system services know.
6222 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6224 synchronized (this) {
6225 // Ensure that any processes we had put on hold are now started
6227 final int NP = mProcessesOnHold.size();
6229 ArrayList<ProcessRecord> procs =
6230 new ArrayList<ProcessRecord>(mProcessesOnHold);
6231 for (int ip=0; ip<NP; ip++) {
6232 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6234 startProcessLocked(procs.get(ip), "on-hold", null);
6238 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6239 // Start looking for apps that are abusing wake locks.
6240 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6241 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6242 // Tell anyone interested that we are done booting!
6243 SystemProperties.set("sys.boot_completed", "1");
6245 // And trigger dev.bootcomplete if we are not showing encryption progress
6246 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6247 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6248 SystemProperties.set("dev.bootcomplete", "1");
6250 for (int i=0; i<mStartedUsers.size(); i++) {
6251 UserStartedState uss = mStartedUsers.valueAt(i);
6252 if (uss.mState == UserStartedState.STATE_BOOTING) {
6253 uss.mState = UserStartedState.STATE_RUNNING;
6254 final int userId = mStartedUsers.keyAt(i);
6255 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6256 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6257 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6258 broadcastIntentLocked(null, null, intent, null,
6259 new IIntentReceiver.Stub() {
6261 public void performReceive(Intent intent, int resultCode,
6262 String data, Bundle extras, boolean ordered,
6263 boolean sticky, int sendingUser) {
6264 synchronized (ActivityManagerService.this) {
6265 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6271 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6272 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6276 scheduleStartProfilesLocked();
6282 public void bootAnimationComplete() {
6283 final boolean callFinishBooting;
6284 synchronized (this) {
6285 callFinishBooting = mCallFinishBooting;
6286 mBootAnimationComplete = true;
6288 if (callFinishBooting) {
6294 public void systemBackupRestored() {
6295 synchronized (this) {
6297 mTaskPersister.restoreTasksFromOtherDeviceLocked();
6299 Slog.w(TAG, "System backup restored before system is ready");
6304 final void ensureBootCompleted() {
6306 boolean enableScreen;
6307 synchronized (this) {
6310 enableScreen = !mBooted;
6319 enableScreenAfterBoot();
6324 public final void activityResumed(IBinder token) {
6325 final long origId = Binder.clearCallingIdentity();
6326 synchronized(this) {
6327 ActivityStack stack = ActivityRecord.getStackLocked(token);
6328 if (stack != null) {
6329 ActivityRecord.activityResumedLocked(token);
6332 Binder.restoreCallingIdentity(origId);
6336 public final void activityPaused(IBinder token) {
6337 final long origId = Binder.clearCallingIdentity();
6338 synchronized(this) {
6339 ActivityStack stack = ActivityRecord.getStackLocked(token);
6340 if (stack != null) {
6341 stack.activityPausedLocked(token, false);
6344 Binder.restoreCallingIdentity(origId);
6348 public final void activityStopped(IBinder token, Bundle icicle,
6349 PersistableBundle persistentState, CharSequence description) {
6350 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6352 // Refuse possible leaked file descriptors
6353 if (icicle != null && icicle.hasFileDescriptors()) {
6354 throw new IllegalArgumentException("File descriptors passed in Bundle");
6357 final long origId = Binder.clearCallingIdentity();
6359 synchronized (this) {
6360 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6362 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6368 Binder.restoreCallingIdentity(origId);
6372 public final void activityDestroyed(IBinder token) {
6373 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6374 synchronized (this) {
6375 ActivityStack stack = ActivityRecord.getStackLocked(token);
6376 if (stack != null) {
6377 stack.activityDestroyedLocked(token, "activityDestroyed");
6383 public final void backgroundResourcesReleased(IBinder token) {
6384 final long origId = Binder.clearCallingIdentity();
6386 synchronized (this) {
6387 ActivityStack stack = ActivityRecord.getStackLocked(token);
6388 if (stack != null) {
6389 stack.backgroundResourcesReleased();
6393 Binder.restoreCallingIdentity(origId);
6398 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6399 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6403 public final void notifyEnterAnimationComplete(IBinder token) {
6404 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6408 public String getCallingPackage(IBinder token) {
6409 synchronized (this) {
6410 ActivityRecord r = getCallingRecordLocked(token);
6411 return r != null ? r.info.packageName : null;
6416 public ComponentName getCallingActivity(IBinder token) {
6417 synchronized (this) {
6418 ActivityRecord r = getCallingRecordLocked(token);
6419 return r != null ? r.intent.getComponent() : null;
6423 private ActivityRecord getCallingRecordLocked(IBinder token) {
6424 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6432 public ComponentName getActivityClassForToken(IBinder token) {
6433 synchronized(this) {
6434 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6438 return r.intent.getComponent();
6443 public String getPackageForToken(IBinder token) {
6444 synchronized(this) {
6445 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6449 return r.packageName;
6454 public IIntentSender getIntentSender(int type,
6455 String packageName, IBinder token, String resultWho,
6456 int requestCode, Intent[] intents, String[] resolvedTypes,
6457 int flags, Bundle options, int userId) {
6458 enforceNotIsolatedCaller("getIntentSender");
6459 // Refuse possible leaked file descriptors
6460 if (intents != null) {
6461 if (intents.length < 1) {
6462 throw new IllegalArgumentException("Intents array length must be >= 1");
6464 for (int i=0; i<intents.length; i++) {
6465 Intent intent = intents[i];
6466 if (intent != null) {
6467 if (intent.hasFileDescriptors()) {
6468 throw new IllegalArgumentException("File descriptors passed in Intent");
6470 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6471 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6472 throw new IllegalArgumentException(
6473 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6475 intents[i] = new Intent(intent);
6478 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6479 throw new IllegalArgumentException(
6480 "Intent array length does not match resolvedTypes length");
6483 if (options != null) {
6484 if (options.hasFileDescriptors()) {
6485 throw new IllegalArgumentException("File descriptors passed in options");
6489 synchronized(this) {
6490 int callingUid = Binder.getCallingUid();
6491 int origUserId = userId;
6492 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6493 type == ActivityManager.INTENT_SENDER_BROADCAST,
6494 ALLOW_NON_FULL, "getIntentSender", null);
6495 if (origUserId == UserHandle.USER_CURRENT) {
6496 // We don't want to evaluate this until the pending intent is
6497 // actually executed. However, we do want to always do the
6498 // security checking for it above.
6499 userId = UserHandle.USER_CURRENT;
6502 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6503 int uid = AppGlobals.getPackageManager()
6504 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6505 if (!UserHandle.isSameApp(callingUid, uid)) {
6506 String msg = "Permission Denial: getIntentSender() from pid="
6507 + Binder.getCallingPid()
6508 + ", uid=" + Binder.getCallingUid()
6509 + ", (need uid=" + uid + ")"
6510 + " is not allowed to send as package " + packageName;
6512 throw new SecurityException(msg);
6516 return getIntentSenderLocked(type, packageName, callingUid, userId,
6517 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6519 } catch (RemoteException e) {
6520 throw new SecurityException(e);
6525 IIntentSender getIntentSenderLocked(int type, String packageName,
6526 int callingUid, int userId, IBinder token, String resultWho,
6527 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6530 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6531 ActivityRecord activity = null;
6532 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6533 activity = ActivityRecord.isInStackLocked(token);
6534 if (activity == null) {
6537 if (activity.finishing) {
6542 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6543 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6544 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6545 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6546 |PendingIntent.FLAG_UPDATE_CURRENT);
6548 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6549 type, packageName, activity, resultWho,
6550 requestCode, intents, resolvedTypes, flags, options, userId);
6551 WeakReference<PendingIntentRecord> ref;
6552 ref = mIntentSenderRecords.get(key);
6553 PendingIntentRecord rec = ref != null ? ref.get() : null;
6555 if (!cancelCurrent) {
6556 if (updateCurrent) {
6557 if (rec.key.requestIntent != null) {
6558 rec.key.requestIntent.replaceExtras(intents != null ?
6559 intents[intents.length - 1] : null);
6561 if (intents != null) {
6562 intents[intents.length-1] = rec.key.requestIntent;
6563 rec.key.allIntents = intents;
6564 rec.key.allResolvedTypes = resolvedTypes;
6566 rec.key.allIntents = null;
6567 rec.key.allResolvedTypes = null;
6572 rec.canceled = true;
6573 mIntentSenderRecords.remove(key);
6578 rec = new PendingIntentRecord(this, key, callingUid);
6579 mIntentSenderRecords.put(key, rec.ref);
6580 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6581 if (activity.pendingResults == null) {
6582 activity.pendingResults
6583 = new HashSet<WeakReference<PendingIntentRecord>>();
6585 activity.pendingResults.add(rec.ref);
6591 public void cancelIntentSender(IIntentSender sender) {
6592 if (!(sender instanceof PendingIntentRecord)) {
6595 synchronized(this) {
6596 PendingIntentRecord rec = (PendingIntentRecord)sender;
6598 int uid = AppGlobals.getPackageManager()
6599 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6600 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6601 String msg = "Permission Denial: cancelIntentSender() from pid="
6602 + Binder.getCallingPid()
6603 + ", uid=" + Binder.getCallingUid()
6604 + " is not allowed to cancel packges "
6605 + rec.key.packageName;
6607 throw new SecurityException(msg);
6609 } catch (RemoteException e) {
6610 throw new SecurityException(e);
6612 cancelIntentSenderLocked(rec, true);
6616 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6617 rec.canceled = true;
6618 mIntentSenderRecords.remove(rec.key);
6619 if (cleanActivity && rec.key.activity != null) {
6620 rec.key.activity.pendingResults.remove(rec.ref);
6625 public String getPackageForIntentSender(IIntentSender pendingResult) {
6626 if (!(pendingResult instanceof PendingIntentRecord)) {
6630 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6631 return res.key.packageName;
6632 } catch (ClassCastException e) {
6638 public int getUidForIntentSender(IIntentSender sender) {
6639 if (sender instanceof PendingIntentRecord) {
6641 PendingIntentRecord res = (PendingIntentRecord)sender;
6643 } catch (ClassCastException e) {
6650 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6651 if (!(pendingResult instanceof PendingIntentRecord)) {
6655 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6656 if (res.key.allIntents == null) {
6659 for (int i=0; i<res.key.allIntents.length; i++) {
6660 Intent intent = res.key.allIntents[i];
6661 if (intent.getPackage() != null && intent.getComponent() != null) {
6666 } catch (ClassCastException e) {
6672 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6673 if (!(pendingResult instanceof PendingIntentRecord)) {
6677 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6678 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6682 } catch (ClassCastException e) {
6688 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6689 if (!(pendingResult instanceof PendingIntentRecord)) {
6693 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6694 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6695 } catch (ClassCastException e) {
6701 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6702 if (!(pendingResult instanceof PendingIntentRecord)) {
6706 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6707 Intent intent = res.key.requestIntent;
6708 if (intent != null) {
6709 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6710 || res.lastTagPrefix.equals(prefix))) {
6713 res.lastTagPrefix = prefix;
6714 StringBuilder sb = new StringBuilder(128);
6715 if (prefix != null) {
6718 if (intent.getAction() != null) {
6719 sb.append(intent.getAction());
6720 } else if (intent.getComponent() != null) {
6721 intent.getComponent().appendShortString(sb);
6725 return res.lastTag = sb.toString();
6727 } catch (ClassCastException e) {
6733 public void setProcessLimit(int max) {
6734 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6735 "setProcessLimit()");
6736 synchronized (this) {
6737 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6738 mProcessLimitOverride = max;
6744 public int getProcessLimit() {
6745 synchronized (this) {
6746 return mProcessLimitOverride;
6750 void foregroundTokenDied(ForegroundToken token) {
6751 synchronized (ActivityManagerService.this) {
6752 synchronized (mPidsSelfLocked) {
6754 = mForegroundProcesses.get(token.pid);
6758 mForegroundProcesses.remove(token.pid);
6759 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6763 pr.forcingToForeground = null;
6764 updateProcessForegroundLocked(pr, false, false);
6766 updateOomAdjLocked();
6771 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6772 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6773 "setProcessForeground()");
6774 synchronized(this) {
6775 boolean changed = false;
6777 synchronized (mPidsSelfLocked) {
6778 ProcessRecord pr = mPidsSelfLocked.get(pid);
6779 if (pr == null && isForeground) {
6780 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6783 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6784 if (oldToken != null) {
6785 oldToken.token.unlinkToDeath(oldToken, 0);
6786 mForegroundProcesses.remove(pid);
6788 pr.forcingToForeground = null;
6792 if (isForeground && token != null) {
6793 ForegroundToken newToken = new ForegroundToken() {
6795 public void binderDied() {
6796 foregroundTokenDied(this);
6800 newToken.token = token;
6802 token.linkToDeath(newToken, 0);
6803 mForegroundProcesses.put(pid, newToken);
6804 pr.forcingToForeground = token;
6806 } catch (RemoteException e) {
6807 // If the process died while doing this, we will later
6808 // do the cleanup with the process death link.
6814 updateOomAdjLocked();
6819 // =========================================================
6821 // =========================================================
6823 static class PermissionController extends IPermissionController.Stub {
6824 ActivityManagerService mActivityManagerService;
6825 PermissionController(ActivityManagerService activityManagerService) {
6826 mActivityManagerService = activityManagerService;
6830 public boolean checkPermission(String permission, int pid, int uid) {
6831 return mActivityManagerService.checkPermission(permission, pid,
6832 uid) == PackageManager.PERMISSION_GRANTED;
6836 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6838 public int checkComponentPermission(String permission, int pid, int uid,
6839 int owningUid, boolean exported) {
6840 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6841 owningUid, exported);
6845 public Object getAMSLock() {
6846 return ActivityManagerService.this;
6851 * This can be called with or without the global lock held.
6853 int checkComponentPermission(String permission, int pid, int uid,
6854 int owningUid, boolean exported) {
6855 if (pid == MY_PID) {
6856 return PackageManager.PERMISSION_GRANTED;
6858 return ActivityManager.checkComponentPermission(permission, uid,
6859 owningUid, exported);
6863 * As the only public entry point for permissions checking, this method
6864 * can enforce the semantic that requesting a check on a null global
6865 * permission is automatically denied. (Internally a null permission
6866 * string is used when calling {@link #checkComponentPermission} in cases
6867 * when only uid-based security is needed.)
6869 * This can be called with or without the global lock held.
6872 public int checkPermission(String permission, int pid, int uid) {
6873 if (permission == null) {
6874 return PackageManager.PERMISSION_DENIED;
6876 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6880 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
6881 if (permission == null) {
6882 return PackageManager.PERMISSION_DENIED;
6885 // We might be performing an operation on behalf of an indirect binder
6886 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
6887 // client identity accordingly before proceeding.
6888 Identity tlsIdentity = sCallerIdentity.get();
6889 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
6890 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6891 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6892 uid = tlsIdentity.uid;
6893 pid = tlsIdentity.pid;
6896 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6900 * Binder IPC calls go through the public entry point.
6901 * This can be called with or without the global lock held.
6903 int checkCallingPermission(String permission) {
6904 return checkPermission(permission,
6905 Binder.getCallingPid(),
6906 UserHandle.getAppId(Binder.getCallingUid()));
6910 * This can be called with or without the global lock held.
6912 void enforceCallingPermission(String permission, String func) {
6913 if (checkCallingPermission(permission)
6914 == PackageManager.PERMISSION_GRANTED) {
6918 String msg = "Permission Denial: " + func + " from pid="
6919 + Binder.getCallingPid()
6920 + ", uid=" + Binder.getCallingUid()
6921 + " requires " + permission;
6923 throw new SecurityException(msg);
6927 * Determine if UID is holding permissions required to access {@link Uri} in
6928 * the given {@link ProviderInfo}. Final permission checking is always done
6929 * in {@link ContentProvider}.
6931 private final boolean checkHoldingPermissionsLocked(
6932 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6933 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6934 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6935 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6936 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6937 != PERMISSION_GRANTED) {
6941 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6944 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6945 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6946 if (pi.applicationInfo.uid == uid) {
6948 } else if (!pi.exported) {
6952 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6953 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6955 // check if target holds top-level <provider> permissions
6956 if (!readMet && pi.readPermission != null && considerUidPermissions
6957 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6960 if (!writeMet && pi.writePermission != null && considerUidPermissions
6961 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6965 // track if unprotected read/write is allowed; any denied
6966 // <path-permission> below removes this ability
6967 boolean allowDefaultRead = pi.readPermission == null;
6968 boolean allowDefaultWrite = pi.writePermission == null;
6970 // check if target holds any <path-permission> that match uri
6971 final PathPermission[] pps = pi.pathPermissions;
6973 final String path = grantUri.uri.getPath();
6975 while (i > 0 && (!readMet || !writeMet)) {
6977 PathPermission pp = pps[i];
6978 if (pp.match(path)) {
6980 final String pprperm = pp.getReadPermission();
6981 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6982 + pprperm + " for " + pp.getPath()
6983 + ": match=" + pp.match(path)
6984 + " check=" + pm.checkUidPermission(pprperm, uid));
6985 if (pprperm != null) {
6986 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6987 == PERMISSION_GRANTED) {
6990 allowDefaultRead = false;
6995 final String ppwperm = pp.getWritePermission();
6996 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6997 + ppwperm + " for " + pp.getPath()
6998 + ": match=" + pp.match(path)
6999 + " check=" + pm.checkUidPermission(ppwperm, uid));
7000 if (ppwperm != null) {
7001 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7002 == PERMISSION_GRANTED) {
7005 allowDefaultWrite = false;
7013 // grant unprotected <provider> read/write, if not blocked by
7014 // <path-permission> above
7015 if (allowDefaultRead) readMet = true;
7016 if (allowDefaultWrite) writeMet = true;
7018 } catch (RemoteException e) {
7022 return readMet && writeMet;
7025 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7026 ProviderInfo pi = null;
7027 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7032 pi = AppGlobals.getPackageManager().resolveContentProvider(
7033 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7034 } catch (RemoteException ex) {
7040 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7041 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7042 if (targetUris != null) {
7043 return targetUris.get(grantUri);
7048 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7049 String targetPkg, int targetUid, GrantUri grantUri) {
7050 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7051 if (targetUris == null) {
7052 targetUris = Maps.newArrayMap();
7053 mGrantedUriPermissions.put(targetUid, targetUris);
7056 UriPermission perm = targetUris.get(grantUri);
7058 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7059 targetUris.put(grantUri, perm);
7065 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7066 final int modeFlags) {
7067 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7068 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7069 : UriPermission.STRENGTH_OWNED;
7071 // Root gets to do everything.
7076 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7077 if (perms == null) return false;
7079 // First look for exact match
7080 final UriPermission exactPerm = perms.get(grantUri);
7081 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7085 // No exact match, look for prefixes
7086 final int N = perms.size();
7087 for (int i = 0; i < N; i++) {
7088 final UriPermission perm = perms.valueAt(i);
7089 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7090 && perm.getStrength(modeFlags) >= minStrength) {
7099 * @param uri This uri must NOT contain an embedded userId.
7100 * @param userId The userId in which the uri is to be resolved.
7103 public int checkUriPermission(Uri uri, int pid, int uid,
7104 final int modeFlags, int userId, IBinder callerToken) {
7105 enforceNotIsolatedCaller("checkUriPermission");
7107 // Another redirected-binder-call permissions check as in
7108 // {@link checkPermissionWithToken}.
7109 Identity tlsIdentity = sCallerIdentity.get();
7110 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7111 uid = tlsIdentity.uid;
7112 pid = tlsIdentity.pid;
7115 // Our own process gets to do everything.
7116 if (pid == MY_PID) {
7117 return PackageManager.PERMISSION_GRANTED;
7119 synchronized (this) {
7120 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7121 ? PackageManager.PERMISSION_GRANTED
7122 : PackageManager.PERMISSION_DENIED;
7127 * Check if the targetPkg can be granted permission to access uri by
7128 * the callingUid using the given modeFlags. Throws a security exception
7129 * if callingUid is not allowed to do this. Returns the uid of the target
7130 * if the URI permission grant should be performed; returns -1 if it is not
7131 * needed (for example targetPkg already has permission to access the URI).
7132 * If you already know the uid of the target, you can supply it in
7133 * lastTargetUid else set that to -1.
7135 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7136 final int modeFlags, int lastTargetUid) {
7137 if (!Intent.isAccessUriMode(modeFlags)) {
7141 if (targetPkg != null) {
7142 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7143 "Checking grant " + targetPkg + " permission to " + grantUri);
7146 final IPackageManager pm = AppGlobals.getPackageManager();
7148 // If this is not a content: uri, we can't do anything with it.
7149 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7150 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7151 "Can't grant URI permission for non-content URI: " + grantUri);
7155 final String authority = grantUri.uri.getAuthority();
7156 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7158 Slog.w(TAG, "No content provider found for permission check: " +
7159 grantUri.uri.toSafeString());
7163 int targetUid = lastTargetUid;
7164 if (targetUid < 0 && targetPkg != null) {
7166 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7167 if (targetUid < 0) {
7168 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7169 "Can't grant URI permission no uid for: " + targetPkg);
7172 } catch (RemoteException ex) {
7177 if (targetUid >= 0) {
7178 // First... does the target actually need this permission?
7179 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7180 // No need to grant the target this permission.
7181 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7182 "Target " + targetPkg + " already has full permission to " + grantUri);
7186 // First... there is no target package, so can anyone access it?
7187 boolean allowed = pi.exported;
7188 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7189 if (pi.readPermission != null) {
7193 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7194 if (pi.writePermission != null) {
7203 /* There is a special cross user grant if:
7204 * - The target is on another user.
7205 * - Apps on the current user can access the uri without any uid permissions.
7206 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7207 * grant uri permissions.
7209 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7210 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7211 modeFlags, false /*without considering the uid permissions*/);
7213 // Second... is the provider allowing granting of URI permissions?
7214 if (!specialCrossUserGrant) {
7215 if (!pi.grantUriPermissions) {
7216 throw new SecurityException("Provider " + pi.packageName
7218 + " does not allow granting of Uri permissions (uri "
7221 if (pi.uriPermissionPatterns != null) {
7222 final int N = pi.uriPermissionPatterns.length;
7223 boolean allowed = false;
7224 for (int i=0; i<N; i++) {
7225 if (pi.uriPermissionPatterns[i] != null
7226 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7232 throw new SecurityException("Provider " + pi.packageName
7234 + " does not allow granting of permission to path of Uri "
7240 // Third... does the caller itself have permission to access
7242 final int callingAppId = UserHandle.getAppId(callingUid);
7243 if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
7244 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
7245 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
7248 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7249 // Require they hold a strong enough Uri permission
7250 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7251 throw new SecurityException("Uid " + callingUid
7252 + " does not have permission to uri " + grantUri);
7260 * @param uri This uri must NOT contain an embedded userId.
7261 * @param userId The userId in which the uri is to be resolved.
7264 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7265 final int modeFlags, int userId) {
7266 enforceNotIsolatedCaller("checkGrantUriPermission");
7267 synchronized(this) {
7268 return checkGrantUriPermissionLocked(callingUid, targetPkg,
7269 new GrantUri(userId, uri, false), modeFlags, -1);
7273 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7274 final int modeFlags, UriPermissionOwner owner) {
7275 if (!Intent.isAccessUriMode(modeFlags)) {
7279 // So here we are: the caller has the assumed permission
7280 // to the uri, and the target doesn't. Let's now give this to
7283 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7284 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7286 final String authority = grantUri.uri.getAuthority();
7287 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7289 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7293 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7294 grantUri.prefix = true;
7296 final UriPermission perm = findOrCreateUriPermissionLocked(
7297 pi.packageName, targetPkg, targetUid, grantUri);
7298 perm.grantModes(modeFlags, owner);
7301 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7302 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7303 if (targetPkg == null) {
7304 throw new NullPointerException("targetPkg");
7307 final IPackageManager pm = AppGlobals.getPackageManager();
7309 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7310 } catch (RemoteException ex) {
7314 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7316 if (targetUid < 0) {
7320 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7324 static class NeededUriGrants extends ArrayList<GrantUri> {
7325 final String targetPkg;
7326 final int targetUid;
7329 NeededUriGrants(String targetPkg, int targetUid, int flags) {
7330 this.targetPkg = targetPkg;
7331 this.targetUid = targetUid;
7337 * Like checkGrantUriPermissionLocked, but takes an Intent.
7339 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7340 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7341 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7342 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7343 + " clip=" + (intent != null ? intent.getClipData() : null)
7344 + " from " + intent + "; flags=0x"
7345 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7347 if (targetPkg == null) {
7348 throw new NullPointerException("targetPkg");
7351 if (intent == null) {
7354 Uri data = intent.getData();
7355 ClipData clip = intent.getClipData();
7356 if (data == null && clip == null) {
7359 // Default userId for uris in the intent (if they don't specify it themselves)
7360 int contentUserHint = intent.getContentUserHint();
7361 if (contentUserHint == UserHandle.USER_CURRENT) {
7362 contentUserHint = UserHandle.getUserId(callingUid);
7364 final IPackageManager pm = AppGlobals.getPackageManager();
7366 if (needed != null) {
7367 targetUid = needed.targetUid;
7370 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7371 } catch (RemoteException ex) {
7374 if (targetUid < 0) {
7375 if (DEBUG_URI_PERMISSION) {
7376 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7377 + " on user " + targetUserId);
7383 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7384 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7386 if (targetUid > 0) {
7387 if (needed == null) {
7388 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7390 needed.add(grantUri);
7394 for (int i=0; i<clip.getItemCount(); i++) {
7395 Uri uri = clip.getItemAt(i).getUri();
7397 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7398 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7400 if (targetUid > 0) {
7401 if (needed == null) {
7402 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7404 needed.add(grantUri);
7407 Intent clipIntent = clip.getItemAt(i).getIntent();
7408 if (clipIntent != null) {
7409 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7410 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7411 if (newNeeded != null) {
7423 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7425 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7426 UriPermissionOwner owner) {
7427 if (needed != null) {
7428 for (int i=0; i<needed.size(); i++) {
7429 GrantUri grantUri = needed.get(i);
7430 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7431 grantUri, needed.flags, owner);
7436 void grantUriPermissionFromIntentLocked(int callingUid,
7437 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7438 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7439 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7440 if (needed == null) {
7444 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7448 * @param uri This uri must NOT contain an embedded userId.
7449 * @param userId The userId in which the uri is to be resolved.
7452 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7453 final int modeFlags, int userId) {
7454 enforceNotIsolatedCaller("grantUriPermission");
7455 GrantUri grantUri = new GrantUri(userId, uri, false);
7456 synchronized(this) {
7457 final ProcessRecord r = getRecordForAppLocked(caller);
7459 throw new SecurityException("Unable to find app for caller "
7461 + " when granting permission to uri " + grantUri);
7463 if (targetPkg == null) {
7464 throw new IllegalArgumentException("null target");
7466 if (grantUri == null) {
7467 throw new IllegalArgumentException("null uri");
7470 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7471 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7472 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7473 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7475 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7476 UserHandle.getUserId(r.uid));
7480 void removeUriPermissionIfNeededLocked(UriPermission perm) {
7481 if (perm.modeFlags == 0) {
7482 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7484 if (perms != null) {
7485 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7486 "Removing " + perm.targetUid + " permission to " + perm.uri);
7488 perms.remove(perm.uri);
7489 if (perms.isEmpty()) {
7490 mGrantedUriPermissions.remove(perm.targetUid);
7496 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7497 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7499 final IPackageManager pm = AppGlobals.getPackageManager();
7500 final String authority = grantUri.uri.getAuthority();
7501 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7503 Slog.w(TAG, "No content provider found for permission revoke: "
7504 + grantUri.toSafeString());
7508 // Does the caller have this permission on the URI?
7509 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7510 // If they don't have direct access to the URI, then revoke any
7511 // ownerless URI permissions that have been granted to them.
7512 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7513 if (perms != null) {
7514 boolean persistChanged = false;
7515 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7516 final UriPermission perm = it.next();
7517 if (perm.uri.sourceUserId == grantUri.sourceUserId
7518 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7519 if (DEBUG_URI_PERMISSION)
7520 Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7521 " permission to " + perm.uri);
7522 persistChanged |= perm.revokeModes(
7523 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7524 if (perm.modeFlags == 0) {
7529 if (perms.isEmpty()) {
7530 mGrantedUriPermissions.remove(callingUid);
7532 if (persistChanged) {
7533 schedulePersistUriGrants();
7539 boolean persistChanged = false;
7541 // Go through all of the permissions and remove any that match.
7542 int N = mGrantedUriPermissions.size();
7543 for (int i = 0; i < N; i++) {
7544 final int targetUid = mGrantedUriPermissions.keyAt(i);
7545 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7547 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7548 final UriPermission perm = it.next();
7549 if (perm.uri.sourceUserId == grantUri.sourceUserId
7550 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7551 if (DEBUG_URI_PERMISSION)
7553 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7554 persistChanged |= perm.revokeModes(
7555 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7556 if (perm.modeFlags == 0) {
7562 if (perms.isEmpty()) {
7563 mGrantedUriPermissions.remove(targetUid);
7569 if (persistChanged) {
7570 schedulePersistUriGrants();
7575 * @param uri This uri must NOT contain an embedded userId.
7576 * @param userId The userId in which the uri is to be resolved.
7579 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7581 enforceNotIsolatedCaller("revokeUriPermission");
7582 synchronized(this) {
7583 final ProcessRecord r = getRecordForAppLocked(caller);
7585 throw new SecurityException("Unable to find app for caller "
7587 + " when revoking permission to uri " + uri);
7590 Slog.w(TAG, "revokeUriPermission: null uri");
7594 if (!Intent.isAccessUriMode(modeFlags)) {
7598 final IPackageManager pm = AppGlobals.getPackageManager();
7599 final String authority = uri.getAuthority();
7600 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7602 Slog.w(TAG, "No content provider found for permission revoke: "
7603 + uri.toSafeString());
7607 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7612 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7615 * @param packageName Package name to match, or {@code null} to apply to all
7617 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7619 * @param persistable If persistable grants should be removed.
7621 private void removeUriPermissionsForPackageLocked(
7622 String packageName, int userHandle, boolean persistable) {
7623 if (userHandle == UserHandle.USER_ALL && packageName == null) {
7624 throw new IllegalArgumentException("Must narrow by either package or user");
7627 boolean persistChanged = false;
7629 int N = mGrantedUriPermissions.size();
7630 for (int i = 0; i < N; i++) {
7631 final int targetUid = mGrantedUriPermissions.keyAt(i);
7632 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7634 // Only inspect grants matching user
7635 if (userHandle == UserHandle.USER_ALL
7636 || userHandle == UserHandle.getUserId(targetUid)) {
7637 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7638 final UriPermission perm = it.next();
7640 // Only inspect grants matching package
7641 if (packageName == null || perm.sourcePkg.equals(packageName)
7642 || perm.targetPkg.equals(packageName)) {
7643 // Hacky solution as part of fixing a security bug; ignore
7644 // grants associated with DownloadManager so we don't have
7645 // to immediately launch it to regrant the permissions
7646 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
7647 && !persistable) continue;
7649 persistChanged |= perm.revokeModes(persistable
7650 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7652 // Only remove when no modes remain; any persisted grants
7653 // will keep this alive.
7654 if (perm.modeFlags == 0) {
7660 if (perms.isEmpty()) {
7661 mGrantedUriPermissions.remove(targetUid);
7668 if (persistChanged) {
7669 schedulePersistUriGrants();
7674 public IBinder newUriPermissionOwner(String name) {
7675 enforceNotIsolatedCaller("newUriPermissionOwner");
7676 synchronized(this) {
7677 UriPermissionOwner owner = new UriPermissionOwner(this, name);
7678 return owner.getExternalTokenLocked();
7683 * @param uri This uri must NOT contain an embedded userId.
7684 * @param sourceUserId The userId in which the uri is to be resolved.
7685 * @param targetUserId The userId of the app that receives the grant.
7688 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7689 final int modeFlags, int sourceUserId, int targetUserId) {
7690 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7691 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7692 synchronized(this) {
7693 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7694 if (owner == null) {
7695 throw new IllegalArgumentException("Unknown owner: " + token);
7697 if (fromUid != Binder.getCallingUid()) {
7698 if (Binder.getCallingUid() != Process.myUid()) {
7699 // Only system code can grant URI permissions on behalf
7701 throw new SecurityException("nice try");
7704 if (targetPkg == null) {
7705 throw new IllegalArgumentException("null target");
7708 throw new IllegalArgumentException("null uri");
7711 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7712 modeFlags, owner, targetUserId);
7717 * @param uri This uri must NOT contain an embedded userId.
7718 * @param userId The userId in which the uri is to be resolved.
7721 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7722 synchronized(this) {
7723 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7724 if (owner == null) {
7725 throw new IllegalArgumentException("Unknown owner: " + token);
7729 owner.removeUriPermissionsLocked(mode);
7731 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7736 private void schedulePersistUriGrants() {
7737 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7738 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7739 10 * DateUtils.SECOND_IN_MILLIS);
7743 private void writeGrantedUriPermissions() {
7744 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7746 // Snapshot permissions so we can persist without lock
7747 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7748 synchronized (this) {
7749 final int size = mGrantedUriPermissions.size();
7750 for (int i = 0; i < size; i++) {
7751 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7752 for (UriPermission perm : perms.values()) {
7753 if (perm.persistedModeFlags != 0) {
7754 persist.add(perm.snapshot());
7760 FileOutputStream fos = null;
7762 fos = mGrantFile.startWrite();
7764 XmlSerializer out = new FastXmlSerializer();
7765 out.setOutput(fos, "utf-8");
7766 out.startDocument(null, true);
7767 out.startTag(null, TAG_URI_GRANTS);
7768 for (UriPermission.Snapshot perm : persist) {
7769 out.startTag(null, TAG_URI_GRANT);
7770 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7771 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7772 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7773 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7774 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7775 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7776 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7777 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7778 out.endTag(null, TAG_URI_GRANT);
7780 out.endTag(null, TAG_URI_GRANTS);
7783 mGrantFile.finishWrite(fos);
7784 } catch (IOException e) {
7786 mGrantFile.failWrite(fos);
7791 private void readGrantedUriPermissionsLocked() {
7792 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7794 final long now = System.currentTimeMillis();
7796 FileInputStream fis = null;
7798 fis = mGrantFile.openRead();
7799 final XmlPullParser in = Xml.newPullParser();
7800 in.setInput(fis, null);
7803 while ((type = in.next()) != END_DOCUMENT) {
7804 final String tag = in.getName();
7805 if (type == START_TAG) {
7806 if (TAG_URI_GRANT.equals(tag)) {
7807 final int sourceUserId;
7808 final int targetUserId;
7809 final int userHandle = readIntAttribute(in,
7810 ATTR_USER_HANDLE, UserHandle.USER_NULL);
7811 if (userHandle != UserHandle.USER_NULL) {
7812 // For backwards compatibility.
7813 sourceUserId = userHandle;
7814 targetUserId = userHandle;
7816 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7817 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7819 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7820 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7821 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7822 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7823 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7824 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7826 // Sanity check that provider still belongs to source package
7827 final ProviderInfo pi = getProviderInfoLocked(
7828 uri.getAuthority(), sourceUserId);
7829 if (pi != null && sourcePkg.equals(pi.packageName)) {
7832 targetUid = AppGlobals.getPackageManager()
7833 .getPackageUid(targetPkg, targetUserId);
7834 } catch (RemoteException e) {
7836 if (targetUid != -1) {
7837 final UriPermission perm = findOrCreateUriPermissionLocked(
7838 sourcePkg, targetPkg, targetUid,
7839 new GrantUri(sourceUserId, uri, prefix));
7840 perm.initPersistedModes(modeFlags, createdTime);
7843 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7844 + " but instead found " + pi);
7849 } catch (FileNotFoundException e) {
7850 // Missing grants is okay
7851 } catch (IOException e) {
7852 Slog.wtf(TAG, "Failed reading Uri grants", e);
7853 } catch (XmlPullParserException e) {
7854 Slog.wtf(TAG, "Failed reading Uri grants", e);
7856 IoUtils.closeQuietly(fis);
7861 * @param uri This uri must NOT contain an embedded userId.
7862 * @param userId The userId in which the uri is to be resolved.
7865 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7866 enforceNotIsolatedCaller("takePersistableUriPermission");
7868 Preconditions.checkFlagsArgument(modeFlags,
7869 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7871 synchronized (this) {
7872 final int callingUid = Binder.getCallingUid();
7873 boolean persistChanged = false;
7874 GrantUri grantUri = new GrantUri(userId, uri, false);
7876 UriPermission exactPerm = findUriPermissionLocked(callingUid,
7877 new GrantUri(userId, uri, false));
7878 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7879 new GrantUri(userId, uri, true));
7881 final boolean exactValid = (exactPerm != null)
7882 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7883 final boolean prefixValid = (prefixPerm != null)
7884 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7886 if (!(exactValid || prefixValid)) {
7887 throw new SecurityException("No persistable permission grants found for UID "
7888 + callingUid + " and Uri " + grantUri.toSafeString());
7892 persistChanged |= exactPerm.takePersistableModes(modeFlags);
7895 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7898 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7900 if (persistChanged) {
7901 schedulePersistUriGrants();
7907 * @param uri This uri must NOT contain an embedded userId.
7908 * @param userId The userId in which the uri is to be resolved.
7911 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7912 enforceNotIsolatedCaller("releasePersistableUriPermission");
7914 Preconditions.checkFlagsArgument(modeFlags,
7915 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7917 synchronized (this) {
7918 final int callingUid = Binder.getCallingUid();
7919 boolean persistChanged = false;
7921 UriPermission exactPerm = findUriPermissionLocked(callingUid,
7922 new GrantUri(userId, uri, false));
7923 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7924 new GrantUri(userId, uri, true));
7925 if (exactPerm == null && prefixPerm == null) {
7926 throw new SecurityException("No permission grants found for UID " + callingUid
7927 + " and Uri " + uri.toSafeString());
7930 if (exactPerm != null) {
7931 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7932 removeUriPermissionIfNeededLocked(exactPerm);
7934 if (prefixPerm != null) {
7935 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7936 removeUriPermissionIfNeededLocked(prefixPerm);
7939 if (persistChanged) {
7940 schedulePersistUriGrants();
7946 * Prune any older {@link UriPermission} for the given UID until outstanding
7947 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7949 * @return if any mutations occured that require persisting.
7951 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7952 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7953 if (perms == null) return false;
7954 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7956 final ArrayList<UriPermission> persisted = Lists.newArrayList();
7957 for (UriPermission perm : perms.values()) {
7958 if (perm.persistedModeFlags != 0) {
7959 persisted.add(perm);
7963 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7964 if (trimCount <= 0) return false;
7966 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7967 for (int i = 0; i < trimCount; i++) {
7968 final UriPermission perm = persisted.get(i);
7970 if (DEBUG_URI_PERMISSION) {
7971 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7974 perm.releasePersistableModes(~0);
7975 removeUriPermissionIfNeededLocked(perm);
7982 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7983 String packageName, boolean incoming) {
7984 enforceNotIsolatedCaller("getPersistedUriPermissions");
7985 Preconditions.checkNotNull(packageName, "packageName");
7987 final int callingUid = Binder.getCallingUid();
7988 final IPackageManager pm = AppGlobals.getPackageManager();
7990 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7991 if (packageUid != callingUid) {
7992 throw new SecurityException(
7993 "Package " + packageName + " does not belong to calling UID " + callingUid);
7995 } catch (RemoteException e) {
7996 throw new SecurityException("Failed to verify package name ownership");
7999 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8000 synchronized (this) {
8002 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8004 if (perms == null) {
8005 Slog.w(TAG, "No permission grants found for " + packageName);
8007 for (UriPermission perm : perms.values()) {
8008 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8009 result.add(perm.buildPersistedPublicApiObject());
8014 final int size = mGrantedUriPermissions.size();
8015 for (int i = 0; i < size; i++) {
8016 final ArrayMap<GrantUri, UriPermission> perms =
8017 mGrantedUriPermissions.valueAt(i);
8018 for (UriPermission perm : perms.values()) {
8019 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8020 result.add(perm.buildPersistedPublicApiObject());
8026 return new ParceledListSlice<android.content.UriPermission>(result);
8030 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8031 synchronized (this) {
8033 who != null ? getRecordForAppLocked(who) : null;
8034 if (app == null) return;
8036 Message msg = Message.obtain();
8037 msg.what = WAIT_FOR_DEBUGGER_MSG;
8039 msg.arg1 = waiting ? 1 : 0;
8040 mHandler.sendMessage(msg);
8045 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8046 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8047 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8048 outInfo.availMem = Process.getFreeMemory();
8049 outInfo.totalMem = Process.getTotalMemory();
8050 outInfo.threshold = homeAppMem;
8051 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8052 outInfo.hiddenAppThreshold = cachedAppMem;
8053 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8054 ProcessList.SERVICE_ADJ);
8055 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8056 ProcessList.VISIBLE_APP_ADJ);
8057 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8058 ProcessList.FOREGROUND_APP_ADJ);
8061 // =========================================================
8063 // =========================================================
8066 public List<IAppTask> getAppTasks(String callingPackage) {
8067 int callingUid = Binder.getCallingUid();
8068 long ident = Binder.clearCallingIdentity();
8070 synchronized(this) {
8071 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8073 if (localLOGV) Slog.v(TAG, "getAppTasks");
8075 final int N = mRecentTasks.size();
8076 for (int i = 0; i < N; i++) {
8077 TaskRecord tr = mRecentTasks.get(i);
8078 // Skip tasks that do not match the caller. We don't need to verify
8079 // callingPackage, because we are also limiting to callingUid and know
8080 // that will limit to the correct security sandbox.
8081 if (tr.effectiveUid != callingUid) {
8084 Intent intent = tr.getBaseIntent();
8085 if (intent == null ||
8086 !callingPackage.equals(intent.getComponent().getPackageName())) {
8089 ActivityManager.RecentTaskInfo taskInfo =
8090 createRecentTaskInfoFromTaskRecord(tr);
8091 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8095 Binder.restoreCallingIdentity(ident);
8102 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8103 final int callingUid = Binder.getCallingUid();
8104 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8106 synchronized(this) {
8107 if (localLOGV) Slog.v(
8108 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8110 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8113 // TODO: Improve with MRU list from all ActivityStacks.
8114 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8121 * Creates a new RecentTaskInfo from a TaskRecord.
8123 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8124 // Update the task description to reflect any changes in the task stack
8125 tr.updateTaskDescription();
8127 // Compose the recent task info
8128 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8129 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8130 rti.persistentId = tr.taskId;
8131 rti.baseIntent = new Intent(tr.getBaseIntent());
8132 rti.origActivity = tr.origActivity;
8133 rti.description = tr.lastDescription;
8134 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8135 rti.userId = tr.userId;
8136 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8137 rti.firstActiveTime = tr.firstActiveTime;
8138 rti.lastActiveTime = tr.lastActiveTime;
8139 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8140 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8144 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8145 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8146 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8148 if (checkPermission(android.Manifest.permission.GET_TASKS,
8149 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8150 // Temporary compatibility: some existing apps on the system image may
8151 // still be requesting the old permission and not switched to the new
8152 // one; if so, we'll still allow them full access. This means we need
8153 // to see if they are holding the old permission and are a system app.
8155 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8157 Slog.w(TAG, caller + ": caller " + callingUid
8158 + " is using old GET_TASKS but privileged; allowing");
8160 } catch (RemoteException e) {
8165 Slog.w(TAG, caller + ": caller " + callingUid
8166 + " does not hold REAL_GET_TASKS; limiting output");
8172 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8173 final int callingUid = Binder.getCallingUid();
8174 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8175 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8177 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8178 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8179 synchronized (this) {
8180 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8182 final boolean detailed = checkCallingPermission(
8183 android.Manifest.permission.GET_DETAILED_TASKS)
8184 == PackageManager.PERMISSION_GRANTED;
8186 final int N = mRecentTasks.size();
8187 ArrayList<ActivityManager.RecentTaskInfo> res
8188 = new ArrayList<ActivityManager.RecentTaskInfo>(
8189 maxNum < N ? maxNum : N);
8191 final Set<Integer> includedUsers;
8192 if (includeProfiles) {
8193 includedUsers = getProfileIdsLocked(userId);
8195 includedUsers = new HashSet<Integer>();
8197 includedUsers.add(Integer.valueOf(userId));
8199 for (int i=0; i<N && maxNum > 0; i++) {
8200 TaskRecord tr = mRecentTasks.get(i);
8201 // Only add calling user or related users recent tasks
8202 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8203 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8207 // Return the entry if desired by the caller. We always return
8208 // the first entry, because callers always expect this to be the
8209 // foreground app. We may filter others if the caller has
8210 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8211 // we should exclude the entry.
8215 || (tr.intent == null)
8216 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8219 // If the caller doesn't have the GET_TASKS permission, then only
8220 // allow them to see a small subset of tasks -- their own and home.
8221 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8222 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8226 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8227 if (tr.stack != null && tr.stack.isHomeStack()) {
8228 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8232 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8233 // Don't include auto remove tasks that are finished or finishing.
8234 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8238 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8239 && !tr.isAvailable) {
8240 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8244 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8246 rti.baseIntent.replaceExtras((Bundle)null);
8257 TaskRecord recentTaskForIdLocked(int id) {
8258 final int N = mRecentTasks.size();
8259 for (int i=0; i<N; i++) {
8260 TaskRecord tr = mRecentTasks.get(i);
8261 if (tr.taskId == id) {
8269 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8270 synchronized (this) {
8271 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8272 "getTaskThumbnail()");
8273 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id);
8275 return tr.getTaskThumbnailLocked();
8282 public int addAppTask(IBinder activityToken, Intent intent,
8283 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8284 final int callingUid = Binder.getCallingUid();
8285 final long callingIdent = Binder.clearCallingIdentity();
8288 synchronized (this) {
8289 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8291 throw new IllegalArgumentException("Activity does not exist; token="
8294 ComponentName comp = intent.getComponent();
8296 throw new IllegalArgumentException("Intent " + intent
8297 + " must specify explicit component");
8299 if (thumbnail.getWidth() != mThumbnailWidth
8300 || thumbnail.getHeight() != mThumbnailHeight) {
8301 throw new IllegalArgumentException("Bad thumbnail size: got "
8302 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8303 + mThumbnailWidth + "x" + mThumbnailHeight);
8305 if (intent.getSelector() != null) {
8306 intent.setSelector(null);
8308 if (intent.getSourceBounds() != null) {
8309 intent.setSourceBounds(null);
8311 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8312 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8313 // The caller has added this as an auto-remove task... that makes no
8314 // sense, so turn off auto-remove.
8315 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8317 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8318 // Must be a new task.
8319 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8321 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8322 mLastAddedTaskActivity = null;
8324 ActivityInfo ainfo = mLastAddedTaskActivity;
8325 if (ainfo == null) {
8326 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8327 comp, 0, UserHandle.getUserId(callingUid));
8328 if (ainfo.applicationInfo.uid != callingUid) {
8329 throw new SecurityException(
8330 "Can't add task for another application: target uid="
8331 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8335 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8336 intent, description);
8338 int trimIdx = trimRecentsForTaskLocked(task, false);
8340 // If this would have caused a trim, then we'll abort because that
8341 // means it would be added at the end of the list but then just removed.
8342 return INVALID_TASK_ID;
8345 final int N = mRecentTasks.size();
8346 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8347 final TaskRecord tr = mRecentTasks.remove(N - 1);
8348 tr.removedFromRecents();
8351 task.inRecents = true;
8352 mRecentTasks.add(task);
8353 r.task.stack.addTask(task, false, false);
8355 task.setLastThumbnail(thumbnail);
8356 task.freeLastThumbnail();
8361 Binder.restoreCallingIdentity(callingIdent);
8366 public Point getAppTaskThumbnailSize() {
8367 synchronized (this) {
8368 return new Point(mThumbnailWidth, mThumbnailHeight);
8373 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8374 synchronized (this) {
8375 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8377 r.setTaskDescription(td);
8378 r.task.updateTaskDescription();
8384 public Bitmap getTaskDescriptionIcon(String filename) {
8385 if (!FileUtils.isValidExtFilename(filename)
8386 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8387 throw new IllegalArgumentException("Bad filename: " + filename);
8389 return mTaskPersister.getTaskDescriptionIcon(filename);
8393 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8394 throws RemoteException {
8395 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8396 opts.getCustomInPlaceResId() == 0) {
8397 throw new IllegalArgumentException("Expected in-place ActivityOption " +
8398 "with valid animation");
8400 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8401 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8402 opts.getCustomInPlaceResId());
8403 mWindowManager.executeAppTransition();
8406 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8407 mRecentTasks.remove(tr);
8408 tr.removedFromRecents();
8409 ComponentName component = tr.getBaseIntent().getComponent();
8410 if (component == null) {
8411 Slog.w(TAG, "No component for base intent of task: " + tr);
8419 // Determine if the process(es) for this task should be killed.
8420 final String pkg = component.getPackageName();
8421 ArrayList<ProcessRecord> procsToKill = new ArrayList<ProcessRecord>();
8422 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8423 for (int i = 0; i < pmap.size(); i++) {
8425 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8426 for (int j = 0; j < uids.size(); j++) {
8427 ProcessRecord proc = uids.valueAt(j);
8428 if (proc.userId != tr.userId) {
8429 // Don't kill process for a different user.
8432 if (proc == mHomeProcess) {
8433 // Don't kill the home process along with tasks from the same package.
8436 if (!proc.pkgList.containsKey(pkg)) {
8437 // Don't kill process that is not associated with this task.
8441 for (int k = 0; k < proc.activities.size(); k++) {
8442 TaskRecord otherTask = proc.activities.get(k).task;
8443 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8444 // Don't kill process(es) that has an activity in a different task that is
8450 // Add process to kill list.
8451 procsToKill.add(proc);
8455 // Find any running services associated with this app and stop if needed.
8456 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8458 // Kill the running processes.
8459 for (int i = 0; i < procsToKill.size(); i++) {
8460 ProcessRecord pr = procsToKill.get(i);
8461 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8462 pr.kill("remove task", true);
8464 pr.waitingToKill = "remove task";
8469 private void removeTasksByPackageNameLocked(String packageName, int userId) {
8470 // Remove all tasks with activities in the specified package from the list of recent tasks
8471 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8472 TaskRecord tr = mRecentTasks.get(i);
8473 if (tr.userId != userId) continue;
8475 ComponentName cn = tr.intent.getComponent();
8476 if (cn != null && cn.getPackageName().equals(packageName)) {
8477 // If the package name matches, remove the task.
8478 removeTaskByIdLocked(tr.taskId, true);
8483 private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
8484 final IPackageManager pm = AppGlobals.getPackageManager();
8485 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
8487 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8488 TaskRecord tr = mRecentTasks.get(i);
8489 if (tr.userId != userId) continue;
8491 ComponentName cn = tr.intent.getComponent();
8492 if (cn != null && cn.getPackageName().equals(packageName)) {
8493 // Skip if component still exists in the package.
8494 if (componentsKnownToExist.contains(cn)) continue;
8497 ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
8499 componentsKnownToExist.add(cn);
8501 removeTaskByIdLocked(tr.taskId, false);
8503 } catch (RemoteException e) {
8504 Log.e(TAG, "Activity info query failed. component=" + cn, e);
8511 * Removes the task with the specified task id.
8513 * @param taskId Identifier of the task to be removed.
8514 * @param killProcess Kill any process associated with the task if possible.
8515 * @return Returns true if the given task was found and removed.
8517 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8518 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8520 tr.removeTaskActivitiesLocked();
8521 cleanUpRemovedTaskLocked(tr, killProcess);
8522 if (tr.isPersistable) {
8523 notifyTaskPersisterLocked(null, true);
8527 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8532 public boolean removeTask(int taskId) {
8533 synchronized (this) {
8534 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8536 long ident = Binder.clearCallingIdentity();
8538 return removeTaskByIdLocked(taskId, true);
8540 Binder.restoreCallingIdentity(ident);
8546 * TODO: Add mController hook
8549 public void moveTaskToFront(int taskId, int flags, Bundle options) {
8550 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8551 "moveTaskToFront()");
8553 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8554 synchronized(this) {
8555 moveTaskToFrontLocked(taskId, flags, options);
8559 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8560 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8561 Binder.getCallingUid(), -1, -1, "Task to front")) {
8562 ActivityOptions.abort(options);
8565 final long origId = Binder.clearCallingIdentity();
8567 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8569 Slog.d(TAG, "Could not find task for id: "+ taskId);
8572 if (mStackSupervisor.isLockTaskModeViolation(task)) {
8573 mStackSupervisor.showLockTaskToast();
8574 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8577 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8578 if (prev != null && prev.isRecentsActivity()) {
8579 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8581 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8583 Binder.restoreCallingIdentity(origId);
8585 ActivityOptions.abort(options);
8589 public void moveTaskToBack(int taskId) {
8590 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8591 "moveTaskToBack()");
8593 synchronized(this) {
8594 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8596 if (tr == mStackSupervisor.mLockTaskModeTask) {
8597 mStackSupervisor.showLockTaskToast();
8600 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8601 ActivityStack stack = tr.stack;
8602 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8603 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8604 Binder.getCallingUid(), -1, -1, "Task to back")) {
8608 final long origId = Binder.clearCallingIdentity();
8610 stack.moveTaskToBackLocked(taskId);
8612 Binder.restoreCallingIdentity(origId);
8619 * Moves an activity, and all of the other activities within the same task, to the bottom
8620 * of the history stack. The activity's order within the task is unchanged.
8622 * @param token A reference to the activity we wish to move
8623 * @param nonRoot If false then this only works if the activity is the root
8624 * of a task; if true it will work for any activity in a task.
8625 * @return Returns true if the move completed, false if not.
8628 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8629 enforceNotIsolatedCaller("moveActivityTaskToBack");
8630 synchronized(this) {
8631 final long origId = Binder.clearCallingIdentity();
8633 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8635 if ((mStackSupervisor.mLockTaskModeTask != null)
8636 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8637 mStackSupervisor.showLockTaskToast();
8640 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8643 Binder.restoreCallingIdentity(origId);
8650 public void moveTaskBackwards(int task) {
8651 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8652 "moveTaskBackwards()");
8654 synchronized(this) {
8655 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8656 Binder.getCallingUid(), -1, -1, "Task backwards")) {
8659 final long origId = Binder.clearCallingIdentity();
8660 moveTaskBackwardsLocked(task);
8661 Binder.restoreCallingIdentity(origId);
8665 private final void moveTaskBackwardsLocked(int task) {
8666 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8670 public IBinder getHomeActivityToken() throws RemoteException {
8671 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8672 "getHomeActivityToken()");
8673 synchronized (this) {
8674 return mStackSupervisor.getHomeActivityToken();
8679 public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8680 IActivityContainerCallback callback) throws RemoteException {
8681 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8682 "createActivityContainer()");
8683 synchronized (this) {
8684 if (parentActivityToken == null) {
8685 throw new IllegalArgumentException("parent token must not be null");
8687 ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8691 if (callback == null) {
8692 throw new IllegalArgumentException("callback must not be null");
8694 return mStackSupervisor.createActivityContainer(r, callback);
8699 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8700 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8701 "deleteActivityContainer()");
8702 synchronized (this) {
8703 mStackSupervisor.deleteActivityContainer(container);
8708 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8709 synchronized (this) {
8710 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8711 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8712 return stack.mActivityContainer.getDisplayId();
8714 return Display.DEFAULT_DISPLAY;
8719 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8720 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8721 "moveTaskToStack()");
8722 if (stackId == HOME_STACK_ID) {
8723 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8724 new RuntimeException("here").fillInStackTrace());
8726 synchronized (this) {
8727 long ident = Binder.clearCallingIdentity();
8729 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8730 + stackId + " toTop=" + toTop);
8731 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8733 Binder.restoreCallingIdentity(ident);
8739 public void resizeStack(int stackBoxId, Rect bounds) {
8740 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8741 "resizeStackBox()");
8742 long ident = Binder.clearCallingIdentity();
8744 mWindowManager.resizeStack(stackBoxId, bounds);
8746 Binder.restoreCallingIdentity(ident);
8751 public List<StackInfo> getAllStackInfos() {
8752 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8753 "getAllStackInfos()");
8754 long ident = Binder.clearCallingIdentity();
8756 synchronized (this) {
8757 return mStackSupervisor.getAllStackInfosLocked();
8760 Binder.restoreCallingIdentity(ident);
8765 public StackInfo getStackInfo(int stackId) {
8766 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8768 long ident = Binder.clearCallingIdentity();
8770 synchronized (this) {
8771 return mStackSupervisor.getStackInfoLocked(stackId);
8774 Binder.restoreCallingIdentity(ident);
8779 public boolean isInHomeStack(int taskId) {
8780 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8782 long ident = Binder.clearCallingIdentity();
8784 synchronized (this) {
8785 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId);
8786 return tr != null && tr.stack != null && tr.stack.isHomeStack();
8789 Binder.restoreCallingIdentity(ident);
8794 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8795 synchronized(this) {
8796 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8800 private boolean isLockTaskAuthorized(String pkg) {
8801 final DevicePolicyManager dpm = (DevicePolicyManager)
8802 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8804 int uid = mContext.getPackageManager().getPackageUid(pkg,
8805 Binder.getCallingUserHandle().getIdentifier());
8806 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8807 } catch (NameNotFoundException e) {
8812 void startLockTaskMode(TaskRecord task) {
8814 synchronized (this) {
8815 pkg = task.intent.getComponent().getPackageName();
8817 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8818 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8819 StatusBarManagerInternal statusBarManager = LocalServices.getService(
8820 StatusBarManagerInternal.class);
8821 if (statusBarManager != null) {
8822 statusBarManager.showScreenPinningRequest();
8826 long ident = Binder.clearCallingIdentity();
8828 synchronized (this) {
8829 // Since we lost lock on task, make sure it is still there.
8830 task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8832 if (!isSystemInitiated
8833 && ((mStackSupervisor.getFocusedStack() == null)
8834 || (task != mStackSupervisor.getFocusedStack().topTask()))) {
8835 throw new IllegalArgumentException("Invalid task, not in foreground");
8837 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated,
8842 Binder.restoreCallingIdentity(ident);
8847 public void startLockTaskMode(int taskId) {
8848 final TaskRecord task;
8849 long ident = Binder.clearCallingIdentity();
8851 synchronized (this) {
8852 task = mStackSupervisor.anyTaskForIdLocked(taskId);
8855 Binder.restoreCallingIdentity(ident);
8858 startLockTaskMode(task);
8863 public void startLockTaskMode(IBinder token) {
8864 final TaskRecord task;
8865 long ident = Binder.clearCallingIdentity();
8867 synchronized (this) {
8868 final ActivityRecord r = ActivityRecord.forToken(token);
8875 Binder.restoreCallingIdentity(ident);
8878 startLockTaskMode(task);
8883 public void startLockTaskModeOnCurrent() throws RemoteException {
8884 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8885 "startLockTaskModeOnCurrent");
8886 long ident = Binder.clearCallingIdentity();
8888 ActivityRecord r = null;
8889 synchronized (this) {
8890 r = mStackSupervisor.topRunningActivityLocked();
8892 startLockTaskMode(r.task);
8894 Binder.restoreCallingIdentity(ident);
8899 public void stopLockTaskMode() {
8900 // Verify that the user matches the package of the intent for the TaskRecord
8901 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode
8902 // and stopLockTaskMode.
8903 final int callingUid = Binder.getCallingUid();
8904 if (callingUid != Process.SYSTEM_UID) {
8907 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8908 int uid = mContext.getPackageManager().getPackageUid(pkg,
8909 Binder.getCallingUserHandle().getIdentifier());
8910 if (uid != callingUid) {
8911 throw new SecurityException("Invalid uid, expected " + uid);
8913 } catch (NameNotFoundException e) {
8914 Log.d(TAG, "stopLockTaskMode " + e);
8918 long ident = Binder.clearCallingIdentity();
8920 Log.d(TAG, "stopLockTaskMode");
8922 synchronized (this) {
8923 mStackSupervisor.setLockTaskModeLocked(null, false, "stopLockTask");
8926 Binder.restoreCallingIdentity(ident);
8931 public void stopLockTaskModeOnCurrent() throws RemoteException {
8932 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8933 "stopLockTaskModeOnCurrent");
8934 long ident = Binder.clearCallingIdentity();
8938 Binder.restoreCallingIdentity(ident);
8943 public boolean isInLockTaskMode() {
8944 synchronized (this) {
8945 return mStackSupervisor.isInLockTaskMode();
8949 // =========================================================
8950 // CONTENT PROVIDERS
8951 // =========================================================
8953 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8954 List<ProviderInfo> providers = null;
8956 providers = AppGlobals.getPackageManager().
8957 queryContentProviders(app.processName, app.uid,
8958 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8959 } catch (RemoteException ex) {
8962 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8963 int userId = app.userId;
8964 if (providers != null) {
8965 int N = providers.size();
8966 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8967 for (int i=0; i<N; i++) {
8969 (ProviderInfo)providers.get(i);
8970 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8971 cpi.name, cpi.flags);
8972 if (singleton && UserHandle.getUserId(app.uid) != 0) {
8973 // This is a singleton provider, but a user besides the
8974 // default user is asking to initialize a process it runs
8975 // in... well, no, it doesn't actually run in this process,
8976 // it runs in the process of the default user. Get rid of it.
8977 providers.remove(i);
8983 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8984 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8986 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8987 mProviderMap.putProviderByClass(comp, cpr);
8990 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8991 app.pubProviders.put(cpi.name, cpr);
8992 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8993 // Don't add this if it is a platform component that is marked
8994 // to run in multiple processes, because this is actually
8995 // part of the framework so doesn't make sense to track as a
8996 // separate apk in the process.
8997 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9000 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9007 * Check if the calling UID has a possible chance at accessing the provider
9008 * at the given authority and user.
9010 public String checkContentProviderAccess(String authority, int userId) {
9011 if (userId == UserHandle.USER_ALL) {
9012 mContext.enforceCallingOrSelfPermission(
9013 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
9014 userId = UserHandle.getCallingUserId();
9017 ProviderInfo cpi = null;
9019 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
9020 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9021 } catch (RemoteException ignored) {
9024 // TODO: make this an outright failure in a future platform release;
9025 // until then anonymous content notifications are unprotected
9026 //return "Failed to find provider " + authority + " for user " + userId;
9030 ProcessRecord r = null;
9031 synchronized (mPidsSelfLocked) {
9032 r = mPidsSelfLocked.get(Binder.getCallingPid());
9035 return "Failed to find PID " + Binder.getCallingPid();
9038 synchronized (this) {
9039 return checkContentProviderPermissionLocked(cpi, r, userId, true);
9045 * Check if {@link ProcessRecord} has a possible chance at accessing the
9046 * given {@link ProviderInfo}. Final permission checking is always done
9047 * in {@link ContentProvider}.
9049 private final String checkContentProviderPermissionLocked(
9050 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9051 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9052 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9053 boolean checkedGrants = false;
9055 // Looking for cross-user grants before enforcing the typical cross-users permissions
9056 int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9057 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9058 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9061 checkedGrants = true;
9063 userId = handleIncomingUser(callingPid, callingUid, userId,
9064 false, ALLOW_NON_FULL,
9065 "checkContentProviderPermissionLocked " + cpi.authority, null);
9066 if (userId != tmpTargetUserId) {
9067 // When we actually went to determine the final targer user ID, this ended
9068 // up different than our initial check for the authority. This is because
9069 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9070 // SELF. So we need to re-check the grants again.
9071 checkedGrants = false;
9074 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9075 cpi.applicationInfo.uid, cpi.exported)
9076 == PackageManager.PERMISSION_GRANTED) {
9079 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9080 cpi.applicationInfo.uid, cpi.exported)
9081 == PackageManager.PERMISSION_GRANTED) {
9085 PathPermission[] pps = cpi.pathPermissions;
9090 PathPermission pp = pps[i];
9091 String pprperm = pp.getReadPermission();
9092 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9093 cpi.applicationInfo.uid, cpi.exported)
9094 == PackageManager.PERMISSION_GRANTED) {
9097 String ppwperm = pp.getWritePermission();
9098 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9099 cpi.applicationInfo.uid, cpi.exported)
9100 == PackageManager.PERMISSION_GRANTED) {
9105 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9110 if (!cpi.exported) {
9111 msg = "Permission Denial: opening provider " + cpi.name
9112 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9113 + ", uid=" + callingUid + ") that is not exported from uid "
9114 + cpi.applicationInfo.uid;
9116 msg = "Permission Denial: opening provider " + cpi.name
9117 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9118 + ", uid=" + callingUid + ") requires "
9119 + cpi.readPermission + " or " + cpi.writePermission;
9126 * Returns if the ContentProvider has granted a uri to callingUid
9128 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9129 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9130 if (perms != null) {
9131 for (int i=perms.size()-1; i>=0; i--) {
9132 GrantUri grantUri = perms.keyAt(i);
9133 if (grantUri.sourceUserId == userId || !checkUser) {
9134 if (matchesProvider(grantUri.uri, cpi)) {
9144 * Returns true if the uri authority is one of the authorities specified in the provider.
9146 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9147 String uriAuth = uri.getAuthority();
9148 String cpiAuth = cpi.authority;
9149 if (cpiAuth.indexOf(';') == -1) {
9150 return cpiAuth.equals(uriAuth);
9152 String[] cpiAuths = cpiAuth.split(";");
9153 int length = cpiAuths.length;
9154 for (int i = 0; i < length; i++) {
9155 if (cpiAuths[i].equals(uriAuth)) return true;
9160 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9161 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9163 for (int i=0; i<r.conProviders.size(); i++) {
9164 ContentProviderConnection conn = r.conProviders.get(i);
9165 if (conn.provider == cpr) {
9166 if (DEBUG_PROVIDER) Slog.v(TAG,
9167 "Adding provider requested by "
9168 + r.processName + " from process "
9169 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9170 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9173 conn.numStableIncs++;
9175 conn.unstableCount++;
9176 conn.numUnstableIncs++;
9181 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9183 conn.stableCount = 1;
9184 conn.numStableIncs = 1;
9186 conn.unstableCount = 1;
9187 conn.numUnstableIncs = 1;
9189 cpr.connections.add(conn);
9190 r.conProviders.add(conn);
9191 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9194 cpr.addExternalProcessHandleLocked(externalProcessToken);
9198 boolean decProviderCountLocked(ContentProviderConnection conn,
9199 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9201 cpr = conn.provider;
9202 if (DEBUG_PROVIDER) Slog.v(TAG,
9203 "Removing provider requested by "
9204 + conn.client.processName + " from process "
9205 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9206 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9210 conn.unstableCount--;
9212 if (conn.stableCount == 0 && conn.unstableCount == 0) {
9213 cpr.connections.remove(conn);
9214 conn.client.conProviders.remove(conn);
9215 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9220 cpr.removeExternalProcessHandleLocked(externalProcessToken);
9224 private void checkTime(long startTime, String where) {
9225 long now = SystemClock.elapsedRealtime();
9226 if ((now-startTime) > 1000) {
9227 // If we are taking more than a second, log about it.
9228 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9232 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9233 String name, IBinder token, boolean stable, int userId) {
9234 ContentProviderRecord cpr;
9235 ContentProviderConnection conn = null;
9236 ProviderInfo cpi = null;
9238 synchronized(this) {
9239 long startTime = SystemClock.elapsedRealtime();
9241 ProcessRecord r = null;
9242 if (caller != null) {
9243 r = getRecordForAppLocked(caller);
9245 throw new SecurityException(
9246 "Unable to find app for caller " + caller
9247 + " (pid=" + Binder.getCallingPid()
9248 + ") when getting content provider " + name);
9252 boolean checkCrossUser = true;
9254 checkTime(startTime, "getContentProviderImpl: getProviderByName");
9256 // First check if this content provider has been published...
9257 cpr = mProviderMap.getProviderByName(name, userId);
9258 // If that didn't work, check if it exists for user 0 and then
9259 // verify that it's a singleton provider before using it.
9260 if (cpr == null && userId != UserHandle.USER_OWNER) {
9261 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9264 if (isSingleton(cpi.processName, cpi.applicationInfo,
9265 cpi.name, cpi.flags)
9266 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9267 userId = UserHandle.USER_OWNER;
9268 checkCrossUser = false;
9276 boolean providerRunning = cpr != null;
9277 if (providerRunning) {
9280 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9281 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9283 throw new SecurityException(msg);
9285 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9287 if (r != null && cpr.canRunHere(r)) {
9288 // This provider has been published or is in the process
9289 // of being published... but it is also allowed to run
9290 // in the caller's process, so don't make a connection
9291 // and just let the caller instantiate its own instance.
9292 ContentProviderHolder holder = cpr.newHolder(null);
9293 // don't give caller the provider object, it needs
9295 holder.provider = null;
9299 final long origId = Binder.clearCallingIdentity();
9301 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9303 // In this case the provider instance already exists, so we can
9304 // return it right away.
9305 conn = incProviderCountLocked(r, cpr, token, stable);
9306 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9307 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9308 // If this is a perceptible app accessing the provider,
9309 // make sure to count it as being accessed and thus
9310 // back up on the LRU list. This is good because
9311 // content providers are often expensive to start.
9312 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9313 updateLruProcessLocked(cpr.proc, false, null);
9314 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9318 if (cpr.proc != null) {
9320 if (cpr.name.flattenToShortString().equals(
9321 "com.android.providers.calendar/.CalendarProvider2")) {
9322 Slog.v(TAG, "****************** KILLING "
9323 + cpr.name.flattenToShortString());
9324 Process.killProcess(cpr.proc.pid);
9327 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9328 boolean success = updateOomAdjLocked(cpr.proc);
9329 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9330 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9331 // NOTE: there is still a race here where a signal could be
9332 // pending on the process even though we managed to update its
9333 // adj level. Not sure what to do about this, but at least
9334 // the race is now smaller.
9336 // Uh oh... it looks like the provider's process
9337 // has been killed on us. We need to wait for a new
9338 // process to be started, and make sure its death
9339 // doesn't kill our process.
9341 "Existing provider " + cpr.name.flattenToShortString()
9342 + " is crashing; detaching " + r);
9343 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9344 checkTime(startTime, "getContentProviderImpl: before appDied");
9345 appDiedLocked(cpr.proc);
9346 checkTime(startTime, "getContentProviderImpl: after appDied");
9348 // This wasn't the last ref our process had on
9349 // the provider... we have now been killed, bail.
9352 providerRunning = false;
9357 Binder.restoreCallingIdentity(origId);
9361 if (!providerRunning) {
9363 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9364 cpi = AppGlobals.getPackageManager().
9365 resolveContentProvider(name,
9366 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9367 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9368 } catch (RemoteException ex) {
9373 // If the provider is a singleton AND
9374 // (it's a call within the same user || the provider is a
9376 // Then allow connecting to the singleton provider
9377 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9378 cpi.name, cpi.flags)
9379 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9381 userId = UserHandle.USER_OWNER;
9383 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9384 checkTime(startTime, "getContentProviderImpl: got app info for user");
9387 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9388 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9390 throw new SecurityException(msg);
9392 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9394 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9395 && !cpi.processName.equals("system")) {
9396 // If this content provider does not run in the system
9397 // process, and the system is not yet ready to run other
9398 // processes, then fail fast instead of hanging.
9399 throw new IllegalArgumentException(
9400 "Attempt to launch content provider before system ready");
9403 // Make sure that the user who owns this provider is running. If not,
9404 // we don't want to allow it to run.
9405 if (!isUserRunningLocked(userId, false)) {
9406 Slog.w(TAG, "Unable to launch app "
9407 + cpi.applicationInfo.packageName + "/"
9408 + cpi.applicationInfo.uid + " for provider "
9409 + name + ": user " + userId + " is stopped");
9413 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9414 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9415 cpr = mProviderMap.getProviderByClass(comp, userId);
9416 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9417 final boolean firstClass = cpr == null;
9419 final long ident = Binder.clearCallingIdentity();
9421 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9422 ApplicationInfo ai =
9423 AppGlobals.getPackageManager().
9425 cpi.applicationInfo.packageName,
9426 STOCK_PM_FLAGS, userId);
9427 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9429 Slog.w(TAG, "No package info for content provider "
9433 ai = getAppInfoForUser(ai, userId);
9434 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9435 } catch (RemoteException ex) {
9436 // pm is in same process, this will never happen.
9438 Binder.restoreCallingIdentity(ident);
9442 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9444 if (r != null && cpr.canRunHere(r)) {
9445 // If this is a multiprocess provider, then just return its
9446 // info and allow the caller to instantiate it. Only do
9447 // this if the provider is the same user as the caller's
9448 // process, or can run as root (so can be in any process).
9449 return cpr.newHolder(null);
9452 if (DEBUG_PROVIDER) {
9453 RuntimeException e = new RuntimeException("here");
9454 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9455 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9458 // This is single process, and our app is now connecting to it.
9459 // See if we are already in the process of launching this
9461 final int N = mLaunchingProviders.size();
9463 for (i=0; i<N; i++) {
9464 if (mLaunchingProviders.get(i) == cpr) {
9469 // If the provider is not already being launched, then get it
9472 final long origId = Binder.clearCallingIdentity();
9475 // Content provider is now in use, its package can't be stopped.
9477 checkTime(startTime, "getContentProviderImpl: before set stopped state");
9478 AppGlobals.getPackageManager().setPackageStoppedState(
9479 cpr.appInfo.packageName, false, userId);
9480 checkTime(startTime, "getContentProviderImpl: after set stopped state");
9481 } catch (RemoteException e) {
9482 } catch (IllegalArgumentException e) {
9483 Slog.w(TAG, "Failed trying to unstop package "
9484 + cpr.appInfo.packageName + ": " + e);
9487 // Use existing process if already started
9488 checkTime(startTime, "getContentProviderImpl: looking for process record");
9489 ProcessRecord proc = getProcessRecordLocked(
9490 cpi.processName, cpr.appInfo.uid, false);
9491 if (proc != null && proc.thread != null) {
9492 if (DEBUG_PROVIDER) {
9493 Slog.d(TAG, "Installing in existing process " + proc);
9495 checkTime(startTime, "getContentProviderImpl: scheduling install");
9496 proc.pubProviders.put(cpi.name, cpr);
9498 proc.thread.scheduleInstallProvider(cpi);
9499 } catch (RemoteException e) {
9502 checkTime(startTime, "getContentProviderImpl: before start process");
9503 proc = startProcessLocked(cpi.processName,
9504 cpr.appInfo, false, 0, "content provider",
9505 new ComponentName(cpi.applicationInfo.packageName,
9506 cpi.name), false, false, false);
9507 checkTime(startTime, "getContentProviderImpl: after start process");
9509 Slog.w(TAG, "Unable to launch app "
9510 + cpi.applicationInfo.packageName + "/"
9511 + cpi.applicationInfo.uid + " for provider "
9512 + name + ": process is bad");
9516 cpr.launchingApp = proc;
9517 mLaunchingProviders.add(cpr);
9519 Binder.restoreCallingIdentity(origId);
9523 checkTime(startTime, "getContentProviderImpl: updating data structures");
9525 // Make sure the provider is published (the same provider class
9526 // may be published under multiple names).
9528 mProviderMap.putProviderByClass(comp, cpr);
9531 mProviderMap.putProviderByName(name, cpr);
9532 conn = incProviderCountLocked(r, cpr, token, stable);
9534 conn.waiting = true;
9537 checkTime(startTime, "getContentProviderImpl: done!");
9540 // Wait for the provider to be published...
9541 synchronized (cpr) {
9542 while (cpr.provider == null) {
9543 if (cpr.launchingApp == null) {
9544 Slog.w(TAG, "Unable to launch app "
9545 + cpi.applicationInfo.packageName + "/"
9546 + cpi.applicationInfo.uid + " for provider "
9547 + name + ": launching app became null");
9548 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9549 UserHandle.getUserId(cpi.applicationInfo.uid),
9550 cpi.applicationInfo.packageName,
9551 cpi.applicationInfo.uid, name);
9556 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9557 + cpr.launchingApp);
9560 conn.waiting = true;
9563 } catch (InterruptedException ex) {
9566 conn.waiting = false;
9571 return cpr != null ? cpr.newHolder(conn) : null;
9575 public final ContentProviderHolder getContentProvider(
9576 IApplicationThread caller, String name, int userId, boolean stable) {
9577 enforceNotIsolatedCaller("getContentProvider");
9578 if (caller == null) {
9579 String msg = "null IApplicationThread when getting content provider "
9582 throw new SecurityException(msg);
9584 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9585 // with cross-user grant.
9586 return getContentProviderImpl(caller, name, null, stable, userId);
9589 public ContentProviderHolder getContentProviderExternal(
9590 String name, int userId, IBinder token) {
9591 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9592 "Do not have permission in call getContentProviderExternal()");
9593 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9594 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9595 return getContentProviderExternalUnchecked(name, token, userId);
9598 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9599 IBinder token, int userId) {
9600 return getContentProviderImpl(null, name, token, true, userId);
9604 * Drop a content provider from a ProcessRecord's bookkeeping
9606 public void removeContentProvider(IBinder connection, boolean stable) {
9607 enforceNotIsolatedCaller("removeContentProvider");
9608 long ident = Binder.clearCallingIdentity();
9610 synchronized (this) {
9611 ContentProviderConnection conn;
9613 conn = (ContentProviderConnection)connection;
9614 } catch (ClassCastException e) {
9615 String msg ="removeContentProvider: " + connection
9616 + " not a ContentProviderConnection";
9618 throw new IllegalArgumentException(msg);
9621 throw new NullPointerException("connection is null");
9623 if (decProviderCountLocked(conn, null, null, stable)) {
9624 updateOomAdjLocked();
9628 Binder.restoreCallingIdentity(ident);
9632 public void removeContentProviderExternal(String name, IBinder token) {
9633 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9634 "Do not have permission in call removeContentProviderExternal()");
9635 int userId = UserHandle.getCallingUserId();
9636 long ident = Binder.clearCallingIdentity();
9638 removeContentProviderExternalUnchecked(name, token, userId);
9640 Binder.restoreCallingIdentity(ident);
9644 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9645 synchronized (this) {
9646 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9648 //remove from mProvidersByClass
9649 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9653 //update content provider record entry info
9654 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9655 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9656 if (localCpr.hasExternalProcessHandles()) {
9657 if (localCpr.removeExternalProcessHandleLocked(token)) {
9658 updateOomAdjLocked();
9660 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9661 + " with no external reference for token: "
9665 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9666 + " with no external references.");
9671 public final void publishContentProviders(IApplicationThread caller,
9672 List<ContentProviderHolder> providers) {
9673 if (providers == null) {
9677 enforceNotIsolatedCaller("publishContentProviders");
9678 synchronized (this) {
9679 final ProcessRecord r = getRecordForAppLocked(caller);
9681 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9683 throw new SecurityException(
9684 "Unable to find app for caller " + caller
9685 + " (pid=" + Binder.getCallingPid()
9686 + ") when publishing content providers");
9689 final long origId = Binder.clearCallingIdentity();
9691 final int N = providers.size();
9692 for (int i=0; i<N; i++) {
9693 ContentProviderHolder src = providers.get(i);
9694 if (src == null || src.info == null || src.provider == null) {
9697 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9699 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9701 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9702 mProviderMap.putProviderByClass(comp, dst);
9703 String names[] = dst.info.authority.split(";");
9704 for (int j = 0; j < names.length; j++) {
9705 mProviderMap.putProviderByName(names[j], dst);
9708 int NL = mLaunchingProviders.size();
9710 for (j=0; j<NL; j++) {
9711 if (mLaunchingProviders.get(j) == dst) {
9712 mLaunchingProviders.remove(j);
9717 synchronized (dst) {
9718 dst.provider = src.provider;
9722 updateOomAdjLocked(r);
9726 Binder.restoreCallingIdentity(origId);
9730 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9731 ContentProviderConnection conn;
9733 conn = (ContentProviderConnection)connection;
9734 } catch (ClassCastException e) {
9735 String msg ="refContentProvider: " + connection
9736 + " not a ContentProviderConnection";
9738 throw new IllegalArgumentException(msg);
9741 throw new NullPointerException("connection is null");
9744 synchronized (this) {
9746 conn.numStableIncs += stable;
9748 stable = conn.stableCount + stable;
9750 throw new IllegalStateException("stableCount < 0: " + stable);
9754 conn.numUnstableIncs += unstable;
9756 unstable = conn.unstableCount + unstable;
9758 throw new IllegalStateException("unstableCount < 0: " + unstable);
9761 if ((stable+unstable) <= 0) {
9762 throw new IllegalStateException("ref counts can't go to zero here: stable="
9763 + stable + " unstable=" + unstable);
9765 conn.stableCount = stable;
9766 conn.unstableCount = unstable;
9771 public void unstableProviderDied(IBinder connection) {
9772 ContentProviderConnection conn;
9774 conn = (ContentProviderConnection)connection;
9775 } catch (ClassCastException e) {
9776 String msg ="refContentProvider: " + connection
9777 + " not a ContentProviderConnection";
9779 throw new IllegalArgumentException(msg);
9782 throw new NullPointerException("connection is null");
9785 // Safely retrieve the content provider associated with the connection.
9786 IContentProvider provider;
9787 synchronized (this) {
9788 provider = conn.provider.provider;
9791 if (provider == null) {
9792 // Um, yeah, we're way ahead of you.
9796 // Make sure the caller is being honest with us.
9797 if (provider.asBinder().pingBinder()) {
9798 // Er, no, still looks good to us.
9799 synchronized (this) {
9800 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9801 + " says " + conn + " died, but we don't agree");
9806 // Well look at that! It's dead!
9807 synchronized (this) {
9808 if (conn.provider.provider != provider) {
9809 // But something changed... good enough.
9813 ProcessRecord proc = conn.provider.proc;
9814 if (proc == null || proc.thread == null) {
9815 // Seems like the process is already cleaned up.
9819 // As far as we're concerned, this is just like receiving a
9820 // death notification... just a bit prematurely.
9821 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9822 + ") early provider death");
9823 final long ident = Binder.clearCallingIdentity();
9825 appDiedLocked(proc);
9827 Binder.restoreCallingIdentity(ident);
9833 public void appNotRespondingViaProvider(IBinder connection) {
9834 enforceCallingPermission(
9835 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9837 final ContentProviderConnection conn = (ContentProviderConnection) connection;
9839 Slog.w(TAG, "ContentProviderConnection is null");
9843 final ProcessRecord host = conn.provider.proc;
9845 Slog.w(TAG, "Failed to find hosting ProcessRecord");
9849 final long token = Binder.clearCallingIdentity();
9851 appNotResponding(host, null, null, false, "ContentProvider not responding");
9853 Binder.restoreCallingIdentity(token);
9857 public final void installSystemProviders() {
9858 List<ProviderInfo> providers;
9859 synchronized (this) {
9860 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9861 providers = generateApplicationProvidersLocked(app);
9862 if (providers != null) {
9863 for (int i=providers.size()-1; i>=0; i--) {
9864 ProviderInfo pi = (ProviderInfo)providers.get(i);
9865 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9866 Slog.w(TAG, "Not installing system proc provider " + pi.name
9867 + ": not system .apk");
9868 providers.remove(i);
9873 if (providers != null) {
9874 mSystemThread.installSystemProviders(providers);
9877 mCoreSettingsObserver = new CoreSettingsObserver(this);
9879 //mUsageStatsService.monitorPackages();
9883 * Allows apps to retrieve the MIME type of a URI.
9884 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9885 * users, then it does not need permission to access the ContentProvider.
9886 * Either, it needs cross-user uri grants.
9888 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9890 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9891 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9893 public String getProviderMimeType(Uri uri, int userId) {
9894 enforceNotIsolatedCaller("getProviderMimeType");
9895 final String name = uri.getAuthority();
9896 int callingUid = Binder.getCallingUid();
9897 int callingPid = Binder.getCallingPid();
9899 boolean clearedIdentity = false;
9900 userId = unsafeConvertIncomingUser(userId);
9901 if (canClearIdentity(callingPid, callingUid, userId)) {
9902 clearedIdentity = true;
9903 ident = Binder.clearCallingIdentity();
9905 ContentProviderHolder holder = null;
9907 holder = getContentProviderExternalUnchecked(name, null, userId);
9908 if (holder != null) {
9909 return holder.provider.getType(uri);
9911 } catch (RemoteException e) {
9912 Log.w(TAG, "Content provider dead retrieving " + uri, e);
9915 // We need to clear the identity to call removeContentProviderExternalUnchecked
9916 if (!clearedIdentity) {
9917 ident = Binder.clearCallingIdentity();
9920 if (holder != null) {
9921 removeContentProviderExternalUnchecked(name, null, userId);
9924 Binder.restoreCallingIdentity(ident);
9931 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9932 if (UserHandle.getUserId(callingUid) == userId) {
9935 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9936 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9937 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9938 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9944 // =========================================================
9945 // GLOBAL MANAGEMENT
9946 // =========================================================
9948 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9949 boolean isolated, int isolatedUid) {
9950 String proc = customProcess != null ? customProcess : info.processName;
9951 BatteryStatsImpl.Uid.Proc ps = null;
9952 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9953 final int userId = UserHandle.getUserId(info.uid);
9956 if (isolatedUid == 0) {
9957 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9959 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9960 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9961 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9963 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9964 mNextIsolatedProcessUid++;
9965 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9966 // No process for this uid, use it.
9970 if (stepsLeft <= 0) {
9975 // Special case for startIsolatedProcess (internal only), where
9976 // the uid of the isolated process is specified by the caller.
9980 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
9981 if (!mBooted && !mBooting
9982 && userId == UserHandle.USER_OWNER
9983 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
9984 r.persistent = true;
9989 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9990 String abiOverride) {
9993 app = getProcessRecordLocked(info.processName, info.uid, true);
9999 app = newProcessRecordLocked(info, null, isolated, 0);
10000 mProcessNames.put(info.processName, app.uid, app);
10002 mIsolatedProcesses.put(app.uid, app);
10004 updateLruProcessLocked(app, false, null);
10005 updateOomAdjLocked();
10008 // This package really, really can not be stopped.
10010 AppGlobals.getPackageManager().setPackageStoppedState(
10011 info.packageName, false, UserHandle.getUserId(app.uid));
10012 } catch (RemoteException e) {
10013 } catch (IllegalArgumentException e) {
10014 Slog.w(TAG, "Failed trying to unstop package "
10015 + info.packageName + ": " + e);
10018 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10019 app.persistent = true;
10020 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10022 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10023 mPersistentStartingProcesses.add(app);
10024 startProcessLocked(app, "added application", app.processName, abiOverride,
10025 null /* entryPoint */, null /* entryPointArgs */);
10031 public void unhandledBack() {
10032 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10033 "unhandledBack()");
10035 synchronized(this) {
10036 final long origId = Binder.clearCallingIdentity();
10038 getFocusedStack().unhandledBackLocked();
10040 Binder.restoreCallingIdentity(origId);
10045 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10046 enforceNotIsolatedCaller("openContentUri");
10047 final int userId = UserHandle.getCallingUserId();
10048 String name = uri.getAuthority();
10049 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10050 ParcelFileDescriptor pfd = null;
10052 // We record the binder invoker's uid in thread-local storage before
10053 // going to the content provider to open the file. Later, in the code
10054 // that handles all permissions checks, we look for this uid and use
10055 // that rather than the Activity Manager's own uid. The effect is that
10056 // we do the check against the caller's permissions even though it looks
10057 // to the content provider like the Activity Manager itself is making
10059 Binder token = new Binder();
10060 sCallerIdentity.set(new Identity(
10061 token, Binder.getCallingPid(), Binder.getCallingUid()));
10063 pfd = cph.provider.openFile(null, uri, "r", null, token);
10064 } catch (FileNotFoundException e) {
10065 // do nothing; pfd will be returned null
10067 // Ensure that whatever happens, we clean up the identity state
10068 sCallerIdentity.remove();
10071 // We've got the fd now, so we're done with the provider.
10072 removeContentProviderExternalUnchecked(name, null, userId);
10074 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10079 // Actually is sleeping or shutting down or whatever else in the future
10080 // is an inactive state.
10081 public boolean isSleepingOrShuttingDown() {
10082 return isSleeping() || mShuttingDown;
10085 public boolean isSleeping() {
10089 void onWakefulnessChanged(int wakefulness) {
10090 synchronized(this) {
10091 mWakefulness = wakefulness;
10092 updateSleepIfNeededLocked();
10096 void finishRunningVoiceLocked() {
10097 if (mRunningVoice) {
10098 mRunningVoice = false;
10099 updateSleepIfNeededLocked();
10103 void updateSleepIfNeededLocked() {
10104 if (mSleeping && !shouldSleepLocked()) {
10106 mStackSupervisor.comeOutOfSleepIfNeededLocked();
10107 } else if (!mSleeping && shouldSleepLocked()) {
10109 mStackSupervisor.goingToSleepLocked();
10111 // Initialize the wake times of all processes.
10112 checkExcessivePowerUsageLocked(false);
10113 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10114 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10115 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10119 private boolean shouldSleepLocked() {
10120 // Resume applications while running a voice interactor.
10121 if (mRunningVoice) {
10125 switch (mWakefulness) {
10126 case PowerManagerInternal.WAKEFULNESS_AWAKE:
10127 case PowerManagerInternal.WAKEFULNESS_DREAMING:
10128 // If we're interactive but applications are already paused then defer
10129 // resuming them until the lock screen is hidden.
10130 return mSleeping && mLockScreenShown != LOCK_SCREEN_HIDDEN;
10131 case PowerManagerInternal.WAKEFULNESS_DOZING:
10132 // If we're dozing then pause applications whenever the lock screen is shown.
10133 return mLockScreenShown != LOCK_SCREEN_HIDDEN;
10134 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10136 // If we're asleep then pause applications unconditionally.
10141 /** Pokes the task persister. */
10142 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10143 if (task != null && task.stack != null && task.stack.isHomeStack()) {
10144 // Never persist the home stack.
10147 mTaskPersister.wakeup(task, flush);
10150 /** Notifies all listeners when the task stack has changed. */
10151 void notifyTaskStackChangedLocked() {
10152 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10153 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10154 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10158 public boolean shutdown(int timeout) {
10159 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10160 != PackageManager.PERMISSION_GRANTED) {
10161 throw new SecurityException("Requires permission "
10162 + android.Manifest.permission.SHUTDOWN);
10165 boolean timedout = false;
10167 synchronized(this) {
10168 mShuttingDown = true;
10169 updateEventDispatchingLocked();
10170 timedout = mStackSupervisor.shutdownLocked(timeout);
10173 mAppOpsService.shutdown();
10174 if (mUsageStatsService != null) {
10175 mUsageStatsService.prepareShutdown();
10177 mBatteryStatsService.shutdown();
10178 synchronized (this) {
10179 mProcessStats.shutdownLocked();
10180 notifyTaskPersisterLocked(null, true);
10186 public final void activitySlept(IBinder token) {
10187 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10189 final long origId = Binder.clearCallingIdentity();
10191 synchronized (this) {
10192 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10194 mStackSupervisor.activitySleptLocked(r);
10198 Binder.restoreCallingIdentity(origId);
10201 private String lockScreenShownToString() {
10202 switch (mLockScreenShown) {
10203 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10204 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10205 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10206 default: return "Unknown=" + mLockScreenShown;
10210 void logLockScreen(String msg) {
10211 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10212 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10213 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10214 + " mSleeping=" + mSleeping);
10217 void startRunningVoiceLocked() {
10218 if (!mRunningVoice) {
10219 mRunningVoice = true;
10220 updateSleepIfNeededLocked();
10224 private void updateEventDispatchingLocked() {
10225 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10228 public void setLockScreenShown(boolean shown) {
10229 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10230 != PackageManager.PERMISSION_GRANTED) {
10231 throw new SecurityException("Requires permission "
10232 + android.Manifest.permission.DEVICE_POWER);
10235 synchronized(this) {
10236 long ident = Binder.clearCallingIdentity();
10238 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10239 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10240 updateSleepIfNeededLocked();
10242 Binder.restoreCallingIdentity(ident);
10248 public void stopAppSwitches() {
10249 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10250 != PackageManager.PERMISSION_GRANTED) {
10251 throw new SecurityException("Requires permission "
10252 + android.Manifest.permission.STOP_APP_SWITCHES);
10255 synchronized(this) {
10256 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10257 + APP_SWITCH_DELAY_TIME;
10258 mDidAppSwitch = false;
10259 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10260 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10261 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10265 public void resumeAppSwitches() {
10266 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10267 != PackageManager.PERMISSION_GRANTED) {
10268 throw new SecurityException("Requires permission "
10269 + android.Manifest.permission.STOP_APP_SWITCHES);
10272 synchronized(this) {
10273 // Note that we don't execute any pending app switches... we will
10274 // let those wait until either the timeout, or the next start
10275 // activity request.
10276 mAppSwitchesAllowedTime = 0;
10280 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10281 int callingPid, int callingUid, String name) {
10282 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10286 int perm = checkComponentPermission(
10287 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10288 sourceUid, -1, true);
10289 if (perm == PackageManager.PERMISSION_GRANTED) {
10293 // If the actual IPC caller is different from the logical source, then
10294 // also see if they are allowed to control app switches.
10295 if (callingUid != -1 && callingUid != sourceUid) {
10296 perm = checkComponentPermission(
10297 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10298 callingUid, -1, true);
10299 if (perm == PackageManager.PERMISSION_GRANTED) {
10304 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10308 public void setDebugApp(String packageName, boolean waitForDebugger,
10309 boolean persistent) {
10310 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10313 long ident = Binder.clearCallingIdentity();
10315 // Note that this is not really thread safe if there are multiple
10316 // callers into it at the same time, but that's not a situation we
10319 final ContentResolver resolver = mContext.getContentResolver();
10320 Settings.Global.putString(
10321 resolver, Settings.Global.DEBUG_APP,
10323 Settings.Global.putInt(
10324 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10325 waitForDebugger ? 1 : 0);
10328 synchronized (this) {
10330 mOrigDebugApp = mDebugApp;
10331 mOrigWaitForDebugger = mWaitForDebugger;
10333 mDebugApp = packageName;
10334 mWaitForDebugger = waitForDebugger;
10335 mDebugTransient = !persistent;
10336 if (packageName != null) {
10337 forceStopPackageLocked(packageName, -1, false, false, true, true,
10338 false, UserHandle.USER_ALL, "set debug app");
10342 Binder.restoreCallingIdentity(ident);
10346 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10347 synchronized (this) {
10348 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10349 if (!isDebuggable) {
10350 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10351 throw new SecurityException("Process not debuggable: " + app.packageName);
10355 mOpenGlTraceApp = processName;
10359 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10360 synchronized (this) {
10361 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10362 if (!isDebuggable) {
10363 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10364 throw new SecurityException("Process not debuggable: " + app.packageName);
10367 mProfileApp = processName;
10368 mProfileFile = profilerInfo.profileFile;
10369 if (mProfileFd != null) {
10371 mProfileFd.close();
10372 } catch (IOException e) {
10376 mProfileFd = profilerInfo.profileFd;
10377 mSamplingInterval = profilerInfo.samplingInterval;
10378 mAutoStopProfiler = profilerInfo.autoStopProfiler;
10384 public void setAlwaysFinish(boolean enabled) {
10385 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10386 "setAlwaysFinish()");
10388 Settings.Global.putInt(
10389 mContext.getContentResolver(),
10390 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10392 synchronized (this) {
10393 mAlwaysFinishActivities = enabled;
10398 public void setActivityController(IActivityController controller) {
10399 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10400 "setActivityController()");
10401 synchronized (this) {
10402 mController = controller;
10403 Watchdog.getInstance().setActivityController(controller);
10408 public void setUserIsMonkey(boolean userIsMonkey) {
10409 synchronized (this) {
10410 synchronized (mPidsSelfLocked) {
10411 final int callingPid = Binder.getCallingPid();
10412 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10413 if (precessRecord == null) {
10414 throw new SecurityException("Unknown process: " + callingPid);
10416 if (precessRecord.instrumentationUiAutomationConnection == null) {
10417 throw new SecurityException("Only an instrumentation process "
10418 + "with a UiAutomation can call setUserIsMonkey");
10421 mUserIsMonkey = userIsMonkey;
10426 public boolean isUserAMonkey() {
10427 synchronized (this) {
10428 // If there is a controller also implies the user is a monkey.
10429 return (mUserIsMonkey || mController != null);
10433 public void requestBugReport() {
10434 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10435 SystemProperties.set("ctl.start", "bugreport");
10438 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10439 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10442 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10443 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10444 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10446 return KEY_DISPATCHING_TIMEOUT;
10450 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10451 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10452 != PackageManager.PERMISSION_GRANTED) {
10453 throw new SecurityException("Requires permission "
10454 + android.Manifest.permission.FILTER_EVENTS);
10456 ProcessRecord proc;
10458 synchronized (this) {
10459 synchronized (mPidsSelfLocked) {
10460 proc = mPidsSelfLocked.get(pid);
10462 timeout = getInputDispatchingTimeoutLocked(proc);
10465 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10473 * Handle input dispatching timeouts.
10474 * Returns whether input dispatching should be aborted or not.
10476 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10477 final ActivityRecord activity, final ActivityRecord parent,
10478 final boolean aboveSystem, String reason) {
10479 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10480 != PackageManager.PERMISSION_GRANTED) {
10481 throw new SecurityException("Requires permission "
10482 + android.Manifest.permission.FILTER_EVENTS);
10485 final String annotation;
10486 if (reason == null) {
10487 annotation = "Input dispatching timed out";
10489 annotation = "Input dispatching timed out (" + reason + ")";
10492 if (proc != null) {
10493 synchronized (this) {
10494 if (proc.debugging) {
10499 // Give more time since we were dexopting.
10500 mDidDexOpt = false;
10504 if (proc.instrumentationClass != null) {
10505 Bundle info = new Bundle();
10506 info.putString("shortMsg", "keyDispatchingTimedOut");
10507 info.putString("longMsg", annotation);
10508 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10512 mHandler.post(new Runnable() {
10514 public void run() {
10515 appNotResponding(proc, activity, parent, aboveSystem, annotation);
10523 public Bundle getAssistContextExtras(int requestType) {
10524 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10525 UserHandle.getCallingUserId());
10529 synchronized (pae) {
10530 while (!pae.haveResult) {
10533 } catch (InterruptedException e) {
10536 if (pae.result != null) {
10537 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10540 synchronized (this) {
10541 mPendingAssistExtras.remove(pae);
10542 mHandler.removeCallbacks(pae);
10547 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10549 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10550 "getAssistContextExtras()");
10551 PendingAssistExtras pae;
10552 Bundle extras = new Bundle();
10553 synchronized (this) {
10554 ActivityRecord activity = getFocusedStack().mResumedActivity;
10555 if (activity == null) {
10556 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10559 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10560 if (activity.app == null || activity.app.thread == null) {
10561 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10564 if (activity.app.pid == Binder.getCallingPid()) {
10565 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10568 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10570 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10572 mPendingAssistExtras.add(pae);
10573 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10574 } catch (RemoteException e) {
10575 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10582 public void reportAssistContextExtras(IBinder token, Bundle extras) {
10583 PendingAssistExtras pae = (PendingAssistExtras)token;
10584 synchronized (pae) {
10585 pae.result = extras;
10586 pae.haveResult = true;
10588 if (pae.intent == null) {
10589 // Caller is just waiting for the result.
10594 // We are now ready to launch the assist activity.
10595 synchronized (this) {
10596 boolean exists = mPendingAssistExtras.remove(pae);
10597 mHandler.removeCallbacks(pae);
10603 pae.intent.replaceExtras(extras);
10604 if (pae.hint != null) {
10605 pae.intent.putExtra(pae.hint, true);
10607 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10608 | Intent.FLAG_ACTIVITY_SINGLE_TOP
10609 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10610 closeSystemDialogs("assist");
10612 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10613 } catch (ActivityNotFoundException e) {
10614 Slog.w(TAG, "No activity to handle assist action.", e);
10618 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10619 return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10622 public void registerProcessObserver(IProcessObserver observer) {
10623 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10624 "registerProcessObserver()");
10625 synchronized (this) {
10626 mProcessObservers.register(observer);
10631 public void unregisterProcessObserver(IProcessObserver observer) {
10632 synchronized (this) {
10633 mProcessObservers.unregister(observer);
10638 public boolean convertFromTranslucent(IBinder token) {
10639 final long origId = Binder.clearCallingIdentity();
10641 synchronized (this) {
10642 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10646 final boolean translucentChanged = r.changeWindowTranslucency(true);
10647 if (translucentChanged) {
10648 r.task.stack.releaseBackgroundResources();
10649 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10651 mWindowManager.setAppFullscreen(token, true);
10652 return translucentChanged;
10655 Binder.restoreCallingIdentity(origId);
10660 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10661 final long origId = Binder.clearCallingIdentity();
10663 synchronized (this) {
10664 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10668 int index = r.task.mActivities.lastIndexOf(r);
10670 ActivityRecord under = r.task.mActivities.get(index - 1);
10671 under.returningOptions = options;
10673 final boolean translucentChanged = r.changeWindowTranslucency(false);
10674 if (translucentChanged) {
10675 r.task.stack.convertToTranslucent(r);
10677 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10678 mWindowManager.setAppFullscreen(token, false);
10679 return translucentChanged;
10682 Binder.restoreCallingIdentity(origId);
10687 public boolean requestVisibleBehind(IBinder token, boolean visible) {
10688 final long origId = Binder.clearCallingIdentity();
10690 synchronized (this) {
10691 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10693 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10698 Binder.restoreCallingIdentity(origId);
10703 public boolean isBackgroundVisibleBehind(IBinder token) {
10704 final long origId = Binder.clearCallingIdentity();
10706 synchronized (this) {
10707 final ActivityStack stack = ActivityRecord.getStackLocked(token);
10708 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10709 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10710 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10714 Binder.restoreCallingIdentity(origId);
10719 public ActivityOptions getActivityOptions(IBinder token) {
10720 final long origId = Binder.clearCallingIdentity();
10722 synchronized (this) {
10723 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10725 final ActivityOptions activityOptions = r.pendingOptions;
10726 r.pendingOptions = null;
10727 return activityOptions;
10732 Binder.restoreCallingIdentity(origId);
10737 public void setImmersive(IBinder token, boolean immersive) {
10738 synchronized(this) {
10739 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10741 throw new IllegalArgumentException();
10743 r.immersive = immersive;
10745 // update associated state if we're frontmost
10746 if (r == mFocusedActivity) {
10747 if (DEBUG_IMMERSIVE) {
10748 Slog.d(TAG, "Frontmost changed immersion: "+ r);
10750 applyUpdateLockStateLocked(r);
10756 public boolean isImmersive(IBinder token) {
10757 synchronized (this) {
10758 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10760 throw new IllegalArgumentException();
10762 return r.immersive;
10766 public boolean isTopActivityImmersive() {
10767 enforceNotIsolatedCaller("startActivity");
10768 synchronized (this) {
10769 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10770 return (r != null) ? r.immersive : false;
10775 public boolean isTopOfTask(IBinder token) {
10776 synchronized (this) {
10777 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10779 throw new IllegalArgumentException();
10781 return r.task.getTopActivity() == r;
10785 public final void enterSafeMode() {
10786 synchronized(this) {
10787 // It only makes sense to do this before the system is ready
10788 // and started launching other packages.
10789 if (!mSystemReady) {
10791 AppGlobals.getPackageManager().enterSafeMode();
10792 } catch (RemoteException e) {
10800 public final void showSafeModeOverlay() {
10801 View v = LayoutInflater.from(mContext).inflate(
10802 com.android.internal.R.layout.safe_mode, null);
10803 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10804 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10805 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10806 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10807 lp.gravity = Gravity.BOTTOM | Gravity.START;
10808 lp.format = v.getBackground().getOpacity();
10809 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10810 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10811 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10812 ((WindowManager)mContext.getSystemService(
10813 Context.WINDOW_SERVICE)).addView(v, lp);
10816 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10817 if (!(sender instanceof PendingIntentRecord)) {
10820 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10821 synchronized (stats) {
10822 if (mBatteryStatsService.isOnBattery()) {
10823 mBatteryStatsService.enforceCallingPermission();
10824 PendingIntentRecord rec = (PendingIntentRecord)sender;
10825 int MY_UID = Binder.getCallingUid();
10826 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10827 BatteryStatsImpl.Uid.Pkg pkg =
10828 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10829 sourcePkg != null ? sourcePkg : rec.key.packageName);
10830 pkg.incWakeupsLocked();
10835 public boolean killPids(int[] pids, String pReason, boolean secure) {
10836 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10837 throw new SecurityException("killPids only available to the system");
10839 String reason = (pReason == null) ? "Unknown" : pReason;
10840 // XXX Note: don't acquire main activity lock here, because the window
10841 // manager calls in with its locks held.
10843 boolean killed = false;
10844 synchronized (mPidsSelfLocked) {
10845 int[] types = new int[pids.length];
10847 for (int i=0; i<pids.length; i++) {
10848 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10849 if (proc != null) {
10850 int type = proc.setAdj;
10852 if (type > worstType) {
10858 // If the worst oom_adj is somewhere in the cached proc LRU range,
10859 // then constrain it so we will kill all cached procs.
10860 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10861 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10862 worstType = ProcessList.CACHED_APP_MIN_ADJ;
10865 // If this is not a secure call, don't let it kill processes that
10867 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10868 worstType = ProcessList.SERVICE_ADJ;
10871 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10872 for (int i=0; i<pids.length; i++) {
10873 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10874 if (proc == null) {
10877 int adj = proc.setAdj;
10878 if (adj >= worstType && !proc.killedByAm) {
10879 proc.kill(reason, true);
10888 public void killUid(int uid, String reason) {
10889 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10890 throw new SecurityException("killUid only available to the system");
10892 synchronized (this) {
10893 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10894 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10895 reason != null ? reason : "kill uid");
10900 public boolean killProcessesBelowForeground(String reason) {
10901 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10902 throw new SecurityException("killProcessesBelowForeground() only available to system");
10905 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10908 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10909 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10910 throw new SecurityException("killProcessesBelowAdj() only available to system");
10913 boolean killed = false;
10914 synchronized (mPidsSelfLocked) {
10915 final int size = mPidsSelfLocked.size();
10916 for (int i = 0; i < size; i++) {
10917 final int pid = mPidsSelfLocked.keyAt(i);
10918 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10919 if (proc == null) continue;
10921 final int adj = proc.setAdj;
10922 if (adj > belowAdj && !proc.killedByAm) {
10923 proc.kill(reason, true);
10932 public void hang(final IBinder who, boolean allowRestart) {
10933 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10934 != PackageManager.PERMISSION_GRANTED) {
10935 throw new SecurityException("Requires permission "
10936 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10939 final IBinder.DeathRecipient death = new DeathRecipient() {
10941 public void binderDied() {
10942 synchronized (this) {
10949 who.linkToDeath(death, 0);
10950 } catch (RemoteException e) {
10951 Slog.w(TAG, "hang: given caller IBinder is already dead.");
10955 synchronized (this) {
10956 Watchdog.getInstance().setAllowRestart(allowRestart);
10957 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10958 synchronized (death) {
10959 while (who.isBinderAlive()) {
10962 } catch (InterruptedException e) {
10966 Watchdog.getInstance().setAllowRestart(true);
10971 public void restart() {
10972 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10973 != PackageManager.PERMISSION_GRANTED) {
10974 throw new SecurityException("Requires permission "
10975 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10978 Log.i(TAG, "Sending shutdown broadcast...");
10980 BroadcastReceiver br = new BroadcastReceiver() {
10981 @Override public void onReceive(Context context, Intent intent) {
10982 // Now the broadcast is done, finish up the low-level shutdown.
10983 Log.i(TAG, "Shutting down activity manager...");
10985 Log.i(TAG, "Shutdown complete, restarting!");
10986 Process.killProcess(Process.myPid());
10991 // First send the high-level shut down broadcast.
10992 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10993 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10994 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10995 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10996 mContext.sendOrderedBroadcastAsUser(intent,
10997 UserHandle.ALL, null, br, mHandler, 0, null, null);
10999 br.onReceive(mContext, intent);
11002 private long getLowRamTimeSinceIdle(long now) {
11003 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11007 public void performIdleMaintenance() {
11008 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11009 != PackageManager.PERMISSION_GRANTED) {
11010 throw new SecurityException("Requires permission "
11011 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11014 synchronized (this) {
11015 final long now = SystemClock.uptimeMillis();
11016 final long timeSinceLastIdle = now - mLastIdleTime;
11017 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11018 mLastIdleTime = now;
11019 mLowRamTimeSinceLastIdle = 0;
11020 if (mLowRamStartTime != 0) {
11021 mLowRamStartTime = now;
11024 StringBuilder sb = new StringBuilder(128);
11025 sb.append("Idle maintenance over ");
11026 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11027 sb.append(" low RAM for ");
11028 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11029 Slog.i(TAG, sb.toString());
11031 // If at least 1/3 of our time since the last idle period has been spent
11032 // with RAM low, then we want to kill processes.
11033 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11035 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11036 ProcessRecord proc = mLruProcesses.get(i);
11037 if (proc.notCachedSinceIdle) {
11038 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
11039 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11040 if (doKilling && proc.initialIdlePss != 0
11041 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11042 sb = new StringBuilder(128);
11044 sb.append(proc.processName);
11045 sb.append(" in idle maint: pss=");
11046 sb.append(proc.lastPss);
11047 sb.append(", initialPss=");
11048 sb.append(proc.initialIdlePss);
11049 sb.append(", period=");
11050 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11051 sb.append(", lowRamPeriod=");
11052 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11053 Slog.wtfQuiet(TAG, sb.toString());
11054 proc.kill("idle maint (pss " + proc.lastPss
11055 + " from " + proc.initialIdlePss + ")", true);
11058 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11059 proc.notCachedSinceIdle = true;
11060 proc.initialIdlePss = 0;
11061 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11062 mTestPssMode, isSleeping(), now);
11066 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11067 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11071 private void retrieveSettings() {
11072 final ContentResolver resolver = mContext.getContentResolver();
11073 String debugApp = Settings.Global.getString(
11074 resolver, Settings.Global.DEBUG_APP);
11075 boolean waitForDebugger = Settings.Global.getInt(
11076 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11077 boolean alwaysFinishActivities = Settings.Global.getInt(
11078 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11079 boolean forceRtl = Settings.Global.getInt(
11080 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11081 // Transfer any global setting for forcing RTL layout, into a System Property
11082 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11084 Configuration configuration = new Configuration();
11085 Settings.System.getConfiguration(resolver, configuration);
11087 // This will take care of setting the correct layout direction flags
11088 configuration.setLayoutDirection(configuration.locale);
11091 synchronized (this) {
11092 mDebugApp = mOrigDebugApp = debugApp;
11093 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11094 mAlwaysFinishActivities = alwaysFinishActivities;
11095 // This happens before any activities are started, so we can
11096 // change mConfiguration in-place.
11097 updateConfigurationLocked(configuration, null, false, true);
11098 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11102 /** Loads resources after the current configuration has been set. */
11103 private void loadResourcesOnSystemReady() {
11104 final Resources res = mContext.getResources();
11105 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11106 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11107 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11110 public boolean testIsSystemReady() {
11111 // no need to synchronize(this) just to read & return the value
11112 return mSystemReady;
11115 private static File getCalledPreBootReceiversFile() {
11116 File dataDir = Environment.getDataDirectory();
11117 File systemDir = new File(dataDir, "system");
11118 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11122 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11123 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11124 File file = getCalledPreBootReceiversFile();
11125 FileInputStream fis = null;
11127 fis = new FileInputStream(file);
11128 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11129 int fvers = dis.readInt();
11130 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11131 String vers = dis.readUTF();
11132 String codename = dis.readUTF();
11133 String build = dis.readUTF();
11134 if (android.os.Build.VERSION.RELEASE.equals(vers)
11135 && android.os.Build.VERSION.CODENAME.equals(codename)
11136 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11137 int num = dis.readInt();
11140 String pkg = dis.readUTF();
11141 String cls = dis.readUTF();
11142 lastDoneReceivers.add(new ComponentName(pkg, cls));
11146 } catch (FileNotFoundException e) {
11147 } catch (IOException e) {
11148 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11153 } catch (IOException e) {
11157 return lastDoneReceivers;
11160 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11161 File file = getCalledPreBootReceiversFile();
11162 FileOutputStream fos = null;
11163 DataOutputStream dos = null;
11165 fos = new FileOutputStream(file);
11166 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11167 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11168 dos.writeUTF(android.os.Build.VERSION.RELEASE);
11169 dos.writeUTF(android.os.Build.VERSION.CODENAME);
11170 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11171 dos.writeInt(list.size());
11172 for (int i=0; i<list.size(); i++) {
11173 dos.writeUTF(list.get(i).getPackageName());
11174 dos.writeUTF(list.get(i).getClassName());
11176 } catch (IOException e) {
11177 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11180 FileUtils.sync(fos);
11184 } catch (IOException e) {
11185 // TODO Auto-generated catch block
11186 e.printStackTrace();
11192 private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11193 ArrayList<ComponentName> doneReceivers, int userId) {
11194 boolean waitingUpdate = false;
11195 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11196 List<ResolveInfo> ris = null;
11198 ris = AppGlobals.getPackageManager().queryIntentReceivers(
11199 intent, null, 0, userId);
11200 } catch (RemoteException e) {
11203 for (int i=ris.size()-1; i>=0; i--) {
11204 if ((ris.get(i).activityInfo.applicationInfo.flags
11205 &ApplicationInfo.FLAG_SYSTEM) == 0) {
11209 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11211 // For User 0, load the version number. When delivering to a new user, deliver
11212 // to all receivers.
11213 if (userId == UserHandle.USER_OWNER) {
11214 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11215 for (int i=0; i<ris.size(); i++) {
11216 ActivityInfo ai = ris.get(i).activityInfo;
11217 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11218 if (lastDoneReceivers.contains(comp)) {
11219 // We already did the pre boot receiver for this app with the current
11220 // platform version, so don't do it again...
11223 // ...however, do keep it as one that has been done, so we don't
11224 // forget about it when rewriting the file of last done receivers.
11225 doneReceivers.add(comp);
11230 // If primary user, send broadcast to all available users, else just to userId
11231 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11232 : new int[] { userId };
11233 for (int i = 0; i < ris.size(); i++) {
11234 ActivityInfo ai = ris.get(i).activityInfo;
11235 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11236 doneReceivers.add(comp);
11237 intent.setComponent(comp);
11238 for (int j=0; j<users.length; j++) {
11239 IIntentReceiver finisher = null;
11240 // On last receiver and user, set up a completion callback
11241 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11242 finisher = new IIntentReceiver.Stub() {
11243 public void performReceive(Intent intent, int resultCode,
11244 String data, Bundle extras, boolean ordered,
11245 boolean sticky, int sendingUser) {
11246 // The raw IIntentReceiver interface is called
11247 // with the AM lock held, so redispatch to
11248 // execute our code without the lock.
11249 mHandler.post(onFinishCallback);
11253 Slog.i(TAG, "Sending system update to " + intent.getComponent()
11254 + " for user " + users[j]);
11255 broadcastIntentLocked(null, null, intent, null, finisher,
11256 0, null, null, null, AppOpsManager.OP_NONE,
11257 true, false, MY_PID, Process.SYSTEM_UID,
11259 if (finisher != null) {
11260 waitingUpdate = true;
11266 return waitingUpdate;
11269 public void systemReady(final Runnable goingCallback) {
11270 synchronized(this) {
11271 if (mSystemReady) {
11272 // If we're done calling all the receivers, run the next "boot phase" passed in
11273 // by the SystemServer
11274 if (goingCallback != null) {
11275 goingCallback.run();
11280 // Make sure we have the current profile info, since it is needed for
11281 // security checks.
11282 updateCurrentProfileIdsLocked();
11284 if (mRecentTasks == null) {
11285 mRecentTasks = mTaskPersister.restoreTasksLocked();
11286 mTaskPersister.restoreTasksFromOtherDeviceLocked();
11287 cleanupRecentTasksLocked(UserHandle.USER_ALL);
11288 mTaskPersister.startPersisting();
11291 // Check to see if there are any update receivers to run.
11293 if (mWaitingUpdate) {
11296 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11297 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11298 public void run() {
11299 synchronized (ActivityManagerService.this) {
11302 writeLastDonePreBootReceivers(doneReceivers);
11303 showBootMessage(mContext.getText(R.string.android_upgrading_complete),
11305 systemReady(goingCallback);
11307 }, doneReceivers, UserHandle.USER_OWNER);
11309 if (mWaitingUpdate) {
11315 mAppOpsService.systemReady();
11316 mSystemReady = true;
11319 ArrayList<ProcessRecord> procsToKill = null;
11320 synchronized(mPidsSelfLocked) {
11321 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11322 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11323 if (!isAllowedWhileBooting(proc.info)){
11324 if (procsToKill == null) {
11325 procsToKill = new ArrayList<ProcessRecord>();
11327 procsToKill.add(proc);
11332 synchronized(this) {
11333 if (procsToKill != null) {
11334 for (int i=procsToKill.size()-1; i>=0; i--) {
11335 ProcessRecord proc = procsToKill.get(i);
11336 Slog.i(TAG, "Removing system update proc: " + proc);
11337 removeProcessLocked(proc, true, false, "system update done");
11341 // Now that we have cleaned up any update processes, we
11342 // are ready to start launching real processes and know that
11343 // we won't trample on them any more.
11344 mProcessesReady = true;
11347 Slog.i(TAG, "System now ready");
11348 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11349 SystemClock.uptimeMillis());
11351 synchronized(this) {
11352 // Make sure we have no pre-ready processes sitting around.
11354 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11355 ResolveInfo ri = mContext.getPackageManager()
11356 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11358 CharSequence errorMsg = null;
11360 ActivityInfo ai = ri.activityInfo;
11361 ApplicationInfo app = ai.applicationInfo;
11362 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11363 mTopAction = Intent.ACTION_FACTORY_TEST;
11365 mTopComponent = new ComponentName(app.packageName,
11368 errorMsg = mContext.getResources().getText(
11369 com.android.internal.R.string.factorytest_not_system);
11372 errorMsg = mContext.getResources().getText(
11373 com.android.internal.R.string.factorytest_no_action);
11375 if (errorMsg != null) {
11378 mTopComponent = null;
11379 Message msg = Message.obtain();
11380 msg.what = SHOW_FACTORY_ERROR_MSG;
11381 msg.getData().putCharSequence("msg", errorMsg);
11382 mHandler.sendMessage(msg);
11387 retrieveSettings();
11388 loadResourcesOnSystemReady();
11390 synchronized (this) {
11391 readGrantedUriPermissionsLocked();
11394 if (goingCallback != null) goingCallback.run();
11396 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11397 Integer.toString(mCurrentUserId), mCurrentUserId);
11398 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11399 Integer.toString(mCurrentUserId), mCurrentUserId);
11400 mSystemServiceManager.startUser(mCurrentUserId);
11402 synchronized (this) {
11403 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11405 List apps = AppGlobals.getPackageManager().
11406 getPersistentApplications(STOCK_PM_FLAGS);
11407 if (apps != null) {
11408 int N = apps.size();
11410 for (i=0; i<N; i++) {
11411 ApplicationInfo info
11412 = (ApplicationInfo)apps.get(i);
11413 if (info != null &&
11414 !info.packageName.equals("android")) {
11415 addAppLocked(info, false, null /* ABI override */);
11419 } catch (RemoteException ex) {
11420 // pm is in same process, this will never happen.
11424 // Start up initial activity.
11426 startHomeActivityLocked(mCurrentUserId, "systemReady");
11429 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11430 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11431 + " data partition or your device will be unstable.");
11432 mHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11434 } catch (RemoteException e) {
11437 if (!Build.isFingerprintConsistent()) {
11438 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11439 mHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11442 long ident = Binder.clearCallingIdentity();
11444 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11445 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11446 | Intent.FLAG_RECEIVER_FOREGROUND);
11447 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11448 broadcastIntentLocked(null, null, intent,
11449 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11450 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11451 intent = new Intent(Intent.ACTION_USER_STARTING);
11452 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11453 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11454 broadcastIntentLocked(null, null, intent,
11455 null, new IIntentReceiver.Stub() {
11457 public void performReceive(Intent intent, int resultCode, String data,
11458 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11459 throws RemoteException {
11462 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11463 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11464 } catch (Throwable t) {
11465 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11467 Binder.restoreCallingIdentity(ident);
11469 mStackSupervisor.resumeTopActivitiesLocked();
11470 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11474 private boolean makeAppCrashingLocked(ProcessRecord app,
11475 String shortMsg, String longMsg, String stackTrace) {
11476 app.crashing = true;
11477 app.crashingReport = generateProcessError(app,
11478 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11479 startAppProblemLocked(app);
11480 app.stopFreezingAllLocked();
11481 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11484 private void makeAppNotRespondingLocked(ProcessRecord app,
11485 String activity, String shortMsg, String longMsg) {
11486 app.notResponding = true;
11487 app.notRespondingReport = generateProcessError(app,
11488 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11489 activity, shortMsg, longMsg, null);
11490 startAppProblemLocked(app);
11491 app.stopFreezingAllLocked();
11495 * Generate a process error record, suitable for attachment to a ProcessRecord.
11497 * @param app The ProcessRecord in which the error occurred.
11498 * @param condition Crashing, Application Not Responding, etc. Values are defined in
11499 * ActivityManager.AppErrorStateInfo
11500 * @param activity The activity associated with the crash, if known.
11501 * @param shortMsg Short message describing the crash.
11502 * @param longMsg Long message describing the crash.
11503 * @param stackTrace Full crash stack trace, may be null.
11505 * @return Returns a fully-formed AppErrorStateInfo record.
11507 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11508 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11509 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11511 report.condition = condition;
11512 report.processName = app.processName;
11513 report.pid = app.pid;
11514 report.uid = app.info.uid;
11515 report.tag = activity;
11516 report.shortMsg = shortMsg;
11517 report.longMsg = longMsg;
11518 report.stackTrace = stackTrace;
11523 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11524 synchronized (this) {
11525 app.crashing = false;
11526 app.crashingReport = null;
11527 app.notResponding = false;
11528 app.notRespondingReport = null;
11529 if (app.anrDialog == fromDialog) {
11530 app.anrDialog = null;
11532 if (app.waitDialog == fromDialog) {
11533 app.waitDialog = null;
11535 if (app.pid > 0 && app.pid != MY_PID) {
11536 handleAppCrashLocked(app, null, null, null);
11537 app.kill("user request after error", true);
11542 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11543 String stackTrace) {
11544 long now = SystemClock.uptimeMillis();
11547 if (!app.isolated) {
11548 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11552 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11553 // This process loses!
11554 Slog.w(TAG, "Process " + app.info.processName
11555 + " has crashed too many times: killing!");
11556 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11557 app.userId, app.info.processName, app.uid);
11558 mStackSupervisor.handleAppCrashLocked(app);
11559 if (!app.persistent) {
11560 // We don't want to start this process again until the user
11561 // explicitly does so... but for persistent process, we really
11562 // need to keep it running. If a persistent process is actually
11563 // repeatedly crashing, then badness for everyone.
11564 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11565 app.info.processName);
11566 if (!app.isolated) {
11567 // XXX We don't have a way to mark isolated processes
11568 // as bad, since they don't have a peristent identity.
11569 mBadProcesses.put(app.info.processName, app.uid,
11570 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11571 mProcessCrashTimes.remove(app.info.processName, app.uid);
11574 app.removed = true;
11575 // Don't let services in this process be restarted and potentially
11576 // annoy the user repeatedly. Unless it is persistent, since those
11577 // processes run critical code.
11578 removeProcessLocked(app, false, false, "crash");
11579 mStackSupervisor.resumeTopActivitiesLocked();
11582 mStackSupervisor.resumeTopActivitiesLocked();
11584 mStackSupervisor.finishTopRunningActivityLocked(app);
11587 // Bump up the crash count of any services currently running in the proc.
11588 for (int i=app.services.size()-1; i>=0; i--) {
11589 // Any services running in the application need to be placed
11590 // back in the pending list.
11591 ServiceRecord sr = app.services.valueAt(i);
11595 // If the crashing process is what we consider to be the "home process" and it has been
11596 // replaced by a third-party app, clear the package preferred activities from packages
11597 // with a home activity running in the process to prevent a repeatedly crashing app
11598 // from blocking the user to manually clear the list.
11599 final ArrayList<ActivityRecord> activities = app.activities;
11600 if (app == mHomeProcess && activities.size() > 0
11601 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11602 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11603 final ActivityRecord r = activities.get(activityNdx);
11604 if (r.isHomeActivity()) {
11605 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11607 ActivityThread.getPackageManager()
11608 .clearPackagePreferredActivities(r.packageName);
11609 } catch (RemoteException c) {
11610 // pm is in same process, this will never happen.
11616 if (!app.isolated) {
11617 // XXX Can't keep track of crash times for isolated processes,
11618 // because they don't have a perisistent identity.
11619 mProcessCrashTimes.put(app.info.processName, app.uid, now);
11622 if (app.crashHandler != null) mHandler.post(app.crashHandler);
11626 void startAppProblemLocked(ProcessRecord app) {
11627 // If this app is not running under the current user, then we
11628 // can't give it a report button because that would require
11629 // launching the report UI under a different user.
11630 app.errorReportReceiver = null;
11632 for (int userId : mCurrentProfileIds) {
11633 if (app.userId == userId) {
11634 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11635 mContext, app.info.packageName, app.info.flags);
11638 skipCurrentReceiverLocked(app);
11641 void skipCurrentReceiverLocked(ProcessRecord app) {
11642 for (BroadcastQueue queue : mBroadcastQueues) {
11643 queue.skipCurrentReceiverLocked(app);
11648 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11649 * The application process will exit immediately after this call returns.
11650 * @param app object of the crashing app, null for the system server
11651 * @param crashInfo describing the exception
11653 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11654 ProcessRecord r = findAppProcess(app, "Crash");
11655 final String processName = app == null ? "system_server"
11656 : (r == null ? "unknown" : r.processName);
11658 handleApplicationCrashInner("crash", r, processName, crashInfo);
11661 /* Native crash reporting uses this inner version because it needs to be somewhat
11662 * decoupled from the AM-managed cleanup lifecycle
11664 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11665 ApplicationErrorReport.CrashInfo crashInfo) {
11666 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11667 UserHandle.getUserId(Binder.getCallingUid()), processName,
11668 r == null ? -1 : r.info.flags,
11669 crashInfo.exceptionClassName,
11670 crashInfo.exceptionMessage,
11671 crashInfo.throwFileName,
11672 crashInfo.throwLineNumber);
11674 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11676 crashApplication(r, crashInfo);
11679 public void handleApplicationStrictModeViolation(
11682 StrictMode.ViolationInfo info) {
11683 ProcessRecord r = findAppProcess(app, "StrictMode");
11688 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11689 Integer stackFingerprint = info.hashCode();
11690 boolean logIt = true;
11691 synchronized (mAlreadyLoggedViolatedStacks) {
11692 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11694 // TODO: sub-sample into EventLog for these, with
11695 // the info.durationMillis? Then we'd get
11696 // the relative pain numbers, without logging all
11697 // the stack traces repeatedly. We'd want to do
11698 // likewise in the client code, which also does
11699 // dup suppression, before the Binder call.
11701 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11702 mAlreadyLoggedViolatedStacks.clear();
11704 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11708 logStrictModeViolationToDropBox(r, info);
11712 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11713 AppErrorResult result = new AppErrorResult();
11714 synchronized (this) {
11715 final long origId = Binder.clearCallingIdentity();
11717 Message msg = Message.obtain();
11718 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11719 HashMap<String, Object> data = new HashMap<String, Object>();
11720 data.put("result", result);
11721 data.put("app", r);
11722 data.put("violationMask", violationMask);
11723 data.put("info", info);
11725 mHandler.sendMessage(msg);
11727 Binder.restoreCallingIdentity(origId);
11729 int res = result.get();
11730 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11734 // Depending on the policy in effect, there could be a bunch of
11735 // these in quick succession so we try to batch these together to
11736 // minimize disk writes, number of dropbox entries, and maximize
11737 // compression, by having more fewer, larger records.
11738 private void logStrictModeViolationToDropBox(
11739 ProcessRecord process,
11740 StrictMode.ViolationInfo info) {
11741 if (info == null) {
11744 final boolean isSystemApp = process == null ||
11745 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11746 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11747 final String processName = process == null ? "unknown" : process.processName;
11748 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11749 final DropBoxManager dbox = (DropBoxManager)
11750 mContext.getSystemService(Context.DROPBOX_SERVICE);
11752 // Exit early if the dropbox isn't configured to accept this report type.
11753 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11755 boolean bufferWasEmpty;
11756 boolean needsFlush;
11757 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11758 synchronized (sb) {
11759 bufferWasEmpty = sb.length() == 0;
11760 appendDropBoxProcessHeaders(process, processName, sb);
11761 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11762 sb.append("System-App: ").append(isSystemApp).append("\n");
11763 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11764 if (info.violationNumThisLoop != 0) {
11765 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11767 if (info.numAnimationsRunning != 0) {
11768 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11770 if (info.broadcastIntentAction != null) {
11771 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11773 if (info.durationMillis != -1) {
11774 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11776 if (info.numInstances != -1) {
11777 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11779 if (info.tags != null) {
11780 for (String tag : info.tags) {
11781 sb.append("Span-Tag: ").append(tag).append("\n");
11785 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11786 sb.append(info.crashInfo.stackTrace);
11790 // Only buffer up to ~64k. Various logging bits truncate
11792 needsFlush = (sb.length() > 64 * 1024);
11795 // Flush immediately if the buffer's grown too large, or this
11796 // is a non-system app. Non-system apps are isolated with a
11797 // different tag & policy and not batched.
11799 // Batching is useful during internal testing with
11800 // StrictMode settings turned up high. Without batching,
11801 // thousands of separate files could be created on boot.
11802 if (!isSystemApp || needsFlush) {
11803 new Thread("Error dump: " + dropboxTag) {
11805 public void run() {
11807 synchronized (sb) {
11808 report = sb.toString();
11809 sb.delete(0, sb.length());
11812 if (report.length() != 0) {
11813 dbox.addText(dropboxTag, report);
11820 // System app batching:
11821 if (!bufferWasEmpty) {
11822 // An existing dropbox-writing thread is outstanding, so
11823 // we don't need to start it up. The existing thread will
11824 // catch the buffer appends we just did.
11828 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11829 // (After this point, we shouldn't access AMS internal data structures.)
11830 new Thread("Error dump: " + dropboxTag) {
11832 public void run() {
11833 // 5 second sleep to let stacks arrive and be batched together
11835 Thread.sleep(5000); // 5 seconds
11836 } catch (InterruptedException e) {}
11838 String errorReport;
11839 synchronized (mStrictModeBuffer) {
11840 errorReport = mStrictModeBuffer.toString();
11841 if (errorReport.length() == 0) {
11844 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11845 mStrictModeBuffer.trimToSize();
11847 dbox.addText(dropboxTag, errorReport);
11853 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11854 * @param app object of the crashing app, null for the system server
11855 * @param tag reported by the caller
11856 * @param system whether this wtf is coming from the system
11857 * @param crashInfo describing the context of the error
11858 * @return true if the process should exit immediately (WTF is fatal)
11860 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11861 final ApplicationErrorReport.CrashInfo crashInfo) {
11862 final int callingUid = Binder.getCallingUid();
11863 final int callingPid = Binder.getCallingPid();
11866 // If this is coming from the system, we could very well have low-level
11867 // system locks held, so we want to do this all asynchronously. And we
11868 // never want this to become fatal, so there is that too.
11869 mHandler.post(new Runnable() {
11870 @Override public void run() {
11871 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11877 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11880 if (r != null && r.pid != Process.myPid() &&
11881 Settings.Global.getInt(mContext.getContentResolver(),
11882 Settings.Global.WTF_IS_FATAL, 0) != 0) {
11883 crashApplication(r, crashInfo);
11890 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11891 final ApplicationErrorReport.CrashInfo crashInfo) {
11892 final ProcessRecord r = findAppProcess(app, "WTF");
11893 final String processName = app == null ? "system_server"
11894 : (r == null ? "unknown" : r.processName);
11896 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11897 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11899 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11905 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11906 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11908 private ProcessRecord findAppProcess(IBinder app, String reason) {
11913 synchronized (this) {
11914 final int NP = mProcessNames.getMap().size();
11915 for (int ip=0; ip<NP; ip++) {
11916 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11917 final int NA = apps.size();
11918 for (int ia=0; ia<NA; ia++) {
11919 ProcessRecord p = apps.valueAt(ia);
11920 if (p.thread != null && p.thread.asBinder() == app) {
11926 Slog.w(TAG, "Can't find mystery application for " + reason
11927 + " from pid=" + Binder.getCallingPid()
11928 + " uid=" + Binder.getCallingUid() + ": " + app);
11934 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11935 * to append various headers to the dropbox log text.
11937 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11938 StringBuilder sb) {
11939 // Watchdog thread ends up invoking this function (with
11940 // a null ProcessRecord) to add the stack file to dropbox.
11941 // Do not acquire a lock on this (am) in such cases, as it
11942 // could cause a potential deadlock, if and when watchdog
11943 // is invoked due to unavailability of lock on am and it
11944 // would prevent watchdog from killing system_server.
11945 if (process == null) {
11946 sb.append("Process: ").append(processName).append("\n");
11949 // Note: ProcessRecord 'process' is guarded by the service
11950 // instance. (notably process.pkgList, which could otherwise change
11951 // concurrently during execution of this method)
11952 synchronized (this) {
11953 sb.append("Process: ").append(processName).append("\n");
11954 int flags = process.info.flags;
11955 IPackageManager pm = AppGlobals.getPackageManager();
11956 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11957 for (int ip=0; ip<process.pkgList.size(); ip++) {
11958 String pkg = process.pkgList.keyAt(ip);
11959 sb.append("Package: ").append(pkg);
11961 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11963 sb.append(" v").append(pi.versionCode);
11964 if (pi.versionName != null) {
11965 sb.append(" (").append(pi.versionName).append(")");
11968 } catch (RemoteException e) {
11969 Slog.e(TAG, "Error getting package info: " + pkg, e);
11976 private static String processClass(ProcessRecord process) {
11977 if (process == null || process.pid == MY_PID) {
11978 return "system_server";
11979 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11980 return "system_app";
11987 * Write a description of an error (crash, WTF, ANR) to the drop box.
11988 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11989 * @param process which caused the error, null means the system server
11990 * @param activity which triggered the error, null if unknown
11991 * @param parent activity related to the error, null if unknown
11992 * @param subject line related to the error, null if absent
11993 * @param report in long form describing the error, null if absent
11994 * @param logFile to include in the report, null if none
11995 * @param crashInfo giving an application stack trace, null if absent
11997 public void addErrorToDropBox(String eventType,
11998 ProcessRecord process, String processName, ActivityRecord activity,
11999 ActivityRecord parent, String subject,
12000 final String report, final File logFile,
12001 final ApplicationErrorReport.CrashInfo crashInfo) {
12002 // NOTE -- this must never acquire the ActivityManagerService lock,
12003 // otherwise the watchdog may be prevented from resetting the system.
12005 final String dropboxTag = processClass(process) + "_" + eventType;
12006 final DropBoxManager dbox = (DropBoxManager)
12007 mContext.getSystemService(Context.DROPBOX_SERVICE);
12009 // Exit early if the dropbox isn't configured to accept this report type.
12010 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12012 final StringBuilder sb = new StringBuilder(1024);
12013 appendDropBoxProcessHeaders(process, processName, sb);
12014 if (activity != null) {
12015 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12017 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12018 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12020 if (parent != null && parent != activity) {
12021 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12023 if (subject != null) {
12024 sb.append("Subject: ").append(subject).append("\n");
12026 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12027 if (Debug.isDebuggerConnected()) {
12028 sb.append("Debugger: Connected\n");
12032 // Do the rest in a worker thread to avoid blocking the caller on I/O
12033 // (After this point, we shouldn't access AMS internal data structures.)
12034 Thread worker = new Thread("Error dump: " + dropboxTag) {
12036 public void run() {
12037 if (report != null) {
12040 if (logFile != null) {
12042 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12043 "\n\n[[TRUNCATED]]"));
12044 } catch (IOException e) {
12045 Slog.e(TAG, "Error reading " + logFile, e);
12048 if (crashInfo != null && crashInfo.stackTrace != null) {
12049 sb.append(crashInfo.stackTrace);
12052 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12053 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12057 // Merge several logcat streams, and take the last N lines
12058 InputStreamReader input = null;
12060 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12061 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12063 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12065 try { logcat.getOutputStream().close(); } catch (IOException e) {}
12066 try { logcat.getErrorStream().close(); } catch (IOException e) {}
12067 input = new InputStreamReader(logcat.getInputStream());
12070 char[] buf = new char[8192];
12071 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12072 } catch (IOException e) {
12073 Slog.e(TAG, "Error running logcat", e);
12075 if (input != null) try { input.close(); } catch (IOException e) {}
12079 dbox.addText(dropboxTag, sb.toString());
12083 if (process == null) {
12084 // If process is null, we are being called from some internal code
12085 // and may be about to die -- run this synchronously.
12093 * Bring up the "unexpected error" dialog box for a crashing app.
12094 * Deal with edge cases (intercepts from instrumented applications,
12095 * ActivityController, error intent receivers, that sort of thing).
12096 * @param r the application crashing
12097 * @param crashInfo describing the failure
12099 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12100 long timeMillis = System.currentTimeMillis();
12101 String shortMsg = crashInfo.exceptionClassName;
12102 String longMsg = crashInfo.exceptionMessage;
12103 String stackTrace = crashInfo.stackTrace;
12104 if (shortMsg != null && longMsg != null) {
12105 longMsg = shortMsg + ": " + longMsg;
12106 } else if (shortMsg != null) {
12107 longMsg = shortMsg;
12110 AppErrorResult result = new AppErrorResult();
12111 synchronized (this) {
12112 if (mController != null) {
12114 String name = r != null ? r.processName : null;
12115 int pid = r != null ? r.pid : Binder.getCallingPid();
12116 int uid = r != null ? r.info.uid : Binder.getCallingUid();
12117 if (!mController.appCrashed(name, pid,
12118 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12119 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12120 && "Native crash".equals(crashInfo.exceptionClassName)) {
12121 Slog.w(TAG, "Skip killing native crashed app " + name
12122 + "(" + pid + ") during testing");
12124 Slog.w(TAG, "Force-killing crashed app " + name
12125 + " at watcher's request");
12127 r.kill("crash", true);
12130 Process.killProcess(pid);
12131 Process.killProcessGroup(uid, pid);
12136 } catch (RemoteException e) {
12137 mController = null;
12138 Watchdog.getInstance().setActivityController(null);
12142 final long origId = Binder.clearCallingIdentity();
12144 // If this process is running instrumentation, finish it.
12145 if (r != null && r.instrumentationClass != null) {
12146 Slog.w(TAG, "Error in app " + r.processName
12147 + " running instrumentation " + r.instrumentationClass + ":");
12148 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
12149 if (longMsg != null) Slog.w(TAG, " " + longMsg);
12150 Bundle info = new Bundle();
12151 info.putString("shortMsg", shortMsg);
12152 info.putString("longMsg", longMsg);
12153 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12154 Binder.restoreCallingIdentity(origId);
12158 // Log crash in battery stats.
12160 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12163 // If we can't identify the process or it's already exceeded its crash quota,
12164 // quit right away without showing a crash dialog.
12165 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12166 Binder.restoreCallingIdentity(origId);
12170 Message msg = Message.obtain();
12171 msg.what = SHOW_ERROR_MSG;
12172 HashMap data = new HashMap();
12173 data.put("result", result);
12174 data.put("app", r);
12176 mHandler.sendMessage(msg);
12178 Binder.restoreCallingIdentity(origId);
12181 int res = result.get();
12183 Intent appErrorIntent = null;
12184 synchronized (this) {
12185 if (r != null && !r.isolated) {
12186 // XXX Can't keep track of crash time for isolated processes,
12187 // since they don't have a persistent identity.
12188 mProcessCrashTimes.put(r.info.processName, r.uid,
12189 SystemClock.uptimeMillis());
12191 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12192 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12196 if (appErrorIntent != null) {
12198 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12199 } catch (ActivityNotFoundException e) {
12200 Slog.w(TAG, "bug report receiver dissappeared", e);
12205 Intent createAppErrorIntentLocked(ProcessRecord r,
12206 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12207 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12208 if (report == null) {
12211 Intent result = new Intent(Intent.ACTION_APP_ERROR);
12212 result.setComponent(r.errorReportReceiver);
12213 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12214 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12218 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12219 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12220 if (r.errorReportReceiver == null) {
12224 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12228 ApplicationErrorReport report = new ApplicationErrorReport();
12229 report.packageName = r.info.packageName;
12230 report.installerPackageName = r.errorReportReceiver.getPackageName();
12231 report.processName = r.processName;
12232 report.time = timeMillis;
12233 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12235 if (r.crashing || r.forceCrashReport) {
12236 report.type = ApplicationErrorReport.TYPE_CRASH;
12237 report.crashInfo = crashInfo;
12238 } else if (r.notResponding) {
12239 report.type = ApplicationErrorReport.TYPE_ANR;
12240 report.anrInfo = new ApplicationErrorReport.AnrInfo();
12242 report.anrInfo.activity = r.notRespondingReport.tag;
12243 report.anrInfo.cause = r.notRespondingReport.shortMsg;
12244 report.anrInfo.info = r.notRespondingReport.longMsg;
12250 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12251 enforceNotIsolatedCaller("getProcessesInErrorState");
12252 // assume our apps are happy - lazy create the list
12253 List<ActivityManager.ProcessErrorStateInfo> errList = null;
12255 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12256 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12257 int userId = UserHandle.getUserId(Binder.getCallingUid());
12259 synchronized (this) {
12261 // iterate across all processes
12262 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12263 ProcessRecord app = mLruProcesses.get(i);
12264 if (!allUsers && app.userId != userId) {
12267 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12268 // This one's in trouble, so we'll generate a report for it
12269 // crashes are higher priority (in case there's a crash *and* an anr)
12270 ActivityManager.ProcessErrorStateInfo report = null;
12271 if (app.crashing) {
12272 report = app.crashingReport;
12273 } else if (app.notResponding) {
12274 report = app.notRespondingReport;
12277 if (report != null) {
12278 if (errList == null) {
12279 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12281 errList.add(report);
12283 Slog.w(TAG, "Missing app error report, app = " + app.processName +
12284 " crashing = " + app.crashing +
12285 " notResponding = " + app.notResponding);
12294 static int procStateToImportance(int procState, int memAdj,
12295 ActivityManager.RunningAppProcessInfo currApp) {
12296 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12297 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12298 currApp.lru = memAdj;
12305 private void fillInProcMemInfo(ProcessRecord app,
12306 ActivityManager.RunningAppProcessInfo outInfo) {
12307 outInfo.pid = app.pid;
12308 outInfo.uid = app.info.uid;
12309 if (mHeavyWeightProcess == app) {
12310 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12312 if (app.persistent) {
12313 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12315 if (app.activities.size() > 0) {
12316 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12318 outInfo.lastTrimLevel = app.trimMemoryLevel;
12319 int adj = app.curAdj;
12320 int procState = app.curProcState;
12321 outInfo.importance = procStateToImportance(procState, adj, outInfo);
12322 outInfo.importanceReasonCode = app.adjTypeCode;
12323 outInfo.processState = app.curProcState;
12326 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12327 enforceNotIsolatedCaller("getRunningAppProcesses");
12329 final int callingUid = Binder.getCallingUid();
12331 // Lazy instantiation of list
12332 List<ActivityManager.RunningAppProcessInfo> runList = null;
12333 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12334 callingUid) == PackageManager.PERMISSION_GRANTED;
12335 final int userId = UserHandle.getUserId(callingUid);
12336 final boolean allUids = isGetTasksAllowed(
12337 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12339 synchronized (this) {
12340 // Iterate across all processes
12341 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12342 ProcessRecord app = mLruProcesses.get(i);
12343 if ((!allUsers && app.userId != userId)
12344 || (!allUids && app.uid != callingUid)) {
12347 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12348 // Generate process state info for running application
12349 ActivityManager.RunningAppProcessInfo currApp =
12350 new ActivityManager.RunningAppProcessInfo(app.processName,
12351 app.pid, app.getPackageList());
12352 fillInProcMemInfo(app, currApp);
12353 if (app.adjSource instanceof ProcessRecord) {
12354 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12355 currApp.importanceReasonImportance =
12356 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12357 app.adjSourceProcState);
12358 } else if (app.adjSource instanceof ActivityRecord) {
12359 ActivityRecord r = (ActivityRecord)app.adjSource;
12360 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12362 if (app.adjTarget instanceof ComponentName) {
12363 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12365 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12366 // + " lru=" + currApp.lru);
12367 if (runList == null) {
12368 runList = new ArrayList<>();
12370 runList.add(currApp);
12377 public List<ApplicationInfo> getRunningExternalApplications() {
12378 enforceNotIsolatedCaller("getRunningExternalApplications");
12379 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12380 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12381 if (runningApps != null && runningApps.size() > 0) {
12382 Set<String> extList = new HashSet<String>();
12383 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12384 if (app.pkgList != null) {
12385 for (String pkg : app.pkgList) {
12390 IPackageManager pm = AppGlobals.getPackageManager();
12391 for (String pkg : extList) {
12393 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12394 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12397 } catch (RemoteException e) {
12405 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12406 enforceNotIsolatedCaller("getMyMemoryState");
12407 synchronized (this) {
12408 ProcessRecord proc;
12409 synchronized (mPidsSelfLocked) {
12410 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12412 fillInProcMemInfo(proc, outInfo);
12417 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12418 if (checkCallingPermission(android.Manifest.permission.DUMP)
12419 != PackageManager.PERMISSION_GRANTED) {
12420 pw.println("Permission Denial: can't dump ActivityManager from from pid="
12421 + Binder.getCallingPid()
12422 + ", uid=" + Binder.getCallingUid()
12423 + " without permission "
12424 + android.Manifest.permission.DUMP);
12428 boolean dumpAll = false;
12429 boolean dumpClient = false;
12430 String dumpPackage = null;
12433 while (opti < args.length) {
12434 String opt = args[opti];
12435 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12439 if ("-a".equals(opt)) {
12441 } else if ("-c".equals(opt)) {
12443 } else if ("-p".equals(opt)) {
12444 if (opti < args.length) {
12445 dumpPackage = args[opti];
12448 pw.println("Error: -p option requires package argument");
12452 } else if ("-h".equals(opt)) {
12453 pw.println("Activity manager dump options:");
12454 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ...");
12455 pw.println(" cmd may be one of:");
12456 pw.println(" a[ctivities]: activity stack state");
12457 pw.println(" r[recents]: recent activities state");
12458 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12459 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
12460 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
12461 pw.println(" o[om]: out of memory management");
12462 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
12463 pw.println(" provider [COMP_SPEC]: provider client-side state");
12464 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
12465 pw.println(" as[sociations]: tracked app associations");
12466 pw.println(" service [COMP_SPEC]: service client-side state");
12467 pw.println(" package [PACKAGE_NAME]: all state related to given package");
12468 pw.println(" all: dump all activities");
12469 pw.println(" top: dump the top activity");
12470 pw.println(" write: write all pending state to storage");
12471 pw.println(" track-associations: enable association tracking");
12472 pw.println(" untrack-associations: disable and clear association tracking");
12473 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
12474 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
12475 pw.println(" a partial substring in a component name, a");
12476 pw.println(" hex object identifier.");
12477 pw.println(" -a: include all available server state.");
12478 pw.println(" -c: include client state.");
12479 pw.println(" -p: limit output to given package.");
12482 pw.println("Unknown argument: " + opt + "; use -h for help");
12486 long origId = Binder.clearCallingIdentity();
12487 boolean more = false;
12488 // Is the caller requesting to dump a particular piece of data?
12489 if (opti < args.length) {
12490 String cmd = args[opti];
12492 if ("activities".equals(cmd) || "a".equals(cmd)) {
12493 synchronized (this) {
12494 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12496 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12497 synchronized (this) {
12498 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12500 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12503 if (opti >= args.length) {
12505 newArgs = EMPTY_STRING_ARRAY;
12507 dumpPackage = args[opti];
12509 newArgs = new String[args.length - opti];
12510 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12511 args.length - opti);
12513 synchronized (this) {
12514 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12516 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12519 if (opti >= args.length) {
12521 newArgs = EMPTY_STRING_ARRAY;
12523 dumpPackage = args[opti];
12525 newArgs = new String[args.length - opti];
12526 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12527 args.length - opti);
12529 synchronized (this) {
12530 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12532 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12535 if (opti >= args.length) {
12537 newArgs = EMPTY_STRING_ARRAY;
12539 dumpPackage = args[opti];
12541 newArgs = new String[args.length - opti];
12542 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12543 args.length - opti);
12545 synchronized (this) {
12546 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
12548 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12549 synchronized (this) {
12550 dumpOomLocked(fd, pw, args, opti, true);
12552 } else if ("provider".equals(cmd)) {
12555 if (opti >= args.length) {
12557 newArgs = EMPTY_STRING_ARRAY;
12561 newArgs = new String[args.length - opti];
12562 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12564 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12565 pw.println("No providers match: " + name);
12566 pw.println("Use -h for help.");
12568 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12569 synchronized (this) {
12570 dumpProvidersLocked(fd, pw, args, opti, true, null);
12572 } else if ("service".equals(cmd)) {
12575 if (opti >= args.length) {
12577 newArgs = EMPTY_STRING_ARRAY;
12581 newArgs = new String[args.length - opti];
12582 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12583 args.length - opti);
12585 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12586 pw.println("No services match: " + name);
12587 pw.println("Use -h for help.");
12589 } else if ("package".equals(cmd)) {
12591 if (opti >= args.length) {
12592 pw.println("package: no package name specified");
12593 pw.println("Use -h for help.");
12595 dumpPackage = args[opti];
12597 newArgs = new String[args.length - opti];
12598 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12599 args.length - opti);
12604 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
12605 synchronized (this) {
12606 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12608 } else if ("services".equals(cmd) || "s".equals(cmd)) {
12609 synchronized (this) {
12610 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12612 } else if ("write".equals(cmd)) {
12613 mTaskPersister.flush();
12614 pw.println("All tasks persisted.");
12616 } else if ("track-associations".equals(cmd)) {
12617 synchronized (this) {
12618 if (!mTrackingAssociations) {
12619 mTrackingAssociations = true;
12620 pw.println("Association tracking started.");
12622 pw.println("Association tracking already enabled.");
12626 } else if ("untrack-associations".equals(cmd)) {
12627 synchronized (this) {
12628 if (mTrackingAssociations) {
12629 mTrackingAssociations = false;
12630 mAssociations.clear();
12631 pw.println("Association tracking stopped.");
12633 pw.println("Association tracking not running.");
12638 // Dumping a single activity?
12639 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12640 pw.println("Bad activity command, or no activities match: " + cmd);
12641 pw.println("Use -h for help.");
12645 Binder.restoreCallingIdentity(origId);
12650 // No piece of data specified, dump everything.
12651 synchronized (this) {
12652 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12655 pw.println("-------------------------------------------------------------------------------");
12657 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12660 pw.println("-------------------------------------------------------------------------------");
12662 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12665 pw.println("-------------------------------------------------------------------------------");
12667 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12670 pw.println("-------------------------------------------------------------------------------");
12672 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12675 pw.println("-------------------------------------------------------------------------------");
12677 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12678 if (mAssociations.size() > 0) {
12681 pw.println("-------------------------------------------------------------------------------");
12683 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12687 pw.println("-------------------------------------------------------------------------------");
12689 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12691 Binder.restoreCallingIdentity(origId);
12694 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12695 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12696 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12698 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12700 boolean needSep = printedAnything;
12702 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12703 dumpPackage, needSep, " mFocusedActivity: ");
12705 printedAnything = true;
12709 if (dumpPackage == null) {
12714 printedAnything = true;
12715 mStackSupervisor.dump(pw, " ");
12718 if (!printedAnything) {
12719 pw.println(" (nothing)");
12723 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12724 int opti, boolean dumpAll, String dumpPackage) {
12725 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12727 boolean printedAnything = false;
12729 if (mRecentTasks != null && mRecentTasks.size() > 0) {
12730 boolean printedHeader = false;
12732 final int N = mRecentTasks.size();
12733 for (int i=0; i<N; i++) {
12734 TaskRecord tr = mRecentTasks.get(i);
12735 if (dumpPackage != null) {
12736 if (tr.realActivity == null ||
12737 !dumpPackage.equals(tr.realActivity)) {
12741 if (!printedHeader) {
12742 pw.println(" Recent tasks:");
12743 printedHeader = true;
12744 printedAnything = true;
12746 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
12749 mRecentTasks.get(i).dump(pw, " ");
12754 if (!printedAnything) {
12755 pw.println(" (nothing)");
12759 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12760 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12761 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
12764 if (dumpPackage != null) {
12765 IPackageManager pm = AppGlobals.getPackageManager();
12767 dumpUid = pm.getPackageUid(dumpPackage, 0);
12768 } catch (RemoteException e) {
12772 boolean printedAnything = false;
12774 final long now = SystemClock.uptimeMillis();
12776 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
12777 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
12778 = mAssociations.valueAt(i1);
12779 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
12780 SparseArray<ArrayMap<String, Association>> sourceUids
12781 = targetComponents.valueAt(i2);
12782 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
12783 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
12784 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
12785 Association ass = sourceProcesses.valueAt(i4);
12786 if (dumpPackage != null) {
12787 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
12788 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
12792 printedAnything = true;
12794 pw.print(ass.mTargetProcess);
12796 UserHandle.formatUid(pw, ass.mTargetUid);
12798 pw.print(ass.mSourceProcess);
12800 UserHandle.formatUid(pw, ass.mSourceUid);
12803 pw.print(ass.mTargetComponent.flattenToShortString());
12806 long dur = ass.mTime;
12807 if (ass.mNesting > 0) {
12808 dur += now - ass.mStartTime;
12810 TimeUtils.formatDuration(dur, pw);
12812 pw.print(ass.mCount);
12813 pw.println(" times)");
12814 if (ass.mNesting > 0) {
12816 pw.print(" Currently active: ");
12817 TimeUtils.formatDuration(now - ass.mStartTime, pw);
12826 if (!printedAnything) {
12827 pw.println(" (nothing)");
12831 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12832 int opti, boolean dumpAll, String dumpPackage) {
12833 boolean needSep = false;
12834 boolean printedAnything = false;
12837 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12840 final int NP = mProcessNames.getMap().size();
12841 for (int ip=0; ip<NP; ip++) {
12842 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12843 final int NA = procs.size();
12844 for (int ia=0; ia<NA; ia++) {
12845 ProcessRecord r = procs.valueAt(ia);
12846 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12850 pw.println(" All known processes:");
12852 printedAnything = true;
12854 pw.print(r.persistent ? " *PERS*" : " *APP*");
12855 pw.print(" UID "); pw.print(procs.keyAt(ia));
12856 pw.print(" "); pw.println(r);
12858 if (r.persistent) {
12865 if (mIsolatedProcesses.size() > 0) {
12866 boolean printed = false;
12867 for (int i=0; i<mIsolatedProcesses.size(); i++) {
12868 ProcessRecord r = mIsolatedProcesses.valueAt(i);
12869 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12876 pw.println(" Isolated process list (sorted by uid):");
12877 printedAnything = true;
12881 pw.println(String.format("%sIsolated #%2d: %s",
12882 " ", i, r.toString()));
12886 if (mLruProcesses.size() > 0) {
12890 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12891 pw.print(" total, non-act at ");
12892 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12893 pw.print(", non-svc at ");
12894 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12896 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
12898 printedAnything = true;
12901 if (dumpAll || dumpPackage != null) {
12902 synchronized (mPidsSelfLocked) {
12903 boolean printed = false;
12904 for (int i=0; i<mPidsSelfLocked.size(); i++) {
12905 ProcessRecord r = mPidsSelfLocked.valueAt(i);
12906 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12910 if (needSep) pw.println();
12912 pw.println(" PID mappings:");
12914 printedAnything = true;
12916 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12917 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12922 if (mForegroundProcesses.size() > 0) {
12923 synchronized (mPidsSelfLocked) {
12924 boolean printed = false;
12925 for (int i=0; i<mForegroundProcesses.size(); i++) {
12926 ProcessRecord r = mPidsSelfLocked.get(
12927 mForegroundProcesses.valueAt(i).pid);
12928 if (dumpPackage != null && (r == null
12929 || !r.pkgList.containsKey(dumpPackage))) {
12933 if (needSep) pw.println();
12935 pw.println(" Foreground Processes:");
12937 printedAnything = true;
12939 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
12940 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12945 if (mPersistentStartingProcesses.size() > 0) {
12946 if (needSep) pw.println();
12948 printedAnything = true;
12949 pw.println(" Persisent processes that are starting:");
12950 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
12951 "Starting Norm", "Restarting PERS", dumpPackage);
12954 if (mRemovedProcesses.size() > 0) {
12955 if (needSep) pw.println();
12957 printedAnything = true;
12958 pw.println(" Processes that are being removed:");
12959 dumpProcessList(pw, this, mRemovedProcesses, " ",
12960 "Removed Norm", "Removed PERS", dumpPackage);
12963 if (mProcessesOnHold.size() > 0) {
12964 if (needSep) pw.println();
12966 printedAnything = true;
12967 pw.println(" Processes that are on old until the system is ready:");
12968 dumpProcessList(pw, this, mProcessesOnHold, " ",
12969 "OnHold Norm", "OnHold PERS", dumpPackage);
12972 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12974 if (mProcessCrashTimes.getMap().size() > 0) {
12975 boolean printed = false;
12976 long now = SystemClock.uptimeMillis();
12977 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12978 final int NP = pmap.size();
12979 for (int ip=0; ip<NP; ip++) {
12980 String pname = pmap.keyAt(ip);
12981 SparseArray<Long> uids = pmap.valueAt(ip);
12982 final int N = uids.size();
12983 for (int i=0; i<N; i++) {
12984 int puid = uids.keyAt(i);
12985 ProcessRecord r = mProcessNames.get(pname, puid);
12986 if (dumpPackage != null && (r == null
12987 || !r.pkgList.containsKey(dumpPackage))) {
12991 if (needSep) pw.println();
12993 pw.println(" Time since processes crashed:");
12995 printedAnything = true;
12997 pw.print(" Process "); pw.print(pname);
12998 pw.print(" uid "); pw.print(puid);
12999 pw.print(": last crashed ");
13000 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13001 pw.println(" ago");
13006 if (mBadProcesses.getMap().size() > 0) {
13007 boolean printed = false;
13008 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13009 final int NP = pmap.size();
13010 for (int ip=0; ip<NP; ip++) {
13011 String pname = pmap.keyAt(ip);
13012 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13013 final int N = uids.size();
13014 for (int i=0; i<N; i++) {
13015 int puid = uids.keyAt(i);
13016 ProcessRecord r = mProcessNames.get(pname, puid);
13017 if (dumpPackage != null && (r == null
13018 || !r.pkgList.containsKey(dumpPackage))) {
13022 if (needSep) pw.println();
13024 pw.println(" Bad processes:");
13025 printedAnything = true;
13027 BadProcessInfo info = uids.valueAt(i);
13028 pw.print(" Bad process "); pw.print(pname);
13029 pw.print(" uid "); pw.print(puid);
13030 pw.print(": crashed at time "); pw.println(info.time);
13031 if (info.shortMsg != null) {
13032 pw.print(" Short msg: "); pw.println(info.shortMsg);
13034 if (info.longMsg != null) {
13035 pw.print(" Long msg: "); pw.println(info.longMsg);
13037 if (info.stack != null) {
13038 pw.println(" Stack:");
13040 for (int pos=0; pos<info.stack.length(); pos++) {
13041 if (info.stack.charAt(pos) == '\n') {
13043 pw.write(info.stack, lastPos, pos-lastPos);
13048 if (lastPos < info.stack.length()) {
13050 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13058 if (dumpPackage == null) {
13061 pw.println(" mStartedUsers:");
13062 for (int i=0; i<mStartedUsers.size(); i++) {
13063 UserStartedState uss = mStartedUsers.valueAt(i);
13064 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
13065 pw.print(": "); uss.dump("", pw);
13067 pw.print(" mStartedUserArray: [");
13068 for (int i=0; i<mStartedUserArray.length; i++) {
13069 if (i > 0) pw.print(", ");
13070 pw.print(mStartedUserArray[i]);
13073 pw.print(" mUserLru: [");
13074 for (int i=0; i<mUserLru.size(); i++) {
13075 if (i > 0) pw.print(", ");
13076 pw.print(mUserLru.get(i));
13080 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13082 synchronized (mUserProfileGroupIdsSelfLocked) {
13083 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13084 pw.println(" mUserProfileGroupIds:");
13085 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13086 pw.print(" User #");
13087 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13088 pw.print(" -> profile #");
13089 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13094 if (mHomeProcess != null && (dumpPackage == null
13095 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13100 pw.println(" mHomeProcess: " + mHomeProcess);
13102 if (mPreviousProcess != null && (dumpPackage == null
13103 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13108 pw.println(" mPreviousProcess: " + mPreviousProcess);
13111 StringBuilder sb = new StringBuilder(128);
13112 sb.append(" mPreviousProcessVisibleTime: ");
13113 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13116 if (mHeavyWeightProcess != null && (dumpPackage == null
13117 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13122 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13124 if (dumpPackage == null) {
13125 pw.println(" mConfiguration: " + mConfiguration);
13128 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13129 if (mCompatModePackages.getPackages().size() > 0) {
13130 boolean printed = false;
13131 for (Map.Entry<String, Integer> entry
13132 : mCompatModePackages.getPackages().entrySet()) {
13133 String pkg = entry.getKey();
13134 int mode = entry.getValue();
13135 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13139 pw.println(" mScreenCompatPackages:");
13142 pw.print(" "); pw.print(pkg); pw.print(": ");
13143 pw.print(mode); pw.println();
13147 if (dumpPackage == null) {
13148 pw.println(" mWakefulness="
13149 + PowerManagerInternal.wakefulnessToString(mWakefulness));
13150 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
13151 + lockScreenShownToString());
13152 pw.println(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice
13153 + " mTestPssMode=" + mTestPssMode);
13155 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13156 || mOrigWaitForDebugger) {
13157 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13158 || dumpPackage.equals(mOrigDebugApp)) {
13163 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13164 + " mDebugTransient=" + mDebugTransient
13165 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13168 if (mOpenGlTraceApp != null) {
13169 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13174 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
13177 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13178 || mProfileFd != null) {
13179 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13184 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13185 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13186 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13187 + mAutoStopProfiler);
13188 pw.println(" mProfileType=" + mProfileType);
13191 if (dumpPackage == null) {
13192 if (mAlwaysFinishActivities || mController != null) {
13193 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
13194 + " mController=" + mController);
13197 pw.println(" Total persistent processes: " + numPers);
13198 pw.println(" mProcessesReady=" + mProcessesReady
13199 + " mSystemReady=" + mSystemReady
13200 + " mBooted=" + mBooted
13201 + " mFactoryTest=" + mFactoryTest);
13202 pw.println(" mBooting=" + mBooting
13203 + " mCallFinishBooting=" + mCallFinishBooting
13204 + " mBootAnimationComplete=" + mBootAnimationComplete);
13205 pw.print(" mLastPowerCheckRealtime=");
13206 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13208 pw.print(" mLastPowerCheckUptime=");
13209 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13211 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13212 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13213 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13214 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
13215 + " (" + mLruProcesses.size() + " total)"
13216 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13217 + " mNumServiceProcs=" + mNumServiceProcs
13218 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13219 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
13220 + " mLastMemoryLevel" + mLastMemoryLevel
13221 + " mLastNumProcesses" + mLastNumProcesses);
13222 long now = SystemClock.uptimeMillis();
13223 pw.print(" mLastIdleTime=");
13224 TimeUtils.formatDuration(now, mLastIdleTime, pw);
13225 pw.print(" mLowRamSinceLastIdle=");
13226 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13231 if (!printedAnything) {
13232 pw.println(" (nothing)");
13236 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13237 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13238 if (mProcessesToGc.size() > 0) {
13239 boolean printed = false;
13240 long now = SystemClock.uptimeMillis();
13241 for (int i=0; i<mProcessesToGc.size(); i++) {
13242 ProcessRecord proc = mProcessesToGc.get(i);
13243 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13247 if (needSep) pw.println();
13249 pw.println(" Processes that are waiting to GC:");
13252 pw.print(" Process "); pw.println(proc);
13253 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
13254 pw.print(", last gced=");
13255 pw.print(now-proc.lastRequestedGc);
13256 pw.print(" ms ago, last lowMem=");
13257 pw.print(now-proc.lastLowMemory);
13258 pw.println(" ms ago");
13265 void printOomLevel(PrintWriter pw, String name, int adj) {
13269 if (adj < 10) pw.print(' ');
13271 if (adj > -10) pw.print(' ');
13277 pw.print(mProcessList.getMemLevel(adj)/1024);
13278 pw.println(" kB)");
13281 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13282 int opti, boolean dumpAll) {
13283 boolean needSep = false;
13285 if (mLruProcesses.size() > 0) {
13286 if (needSep) pw.println();
13288 pw.println(" OOM levels:");
13289 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13290 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13291 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13292 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13293 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13294 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13295 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13296 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13297 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13298 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13299 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13300 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13301 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13302 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13304 if (needSep) pw.println();
13305 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
13306 pw.print(" total, non-act at ");
13307 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13308 pw.print(", non-svc at ");
13309 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13311 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
13315 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13318 pw.println(" mHomeProcess: " + mHomeProcess);
13319 pw.println(" mPreviousProcess: " + mPreviousProcess);
13320 if (mHeavyWeightProcess != null) {
13321 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13328 * There are three ways to call this:
13329 * - no provider specified: dump all the providers
13330 * - a flattened component name that matched an existing provider was specified as the
13331 * first arg: dump that one provider
13332 * - the first arg isn't the flattened component name of an existing provider:
13333 * dump all providers whose component contains the first arg as a substring
13335 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13336 int opti, boolean dumpAll) {
13337 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13340 static class ItemMatcher {
13341 ArrayList<ComponentName> components;
13342 ArrayList<String> strings;
13343 ArrayList<Integer> objects;
13350 void build(String name) {
13351 ComponentName componentName = ComponentName.unflattenFromString(name);
13352 if (componentName != null) {
13353 if (components == null) {
13354 components = new ArrayList<ComponentName>();
13356 components.add(componentName);
13360 // Not a '/' separated full component name; maybe an object ID?
13362 objectId = Integer.parseInt(name, 16);
13363 if (objects == null) {
13364 objects = new ArrayList<Integer>();
13366 objects.add(objectId);
13368 } catch (RuntimeException e) {
13369 // Not an integer; just do string match.
13370 if (strings == null) {
13371 strings = new ArrayList<String>();
13379 int build(String[] args, int opti) {
13380 for (; opti<args.length; opti++) {
13381 String name = args[opti];
13382 if ("--".equals(name)) {
13390 boolean match(Object object, ComponentName comp) {
13394 if (components != null) {
13395 for (int i=0; i<components.size(); i++) {
13396 if (components.get(i).equals(comp)) {
13401 if (objects != null) {
13402 for (int i=0; i<objects.size(); i++) {
13403 if (System.identityHashCode(object) == objects.get(i)) {
13408 if (strings != null) {
13409 String flat = comp.flattenToString();
13410 for (int i=0; i<strings.size(); i++) {
13411 if (flat.contains(strings.get(i))) {
13421 * There are three things that cmd can be:
13422 * - a flattened component name that matches an existing activity
13423 * - the cmd arg isn't the flattened component name of an existing activity:
13424 * dump all activity whose component contains the cmd as a substring
13425 * - A hex number of the ActivityRecord object instance.
13427 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13428 int opti, boolean dumpAll) {
13429 ArrayList<ActivityRecord> activities;
13431 synchronized (this) {
13432 activities = mStackSupervisor.getDumpActivitiesLocked(name);
13435 if (activities.size() <= 0) {
13439 String[] newArgs = new String[args.length - opti];
13440 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13442 TaskRecord lastTask = null;
13443 boolean needSep = false;
13444 for (int i=activities.size()-1; i>=0; i--) {
13445 ActivityRecord r = activities.get(i);
13450 synchronized (this) {
13451 if (lastTask != r.task) {
13453 pw.print("TASK "); pw.print(lastTask.affinity);
13454 pw.print(" id="); pw.println(lastTask.taskId);
13456 lastTask.dump(pw, " ");
13460 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
13466 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13467 * there is a thread associated with the activity.
13469 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13470 final ActivityRecord r, String[] args, boolean dumpAll) {
13471 String innerPrefix = prefix + " ";
13472 synchronized (this) {
13473 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13474 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13476 if (r.app != null) pw.println(r.app.pid);
13477 else pw.println("(not running)");
13479 r.dump(pw, innerPrefix);
13482 if (r.app != null && r.app.thread != null) {
13483 // flush anything that is already in the PrintWriter since the thread is going
13484 // to write to the file descriptor directly
13487 TransferPipe tp = new TransferPipe();
13489 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13490 r.appToken, innerPrefix, args);
13495 } catch (IOException e) {
13496 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13497 } catch (RemoteException e) {
13498 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13503 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13504 int opti, boolean dumpAll, String dumpPackage) {
13505 boolean needSep = false;
13506 boolean onlyHistory = false;
13507 boolean printedAnything = false;
13509 if ("history".equals(dumpPackage)) {
13510 if (opti < args.length && "-s".equals(args[opti])) {
13513 onlyHistory = true;
13514 dumpPackage = null;
13517 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13518 if (!onlyHistory && dumpAll) {
13519 if (mRegisteredReceivers.size() > 0) {
13520 boolean printed = false;
13521 Iterator it = mRegisteredReceivers.values().iterator();
13522 while (it.hasNext()) {
13523 ReceiverList r = (ReceiverList)it.next();
13524 if (dumpPackage != null && (r.app == null ||
13525 !dumpPackage.equals(r.app.info.packageName))) {
13529 pw.println(" Registered Receivers:");
13532 printedAnything = true;
13534 pw.print(" * "); pw.println(r);
13539 if (mReceiverResolver.dump(pw, needSep ?
13540 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
13541 " ", dumpPackage, false, false)) {
13543 printedAnything = true;
13547 for (BroadcastQueue q : mBroadcastQueues) {
13548 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13549 printedAnything |= needSep;
13554 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13555 for (int user=0; user<mStickyBroadcasts.size(); user++) {
13560 printedAnything = true;
13561 pw.print(" Sticky broadcasts for user ");
13562 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13563 StringBuilder sb = new StringBuilder(128);
13564 for (Map.Entry<String, ArrayList<Intent>> ent
13565 : mStickyBroadcasts.valueAt(user).entrySet()) {
13566 pw.print(" * Sticky action "); pw.print(ent.getKey());
13569 ArrayList<Intent> intents = ent.getValue();
13570 final int N = intents.size();
13571 for (int i=0; i<N; i++) {
13573 sb.append(" Intent: ");
13574 intents.get(i).toShortString(sb, false, true, false, false);
13575 pw.println(sb.toString());
13576 Bundle bundle = intents.get(i).getExtras();
13577 if (bundle != null) {
13579 pw.println(bundle.toString());
13589 if (!onlyHistory && dumpAll) {
13591 for (BroadcastQueue queue : mBroadcastQueues) {
13592 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
13593 + queue.mBroadcastsScheduled);
13595 pw.println(" mHandler:");
13596 mHandler.dump(new PrintWriterPrinter(pw), " ");
13598 printedAnything = true;
13601 if (!printedAnything) {
13602 pw.println(" (nothing)");
13606 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13607 int opti, boolean dumpAll, String dumpPackage) {
13609 boolean printedAnything = false;
13611 ItemMatcher matcher = new ItemMatcher();
13612 matcher.build(args, opti);
13614 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13616 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13617 printedAnything |= needSep;
13619 if (mLaunchingProviders.size() > 0) {
13620 boolean printed = false;
13621 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13622 ContentProviderRecord r = mLaunchingProviders.get(i);
13623 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13627 if (needSep) pw.println();
13629 pw.println(" Launching content providers:");
13631 printedAnything = true;
13633 pw.print(" Launching #"); pw.print(i); pw.print(": ");
13638 if (mGrantedUriPermissions.size() > 0) {
13639 boolean printed = false;
13641 if (dumpPackage != null) {
13643 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13644 } catch (NameNotFoundException e) {
13648 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13649 int uid = mGrantedUriPermissions.keyAt(i);
13650 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13653 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13655 if (needSep) pw.println();
13657 pw.println(" Granted Uri Permissions:");
13659 printedAnything = true;
13661 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
13662 for (UriPermission perm : perms.values()) {
13663 pw.print(" "); pw.println(perm);
13665 perm.dump(pw, " ");
13671 if (!printedAnything) {
13672 pw.println(" (nothing)");
13676 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13677 int opti, boolean dumpAll, String dumpPackage) {
13678 boolean printed = false;
13680 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13682 if (mIntentSenderRecords.size() > 0) {
13683 Iterator<WeakReference<PendingIntentRecord>> it
13684 = mIntentSenderRecords.values().iterator();
13685 while (it.hasNext()) {
13686 WeakReference<PendingIntentRecord> ref = it.next();
13687 PendingIntentRecord rec = ref != null ? ref.get(): null;
13688 if (dumpPackage != null && (rec == null
13689 || !dumpPackage.equals(rec.key.packageName))) {
13694 pw.print(" * "); pw.println(rec);
13699 pw.print(" * "); pw.println(ref);
13705 pw.println(" (nothing)");
13709 private static final int dumpProcessList(PrintWriter pw,
13710 ActivityManagerService service, List list,
13711 String prefix, String normalLabel, String persistentLabel,
13712 String dumpPackage) {
13714 final int N = list.size()-1;
13715 for (int i=N; i>=0; i--) {
13716 ProcessRecord r = (ProcessRecord)list.get(i);
13717 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13720 pw.println(String.format("%s%s #%2d: %s",
13721 prefix, (r.persistent ? persistentLabel : normalLabel),
13723 if (r.persistent) {
13730 private static final boolean dumpProcessOomList(PrintWriter pw,
13731 ActivityManagerService service, List<ProcessRecord> origList,
13732 String prefix, String normalLabel, String persistentLabel,
13733 boolean inclDetails, String dumpPackage) {
13735 ArrayList<Pair<ProcessRecord, Integer>> list
13736 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13737 for (int i=0; i<origList.size(); i++) {
13738 ProcessRecord r = origList.get(i);
13739 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13742 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13745 if (list.size() <= 0) {
13749 Comparator<Pair<ProcessRecord, Integer>> comparator
13750 = new Comparator<Pair<ProcessRecord, Integer>>() {
13752 public int compare(Pair<ProcessRecord, Integer> object1,
13753 Pair<ProcessRecord, Integer> object2) {
13754 if (object1.first.setAdj != object2.first.setAdj) {
13755 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13757 if (object1.second.intValue() != object2.second.intValue()) {
13758 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13764 Collections.sort(list, comparator);
13766 final long curRealtime = SystemClock.elapsedRealtime();
13767 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13768 final long curUptime = SystemClock.uptimeMillis();
13769 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13771 for (int i=list.size()-1; i>=0; i--) {
13772 ProcessRecord r = list.get(i).first;
13773 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13775 switch (r.setSchedGroup) {
13776 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13779 case Process.THREAD_GROUP_DEFAULT:
13787 if (r.foregroundActivities) {
13789 } else if (r.foregroundServices) {
13794 String procState = ProcessList.makeProcStateString(r.curProcState);
13796 pw.print(r.persistent ? persistentLabel : normalLabel);
13798 int num = (origList.size()-1)-list.get(i).second;
13799 if (num < 10) pw.print(' ');
13804 pw.print(schedGroup);
13806 pw.print(foreground);
13808 pw.print(procState);
13810 if (r.trimMemoryLevel < 10) pw.print(' ');
13811 pw.print(r.trimMemoryLevel);
13813 pw.print(r.toShortString());
13815 pw.print(r.adjType);
13817 if (r.adjSource != null || r.adjTarget != null) {
13820 if (r.adjTarget instanceof ComponentName) {
13821 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13822 } else if (r.adjTarget != null) {
13823 pw.print(r.adjTarget.toString());
13825 pw.print("{null}");
13828 if (r.adjSource instanceof ProcessRecord) {
13830 pw.print(((ProcessRecord)r.adjSource).toShortString());
13832 } else if (r.adjSource != null) {
13833 pw.println(r.adjSource.toString());
13835 pw.println("{null}");
13841 pw.print("oom: max="); pw.print(r.maxAdj);
13842 pw.print(" curRaw="); pw.print(r.curRawAdj);
13843 pw.print(" setRaw="); pw.print(r.setRawAdj);
13844 pw.print(" cur="); pw.print(r.curAdj);
13845 pw.print(" set="); pw.println(r.setAdj);
13848 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13849 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13850 pw.print(" lastPss="); pw.print(r.lastPss);
13851 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13854 pw.print("cached="); pw.print(r.cached);
13855 pw.print(" empty="); pw.print(r.empty);
13856 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13858 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13859 if (r.lastWakeTime != 0) {
13861 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13862 synchronized (stats) {
13863 wtime = stats.getProcessWakeTime(r.info.uid,
13864 r.pid, curRealtime);
13866 long timeUsed = wtime - r.lastWakeTime;
13869 pw.print("keep awake over ");
13870 TimeUtils.formatDuration(realtimeSince, pw);
13871 pw.print(" used ");
13872 TimeUtils.formatDuration(timeUsed, pw);
13874 pw.print((timeUsed*100)/realtimeSince);
13877 if (r.lastCpuTime != 0) {
13878 long timeUsed = r.curCpuTime - r.lastCpuTime;
13881 pw.print("run cpu over ");
13882 TimeUtils.formatDuration(uptimeSince, pw);
13883 pw.print(" used ");
13884 TimeUtils.formatDuration(timeUsed, pw);
13886 pw.print((timeUsed*100)/uptimeSince);
13895 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13897 ArrayList<ProcessRecord> procs;
13898 synchronized (this) {
13899 if (args != null && args.length > start
13900 && args[start].charAt(0) != '-') {
13901 procs = new ArrayList<ProcessRecord>();
13904 pid = Integer.parseInt(args[start]);
13905 } catch (NumberFormatException e) {
13907 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13908 ProcessRecord proc = mLruProcesses.get(i);
13909 if (proc.pid == pid) {
13911 } else if (allPkgs && proc.pkgList != null
13912 && proc.pkgList.containsKey(args[start])) {
13914 } else if (proc.processName.equals(args[start])) {
13918 if (procs.size() <= 0) {
13922 procs = new ArrayList<ProcessRecord>(mLruProcesses);
13928 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13929 PrintWriter pw, String[] args) {
13930 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13931 if (procs == null) {
13932 pw.println("No process found for: " + args[0]);
13936 long uptime = SystemClock.uptimeMillis();
13937 long realtime = SystemClock.elapsedRealtime();
13938 pw.println("Applications Graphics Acceleration Info:");
13939 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13941 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13942 ProcessRecord r = procs.get(i);
13943 if (r.thread != null) {
13944 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13947 TransferPipe tp = new TransferPipe();
13949 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13954 } catch (IOException e) {
13955 pw.println("Failure while dumping the app: " + r);
13957 } catch (RemoteException e) {
13958 pw.println("Got a RemoteException while dumping the app " + r);
13965 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13966 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13967 if (procs == null) {
13968 pw.println("No process found for: " + args[0]);
13972 pw.println("Applications Database Info:");
13974 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13975 ProcessRecord r = procs.get(i);
13976 if (r.thread != null) {
13977 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13980 TransferPipe tp = new TransferPipe();
13982 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13987 } catch (IOException e) {
13988 pw.println("Failure while dumping the app: " + r);
13990 } catch (RemoteException e) {
13991 pw.println("Got a RemoteException while dumping the app " + r);
13998 final static class MemItem {
13999 final boolean isProc;
14000 final String label;
14001 final String shortLabel;
14004 final boolean hasActivities;
14005 ArrayList<MemItem> subitems;
14007 public MemItem(String _label, String _shortLabel, long _pss, int _id,
14008 boolean _hasActivities) {
14011 shortLabel = _shortLabel;
14014 hasActivities = _hasActivities;
14017 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14020 shortLabel = _shortLabel;
14023 hasActivities = false;
14027 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14028 ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14029 if (sort && !isCompact) {
14030 Collections.sort(items, new Comparator<MemItem>() {
14032 public int compare(MemItem lhs, MemItem rhs) {
14033 if (lhs.pss < rhs.pss) {
14035 } else if (lhs.pss > rhs.pss) {
14043 for (int i=0; i<items.size(); i++) {
14044 MemItem mi = items.get(i);
14046 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14047 } else if (mi.isProc) {
14048 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14049 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14050 pw.println(mi.hasActivities ? ",a" : ",e");
14052 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14053 pw.println(mi.pss);
14055 if (mi.subitems != null) {
14056 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
14062 // These are in KB.
14063 static final long[] DUMP_MEM_BUCKETS = new long[] {
14064 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14065 120*1024, 160*1024, 200*1024,
14066 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14067 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14070 static final void appendMemBucket(StringBuilder out, long memKB, String label,
14071 boolean stackLike) {
14072 int start = label.lastIndexOf('.');
14073 if (start >= 0) start++;
14075 int end = label.length();
14076 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14077 if (DUMP_MEM_BUCKETS[i] >= memKB) {
14078 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14079 out.append(bucket);
14080 out.append(stackLike ? "MB." : "MB ");
14081 out.append(label, start, end);
14085 out.append(memKB/1024);
14086 out.append(stackLike ? "MB." : "MB ");
14087 out.append(label, start, end);
14090 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14091 ProcessList.NATIVE_ADJ,
14092 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14093 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14094 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14095 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14096 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14097 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14099 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14101 "System", "Persistent", "Persistent Service", "Foreground",
14102 "Visible", "Perceptible",
14103 "Heavy Weight", "Backup",
14104 "A Services", "Home",
14105 "Previous", "B Services", "Cached"
14107 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14109 "sys", "pers", "persvc", "fore",
14112 "servicea", "home",
14113 "prev", "serviceb", "cached"
14116 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14117 long realtime, boolean isCheckinRequest, boolean isCompact) {
14118 if (isCheckinRequest || isCompact) {
14119 // short checkin version
14120 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14122 pw.println("Applications Memory Usage (kB):");
14123 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14127 private static final int KSM_SHARED = 0;
14128 private static final int KSM_SHARING = 1;
14129 private static final int KSM_UNSHARED = 2;
14130 private static final int KSM_VOLATILE = 3;
14132 private final long[] getKsmInfo() {
14133 long[] longOut = new long[4];
14134 final int[] SINGLE_LONG_FORMAT = new int[] {
14135 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14137 long[] longTmp = new long[1];
14138 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14139 SINGLE_LONG_FORMAT, null, longTmp, null);
14140 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14142 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14143 SINGLE_LONG_FORMAT, null, longTmp, null);
14144 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14146 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14147 SINGLE_LONG_FORMAT, null, longTmp, null);
14148 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14150 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14151 SINGLE_LONG_FORMAT, null, longTmp, null);
14152 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14156 final void dumpApplicationMemoryUsage(FileDescriptor fd,
14157 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14158 boolean dumpDetails = false;
14159 boolean dumpFullDetails = false;
14160 boolean dumpDalvik = false;
14161 boolean oomOnly = false;
14162 boolean isCompact = false;
14163 boolean localOnly = false;
14164 boolean packages = false;
14167 while (opti < args.length) {
14168 String opt = args[opti];
14169 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14173 if ("-a".equals(opt)) {
14174 dumpDetails = true;
14175 dumpFullDetails = true;
14177 } else if ("-d".equals(opt)) {
14179 } else if ("-c".equals(opt)) {
14181 } else if ("--oom".equals(opt)) {
14183 } else if ("--local".equals(opt)) {
14185 } else if ("--package".equals(opt)) {
14187 } else if ("-h".equals(opt)) {
14188 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
14189 pw.println(" -a: include all available information for each process.");
14190 pw.println(" -d: include dalvik details when dumping process details.");
14191 pw.println(" -c: dump in a compact machine-parseable representation.");
14192 pw.println(" --oom: only show processes organized by oom adj.");
14193 pw.println(" --local: only collect details locally, don't call process.");
14194 pw.println(" --package: interpret process arg as package, dumping all");
14195 pw.println(" processes that have loaded that package.");
14196 pw.println("If [process] is specified it can be the name or ");
14197 pw.println("pid of a specific process to dump.");
14200 pw.println("Unknown argument: " + opt + "; use -h for help");
14204 final boolean isCheckinRequest = scanArgs(args, "--checkin");
14205 long uptime = SystemClock.uptimeMillis();
14206 long realtime = SystemClock.elapsedRealtime();
14207 final long[] tmpLong = new long[1];
14209 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14210 if (procs == null) {
14211 // No Java processes. Maybe they want to print a native process.
14212 if (args != null && args.length > opti
14213 && args[opti].charAt(0) != '-') {
14214 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14215 = new ArrayList<ProcessCpuTracker.Stats>();
14216 updateCpuStatsNow();
14219 findPid = Integer.parseInt(args[opti]);
14220 } catch (NumberFormatException e) {
14222 synchronized (mProcessCpuTracker) {
14223 final int N = mProcessCpuTracker.countStats();
14224 for (int i=0; i<N; i++) {
14225 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14226 if (st.pid == findPid || (st.baseName != null
14227 && st.baseName.equals(args[opti]))) {
14228 nativeProcs.add(st);
14232 if (nativeProcs.size() > 0) {
14233 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14235 Debug.MemoryInfo mi = null;
14236 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14237 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14238 final int pid = r.pid;
14239 if (!isCheckinRequest && dumpDetails) {
14240 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14243 mi = new Debug.MemoryInfo();
14245 if (dumpDetails || (!brief && !oomOnly)) {
14246 Debug.getMemoryInfo(pid, mi);
14248 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14249 mi.dalvikPrivateDirty = (int)tmpLong[0];
14251 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14252 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14253 if (isCheckinRequest) {
14260 pw.println("No process found for: " + args[opti]);
14264 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14265 dumpDetails = true;
14268 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14270 String[] innerArgs = new String[args.length-opti];
14271 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14273 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14274 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14275 long nativePss = 0;
14276 long dalvikPss = 0;
14278 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14280 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14281 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14282 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14285 long cachedPss = 0;
14287 Debug.MemoryInfo mi = null;
14288 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14289 final ProcessRecord r = procs.get(i);
14290 final IApplicationThread thread;
14293 final boolean hasActivities;
14294 synchronized (this) {
14297 oomAdj = r.getSetAdjWithServices();
14298 hasActivities = r.activities.size() > 0;
14300 if (thread != null) {
14301 if (!isCheckinRequest && dumpDetails) {
14302 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14305 mi = new Debug.MemoryInfo();
14307 if (dumpDetails || (!brief && !oomOnly)) {
14308 Debug.getMemoryInfo(pid, mi);
14310 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14311 mi.dalvikPrivateDirty = (int)tmpLong[0];
14315 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14316 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14317 if (isCheckinRequest) {
14323 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14324 dumpDalvik, innerArgs);
14325 } catch (RemoteException e) {
14326 if (!isCheckinRequest) {
14327 pw.println("Got RemoteException!");
14334 final long myTotalPss = mi.getTotalPss();
14335 final long myTotalUss = mi.getTotalUss();
14337 synchronized (this) {
14338 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14339 // Record this for posterity if the process has been stable.
14340 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14344 if (!isCheckinRequest && mi != null) {
14345 totalPss += myTotalPss;
14346 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14347 (hasActivities ? " / activities)" : ")"),
14348 r.processName, myTotalPss, pid, hasActivities);
14349 procMems.add(pssItem);
14350 procMemsMap.put(pid, pssItem);
14352 nativePss += mi.nativePss;
14353 dalvikPss += mi.dalvikPss;
14354 otherPss += mi.otherPss;
14355 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14356 long mem = mi.getOtherPss(j);
14361 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14362 cachedPss += myTotalPss;
14365 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14366 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14367 || oomIndex == (oomPss.length-1)) {
14368 oomPss[oomIndex] += myTotalPss;
14369 if (oomProcs[oomIndex] == null) {
14370 oomProcs[oomIndex] = new ArrayList<MemItem>();
14372 oomProcs[oomIndex].add(pssItem);
14380 long nativeProcTotalPss = 0;
14382 if (!isCheckinRequest && procs.size() > 1 && !packages) {
14383 // If we are showing aggregations, also look for native processes to
14384 // include so that our aggregations are more accurate.
14385 updateCpuStatsNow();
14387 synchronized (mProcessCpuTracker) {
14388 final int N = mProcessCpuTracker.countStats();
14389 for (int i=0; i<N; i++) {
14390 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14391 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14393 mi = new Debug.MemoryInfo();
14395 if (!brief && !oomOnly) {
14396 Debug.getMemoryInfo(st.pid, mi);
14398 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14399 mi.nativePrivateDirty = (int)tmpLong[0];
14402 final long myTotalPss = mi.getTotalPss();
14403 totalPss += myTotalPss;
14404 nativeProcTotalPss += myTotalPss;
14406 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14407 st.name, myTotalPss, st.pid, false);
14408 procMems.add(pssItem);
14410 nativePss += mi.nativePss;
14411 dalvikPss += mi.dalvikPss;
14412 otherPss += mi.otherPss;
14413 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14414 long mem = mi.getOtherPss(j);
14418 oomPss[0] += myTotalPss;
14419 if (oomProcs[0] == null) {
14420 oomProcs[0] = new ArrayList<MemItem>();
14422 oomProcs[0].add(pssItem);
14427 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14429 catMems.add(new MemItem("Native", "Native", nativePss, -1));
14430 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14431 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14432 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14433 String label = Debug.MemoryInfo.getOtherLabel(j);
14434 catMems.add(new MemItem(label, label, miscPss[j], j));
14437 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14438 for (int j=0; j<oomPss.length; j++) {
14439 if (oomPss[j] != 0) {
14440 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14441 : DUMP_MEM_OOM_LABEL[j];
14442 MemItem item = new MemItem(label, label, oomPss[j],
14443 DUMP_MEM_OOM_ADJ[j]);
14444 item.subitems = oomProcs[j];
14449 if (!brief && !oomOnly && !isCompact) {
14451 pw.println("Total PSS by process:");
14452 dumpMemItems(pw, " ", "proc", procMems, true, isCompact);
14456 pw.println("Total PSS by OOM adjustment:");
14458 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact);
14459 if (!brief && !oomOnly) {
14460 PrintWriter out = categoryPw != null ? categoryPw : pw;
14463 out.println("Total PSS by category:");
14465 dumpMemItems(out, " ", "cat", catMems, true, isCompact);
14470 MemInfoReader memInfo = new MemInfoReader();
14471 memInfo.readMemInfo();
14472 if (nativeProcTotalPss > 0) {
14473 synchronized (this) {
14474 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14475 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14476 memInfo.getKernelUsedSizeKb(), nativeProcTotalPss);
14481 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14482 pw.print(" kB (status ");
14483 switch (mLastMemoryLevel) {
14484 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14485 pw.println("normal)");
14487 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14488 pw.println("moderate)");
14490 case ProcessStats.ADJ_MEM_FACTOR_LOW:
14491 pw.println("low)");
14493 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14494 pw.println("critical)");
14497 pw.print(mLastMemoryLevel);
14501 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14502 + memInfo.getFreeSizeKb()); pw.print(" kB (");
14503 pw.print(cachedPss); pw.print(" cached pss + ");
14504 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
14505 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14507 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14508 pw.print(cachedPss + memInfo.getCachedSizeKb()
14509 + memInfo.getFreeSizeKb()); pw.print(",");
14510 pw.println(totalPss - cachedPss);
14514 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14515 + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
14516 pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14517 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
14518 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14519 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14520 - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
14523 if (memInfo.getZramTotalSizeKb() != 0) {
14525 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14526 pw.print(" kB physical used for ");
14527 pw.print(memInfo.getSwapTotalSizeKb()
14528 - memInfo.getSwapFreeSizeKb());
14529 pw.print(" kB in swap (");
14530 pw.print(memInfo.getSwapTotalSizeKb());
14531 pw.println(" kB total swap)");
14533 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14534 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14535 pw.println(memInfo.getSwapFreeSizeKb());
14538 final long[] ksm = getKsmInfo();
14540 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14541 || ksm[KSM_VOLATILE] != 0) {
14542 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]);
14543 pw.print(" kB saved from shared ");
14544 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
14545 pw.print(" "); pw.print(ksm[KSM_UNSHARED]);
14546 pw.print(" kB unshared; ");
14547 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
14549 pw.print(" Tuning: ");
14550 pw.print(ActivityManager.staticGetMemoryClass());
14551 pw.print(" (large ");
14552 pw.print(ActivityManager.staticGetLargeMemoryClass());
14553 pw.print("), oom ");
14554 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14556 pw.print(", restore limit ");
14557 pw.print(mProcessList.getCachedRestoreThresholdKb());
14559 if (ActivityManager.isLowRamDeviceStatic()) {
14560 pw.print(" (low-ram)");
14562 if (ActivityManager.isHighEndGfx()) {
14563 pw.print(" (high-end-gfx)");
14567 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
14568 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
14569 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
14570 pw.print("tuning,");
14571 pw.print(ActivityManager.staticGetMemoryClass());
14573 pw.print(ActivityManager.staticGetLargeMemoryClass());
14575 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14576 if (ActivityManager.isLowRamDeviceStatic()) {
14577 pw.print(",low-ram");
14579 if (ActivityManager.isHighEndGfx()) {
14580 pw.print(",high-end-gfx");
14588 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
14589 long memtrack, String name) {
14591 sb.append(ProcessList.makeOomAdjString(oomAdj));
14593 sb.append(ProcessList.makeProcStateString(procState));
14595 ProcessList.appendRamKb(sb, pss);
14596 sb.append(" kB: ");
14598 if (memtrack > 0) {
14600 sb.append(memtrack);
14601 sb.append(" kB memtrack)");
14605 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
14606 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
14607 sb.append(" (pid ");
14610 sb.append(mi.adjType);
14612 if (mi.adjReason != null) {
14614 sb.append(mi.adjReason);
14619 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
14620 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
14621 for (int i=0, N=memInfos.size(); i<N; i++) {
14622 ProcessMemInfo mi = memInfos.get(i);
14623 infoMap.put(mi.pid, mi);
14625 updateCpuStatsNow();
14626 long[] memtrackTmp = new long[1];
14627 synchronized (mProcessCpuTracker) {
14628 final int N = mProcessCpuTracker.countStats();
14629 for (int i=0; i<N; i++) {
14630 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14631 if (st.vsize > 0) {
14632 long pss = Debug.getPss(st.pid, null, memtrackTmp);
14634 if (infoMap.indexOfKey(st.pid) < 0) {
14635 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
14636 ProcessList.NATIVE_ADJ, -1, "native", null);
14638 mi.memtrack = memtrackTmp[0];
14647 long totalMemtrack = 0;
14648 for (int i=0, N=memInfos.size(); i<N; i++) {
14649 ProcessMemInfo mi = memInfos.get(i);
14651 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
14652 mi.memtrack = memtrackTmp[0];
14654 totalPss += mi.pss;
14655 totalMemtrack += mi.memtrack;
14657 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
14658 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
14659 if (lhs.oomAdj != rhs.oomAdj) {
14660 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
14662 if (lhs.pss != rhs.pss) {
14663 return lhs.pss < rhs.pss ? 1 : -1;
14669 StringBuilder tag = new StringBuilder(128);
14670 StringBuilder stack = new StringBuilder(128);
14671 tag.append("Low on memory -- ");
14672 appendMemBucket(tag, totalPss, "total", false);
14673 appendMemBucket(stack, totalPss, "total", true);
14675 StringBuilder fullNativeBuilder = new StringBuilder(1024);
14676 StringBuilder shortNativeBuilder = new StringBuilder(1024);
14677 StringBuilder fullJavaBuilder = new StringBuilder(1024);
14679 boolean firstLine = true;
14680 int lastOomAdj = Integer.MIN_VALUE;
14681 long extraNativeRam = 0;
14682 long extraNativeMemtrack = 0;
14683 long cachedPss = 0;
14684 for (int i=0, N=memInfos.size(); i<N; i++) {
14685 ProcessMemInfo mi = memInfos.get(i);
14687 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14688 cachedPss += mi.pss;
14691 if (mi.oomAdj != ProcessList.NATIVE_ADJ
14692 && (mi.oomAdj < ProcessList.SERVICE_ADJ
14693 || mi.oomAdj == ProcessList.HOME_APP_ADJ
14694 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
14695 if (lastOomAdj != mi.oomAdj) {
14696 lastOomAdj = mi.oomAdj;
14697 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14700 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
14705 stack.append("\n\t at ");
14713 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14714 appendMemBucket(tag, mi.pss, mi.name, false);
14716 appendMemBucket(stack, mi.pss, mi.name, true);
14717 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
14718 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
14720 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
14721 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
14722 stack.append(DUMP_MEM_OOM_LABEL[k]);
14724 stack.append(DUMP_MEM_OOM_ADJ[k]);
14731 appendMemInfo(fullNativeBuilder, mi);
14732 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
14733 // The short form only has native processes that are >= 512K.
14734 if (mi.pss >= 512) {
14735 appendMemInfo(shortNativeBuilder, mi);
14737 extraNativeRam += mi.pss;
14738 extraNativeMemtrack += mi.memtrack;
14741 // Short form has all other details, but if we have collected RAM
14742 // from smaller native processes let's dump a summary of that.
14743 if (extraNativeRam > 0) {
14744 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
14745 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
14746 shortNativeBuilder.append('\n');
14747 extraNativeRam = 0;
14749 appendMemInfo(fullJavaBuilder, mi);
14753 fullJavaBuilder.append(" ");
14754 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
14755 fullJavaBuilder.append(" kB: TOTAL");
14756 if (totalMemtrack > 0) {
14757 fullJavaBuilder.append(" (");
14758 fullJavaBuilder.append(totalMemtrack);
14759 fullJavaBuilder.append(" kB memtrack)");
14762 fullJavaBuilder.append("\n");
14764 MemInfoReader memInfo = new MemInfoReader();
14765 memInfo.readMemInfo();
14766 final long[] infos = memInfo.getRawInfo();
14768 StringBuilder memInfoBuilder = new StringBuilder(1024);
14769 Debug.getMemInfo(infos);
14770 memInfoBuilder.append(" MemInfo: ");
14771 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
14772 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
14773 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
14774 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
14775 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
14776 memInfoBuilder.append(" ");
14777 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
14778 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
14779 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
14780 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
14781 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
14782 memInfoBuilder.append(" ZRAM: ");
14783 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
14784 memInfoBuilder.append(" kB RAM, ");
14785 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
14786 memInfoBuilder.append(" kB swap total, ");
14787 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
14788 memInfoBuilder.append(" kB swap free\n");
14790 final long[] ksm = getKsmInfo();
14791 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
14792 || ksm[KSM_VOLATILE] != 0) {
14793 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
14794 memInfoBuilder.append(" kB saved from shared ");
14795 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
14796 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
14797 memInfoBuilder.append(" kB unshared; ");
14798 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
14800 memInfoBuilder.append(" Free RAM: ");
14801 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
14802 + memInfo.getFreeSizeKb());
14803 memInfoBuilder.append(" kB\n");
14804 memInfoBuilder.append(" Used RAM: ");
14805 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
14806 memInfoBuilder.append(" kB\n");
14807 memInfoBuilder.append(" Lost RAM: ");
14808 memInfoBuilder.append(memInfo.getTotalSizeKb()
14809 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14810 - memInfo.getKernelUsedSizeKb());
14811 memInfoBuilder.append(" kB\n");
14812 Slog.i(TAG, "Low on memory:");
14813 Slog.i(TAG, shortNativeBuilder.toString());
14814 Slog.i(TAG, fullJavaBuilder.toString());
14815 Slog.i(TAG, memInfoBuilder.toString());
14817 StringBuilder dropBuilder = new StringBuilder(1024);
14819 StringWriter oomSw = new StringWriter();
14820 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
14821 StringWriter catSw = new StringWriter();
14822 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14823 String[] emptyArgs = new String[] { };
14824 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
14826 String oomString = oomSw.toString();
14828 dropBuilder.append("Low on memory:");
14829 dropBuilder.append(stack);
14830 dropBuilder.append('\n');
14831 dropBuilder.append(fullNativeBuilder);
14832 dropBuilder.append(fullJavaBuilder);
14833 dropBuilder.append('\n');
14834 dropBuilder.append(memInfoBuilder);
14835 dropBuilder.append('\n');
14837 dropBuilder.append(oomString);
14838 dropBuilder.append('\n');
14840 StringWriter catSw = new StringWriter();
14841 synchronized (ActivityManagerService.this) {
14842 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
14843 String[] emptyArgs = new String[] { };
14845 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
14847 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
14848 false, false, null);
14850 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
14853 dropBuilder.append(catSw.toString());
14854 addErrorToDropBox("lowmem", null, "system_server", null,
14855 null, tag.toString(), dropBuilder.toString(), null, null);
14856 //Slog.i(TAG, "Sent to dropbox:");
14857 //Slog.i(TAG, dropBuilder.toString());
14858 synchronized (ActivityManagerService.this) {
14859 long now = SystemClock.uptimeMillis();
14860 if (mLastMemUsageReportTime < now) {
14861 mLastMemUsageReportTime = now;
14867 * Searches array of arguments for the specified string
14868 * @param args array of argument strings
14869 * @param value value to search for
14870 * @return true if the value is contained in the array
14872 private static boolean scanArgs(String[] args, String value) {
14873 if (args != null) {
14874 for (String arg : args) {
14875 if (value.equals(arg)) {
14883 private final boolean removeDyingProviderLocked(ProcessRecord proc,
14884 ContentProviderRecord cpr, boolean always) {
14885 final boolean inLaunching = mLaunchingProviders.contains(cpr);
14887 if (!inLaunching || always) {
14888 synchronized (cpr) {
14889 cpr.launchingApp = null;
14892 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14893 String names[] = cpr.info.authority.split(";");
14894 for (int j = 0; j < names.length; j++) {
14895 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14899 for (int i=0; i<cpr.connections.size(); i++) {
14900 ContentProviderConnection conn = cpr.connections.get(i);
14901 if (conn.waiting) {
14902 // If this connection is waiting for the provider, then we don't
14903 // need to mess with its process unless we are always removing
14904 // or for some reason the provider is not currently launching.
14905 if (inLaunching && !always) {
14909 ProcessRecord capp = conn.client;
14911 if (conn.stableCount > 0) {
14912 if (!capp.persistent && capp.thread != null
14914 && capp.pid != MY_PID) {
14915 capp.kill("depends on provider "
14916 + cpr.name.flattenToShortString()
14917 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14919 } else if (capp.thread != null && conn.provider.provider != null) {
14921 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14922 } catch (RemoteException e) {
14924 // In the protocol here, we don't expect the client to correctly
14925 // clean up this connection, we'll just remove it.
14926 cpr.connections.remove(i);
14927 if (conn.client.conProviders.remove(conn)) {
14928 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
14933 if (inLaunching && always) {
14934 mLaunchingProviders.remove(cpr);
14936 return inLaunching;
14940 * Main code for cleaning up a process when it has gone away. This is
14941 * called both as a result of the process dying, or directly when stopping
14942 * a process when running in single process mode.
14944 * @return Returns true if the given process has been restarted, so the
14945 * app that was passed in must remain on the process lists.
14947 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14948 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
14949 Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
14951 removeLruProcessLocked(app);
14952 ProcessList.remove(app.pid);
14955 mProcessesToGc.remove(app);
14956 mPendingPssProcesses.remove(app);
14958 // Dismiss any open dialogs.
14959 if (app.crashDialog != null && !app.forceCrashReport) {
14960 app.crashDialog.dismiss();
14961 app.crashDialog = null;
14963 if (app.anrDialog != null) {
14964 app.anrDialog.dismiss();
14965 app.anrDialog = null;
14967 if (app.waitDialog != null) {
14968 app.waitDialog.dismiss();
14969 app.waitDialog = null;
14972 app.crashing = false;
14973 app.notResponding = false;
14975 app.resetPackageList(mProcessStats);
14976 app.unlinkDeathRecipient();
14977 app.makeInactive(mProcessStats);
14978 app.waitingToKill = null;
14979 app.forcingToForeground = null;
14980 updateProcessForegroundLocked(app, false, false);
14981 app.foregroundActivities = false;
14982 app.hasShownUi = false;
14983 app.treatLikeActivity = false;
14984 app.hasAboveClient = false;
14985 app.hasClientActivities = false;
14987 mServices.killServicesLocked(app, allowRestart);
14989 boolean restart = false;
14991 // Remove published content providers.
14992 for (int i=app.pubProviders.size()-1; i>=0; i--) {
14993 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14994 final boolean always = app.bad || !allowRestart;
14995 if (removeDyingProviderLocked(app, cpr, always) || always) {
14996 // We left the provider in the launching list, need to
15001 cpr.provider = null;
15004 app.pubProviders.clear();
15006 // Take care of any launching providers waiting for this process.
15007 if (checkAppInLaunchingProvidersLocked(app, false)) {
15011 // Unregister from connected content providers.
15012 if (!app.conProviders.isEmpty()) {
15013 for (int i=0; i<app.conProviders.size(); i++) {
15014 ContentProviderConnection conn = app.conProviders.get(i);
15015 conn.provider.connections.remove(conn);
15016 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15017 conn.provider.name);
15019 app.conProviders.clear();
15022 // At this point there may be remaining entries in mLaunchingProviders
15023 // where we were the only one waiting, so they are no longer of use.
15024 // Look for these and clean up if found.
15025 // XXX Commented out for now. Trying to figure out a way to reproduce
15026 // the actual situation to identify what is actually going on.
15028 for (int i=0; i<mLaunchingProviders.size(); i++) {
15029 ContentProviderRecord cpr = (ContentProviderRecord)
15030 mLaunchingProviders.get(i);
15031 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15032 synchronized (cpr) {
15033 cpr.launchingApp = null;
15040 skipCurrentReceiverLocked(app);
15042 // Unregister any receivers.
15043 for (int i=app.receivers.size()-1; i>=0; i--) {
15044 removeReceiverLocked(app.receivers.valueAt(i));
15046 app.receivers.clear();
15048 // If the app is undergoing backup, tell the backup manager about it
15049 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15050 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
15051 + mBackupTarget.appInfo + " died during backup");
15053 IBackupManager bm = IBackupManager.Stub.asInterface(
15054 ServiceManager.getService(Context.BACKUP_SERVICE));
15055 bm.agentDisconnected(app.info.packageName);
15056 } catch (RemoteException e) {
15057 // can't happen; backup manager is local
15061 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
15062 ProcessChangeItem item = mPendingProcessChanges.get(i);
15063 if (item.pid == app.pid) {
15064 mPendingProcessChanges.remove(i);
15065 mAvailProcessChanges.add(item);
15068 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15070 // If the caller is restarting this app, then leave it in its
15071 // current lists and let the caller take care of it.
15076 if (!app.persistent || app.isolated) {
15077 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
15078 "Removing non-persistent process during cleanup: " + app);
15079 if (!replacingPid) {
15080 mProcessNames.remove(app.processName, app.uid);
15081 mIsolatedProcesses.remove(app.uid);
15083 if (mHeavyWeightProcess == app) {
15084 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15085 mHeavyWeightProcess.userId, 0));
15086 mHeavyWeightProcess = null;
15088 } else if (!app.removed) {
15089 // This app is persistent, so we need to keep its record around.
15090 // If it is not already on the pending app list, add it there
15091 // and start a new process for it.
15092 if (mPersistentStartingProcesses.indexOf(app) < 0) {
15093 mPersistentStartingProcesses.add(app);
15097 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
15098 "Clean-up removing on hold: " + app);
15099 mProcessesOnHold.remove(app);
15101 if (app == mHomeProcess) {
15102 mHomeProcess = null;
15104 if (app == mPreviousProcess) {
15105 mPreviousProcess = null;
15108 if (restart && !app.isolated) {
15109 // We have components that still need to be running in the
15110 // process, so re-launch it.
15112 ProcessList.remove(app.pid);
15114 mProcessNames.put(app.processName, app.uid, app);
15115 startProcessLocked(app, "restart", app.processName);
15117 } else if (app.pid > 0 && app.pid != MY_PID) {
15120 synchronized (mPidsSelfLocked) {
15121 mPidsSelfLocked.remove(app.pid);
15122 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15124 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15125 if (app.isolated) {
15126 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15133 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15134 // Look through the content providers we are waiting to have launched,
15135 // and if any run in this process then either schedule a restart of
15136 // the process or kill the client waiting for it if this process has
15138 int NL = mLaunchingProviders.size();
15139 boolean restart = false;
15140 for (int i=0; i<NL; i++) {
15141 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15142 if (cpr.launchingApp == app) {
15143 if (!alwaysBad && !app.bad) {
15146 removeDyingProviderLocked(app, cpr, true);
15147 // cpr should have been removed from mLaunchingProviders
15148 NL = mLaunchingProviders.size();
15156 // =========================================================
15158 // =========================================================
15161 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15163 enforceNotIsolatedCaller("getServices");
15164 synchronized (this) {
15165 return mServices.getRunningServiceInfoLocked(maxNum, flags);
15170 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15171 enforceNotIsolatedCaller("getRunningServiceControlPanel");
15172 synchronized (this) {
15173 return mServices.getRunningServiceControlPanelLocked(name);
15178 public ComponentName startService(IApplicationThread caller, Intent service,
15179 String resolvedType, int userId) {
15180 enforceNotIsolatedCaller("startService");
15181 // Refuse possible leaked file descriptors
15182 if (service != null && service.hasFileDescriptors() == true) {
15183 throw new IllegalArgumentException("File descriptors passed in Intent");
15187 Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
15188 synchronized(this) {
15189 final int callingPid = Binder.getCallingPid();
15190 final int callingUid = Binder.getCallingUid();
15191 final long origId = Binder.clearCallingIdentity();
15192 ComponentName res = mServices.startServiceLocked(caller, service,
15193 resolvedType, callingPid, callingUid, userId);
15194 Binder.restoreCallingIdentity(origId);
15199 ComponentName startServiceInPackage(int uid,
15200 Intent service, String resolvedType, int userId) {
15201 synchronized(this) {
15203 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
15204 final long origId = Binder.clearCallingIdentity();
15205 ComponentName res = mServices.startServiceLocked(null, service,
15206 resolvedType, -1, uid, userId);
15207 Binder.restoreCallingIdentity(origId);
15213 public int stopService(IApplicationThread caller, Intent service,
15214 String resolvedType, int userId) {
15215 enforceNotIsolatedCaller("stopService");
15216 // Refuse possible leaked file descriptors
15217 if (service != null && service.hasFileDescriptors() == true) {
15218 throw new IllegalArgumentException("File descriptors passed in Intent");
15221 synchronized(this) {
15222 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15227 public IBinder peekService(Intent service, String resolvedType) {
15228 enforceNotIsolatedCaller("peekService");
15229 // Refuse possible leaked file descriptors
15230 if (service != null && service.hasFileDescriptors() == true) {
15231 throw new IllegalArgumentException("File descriptors passed in Intent");
15233 synchronized(this) {
15234 return mServices.peekServiceLocked(service, resolvedType);
15239 public boolean stopServiceToken(ComponentName className, IBinder token,
15241 synchronized(this) {
15242 return mServices.stopServiceTokenLocked(className, token, startId);
15247 public void setServiceForeground(ComponentName className, IBinder token,
15248 int id, Notification notification, boolean removeNotification) {
15249 synchronized(this) {
15250 mServices.setServiceForegroundLocked(className, token, id, notification,
15251 removeNotification);
15256 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15257 boolean requireFull, String name, String callerPackage) {
15258 return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15259 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15262 int unsafeConvertIncomingUser(int userId) {
15263 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15264 ? mCurrentUserId : userId;
15267 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15268 int allowMode, String name, String callerPackage) {
15269 final int callingUserId = UserHandle.getUserId(callingUid);
15270 if (callingUserId == userId) {
15274 // Note that we may be accessing mCurrentUserId outside of a lock...
15275 // shouldn't be a big deal, if this is being called outside
15276 // of a locked context there is intrinsically a race with
15277 // the value the caller will receive and someone else changing it.
15278 // We assume that USER_CURRENT_OR_SELF will use the current user; later
15279 // we will switch to the calling user if access to the current user fails.
15280 int targetUserId = unsafeConvertIncomingUser(userId);
15282 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15283 final boolean allow;
15284 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15285 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15286 // If the caller has this permission, they always pass go. And collect $200.
15288 } else if (allowMode == ALLOW_FULL_ONLY) {
15289 // We require full access, sucks to be you.
15291 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15292 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15293 // If the caller does not have either permission, they are always doomed.
15295 } else if (allowMode == ALLOW_NON_FULL) {
15296 // We are blanket allowing non-full access, you lucky caller!
15298 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15299 // We may or may not allow this depending on whether the two users are
15300 // in the same profile.
15301 synchronized (mUserProfileGroupIdsSelfLocked) {
15302 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15303 UserInfo.NO_PROFILE_GROUP_ID);
15304 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15305 UserInfo.NO_PROFILE_GROUP_ID);
15306 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15307 && callingProfile == targetProfile;
15310 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15313 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15314 // In this case, they would like to just execute as their
15315 // owner user instead of failing.
15316 targetUserId = callingUserId;
15318 StringBuilder builder = new StringBuilder(128);
15319 builder.append("Permission Denial: ");
15320 builder.append(name);
15321 if (callerPackage != null) {
15322 builder.append(" from ");
15323 builder.append(callerPackage);
15325 builder.append(" asks to run as user ");
15326 builder.append(userId);
15327 builder.append(" but is calling from user ");
15328 builder.append(UserHandle.getUserId(callingUid));
15329 builder.append("; this requires ");
15330 builder.append(INTERACT_ACROSS_USERS_FULL);
15331 if (allowMode != ALLOW_FULL_ONLY) {
15332 builder.append(" or ");
15333 builder.append(INTERACT_ACROSS_USERS);
15335 String msg = builder.toString();
15337 throw new SecurityException(msg);
15341 if (!allowAll && targetUserId < 0) {
15342 throw new IllegalArgumentException(
15343 "Call does not support special user #" + targetUserId);
15345 // Check shell permission
15346 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15347 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15349 throw new SecurityException("Shell does not have permission to access user "
15350 + targetUserId + "\n " + Debug.getCallers(3));
15353 return targetUserId;
15356 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15357 String className, int flags) {
15358 boolean result = false;
15359 // For apps that don't have pre-defined UIDs, check for permission
15360 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15361 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15362 if (ActivityManager.checkUidPermission(
15363 INTERACT_ACROSS_USERS,
15364 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15365 ComponentName comp = new ComponentName(aInfo.packageName, className);
15366 String msg = "Permission Denial: Component " + comp.flattenToShortString()
15367 + " requests FLAG_SINGLE_USER, but app does not hold "
15368 + INTERACT_ACROSS_USERS;
15370 throw new SecurityException(msg);
15372 // Permission passed
15375 } else if ("system".equals(componentProcessName)) {
15377 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15378 // Phone app and persistent apps are allowed to export singleuser providers.
15379 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15380 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15383 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
15384 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
15390 * Checks to see if the caller is in the same app as the singleton
15391 * component, or the component is in a special app. It allows special apps
15392 * to export singleton components but prevents exporting singleton
15393 * components for regular apps.
15395 boolean isValidSingletonCall(int callingUid, int componentUid) {
15396 int componentAppId = UserHandle.getAppId(componentUid);
15397 return UserHandle.isSameApp(callingUid, componentUid)
15398 || componentAppId == Process.SYSTEM_UID
15399 || componentAppId == Process.PHONE_UID
15400 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15401 == PackageManager.PERMISSION_GRANTED;
15404 public int bindService(IApplicationThread caller, IBinder token,
15405 Intent service, String resolvedType,
15406 IServiceConnection connection, int flags, int userId) {
15407 enforceNotIsolatedCaller("bindService");
15409 // Refuse possible leaked file descriptors
15410 if (service != null && service.hasFileDescriptors() == true) {
15411 throw new IllegalArgumentException("File descriptors passed in Intent");
15414 synchronized(this) {
15415 return mServices.bindServiceLocked(caller, token, service, resolvedType,
15416 connection, flags, userId);
15420 public boolean unbindService(IServiceConnection connection) {
15421 synchronized (this) {
15422 return mServices.unbindServiceLocked(connection);
15426 public void publishService(IBinder token, Intent intent, IBinder service) {
15427 // Refuse possible leaked file descriptors
15428 if (intent != null && intent.hasFileDescriptors() == true) {
15429 throw new IllegalArgumentException("File descriptors passed in Intent");
15432 synchronized(this) {
15433 if (!(token instanceof ServiceRecord)) {
15434 throw new IllegalArgumentException("Invalid service token");
15436 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
15440 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
15441 // Refuse possible leaked file descriptors
15442 if (intent != null && intent.hasFileDescriptors() == true) {
15443 throw new IllegalArgumentException("File descriptors passed in Intent");
15446 synchronized(this) {
15447 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
15451 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
15452 synchronized(this) {
15453 if (!(token instanceof ServiceRecord)) {
15454 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
15455 throw new IllegalArgumentException("Invalid service token");
15457 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
15461 // =========================================================
15462 // BACKUP AND RESTORE
15463 // =========================================================
15465 // Cause the target app to be launched if necessary and its backup agent
15466 // instantiated. The backup agent will invoke backupAgentCreated() on the
15467 // activity manager to announce its creation.
15468 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
15469 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
15470 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
15472 IPackageManager pm = AppGlobals.getPackageManager();
15473 ApplicationInfo app = null;
15475 app = pm.getApplicationInfo(packageName, 0, userId);
15476 } catch (RemoteException e) {
15477 // can't happen; package manager is process-local
15480 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
15484 synchronized(this) {
15485 // !!! TODO: currently no check here that we're already bound
15486 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
15487 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15488 synchronized (stats) {
15489 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15492 // Backup agent is now in use, its package can't be stopped.
15494 AppGlobals.getPackageManager().setPackageStoppedState(
15495 app.packageName, false, UserHandle.getUserId(app.uid));
15496 } catch (RemoteException e) {
15497 } catch (IllegalArgumentException e) {
15498 Slog.w(TAG, "Failed trying to unstop package "
15499 + app.packageName + ": " + e);
15502 BackupRecord r = new BackupRecord(ss, app, backupMode);
15503 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15504 ? new ComponentName(app.packageName, app.backupAgentName)
15505 : new ComponentName("android", "FullBackupAgent");
15506 // startProcessLocked() returns existing proc's record if it's already running
15507 ProcessRecord proc = startProcessLocked(app.processName, app,
15508 false, 0, "backup", hostingName, false, false, false);
15509 if (proc == null) {
15510 Slog.e(TAG, "Unable to start backup agent process " + r);
15516 mBackupAppName = app.packageName;
15518 // Try not to kill the process during backup
15519 updateOomAdjLocked(proc);
15521 // If the process is already attached, schedule the creation of the backup agent now.
15522 // If it is not yet live, this will be done when it attaches to the framework.
15523 if (proc.thread != null) {
15524 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15526 proc.thread.scheduleCreateBackupAgent(app,
15527 compatibilityInfoForPackageLocked(app), backupMode);
15528 } catch (RemoteException e) {
15529 // Will time out on the backup manager side
15532 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15534 // Invariants: at this point, the target app process exists and the application
15535 // is either already running or in the process of coming up. mBackupTarget and
15536 // mBackupAppName describe the app, so that when it binds back to the AM we
15537 // know that it's scheduled for a backup-agent operation.
15544 public void clearPendingBackup() {
15545 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15546 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15548 synchronized (this) {
15549 mBackupTarget = null;
15550 mBackupAppName = null;
15554 // A backup agent has just come up
15555 public void backupAgentCreated(String agentPackageName, IBinder agent) {
15556 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15559 synchronized(this) {
15560 if (!agentPackageName.equals(mBackupAppName)) {
15561 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15566 long oldIdent = Binder.clearCallingIdentity();
15568 IBackupManager bm = IBackupManager.Stub.asInterface(
15569 ServiceManager.getService(Context.BACKUP_SERVICE));
15570 bm.agentConnected(agentPackageName, agent);
15571 } catch (RemoteException e) {
15572 // can't happen; the backup manager service is local
15573 } catch (Exception e) {
15574 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15575 e.printStackTrace();
15577 Binder.restoreCallingIdentity(oldIdent);
15581 // done with this agent
15582 public void unbindBackupAgent(ApplicationInfo appInfo) {
15583 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15584 if (appInfo == null) {
15585 Slog.w(TAG, "unbind backup agent for null app");
15589 synchronized(this) {
15591 if (mBackupAppName == null) {
15592 Slog.w(TAG, "Unbinding backup agent with no active backup");
15596 if (!mBackupAppName.equals(appInfo.packageName)) {
15597 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15601 // Not backing this app up any more; reset its OOM adjustment
15602 final ProcessRecord proc = mBackupTarget.app;
15603 updateOomAdjLocked(proc);
15605 // If the app crashed during backup, 'thread' will be null here
15606 if (proc.thread != null) {
15608 proc.thread.scheduleDestroyBackupAgent(appInfo,
15609 compatibilityInfoForPackageLocked(appInfo));
15610 } catch (Exception e) {
15611 Slog.e(TAG, "Exception when unbinding backup agent:");
15612 e.printStackTrace();
15616 mBackupTarget = null;
15617 mBackupAppName = null;
15621 // =========================================================
15623 // =========================================================
15625 private final List getStickiesLocked(String action, IntentFilter filter,
15626 List cur, int userId) {
15627 final ContentResolver resolver = mContext.getContentResolver();
15628 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15629 if (stickies == null) {
15632 final ArrayList<Intent> list = stickies.get(action);
15633 if (list == null) {
15636 int N = list.size();
15637 for (int i=0; i<N; i++) {
15638 Intent intent = list.get(i);
15639 if (filter.match(resolver, intent, true, TAG) >= 0) {
15641 cur = new ArrayList<Intent>();
15649 boolean isPendingBroadcastProcessLocked(int pid) {
15650 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15651 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15654 void skipPendingBroadcastLocked(int pid) {
15655 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15656 for (BroadcastQueue queue : mBroadcastQueues) {
15657 queue.skipPendingBroadcastLocked(pid);
15661 // The app just attached; send any pending broadcasts that it should receive
15662 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15663 boolean didSomething = false;
15664 for (BroadcastQueue queue : mBroadcastQueues) {
15665 didSomething |= queue.sendPendingBroadcastsLocked(app);
15667 return didSomething;
15670 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15671 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15672 enforceNotIsolatedCaller("registerReceiver");
15675 synchronized(this) {
15676 ProcessRecord callerApp = null;
15677 if (caller != null) {
15678 callerApp = getRecordForAppLocked(caller);
15679 if (callerApp == null) {
15680 throw new SecurityException(
15681 "Unable to find app for caller " + caller
15682 + " (pid=" + Binder.getCallingPid()
15683 + ") when registering receiver " + receiver);
15685 if (callerApp.info.uid != Process.SYSTEM_UID &&
15686 !callerApp.pkgList.containsKey(callerPackage) &&
15687 !"android".equals(callerPackage)) {
15688 throw new SecurityException("Given caller package " + callerPackage
15689 + " is not running in process " + callerApp);
15691 callingUid = callerApp.info.uid;
15692 callingPid = callerApp.pid;
15694 callerPackage = null;
15695 callingUid = Binder.getCallingUid();
15696 callingPid = Binder.getCallingPid();
15699 userId = this.handleIncomingUser(callingPid, callingUid, userId,
15700 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15702 List allSticky = null;
15704 // Look for any matching sticky broadcasts...
15705 Iterator actions = filter.actionsIterator();
15706 if (actions != null) {
15707 while (actions.hasNext()) {
15708 String action = (String)actions.next();
15709 allSticky = getStickiesLocked(action, filter, allSticky,
15710 UserHandle.USER_ALL);
15711 allSticky = getStickiesLocked(action, filter, allSticky,
15712 UserHandle.getUserId(callingUid));
15715 allSticky = getStickiesLocked(null, filter, allSticky,
15716 UserHandle.USER_ALL);
15717 allSticky = getStickiesLocked(null, filter, allSticky,
15718 UserHandle.getUserId(callingUid));
15721 // The first sticky in the list is returned directly back to
15723 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15725 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15728 if (receiver == null) {
15733 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15735 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15737 if (rl.app != null) {
15738 rl.app.receivers.add(rl);
15741 receiver.asBinder().linkToDeath(rl, 0);
15742 } catch (RemoteException e) {
15745 rl.linkedToDeath = true;
15747 mRegisteredReceivers.put(receiver.asBinder(), rl);
15748 } else if (rl.uid != callingUid) {
15749 throw new IllegalArgumentException(
15750 "Receiver requested to register for uid " + callingUid
15751 + " was previously registered for uid " + rl.uid);
15752 } else if (rl.pid != callingPid) {
15753 throw new IllegalArgumentException(
15754 "Receiver requested to register for pid " + callingPid
15755 + " was previously registered for pid " + rl.pid);
15756 } else if (rl.userId != userId) {
15757 throw new IllegalArgumentException(
15758 "Receiver requested to register for user " + userId
15759 + " was previously registered for user " + rl.userId);
15761 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15762 permission, callingUid, userId);
15764 if (!bf.debugCheck()) {
15765 Slog.w(TAG, "==> For Dynamic broadast");
15767 mReceiverResolver.addFilter(bf);
15769 // Enqueue broadcasts for all existing stickies that match
15771 if (allSticky != null) {
15772 ArrayList receivers = new ArrayList();
15775 int N = allSticky.size();
15776 for (int i=0; i<N; i++) {
15777 Intent intent = (Intent)allSticky.get(i);
15778 BroadcastQueue queue = broadcastQueueForIntent(intent);
15779 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15780 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15781 null, null, false, true, true, -1);
15782 queue.enqueueParallelBroadcastLocked(r);
15783 queue.scheduleBroadcastsLocked();
15791 public void unregisterReceiver(IIntentReceiver receiver) {
15792 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15794 final long origId = Binder.clearCallingIdentity();
15796 boolean doTrim = false;
15798 synchronized(this) {
15799 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15801 if (rl.curBroadcast != null) {
15802 BroadcastRecord r = rl.curBroadcast;
15803 final boolean doNext = finishReceiverLocked(
15804 receiver.asBinder(), r.resultCode, r.resultData,
15805 r.resultExtras, r.resultAbort);
15808 r.queue.processNextBroadcast(false);
15812 if (rl.app != null) {
15813 rl.app.receivers.remove(rl);
15815 removeReceiverLocked(rl);
15816 if (rl.linkedToDeath) {
15817 rl.linkedToDeath = false;
15818 rl.receiver.asBinder().unlinkToDeath(rl, 0);
15823 // If we actually concluded any broadcasts, we might now be able
15824 // to trim the recipients' apps from our working set
15826 trimApplications();
15831 Binder.restoreCallingIdentity(origId);
15835 void removeReceiverLocked(ReceiverList rl) {
15836 mRegisteredReceivers.remove(rl.receiver.asBinder());
15838 for (int i=0; i<N; i++) {
15839 mReceiverResolver.removeFilter(rl.get(i));
15843 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15844 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15845 ProcessRecord r = mLruProcesses.get(i);
15846 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15848 r.thread.dispatchPackageBroadcast(cmd, packages);
15849 } catch (RemoteException ex) {
15855 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15856 int callingUid, int[] users) {
15857 List<ResolveInfo> receivers = null;
15859 HashSet<ComponentName> singleUserReceivers = null;
15860 boolean scannedFirstReceivers = false;
15861 for (int user : users) {
15862 // Skip users that have Shell restrictions
15863 if (callingUid == Process.SHELL_UID
15864 && getUserManagerLocked().hasUserRestriction(
15865 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15868 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15869 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15870 if (user != 0 && newReceivers != null) {
15871 // If this is not the primary user, we need to check for
15872 // any receivers that should be filtered out.
15873 for (int i=0; i<newReceivers.size(); i++) {
15874 ResolveInfo ri = newReceivers.get(i);
15875 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15876 newReceivers.remove(i);
15881 if (newReceivers != null && newReceivers.size() == 0) {
15882 newReceivers = null;
15884 if (receivers == null) {
15885 receivers = newReceivers;
15886 } else if (newReceivers != null) {
15887 // We need to concatenate the additional receivers
15888 // found with what we have do far. This would be easy,
15889 // but we also need to de-dup any receivers that are
15891 if (!scannedFirstReceivers) {
15892 // Collect any single user receivers we had already retrieved.
15893 scannedFirstReceivers = true;
15894 for (int i=0; i<receivers.size(); i++) {
15895 ResolveInfo ri = receivers.get(i);
15896 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15897 ComponentName cn = new ComponentName(
15898 ri.activityInfo.packageName, ri.activityInfo.name);
15899 if (singleUserReceivers == null) {
15900 singleUserReceivers = new HashSet<ComponentName>();
15902 singleUserReceivers.add(cn);
15906 // Add the new results to the existing results, tracking
15907 // and de-dupping single user receivers.
15908 for (int i=0; i<newReceivers.size(); i++) {
15909 ResolveInfo ri = newReceivers.get(i);
15910 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15911 ComponentName cn = new ComponentName(
15912 ri.activityInfo.packageName, ri.activityInfo.name);
15913 if (singleUserReceivers == null) {
15914 singleUserReceivers = new HashSet<ComponentName>();
15916 if (!singleUserReceivers.contains(cn)) {
15917 singleUserReceivers.add(cn);
15926 } catch (RemoteException ex) {
15927 // pm is in same process, this will never happen.
15932 private final int broadcastIntentLocked(ProcessRecord callerApp,
15933 String callerPackage, Intent intent, String resolvedType,
15934 IIntentReceiver resultTo, int resultCode, String resultData,
15935 Bundle map, String requiredPermission, int appOp,
15936 boolean ordered, boolean sticky, int callingPid, int callingUid,
15938 intent = new Intent(intent);
15940 // By default broadcasts do not go to stopped apps.
15941 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15943 if (DEBUG_BROADCAST_LIGHT) Slog.v(
15944 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15945 + " ordered=" + ordered + " userid=" + userId);
15946 if ((resultTo != null) && !ordered) {
15947 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15950 userId = handleIncomingUser(callingPid, callingUid, userId,
15951 true, ALLOW_NON_FULL, "broadcast", callerPackage);
15953 // Make sure that the user who is receiving this broadcast is running.
15954 // If not, we will just skip it. Make an exception for shutdown broadcasts
15955 // and upgrade steps.
15957 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
15958 if ((callingUid != Process.SYSTEM_UID
15959 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
15960 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
15961 Slog.w(TAG, "Skipping broadcast of " + intent
15962 + ": user " + userId + " is stopped");
15963 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
15968 * Prevent non-system code (defined here to be non-persistent
15969 * processes) from sending protected broadcasts.
15971 int callingAppId = UserHandle.getAppId(callingUid);
15972 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15973 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15974 || callingAppId == Process.NFC_UID || callingUid == 0) {
15976 } else if (callerApp == null || !callerApp.persistent) {
15978 if (AppGlobals.getPackageManager().isProtectedBroadcast(
15979 intent.getAction())) {
15980 String msg = "Permission Denial: not allowed to send broadcast "
15981 + intent.getAction() + " from pid="
15982 + callingPid + ", uid=" + callingUid;
15984 throw new SecurityException(msg);
15985 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15986 // Special case for compatibility: we don't want apps to send this,
15987 // but historically it has not been protected and apps may be using it
15988 // to poke their own app widget. So, instead of making it protected,
15989 // just limit it to the caller.
15990 if (callerApp == null) {
15991 String msg = "Permission Denial: not allowed to send broadcast "
15992 + intent.getAction() + " from unknown caller.";
15994 throw new SecurityException(msg);
15995 } else if (intent.getComponent() != null) {
15996 // They are good enough to send to an explicit component... verify
15997 // it is being sent to the calling app.
15998 if (!intent.getComponent().getPackageName().equals(
15999 callerApp.info.packageName)) {
16000 String msg = "Permission Denial: not allowed to send broadcast "
16001 + intent.getAction() + " to "
16002 + intent.getComponent().getPackageName() + " from "
16003 + callerApp.info.packageName;
16005 throw new SecurityException(msg);
16008 // Limit broadcast to their own package.
16009 intent.setPackage(callerApp.info.packageName);
16012 } catch (RemoteException e) {
16013 Slog.w(TAG, "Remote exception", e);
16014 return ActivityManager.BROADCAST_SUCCESS;
16018 final String action = intent.getAction();
16019 if (action != null) {
16021 case Intent.ACTION_UID_REMOVED:
16022 case Intent.ACTION_PACKAGE_REMOVED:
16023 case Intent.ACTION_PACKAGE_CHANGED:
16024 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16025 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16026 // Handle special intents: if this broadcast is from the package
16027 // manager about a package being removed, we need to remove all of
16028 // its activities from the history stack.
16029 if (checkComponentPermission(
16030 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16031 callingPid, callingUid, -1, true)
16032 != PackageManager.PERMISSION_GRANTED) {
16033 String msg = "Permission Denial: " + intent.getAction()
16034 + " broadcast from " + callerPackage + " (pid=" + callingPid
16035 + ", uid=" + callingUid + ")"
16037 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16039 throw new SecurityException(msg);
16042 case Intent.ACTION_UID_REMOVED:
16043 final Bundle intentExtras = intent.getExtras();
16044 final int uid = intentExtras != null
16045 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16047 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
16048 synchronized (bs) {
16049 bs.removeUidStatsLocked(uid);
16051 mAppOpsService.uidRemoved(uid);
16054 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16055 // If resources are unavailable just force stop all those packages
16056 // and flush the attribute cache as well.
16058 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16059 if (list != null && list.length > 0) {
16060 for (int i = 0; i < list.length; i++) {
16061 forceStopPackageLocked(list[i], -1, false, true, true,
16062 false, false, userId, "storage unmount");
16064 cleanupRecentTasksLocked(UserHandle.USER_ALL);
16065 sendPackageBroadcastLocked(
16066 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16070 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16071 cleanupRecentTasksLocked(UserHandle.USER_ALL);
16073 case Intent.ACTION_PACKAGE_REMOVED:
16074 case Intent.ACTION_PACKAGE_CHANGED:
16075 Uri data = intent.getData();
16077 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16078 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16079 boolean fullUninstall = removed &&
16080 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16081 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
16082 forceStopPackageLocked(ssp, UserHandle.getAppId(
16083 intent.getIntExtra(Intent.EXTRA_UID, -1)),
16084 false, true, true, false, fullUninstall, userId,
16085 removed ? "pkg removed" : "pkg changed");
16088 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16089 new String[] {ssp}, userId);
16090 if (fullUninstall) {
16091 mAppOpsService.packageRemoved(
16092 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16094 // Remove all permissions granted from/to this package
16095 removeUriPermissionsForPackageLocked(ssp, userId, true);
16097 removeTasksByPackageNameLocked(ssp, userId);
16098 if (userId == UserHandle.USER_OWNER) {
16099 mTaskPersister.removeFromPackageCache(ssp);
16103 removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16104 if (userId == UserHandle.USER_OWNER) {
16105 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16112 case Intent.ACTION_PACKAGE_ADDED:
16113 // Special case for adding a package: by default turn on compatibility mode.
16114 Uri data = intent.getData();
16116 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16117 final boolean replacing =
16118 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16119 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16122 removeTasksByRemovedPackageComponentsLocked(ssp, userId);
16124 if (userId == UserHandle.USER_OWNER) {
16125 mTaskPersister.addOtherDeviceTasksToRecentsLocked(ssp);
16129 case Intent.ACTION_TIMEZONE_CHANGED:
16130 // If this is the time zone changed action, queue up a message that will reset
16131 // the timezone of all currently running processes. This message will get
16132 // queued up before the broadcast happens.
16133 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16135 case Intent.ACTION_TIME_CHANGED:
16136 // If the user set the time, let all running processes know.
16137 final int is24Hour =
16138 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16140 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16141 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16142 synchronized (stats) {
16143 stats.noteCurrentTimeChangedLocked();
16146 case Intent.ACTION_CLEAR_DNS_CACHE:
16147 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16149 case Proxy.PROXY_CHANGE_ACTION:
16150 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16151 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16156 // Add to the sticky list if requested.
16158 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16159 callingPid, callingUid)
16160 != PackageManager.PERMISSION_GRANTED) {
16161 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16162 + callingPid + ", uid=" + callingUid
16163 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16165 throw new SecurityException(msg);
16167 if (requiredPermission != null) {
16168 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16169 + " and enforce permission " + requiredPermission);
16170 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16172 if (intent.getComponent() != null) {
16173 throw new SecurityException(
16174 "Sticky broadcasts can't target a specific component");
16176 // We use userId directly here, since the "all" target is maintained
16177 // as a separate set of sticky broadcasts.
16178 if (userId != UserHandle.USER_ALL) {
16179 // But first, if this is not a broadcast to all users, then
16180 // make sure it doesn't conflict with an existing broadcast to
16182 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16183 UserHandle.USER_ALL);
16184 if (stickies != null) {
16185 ArrayList<Intent> list = stickies.get(intent.getAction());
16186 if (list != null) {
16187 int N = list.size();
16189 for (i=0; i<N; i++) {
16190 if (intent.filterEquals(list.get(i))) {
16191 throw new IllegalArgumentException(
16192 "Sticky broadcast " + intent + " for user "
16193 + userId + " conflicts with existing global broadcast");
16199 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16200 if (stickies == null) {
16201 stickies = new ArrayMap<String, ArrayList<Intent>>();
16202 mStickyBroadcasts.put(userId, stickies);
16204 ArrayList<Intent> list = stickies.get(intent.getAction());
16205 if (list == null) {
16206 list = new ArrayList<Intent>();
16207 stickies.put(intent.getAction(), list);
16209 int N = list.size();
16211 for (i=0; i<N; i++) {
16212 if (intent.filterEquals(list.get(i))) {
16213 // This sticky already exists, replace it.
16214 list.set(i, new Intent(intent));
16219 list.add(new Intent(intent));
16224 if (userId == UserHandle.USER_ALL) {
16225 // Caller wants broadcast to go to all started users.
16226 users = mStartedUserArray;
16228 // Caller wants broadcast to go to one specific user.
16229 users = new int[] {userId};
16232 // Figure out who all will receive this broadcast.
16233 List receivers = null;
16234 List<BroadcastFilter> registeredReceivers = null;
16235 // Need to resolve the intent to interested receivers...
16236 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16238 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16240 if (intent.getComponent() == null) {
16241 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16242 // Query one target user at a time, excluding shell-restricted users
16243 UserManagerService ums = getUserManagerLocked();
16244 for (int i = 0; i < users.length; i++) {
16245 if (ums.hasUserRestriction(
16246 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16249 List<BroadcastFilter> registeredReceiversForUser =
16250 mReceiverResolver.queryIntent(intent,
16251 resolvedType, false, users[i]);
16252 if (registeredReceivers == null) {
16253 registeredReceivers = registeredReceiversForUser;
16254 } else if (registeredReceiversForUser != null) {
16255 registeredReceivers.addAll(registeredReceiversForUser);
16259 registeredReceivers = mReceiverResolver.queryIntent(intent,
16260 resolvedType, false, userId);
16264 final boolean replacePending =
16265 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16267 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
16268 + " replacePending=" + replacePending);
16270 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16271 if (!ordered && NR > 0) {
16272 // If we are not serializing this broadcast, then send the
16273 // registered receivers separately so they don't wait for the
16274 // components to be launched.
16275 final BroadcastQueue queue = broadcastQueueForIntent(intent);
16276 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16277 callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
16278 appOp, registeredReceivers, resultTo, resultCode, resultData, map,
16279 ordered, sticky, false, userId);
16280 if (DEBUG_BROADCAST) Slog.v(
16281 TAG, "Enqueueing parallel broadcast " + r);
16282 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16284 queue.enqueueParallelBroadcastLocked(r);
16285 queue.scheduleBroadcastsLocked();
16287 registeredReceivers = null;
16291 // Merge into one list.
16293 if (receivers != null) {
16294 // A special case for PACKAGE_ADDED: do not allow the package
16295 // being added to see this broadcast. This prevents them from
16296 // using this as a back door to get run as soon as they are
16297 // installed. Maybe in the future we want to have a special install
16298 // broadcast or such for apps, but we'd like to deliberately make
16300 String skipPackages[] = null;
16301 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16302 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16303 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16304 Uri data = intent.getData();
16305 if (data != null) {
16306 String pkgName = data.getSchemeSpecificPart();
16307 if (pkgName != null) {
16308 skipPackages = new String[] { pkgName };
16311 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16312 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16314 if (skipPackages != null && (skipPackages.length > 0)) {
16315 for (String skipPackage : skipPackages) {
16316 if (skipPackage != null) {
16317 int NT = receivers.size();
16318 for (int it=0; it<NT; it++) {
16319 ResolveInfo curt = (ResolveInfo)receivers.get(it);
16320 if (curt.activityInfo.packageName.equals(skipPackage)) {
16321 receivers.remove(it);
16330 int NT = receivers != null ? receivers.size() : 0;
16332 ResolveInfo curt = null;
16333 BroadcastFilter curr = null;
16334 while (it < NT && ir < NR) {
16335 if (curt == null) {
16336 curt = (ResolveInfo)receivers.get(it);
16338 if (curr == null) {
16339 curr = registeredReceivers.get(ir);
16341 if (curr.getPriority() >= curt.priority) {
16342 // Insert this broadcast record into the final list.
16343 receivers.add(it, curr);
16349 // Skip to the next ResolveInfo in the final list.
16356 if (receivers == null) {
16357 receivers = new ArrayList();
16359 receivers.add(registeredReceivers.get(ir));
16363 if ((receivers != null && receivers.size() > 0)
16364 || resultTo != null) {
16365 BroadcastQueue queue = broadcastQueueForIntent(intent);
16366 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16367 callerPackage, callingPid, callingUid, resolvedType,
16368 requiredPermission, appOp, receivers, resultTo, resultCode,
16369 resultData, map, ordered, sticky, false, userId);
16370 if (DEBUG_BROADCAST) Slog.v(
16371 TAG, "Enqueueing ordered broadcast " + r
16372 + ": prev had " + queue.mOrderedBroadcasts.size());
16373 if (DEBUG_BROADCAST) {
16374 int seq = r.intent.getIntExtra("seq", -1);
16375 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
16377 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16379 queue.enqueueOrderedBroadcastLocked(r);
16380 queue.scheduleBroadcastsLocked();
16384 return ActivityManager.BROADCAST_SUCCESS;
16387 final Intent verifyBroadcastLocked(Intent intent) {
16388 // Refuse possible leaked file descriptors
16389 if (intent != null && intent.hasFileDescriptors() == true) {
16390 throw new IllegalArgumentException("File descriptors passed in Intent");
16393 int flags = intent.getFlags();
16395 if (!mProcessesReady) {
16396 // if the caller really truly claims to know what they're doing, go
16397 // ahead and allow the broadcast without launching any receivers
16398 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16399 intent = new Intent(intent);
16400 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16401 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16402 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16403 + " before boot completion");
16404 throw new IllegalStateException("Cannot broadcast before boot completed");
16408 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16409 throw new IllegalArgumentException(
16410 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16416 public final int broadcastIntent(IApplicationThread caller,
16417 Intent intent, String resolvedType, IIntentReceiver resultTo,
16418 int resultCode, String resultData, Bundle map,
16419 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
16420 enforceNotIsolatedCaller("broadcastIntent");
16421 synchronized(this) {
16422 intent = verifyBroadcastLocked(intent);
16424 final ProcessRecord callerApp = getRecordForAppLocked(caller);
16425 final int callingPid = Binder.getCallingPid();
16426 final int callingUid = Binder.getCallingUid();
16427 final long origId = Binder.clearCallingIdentity();
16428 int res = broadcastIntentLocked(callerApp,
16429 callerApp != null ? callerApp.info.packageName : null,
16430 intent, resolvedType, resultTo,
16431 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
16432 callingPid, callingUid, userId);
16433 Binder.restoreCallingIdentity(origId);
16438 int broadcastIntentInPackage(String packageName, int uid,
16439 Intent intent, String resolvedType, IIntentReceiver resultTo,
16440 int resultCode, String resultData, Bundle map,
16441 String requiredPermission, boolean serialized, boolean sticky, int userId) {
16442 synchronized(this) {
16443 intent = verifyBroadcastLocked(intent);
16445 final long origId = Binder.clearCallingIdentity();
16446 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
16447 resultTo, resultCode, resultData, map, requiredPermission,
16448 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
16449 Binder.restoreCallingIdentity(origId);
16454 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
16455 // Refuse possible leaked file descriptors
16456 if (intent != null && intent.hasFileDescriptors() == true) {
16457 throw new IllegalArgumentException("File descriptors passed in Intent");
16460 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16461 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
16463 synchronized(this) {
16464 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
16465 != PackageManager.PERMISSION_GRANTED) {
16466 String msg = "Permission Denial: unbroadcastIntent() from pid="
16467 + Binder.getCallingPid()
16468 + ", uid=" + Binder.getCallingUid()
16469 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16471 throw new SecurityException(msg);
16473 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16474 if (stickies != null) {
16475 ArrayList<Intent> list = stickies.get(intent.getAction());
16476 if (list != null) {
16477 int N = list.size();
16479 for (i=0; i<N; i++) {
16480 if (intent.filterEquals(list.get(i))) {
16485 if (list.size() <= 0) {
16486 stickies.remove(intent.getAction());
16489 if (stickies.size() <= 0) {
16490 mStickyBroadcasts.remove(userId);
16496 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
16497 String resultData, Bundle resultExtras, boolean resultAbort) {
16498 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
16500 Slog.w(TAG, "finishReceiver called but not found on queue");
16504 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
16507 void backgroundServicesFinishedLocked(int userId) {
16508 for (BroadcastQueue queue : mBroadcastQueues) {
16509 queue.backgroundServicesFinishedLocked(userId);
16513 public void finishReceiver(IBinder who, int resultCode, String resultData,
16514 Bundle resultExtras, boolean resultAbort) {
16515 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16517 // Refuse possible leaked file descriptors
16518 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16519 throw new IllegalArgumentException("File descriptors passed in Bundle");
16522 final long origId = Binder.clearCallingIdentity();
16524 boolean doNext = false;
16527 synchronized(this) {
16528 r = broadcastRecordForReceiverLocked(who);
16530 doNext = r.queue.finishReceiverLocked(r, resultCode,
16531 resultData, resultExtras, resultAbort, true);
16536 r.queue.processNextBroadcast(false);
16538 trimApplications();
16540 Binder.restoreCallingIdentity(origId);
16544 // =========================================================
16546 // =========================================================
16548 public boolean startInstrumentation(ComponentName className,
16549 String profileFile, int flags, Bundle arguments,
16550 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16551 int userId, String abiOverride) {
16552 enforceNotIsolatedCaller("startInstrumentation");
16553 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16554 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16555 // Refuse possible leaked file descriptors
16556 if (arguments != null && arguments.hasFileDescriptors()) {
16557 throw new IllegalArgumentException("File descriptors passed in Bundle");
16560 synchronized(this) {
16561 InstrumentationInfo ii = null;
16562 ApplicationInfo ai = null;
16564 ii = mContext.getPackageManager().getInstrumentationInfo(
16565 className, STOCK_PM_FLAGS);
16566 ai = AppGlobals.getPackageManager().getApplicationInfo(
16567 ii.targetPackage, STOCK_PM_FLAGS, userId);
16568 } catch (PackageManager.NameNotFoundException e) {
16569 } catch (RemoteException e) {
16572 reportStartInstrumentationFailure(watcher, className,
16573 "Unable to find instrumentation info for: " + className);
16577 reportStartInstrumentationFailure(watcher, className,
16578 "Unable to find instrumentation target package: " + ii.targetPackage);
16582 int match = mContext.getPackageManager().checkSignatures(
16583 ii.targetPackage, ii.packageName);
16584 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16585 String msg = "Permission Denial: starting instrumentation "
16586 + className + " from pid="
16587 + Binder.getCallingPid()
16588 + ", uid=" + Binder.getCallingPid()
16589 + " not allowed because package " + ii.packageName
16590 + " does not have a signature matching the target "
16591 + ii.targetPackage;
16592 reportStartInstrumentationFailure(watcher, className, msg);
16593 throw new SecurityException(msg);
16596 final long origId = Binder.clearCallingIdentity();
16597 // Instrumentation can kill and relaunch even persistent processes
16598 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16600 ProcessRecord app = addAppLocked(ai, false, abiOverride);
16601 app.instrumentationClass = className;
16602 app.instrumentationInfo = ai;
16603 app.instrumentationProfileFile = profileFile;
16604 app.instrumentationArguments = arguments;
16605 app.instrumentationWatcher = watcher;
16606 app.instrumentationUiAutomationConnection = uiAutomationConnection;
16607 app.instrumentationResultClass = className;
16608 Binder.restoreCallingIdentity(origId);
16615 * Report errors that occur while attempting to start Instrumentation. Always writes the
16616 * error to the logs, but if somebody is watching, send the report there too. This enables
16617 * the "am" command to report errors with more information.
16619 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
16620 * @param cn The component name of the instrumentation.
16621 * @param report The error report.
16623 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16624 ComponentName cn, String report) {
16625 Slog.w(TAG, report);
16627 if (watcher != null) {
16628 Bundle results = new Bundle();
16629 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16630 results.putString("Error", report);
16631 watcher.instrumentationStatus(cn, -1, results);
16633 } catch (RemoteException e) {
16638 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16639 if (app.instrumentationWatcher != null) {
16641 // NOTE: IInstrumentationWatcher *must* be oneway here
16642 app.instrumentationWatcher.instrumentationFinished(
16643 app.instrumentationClass,
16646 } catch (RemoteException e) {
16649 if (app.instrumentationUiAutomationConnection != null) {
16651 app.instrumentationUiAutomationConnection.shutdown();
16652 } catch (RemoteException re) {
16655 // Only a UiAutomation can set this flag and now that
16656 // it is finished we make sure it is reset to its default.
16657 mUserIsMonkey = false;
16659 app.instrumentationWatcher = null;
16660 app.instrumentationUiAutomationConnection = null;
16661 app.instrumentationClass = null;
16662 app.instrumentationInfo = null;
16663 app.instrumentationProfileFile = null;
16664 app.instrumentationArguments = null;
16666 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16670 public void finishInstrumentation(IApplicationThread target,
16671 int resultCode, Bundle results) {
16672 int userId = UserHandle.getCallingUserId();
16673 // Refuse possible leaked file descriptors
16674 if (results != null && results.hasFileDescriptors()) {
16675 throw new IllegalArgumentException("File descriptors passed in Intent");
16678 synchronized(this) {
16679 ProcessRecord app = getRecordForAppLocked(target);
16681 Slog.w(TAG, "finishInstrumentation: no app for " + target);
16684 final long origId = Binder.clearCallingIdentity();
16685 finishInstrumentationLocked(app, resultCode, results);
16686 Binder.restoreCallingIdentity(origId);
16690 // =========================================================
16692 // =========================================================
16694 public ConfigurationInfo getDeviceConfigurationInfo() {
16695 ConfigurationInfo config = new ConfigurationInfo();
16696 synchronized (this) {
16697 config.reqTouchScreen = mConfiguration.touchscreen;
16698 config.reqKeyboardType = mConfiguration.keyboard;
16699 config.reqNavigation = mConfiguration.navigation;
16700 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16701 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16702 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16704 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16705 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16706 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16708 config.reqGlEsVersion = GL_ES_VERSION;
16713 ActivityStack getFocusedStack() {
16714 return mStackSupervisor.getFocusedStack();
16717 public Configuration getConfiguration() {
16719 synchronized(this) {
16720 ci = new Configuration(mConfiguration);
16721 ci.userSetLocale = false;
16726 public void updatePersistentConfiguration(Configuration values) {
16727 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16728 "updateConfiguration()");
16729 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16730 "updateConfiguration()");
16731 if (values == null) {
16732 throw new NullPointerException("Configuration must not be null");
16735 synchronized(this) {
16736 final long origId = Binder.clearCallingIdentity();
16737 updateConfigurationLocked(values, null, true, false);
16738 Binder.restoreCallingIdentity(origId);
16742 public void updateConfiguration(Configuration values) {
16743 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16744 "updateConfiguration()");
16746 synchronized(this) {
16747 if (values == null && mWindowManager != null) {
16748 // sentinel: fetch the current configuration from the window manager
16749 values = mWindowManager.computeNewConfiguration();
16752 if (mWindowManager != null) {
16753 mProcessList.applyDisplaySize(mWindowManager);
16756 final long origId = Binder.clearCallingIdentity();
16757 if (values != null) {
16758 Settings.System.clearConfiguration(values);
16760 updateConfigurationLocked(values, null, false, false);
16761 Binder.restoreCallingIdentity(origId);
16766 * Do either or both things: (1) change the current configuration, and (2)
16767 * make sure the given activity is running with the (now) current
16768 * configuration. Returns true if the activity has been left running, or
16769 * false if <var>starting</var> is being destroyed to match the new
16771 * @param persistent TODO
16773 boolean updateConfigurationLocked(Configuration values,
16774 ActivityRecord starting, boolean persistent, boolean initLocale) {
16777 if (values != null) {
16778 Configuration newConfig = new Configuration(mConfiguration);
16779 changes = newConfig.updateFrom(values);
16780 if (changes != 0) {
16781 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16782 Slog.i(TAG, "Updating configuration to: " + values);
16785 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16787 if (values.locale != null && !initLocale) {
16788 saveLocaleLocked(values.locale,
16789 !values.locale.equals(mConfiguration.locale),
16790 values.userSetLocale);
16793 mConfigurationSeq++;
16794 if (mConfigurationSeq <= 0) {
16795 mConfigurationSeq = 1;
16797 newConfig.seq = mConfigurationSeq;
16798 mConfiguration = newConfig;
16799 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16800 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16801 //mUsageStatsService.noteStartConfig(newConfig);
16803 final Configuration configCopy = new Configuration(mConfiguration);
16805 // TODO: If our config changes, should we auto dismiss any currently
16806 // showing dialogs?
16807 mShowDialogs = shouldShowDialogs(newConfig);
16809 AttributeCache ac = AttributeCache.instance();
16811 ac.updateConfiguration(configCopy);
16814 // Make sure all resources in our process are updated
16815 // right now, so that anyone who is going to retrieve
16816 // resource values after we return will be sure to get
16817 // the new ones. This is especially important during
16818 // boot, where the first config change needs to guarantee
16819 // all resources have that config before following boot
16820 // code is executed.
16821 mSystemThread.applyConfigurationToResources(configCopy);
16823 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16824 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16825 msg.obj = new Configuration(configCopy);
16826 mHandler.sendMessage(msg);
16829 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16830 ProcessRecord app = mLruProcesses.get(i);
16832 if (app.thread != null) {
16833 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16834 + app.processName + " new config " + mConfiguration);
16835 app.thread.scheduleConfigurationChanged(configCopy);
16837 } catch (Exception e) {
16840 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16841 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16842 | Intent.FLAG_RECEIVER_REPLACE_PENDING
16843 | Intent.FLAG_RECEIVER_FOREGROUND);
16844 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16845 null, AppOpsManager.OP_NONE, false, false, MY_PID,
16846 Process.SYSTEM_UID, UserHandle.USER_ALL);
16847 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16848 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16849 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16850 if (!mProcessesReady) {
16851 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16853 broadcastIntentLocked(null, null, intent,
16854 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16855 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16860 boolean kept = true;
16861 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16862 // mainStack is null during startup.
16863 if (mainStack != null) {
16864 if (changes != 0 && starting == null) {
16865 // If the configuration changed, and the caller is not already
16866 // in the process of starting an activity, then find the top
16867 // activity to check if its configuration needs to change.
16868 starting = mainStack.topRunningActivityLocked(null);
16871 if (starting != null) {
16872 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16873 // And we need to make sure at this point that all other activities
16874 // are made visible with the correct configuration.
16875 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16879 if (values != null && mWindowManager != null) {
16880 mWindowManager.setNewConfiguration(mConfiguration);
16887 * Decide based on the configuration whether we should shouw the ANR,
16888 * crash, etc dialogs. The idea is that if there is no affordnace to
16889 * press the on-screen buttons, we shouldn't show the dialog.
16891 * A thought: SystemUI might also want to get told about this, the Power
16892 * dialog / global actions also might want different behaviors.
16894 private static final boolean shouldShowDialogs(Configuration config) {
16895 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16896 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16900 * Save the locale. You must be inside a synchronized (this) block.
16902 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16904 SystemProperties.set("user.language", l.getLanguage());
16905 SystemProperties.set("user.region", l.getCountry());
16909 SystemProperties.set("persist.sys.language", l.getLanguage());
16910 SystemProperties.set("persist.sys.country", l.getCountry());
16911 SystemProperties.set("persist.sys.localevar", l.getVariant());
16913 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16918 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16919 synchronized (this) {
16920 ActivityRecord srec = ActivityRecord.forToken(token);
16921 if (srec.task != null && srec.task.stack != null) {
16922 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16928 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16929 Intent resultData) {
16931 synchronized (this) {
16932 final ActivityStack stack = ActivityRecord.getStackLocked(token);
16933 if (stack != null) {
16934 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16940 public int getLaunchedFromUid(IBinder activityToken) {
16941 ActivityRecord srec = ActivityRecord.forToken(activityToken);
16942 if (srec == null) {
16945 return srec.launchedFromUid;
16948 public String getLaunchedFromPackage(IBinder activityToken) {
16949 ActivityRecord srec = ActivityRecord.forToken(activityToken);
16950 if (srec == null) {
16953 return srec.launchedFromPackage;
16956 // =========================================================
16957 // LIFETIME MANAGEMENT
16958 // =========================================================
16960 // Returns which broadcast queue the app is the current [or imminent] receiver
16961 // on, or 'null' if the app is not an active broadcast recipient.
16962 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16963 BroadcastRecord r = app.curReceiver;
16968 // It's not the current receiver, but it might be starting up to become one
16969 synchronized (this) {
16970 for (BroadcastQueue queue : mBroadcastQueues) {
16971 r = queue.mPendingBroadcast;
16972 if (r != null && r.curApp == app) {
16973 // found it; report which queue it's in
16982 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
16983 ComponentName targetComponent, String targetProcess) {
16984 if (!mTrackingAssociations) {
16987 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
16988 = mAssociations.get(targetUid);
16989 if (components == null) {
16990 components = new ArrayMap<>();
16991 mAssociations.put(targetUid, components);
16993 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
16994 if (sourceUids == null) {
16995 sourceUids = new SparseArray<>();
16996 components.put(targetComponent, sourceUids);
16998 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
16999 if (sourceProcesses == null) {
17000 sourceProcesses = new ArrayMap<>();
17001 sourceUids.put(sourceUid, sourceProcesses);
17003 Association ass = sourceProcesses.get(sourceProcess);
17005 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17007 sourceProcesses.put(sourceProcess, ass);
17011 if (ass.mNesting == 1) {
17012 ass.mStartTime = SystemClock.uptimeMillis();
17017 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17018 ComponentName targetComponent) {
17019 if (!mTrackingAssociations) {
17022 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17023 = mAssociations.get(targetUid);
17024 if (components == null) {
17027 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17028 if (sourceUids == null) {
17031 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17032 if (sourceProcesses == null) {
17035 Association ass = sourceProcesses.get(sourceProcess);
17036 if (ass == null || ass.mNesting <= 0) {
17040 if (ass.mNesting == 0) {
17041 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17045 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17046 boolean doingAll, long now) {
17047 if (mAdjSeq == app.adjSeq) {
17048 // This adjustment has already been computed.
17049 return app.curRawAdj;
17052 if (app.thread == null) {
17053 app.adjSeq = mAdjSeq;
17054 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17055 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17056 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17059 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17060 app.adjSource = null;
17061 app.adjTarget = null;
17063 app.cached = false;
17065 final int activitiesSize = app.activities.size();
17067 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17068 // The max adjustment doesn't allow this app to be anything
17069 // below foreground, so it is not worth doing work for it.
17070 app.adjType = "fixed";
17071 app.adjSeq = mAdjSeq;
17072 app.curRawAdj = app.maxAdj;
17073 app.foregroundActivities = false;
17074 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17075 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17076 // System processes can do UI, and when they do we want to have
17077 // them trim their memory after the user leaves the UI. To
17078 // facilitate this, here we need to determine whether or not it
17079 // is currently showing UI.
17080 app.systemNoUi = true;
17081 if (app == TOP_APP) {
17082 app.systemNoUi = false;
17083 } else if (activitiesSize > 0) {
17084 for (int j = 0; j < activitiesSize; j++) {
17085 final ActivityRecord r = app.activities.get(j);
17087 app.systemNoUi = false;
17091 if (!app.systemNoUi) {
17092 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17094 return (app.curAdj=app.maxAdj);
17097 app.systemNoUi = false;
17099 // Determine the importance of the process, starting with most
17100 // important to least, and assign an appropriate OOM adjustment.
17104 boolean foregroundActivities = false;
17105 BroadcastQueue queue;
17106 if (app == TOP_APP) {
17107 // The last app on the list is the foreground app.
17108 adj = ProcessList.FOREGROUND_APP_ADJ;
17109 schedGroup = Process.THREAD_GROUP_DEFAULT;
17110 app.adjType = "top-activity";
17111 foregroundActivities = true;
17112 procState = ActivityManager.PROCESS_STATE_TOP;
17113 } else if (app.instrumentationClass != null) {
17114 // Don't want to kill running instrumentation.
17115 adj = ProcessList.FOREGROUND_APP_ADJ;
17116 schedGroup = Process.THREAD_GROUP_DEFAULT;
17117 app.adjType = "instrumentation";
17118 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17119 } else if ((queue = isReceivingBroadcast(app)) != null) {
17120 // An app that is currently receiving a broadcast also
17121 // counts as being in the foreground for OOM killer purposes.
17122 // It's placed in a sched group based on the nature of the
17123 // broadcast as reflected by which queue it's active in.
17124 adj = ProcessList.FOREGROUND_APP_ADJ;
17125 schedGroup = (queue == mFgBroadcastQueue)
17126 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17127 app.adjType = "broadcast";
17128 procState = ActivityManager.PROCESS_STATE_RECEIVER;
17129 } else if (app.executingServices.size() > 0) {
17130 // An app that is currently executing a service callback also
17131 // counts as being in the foreground.
17132 adj = ProcessList.FOREGROUND_APP_ADJ;
17133 schedGroup = app.execServicesFg ?
17134 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17135 app.adjType = "exec-service";
17136 procState = ActivityManager.PROCESS_STATE_SERVICE;
17137 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17139 // As far as we know the process is empty. We may change our mind later.
17140 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17141 // At this point we don't actually know the adjustment. Use the cached adj
17142 // value that the caller wants us to.
17144 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17147 app.adjType = "cch-empty";
17150 // Examine all activities if not already foreground.
17151 if (!foregroundActivities && activitiesSize > 0) {
17152 for (int j = 0; j < activitiesSize; j++) {
17153 final ActivityRecord r = app.activities.get(j);
17154 if (r.app != app) {
17155 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17160 // App has a visible activity; only upgrade adjustment.
17161 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17162 adj = ProcessList.VISIBLE_APP_ADJ;
17163 app.adjType = "visible";
17165 if (procState > ActivityManager.PROCESS_STATE_TOP) {
17166 procState = ActivityManager.PROCESS_STATE_TOP;
17168 schedGroup = Process.THREAD_GROUP_DEFAULT;
17169 app.cached = false;
17171 foregroundActivities = true;
17173 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17174 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17175 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17176 app.adjType = "pausing";
17178 if (procState > ActivityManager.PROCESS_STATE_TOP) {
17179 procState = ActivityManager.PROCESS_STATE_TOP;
17181 schedGroup = Process.THREAD_GROUP_DEFAULT;
17182 app.cached = false;
17184 foregroundActivities = true;
17185 } else if (r.state == ActivityState.STOPPING) {
17186 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17187 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17188 app.adjType = "stopping";
17190 // For the process state, we will at this point consider the
17191 // process to be cached. It will be cached either as an activity
17192 // or empty depending on whether the activity is finishing. We do
17193 // this so that we can treat the process as cached for purposes of
17194 // memory trimming (determing current memory level, trim command to
17195 // send to process) since there can be an arbitrary number of stopping
17196 // processes and they should soon all go into the cached state.
17197 if (!r.finishing) {
17198 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17199 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17202 app.cached = false;
17204 foregroundActivities = true;
17206 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17207 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17208 app.adjType = "cch-act";
17214 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17215 if (app.foregroundServices) {
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 = "fg-service";
17221 schedGroup = Process.THREAD_GROUP_DEFAULT;
17222 } else if (app.forcingToForeground != null) {
17223 // The user is aware of this app, so make it visible.
17224 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17225 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17226 app.cached = false;
17227 app.adjType = "force-fg";
17228 app.adjSource = app.forcingToForeground;
17229 schedGroup = Process.THREAD_GROUP_DEFAULT;
17233 if (app == mHeavyWeightProcess) {
17234 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17235 // We don't want to kill the current heavy-weight process.
17236 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17237 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17238 app.cached = false;
17239 app.adjType = "heavy";
17241 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17242 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17246 if (app == mHomeProcess) {
17247 if (adj > ProcessList.HOME_APP_ADJ) {
17248 // This process is hosting what we currently consider to be the
17249 // home app, so we don't want to let it go into the background.
17250 adj = ProcessList.HOME_APP_ADJ;
17251 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17252 app.cached = false;
17253 app.adjType = "home";
17255 if (procState > ActivityManager.PROCESS_STATE_HOME) {
17256 procState = ActivityManager.PROCESS_STATE_HOME;
17260 if (app == mPreviousProcess && app.activities.size() > 0) {
17261 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17262 // This was the previous process that showed UI to the user.
17263 // We want to try to keep it around more aggressively, to give
17264 // a good experience around switching between two apps.
17265 adj = ProcessList.PREVIOUS_APP_ADJ;
17266 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17267 app.cached = false;
17268 app.adjType = "previous";
17270 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17271 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17275 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17276 + " reason=" + app.adjType);
17278 // By default, we use the computed adjustment. It may be changed if
17279 // there are applications dependent on our services or providers, but
17280 // this gives us a baseline and makes sure we don't get into an
17281 // infinite recursion.
17282 app.adjSeq = mAdjSeq;
17283 app.curRawAdj = adj;
17284 app.hasStartedServices = false;
17286 if (mBackupTarget != null && app == mBackupTarget.app) {
17287 // If possible we want to avoid killing apps while they're being backed up
17288 if (adj > ProcessList.BACKUP_APP_ADJ) {
17289 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
17290 adj = ProcessList.BACKUP_APP_ADJ;
17291 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17292 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17294 app.adjType = "backup";
17295 app.cached = false;
17297 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17298 procState = ActivityManager.PROCESS_STATE_BACKUP;
17302 boolean mayBeTop = false;
17304 for (int is = app.services.size()-1;
17305 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17306 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17307 || procState > ActivityManager.PROCESS_STATE_TOP);
17309 ServiceRecord s = app.services.valueAt(is);
17310 if (s.startRequested) {
17311 app.hasStartedServices = true;
17312 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17313 procState = ActivityManager.PROCESS_STATE_SERVICE;
17315 if (app.hasShownUi && app != mHomeProcess) {
17316 // If this process has shown some UI, let it immediately
17317 // go to the LRU list because it may be pretty heavy with
17318 // UI stuff. We'll tag it with a label just to help
17319 // debug and understand what is going on.
17320 if (adj > ProcessList.SERVICE_ADJ) {
17321 app.adjType = "cch-started-ui-services";
17324 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17325 // This service has seen some activity within
17326 // recent memory, so we will keep its process ahead
17327 // of the background processes.
17328 if (adj > ProcessList.SERVICE_ADJ) {
17329 adj = ProcessList.SERVICE_ADJ;
17330 app.adjType = "started-services";
17331 app.cached = false;
17334 // If we have let the service slide into the background
17335 // state, still have some text describing what it is doing
17336 // even though the service no longer has an impact.
17337 if (adj > ProcessList.SERVICE_ADJ) {
17338 app.adjType = "cch-started-services";
17342 for (int conni = s.connections.size()-1;
17343 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17344 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17345 || procState > ActivityManager.PROCESS_STATE_TOP);
17347 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17349 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17350 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17351 || procState > ActivityManager.PROCESS_STATE_TOP);
17353 // XXX should compute this based on the max of
17354 // all connected clients.
17355 ConnectionRecord cr = clist.get(i);
17356 if (cr.binding.client == app) {
17357 // Binding to ourself is not interesting.
17360 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17361 ProcessRecord client = cr.binding.client;
17362 int clientAdj = computeOomAdjLocked(client, cachedAdj,
17363 TOP_APP, doingAll, now);
17364 int clientProcState = client.curProcState;
17365 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17366 // If the other app is cached for any reason, for purposes here
17367 // we are going to consider it empty. The specific cached state
17368 // doesn't propagate except under certain conditions.
17369 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17371 String adjType = null;
17372 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17373 // Not doing bind OOM management, so treat
17374 // this guy more like a started service.
17375 if (app.hasShownUi && app != mHomeProcess) {
17376 // If this process has shown some UI, let it immediately
17377 // go to the LRU list because it may be pretty heavy with
17378 // UI stuff. We'll tag it with a label just to help
17379 // debug and understand what is going on.
17380 if (adj > clientAdj) {
17381 adjType = "cch-bound-ui-services";
17383 app.cached = false;
17385 clientProcState = procState;
17387 if (now >= (s.lastActivity
17388 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17389 // This service has not seen activity within
17390 // recent memory, so allow it to drop to the
17391 // LRU list if there is no other reason to keep
17392 // it around. We'll also tag it with a label just
17393 // to help debug and undertand what is going on.
17394 if (adj > clientAdj) {
17395 adjType = "cch-bound-services";
17401 if (adj > clientAdj) {
17402 // If this process has recently shown UI, and
17403 // the process that is binding to it is less
17404 // important than being visible, then we don't
17405 // care about the binding as much as we care
17406 // about letting this process get into the LRU
17407 // list to be killed and restarted if needed for
17409 if (app.hasShownUi && app != mHomeProcess
17410 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17411 adjType = "cch-bound-ui-services";
17413 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
17414 |Context.BIND_IMPORTANT)) != 0) {
17415 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
17416 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
17417 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
17418 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
17419 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17420 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17421 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
17424 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17425 adj = ProcessList.VISIBLE_APP_ADJ;
17428 if (!client.cached) {
17429 app.cached = false;
17431 adjType = "service";
17434 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17435 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17436 schedGroup = Process.THREAD_GROUP_DEFAULT;
17438 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17439 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17440 // Special handling of clients who are in the top state.
17441 // We *may* want to consider this process to be in the
17442 // top state as well, but only if there is not another
17443 // reason for it to be running. Being on the top is a
17444 // special state, meaning you are specifically running
17445 // for the current top app. If the process is already
17446 // running in the background for some other reason, it
17447 // is more important to continue considering it to be
17448 // in the background state.
17450 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17452 // Special handling for above-top states (persistent
17453 // processes). These should not bring the current process
17454 // into the top state, since they are not on top. Instead
17455 // give them the best state after that.
17457 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17461 if (clientProcState <
17462 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17464 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17467 if (procState > clientProcState) {
17468 procState = clientProcState;
17470 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17471 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
17472 app.pendingUiClean = true;
17474 if (adjType != null) {
17475 app.adjType = adjType;
17476 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17477 .REASON_SERVICE_IN_USE;
17478 app.adjSource = cr.binding.client;
17479 app.adjSourceProcState = clientProcState;
17480 app.adjTarget = s.name;
17483 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
17484 app.treatLikeActivity = true;
17486 final ActivityRecord a = cr.activity;
17487 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
17488 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
17489 (a.visible || a.state == ActivityState.RESUMED
17490 || a.state == ActivityState.PAUSING)) {
17491 adj = ProcessList.FOREGROUND_APP_ADJ;
17492 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
17493 schedGroup = Process.THREAD_GROUP_DEFAULT;
17495 app.cached = false;
17496 app.adjType = "service";
17497 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17498 .REASON_SERVICE_IN_USE;
17500 app.adjSourceProcState = procState;
17501 app.adjTarget = s.name;
17508 for (int provi = app.pubProviders.size()-1;
17509 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17510 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17511 || procState > ActivityManager.PROCESS_STATE_TOP);
17513 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
17514 for (int i = cpr.connections.size()-1;
17515 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17516 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17517 || procState > ActivityManager.PROCESS_STATE_TOP);
17519 ContentProviderConnection conn = cpr.connections.get(i);
17520 ProcessRecord client = conn.client;
17521 if (client == app) {
17522 // Being our own client is not interesting.
17525 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
17526 int clientProcState = client.curProcState;
17527 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17528 // If the other app is cached for any reason, for purposes here
17529 // we are going to consider it empty.
17530 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17532 if (adj > clientAdj) {
17533 if (app.hasShownUi && app != mHomeProcess
17534 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17535 app.adjType = "cch-ui-provider";
17537 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
17538 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
17539 app.adjType = "provider";
17541 app.cached &= client.cached;
17542 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
17543 .REASON_PROVIDER_IN_USE;
17544 app.adjSource = client;
17545 app.adjSourceProcState = clientProcState;
17546 app.adjTarget = cpr.name;
17548 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
17549 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
17550 // Special handling of clients who are in the top state.
17551 // We *may* want to consider this process to be in the
17552 // top state as well, but only if there is not another
17553 // reason for it to be running. Being on the top is a
17554 // special state, meaning you are specifically running
17555 // for the current top app. If the process is already
17556 // running in the background for some other reason, it
17557 // is more important to continue considering it to be
17558 // in the background state.
17560 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17562 // Special handling for above-top states (persistent
17563 // processes). These should not bring the current process
17564 // into the top state, since they are not on top. Instead
17565 // give them the best state after that.
17567 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17570 if (procState > clientProcState) {
17571 procState = clientProcState;
17573 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
17574 schedGroup = Process.THREAD_GROUP_DEFAULT;
17577 // If the provider has external (non-framework) process
17578 // dependencies, ensure that its adjustment is at least
17579 // FOREGROUND_APP_ADJ.
17580 if (cpr.hasExternalProcessHandles()) {
17581 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17582 adj = ProcessList.FOREGROUND_APP_ADJ;
17583 schedGroup = Process.THREAD_GROUP_DEFAULT;
17584 app.cached = false;
17585 app.adjType = "provider";
17586 app.adjTarget = cpr.name;
17588 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17589 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17594 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17595 // A client of one of our services or providers is in the top state. We
17596 // *may* want to be in the top state, but not if we are already running in
17597 // the background for some other reason. For the decision here, we are going
17598 // to pick out a few specific states that we want to remain in when a client
17599 // is top (states that tend to be longer-term) and otherwise allow it to go
17600 // to the top state.
17601 switch (procState) {
17602 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17603 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17604 case ActivityManager.PROCESS_STATE_SERVICE:
17605 // These all are longer-term states, so pull them up to the top
17606 // of the background states, but not all the way to the top state.
17607 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17610 // Otherwise, top is a better choice, so take it.
17611 procState = ActivityManager.PROCESS_STATE_TOP;
17616 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17617 if (app.hasClientActivities) {
17618 // This is a cached process, but with client activities. Mark it so.
17619 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17620 app.adjType = "cch-client-act";
17621 } else if (app.treatLikeActivity) {
17622 // This is a cached process, but somebody wants us to treat it like it has
17623 // an activity, okay!
17624 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17625 app.adjType = "cch-as-act";
17629 if (adj == ProcessList.SERVICE_ADJ) {
17631 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17632 mNewNumServiceProcs++;
17633 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17634 if (!app.serviceb) {
17635 // This service isn't far enough down on the LRU list to
17636 // normally be a B service, but if we are low on RAM and it
17637 // is large we want to force it down since we would prefer to
17638 // keep launcher over it.
17639 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17640 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17641 app.serviceHighRam = true;
17642 app.serviceb = true;
17643 //Slog.i(TAG, "ADJ " + app + " high ram!");
17645 mNewNumAServiceProcs++;
17646 //Slog.i(TAG, "ADJ " + app + " not high ram!");
17649 app.serviceHighRam = false;
17652 if (app.serviceb) {
17653 adj = ProcessList.SERVICE_B_ADJ;
17657 app.curRawAdj = adj;
17659 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17660 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17661 if (adj > app.maxAdj) {
17663 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17664 schedGroup = Process.THREAD_GROUP_DEFAULT;
17668 // Do final modification to adj. Everything we do between here and applying
17669 // the final setAdj must be done in this function, because we will also use
17670 // it when computing the final cached adj later. Note that we don't need to
17671 // worry about this for max adj above, since max adj will always be used to
17672 // keep it out of the cached vaues.
17673 app.curAdj = app.modifyRawOomAdj(adj);
17674 app.curSchedGroup = schedGroup;
17675 app.curProcState = procState;
17676 app.foregroundActivities = foregroundActivities;
17678 return app.curRawAdj;
17682 * Record new PSS sample for a process.
17684 void recordPssSample(ProcessRecord proc, int procState, long pss, long uss, long now) {
17685 proc.lastPssTime = now;
17686 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
17687 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
17688 + ": " + pss + " lastPss=" + proc.lastPss
17689 + " state=" + ProcessList.makeProcStateString(procState));
17690 if (proc.initialIdlePss == 0) {
17691 proc.initialIdlePss = pss;
17693 proc.lastPss = pss;
17694 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
17695 proc.lastCachedPss = pss;
17700 * Schedule PSS collection of a process.
17702 void requestPssLocked(ProcessRecord proc, int procState) {
17703 if (mPendingPssProcesses.contains(proc)) {
17706 if (mPendingPssProcesses.size() == 0) {
17707 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17709 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17710 proc.pssProcState = procState;
17711 mPendingPssProcesses.add(proc);
17715 * Schedule PSS collection of all processes.
17717 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17719 if (now < (mLastFullPssTime +
17720 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17724 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered);
17725 mLastFullPssTime = now;
17726 mFullPssPending = true;
17727 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17728 mPendingPssProcesses.clear();
17729 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17730 ProcessRecord app = mLruProcesses.get(i);
17731 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17732 app.pssProcState = app.setProcState;
17733 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17734 mTestPssMode, isSleeping(), now);
17735 mPendingPssProcesses.add(app);
17738 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17741 public void setTestPssMode(boolean enabled) {
17742 synchronized (this) {
17743 mTestPssMode = enabled;
17745 // Whenever we enable the mode, we want to take a snapshot all of current
17746 // process mem use.
17747 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
17753 * Ask a given process to GC right now.
17755 final void performAppGcLocked(ProcessRecord app) {
17757 app.lastRequestedGc = SystemClock.uptimeMillis();
17758 if (app.thread != null) {
17759 if (app.reportLowMemory) {
17760 app.reportLowMemory = false;
17761 app.thread.scheduleLowMemory();
17763 app.thread.processInBackground();
17766 } catch (Exception e) {
17772 * Returns true if things are idle enough to perform GCs.
17774 private final boolean canGcNowLocked() {
17775 boolean processingBroadcasts = false;
17776 for (BroadcastQueue q : mBroadcastQueues) {
17777 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17778 processingBroadcasts = true;
17781 return !processingBroadcasts
17782 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17786 * Perform GCs on all processes that are waiting for it, but only
17787 * if things are idle.
17789 final void performAppGcsLocked() {
17790 final int N = mProcessesToGc.size();
17794 if (canGcNowLocked()) {
17795 while (mProcessesToGc.size() > 0) {
17796 ProcessRecord proc = mProcessesToGc.remove(0);
17797 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17798 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17799 <= SystemClock.uptimeMillis()) {
17800 // To avoid spamming the system, we will GC processes one
17801 // at a time, waiting a few seconds between each.
17802 performAppGcLocked(proc);
17803 scheduleAppGcsLocked();
17806 // It hasn't been long enough since we last GCed this
17807 // process... put it in the list to wait for its time.
17808 addProcessToGcListLocked(proc);
17814 scheduleAppGcsLocked();
17819 * If all looks good, perform GCs on all processes waiting for them.
17821 final void performAppGcsIfAppropriateLocked() {
17822 if (canGcNowLocked()) {
17823 performAppGcsLocked();
17826 // Still not idle, wait some more.
17827 scheduleAppGcsLocked();
17831 * Schedule the execution of all pending app GCs.
17833 final void scheduleAppGcsLocked() {
17834 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17836 if (mProcessesToGc.size() > 0) {
17837 // Schedule a GC for the time to the next process.
17838 ProcessRecord proc = mProcessesToGc.get(0);
17839 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17841 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17842 long now = SystemClock.uptimeMillis();
17843 if (when < (now+GC_TIMEOUT)) {
17844 when = now + GC_TIMEOUT;
17846 mHandler.sendMessageAtTime(msg, when);
17851 * Add a process to the array of processes waiting to be GCed. Keeps the
17852 * list in sorted order by the last GC time. The process can't already be
17855 final void addProcessToGcListLocked(ProcessRecord proc) {
17856 boolean added = false;
17857 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17858 if (mProcessesToGc.get(i).lastRequestedGc <
17859 proc.lastRequestedGc) {
17861 mProcessesToGc.add(i+1, proc);
17866 mProcessesToGc.add(0, proc);
17871 * Set up to ask a process to GC itself. This will either do it
17872 * immediately, or put it on the list of processes to gc the next
17873 * time things are idle.
17875 final void scheduleAppGcLocked(ProcessRecord app) {
17876 long now = SystemClock.uptimeMillis();
17877 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17880 if (!mProcessesToGc.contains(app)) {
17881 addProcessToGcListLocked(app);
17882 scheduleAppGcsLocked();
17886 final void checkExcessivePowerUsageLocked(boolean doKills) {
17887 updateCpuStatsNow();
17889 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17890 boolean doWakeKills = doKills;
17891 boolean doCpuKills = doKills;
17892 if (mLastPowerCheckRealtime == 0) {
17893 doWakeKills = false;
17895 if (mLastPowerCheckUptime == 0) {
17896 doCpuKills = false;
17898 if (stats.isScreenOn()) {
17899 doWakeKills = false;
17901 final long curRealtime = SystemClock.elapsedRealtime();
17902 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17903 final long curUptime = SystemClock.uptimeMillis();
17904 final long uptimeSince = curUptime - mLastPowerCheckUptime;
17905 mLastPowerCheckRealtime = curRealtime;
17906 mLastPowerCheckUptime = curUptime;
17907 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17908 doWakeKills = false;
17910 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17911 doCpuKills = false;
17913 int i = mLruProcesses.size();
17916 ProcessRecord app = mLruProcesses.get(i);
17917 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17919 synchronized (stats) {
17920 wtime = stats.getProcessWakeTime(app.info.uid,
17921 app.pid, curRealtime);
17923 long wtimeUsed = wtime - app.lastWakeTime;
17924 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17926 StringBuilder sb = new StringBuilder(128);
17927 sb.append("Wake for ");
17928 app.toShortString(sb);
17929 sb.append(": over ");
17930 TimeUtils.formatDuration(realtimeSince, sb);
17931 sb.append(" used ");
17932 TimeUtils.formatDuration(wtimeUsed, sb);
17934 sb.append((wtimeUsed*100)/realtimeSince);
17936 Slog.i(TAG, sb.toString());
17938 sb.append("CPU for ");
17939 app.toShortString(sb);
17940 sb.append(": over ");
17941 TimeUtils.formatDuration(uptimeSince, sb);
17942 sb.append(" used ");
17943 TimeUtils.formatDuration(cputimeUsed, sb);
17945 sb.append((cputimeUsed*100)/uptimeSince);
17947 Slog.i(TAG, sb.toString());
17949 // If a process has held a wake lock for more
17950 // than 50% of the time during this period,
17951 // that sounds bad. Kill!
17952 if (doWakeKills && realtimeSince > 0
17953 && ((wtimeUsed*100)/realtimeSince) >= 50) {
17954 synchronized (stats) {
17955 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17956 realtimeSince, wtimeUsed);
17958 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17959 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17960 } else if (doCpuKills && uptimeSince > 0
17961 && ((cputimeUsed*100)/uptimeSince) >= 25) {
17962 synchronized (stats) {
17963 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17964 uptimeSince, cputimeUsed);
17966 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17967 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17969 app.lastWakeTime = wtime;
17970 app.lastCpuTime = app.curCpuTime;
17976 private final boolean applyOomAdjLocked(ProcessRecord app,
17977 ProcessRecord TOP_APP, boolean doingAll, long now) {
17978 boolean success = true;
17980 if (app.curRawAdj != app.setRawAdj) {
17981 app.setRawAdj = app.curRawAdj;
17986 if (app.curAdj != app.setAdj) {
17987 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17988 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17989 TAG, "Set " + app.pid + " " + app.processName +
17990 " adj " + app.curAdj + ": " + app.adjType);
17991 app.setAdj = app.curAdj;
17994 if (app.setSchedGroup != app.curSchedGroup) {
17995 app.setSchedGroup = app.curSchedGroup;
17996 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17997 "Setting process group of " + app.processName
17998 + " to " + app.curSchedGroup);
17999 if (app.waitingToKill != null &&
18000 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18001 app.kill(app.waitingToKill, true);
18005 long oldId = Binder.clearCallingIdentity();
18007 Process.setProcessGroup(app.pid, app.curSchedGroup);
18008 } catch (Exception e) {
18009 Slog.w(TAG, "Failed setting process group of " + app.pid
18010 + " to " + app.curSchedGroup);
18011 e.printStackTrace();
18013 Binder.restoreCallingIdentity(oldId);
18016 if (app.thread != null) {
18018 app.thread.setSchedulingGroup(app.curSchedGroup);
18019 } catch (RemoteException e) {
18023 Process.setSwappiness(app.pid,
18024 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18027 if (app.repForegroundActivities != app.foregroundActivities) {
18028 app.repForegroundActivities = app.foregroundActivities;
18029 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18031 if (app.repProcState != app.curProcState) {
18032 app.repProcState = app.curProcState;
18033 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18034 if (app.thread != null) {
18037 //RuntimeException h = new RuntimeException("here");
18038 Slog.i(TAG, "Sending new process state " + app.repProcState
18039 + " to " + app /*, h*/);
18041 app.thread.setProcessState(app.repProcState);
18042 } catch (RemoteException e) {
18046 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
18047 app.setProcState)) {
18048 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18049 // Experimental code to more aggressively collect pss while
18050 // running test... the problem is that this tends to collect
18051 // the data right when a process is transitioning between process
18052 // states, which well tend to give noisy data.
18053 long start = SystemClock.uptimeMillis();
18054 long pss = Debug.getPss(app.pid, mTmpLong, null);
18055 recordPssSample(app, app.curProcState, pss, mTmpLong[0], now);
18056 mPendingPssProcesses.remove(app);
18057 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18058 + " to " + app.curProcState + ": "
18059 + (SystemClock.uptimeMillis()-start) + "ms");
18061 app.lastStateTime = now;
18062 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18063 mTestPssMode, isSleeping(), now);
18064 if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
18065 + ProcessList.makeProcStateString(app.setProcState) + " to "
18066 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18067 + (app.nextPssTime-now) + ": " + app);
18069 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18070 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18072 requestPssLocked(app, app.setProcState);
18073 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18074 mTestPssMode, isSleeping(), now);
18075 } else if (false && DEBUG_PSS) {
18076 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18079 if (app.setProcState != app.curProcState) {
18080 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18081 "Proc state change of " + app.processName
18082 + " to " + app.curProcState);
18083 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18084 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18085 if (setImportant && !curImportant) {
18086 // This app is no longer something we consider important enough to allow to
18087 // use arbitrary amounts of battery power. Note
18088 // its current wake lock time to later know to kill it if
18089 // it is not behaving well.
18090 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18091 synchronized (stats) {
18092 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18093 app.pid, SystemClock.elapsedRealtime());
18095 app.lastCpuTime = app.curCpuTime;
18098 app.setProcState = app.curProcState;
18099 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18100 app.notCachedSinceIdle = false;
18103 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18105 app.procStateChanged = true;
18109 if (changes != 0) {
18110 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
18111 int i = mPendingProcessChanges.size()-1;
18112 ProcessChangeItem item = null;
18114 item = mPendingProcessChanges.get(i);
18115 if (item.pid == app.pid) {
18116 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
18122 // No existing item in pending changes; need a new one.
18123 final int NA = mAvailProcessChanges.size();
18125 item = mAvailProcessChanges.remove(NA-1);
18126 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
18128 item = new ProcessChangeItem();
18129 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
18132 item.pid = app.pid;
18133 item.uid = app.info.uid;
18134 if (mPendingProcessChanges.size() == 0) {
18135 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
18136 "*** Enqueueing dispatch processes changed!");
18137 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18139 mPendingProcessChanges.add(item);
18141 item.changes |= changes;
18142 item.processState = app.repProcState;
18143 item.foregroundActivities = app.repForegroundActivities;
18144 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
18145 + Integer.toHexString(System.identityHashCode(item))
18146 + " " + app.toShortString() + ": changes=" + item.changes
18147 + " procState=" + item.processState
18148 + " foreground=" + item.foregroundActivities
18149 + " type=" + app.adjType + " source=" + app.adjSource
18150 + " target=" + app.adjTarget);
18156 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18157 if (proc.thread != null) {
18158 if (proc.baseProcessTracker != null) {
18159 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18161 if (proc.repProcState >= 0) {
18162 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18163 proc.repProcState);
18168 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18169 ProcessRecord TOP_APP, boolean doingAll, long now) {
18170 if (app.thread == null) {
18174 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18176 return applyOomAdjLocked(app, TOP_APP, doingAll, now);
18179 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18181 if (isForeground != proc.foregroundServices) {
18182 proc.foregroundServices = isForeground;
18183 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18185 if (isForeground) {
18186 if (curProcs == null) {
18187 curProcs = new ArrayList<ProcessRecord>();
18188 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18190 if (!curProcs.contains(proc)) {
18191 curProcs.add(proc);
18192 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18193 proc.info.packageName, proc.info.uid);
18196 if (curProcs != null) {
18197 if (curProcs.remove(proc)) {
18198 mBatteryStatsService.noteEvent(
18199 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18200 proc.info.packageName, proc.info.uid);
18201 if (curProcs.size() <= 0) {
18202 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18208 updateOomAdjLocked();
18213 private final ActivityRecord resumedAppLocked() {
18214 ActivityRecord act = mStackSupervisor.resumedAppLocked();
18218 pkg = act.packageName;
18219 uid = act.info.applicationInfo.uid;
18224 // Has the UID or resumed package name changed?
18225 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18226 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18227 if (mCurResumedPackage != null) {
18228 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
18229 mCurResumedPackage, mCurResumedUid);
18231 mCurResumedPackage = pkg;
18232 mCurResumedUid = uid;
18233 if (mCurResumedPackage != null) {
18234 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
18235 mCurResumedPackage, mCurResumedUid);
18241 final boolean updateOomAdjLocked(ProcessRecord app) {
18242 final ActivityRecord TOP_ACT = resumedAppLocked();
18243 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18244 final boolean wasCached = app.cached;
18248 // This is the desired cached adjusment we want to tell it to use.
18249 // If our app is currently cached, we know it, and that is it. Otherwise,
18250 // we don't know it yet, and it needs to now be cached we will then
18251 // need to do a complete oom adj.
18252 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
18253 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
18254 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
18255 SystemClock.uptimeMillis());
18256 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
18257 // Changed to/from cached state, so apps after it in the LRU
18258 // list may also be changed.
18259 updateOomAdjLocked();
18264 final void updateOomAdjLocked() {
18265 final ActivityRecord TOP_ACT = resumedAppLocked();
18266 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
18267 final long now = SystemClock.uptimeMillis();
18268 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
18269 final int N = mLruProcesses.size();
18272 RuntimeException e = new RuntimeException();
18273 e.fillInStackTrace();
18274 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
18278 mNewNumServiceProcs = 0;
18279 mNewNumAServiceProcs = 0;
18281 final int emptyProcessLimit;
18282 final int cachedProcessLimit;
18283 if (mProcessLimit <= 0) {
18284 emptyProcessLimit = cachedProcessLimit = 0;
18285 } else if (mProcessLimit == 1) {
18286 emptyProcessLimit = 1;
18287 cachedProcessLimit = 0;
18289 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
18290 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
18293 // Let's determine how many processes we have running vs.
18294 // how many slots we have for background processes; we may want
18295 // to put multiple processes in a slot of there are enough of
18297 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
18298 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
18299 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
18300 if (numEmptyProcs > cachedProcessLimit) {
18301 // If there are more empty processes than our limit on cached
18302 // processes, then use the cached process limit for the factor.
18303 // This ensures that the really old empty processes get pushed
18304 // down to the bottom, so if we are running low on memory we will
18305 // have a better chance at keeping around more cached processes
18306 // instead of a gazillion empty processes.
18307 numEmptyProcs = cachedProcessLimit;
18309 int emptyFactor = numEmptyProcs/numSlots;
18310 if (emptyFactor < 1) emptyFactor = 1;
18311 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
18312 if (cachedFactor < 1) cachedFactor = 1;
18313 int stepCached = 0;
18317 int numTrimming = 0;
18319 mNumNonCachedProcs = 0;
18320 mNumCachedHiddenProcs = 0;
18322 // First update the OOM adjustment for each of the
18323 // application processes based on their current state.
18324 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
18325 int nextCachedAdj = curCachedAdj+1;
18326 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
18327 int nextEmptyAdj = curEmptyAdj+2;
18328 for (int i=N-1; i>=0; i--) {
18329 ProcessRecord app = mLruProcesses.get(i);
18330 if (!app.killedByAm && app.thread != null) {
18331 app.procStateChanged = false;
18332 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
18334 // If we haven't yet assigned the final cached adj
18335 // to the process, do that now.
18336 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
18337 switch (app.curProcState) {
18338 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18339 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18340 // This process is a cached process holding activities...
18341 // assign it the next cached value for that type, and then
18342 // step that cached level.
18343 app.curRawAdj = curCachedAdj;
18344 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
18345 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
18346 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
18348 if (curCachedAdj != nextCachedAdj) {
18350 if (stepCached >= cachedFactor) {
18352 curCachedAdj = nextCachedAdj;
18353 nextCachedAdj += 2;
18354 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18355 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
18361 // For everything else, assign next empty cached process
18362 // level and bump that up. Note that this means that
18363 // long-running services that have dropped down to the
18364 // cached level will be treated as empty (since their process
18365 // state is still as a service), which is what we want.
18366 app.curRawAdj = curEmptyAdj;
18367 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
18368 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
18369 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
18371 if (curEmptyAdj != nextEmptyAdj) {
18373 if (stepEmpty >= emptyFactor) {
18375 curEmptyAdj = nextEmptyAdj;
18377 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
18378 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
18386 applyOomAdjLocked(app, TOP_APP, true, now);
18388 // Count the number of process types.
18389 switch (app.curProcState) {
18390 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
18391 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
18392 mNumCachedHiddenProcs++;
18394 if (numCached > cachedProcessLimit) {
18395 app.kill("cached #" + numCached, true);
18398 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
18399 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
18400 && app.lastActivityTime < oldTime) {
18401 app.kill("empty for "
18402 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
18403 / 1000) + "s", true);
18406 if (numEmpty > emptyProcessLimit) {
18407 app.kill("empty #" + numEmpty, true);
18412 mNumNonCachedProcs++;
18416 if (app.isolated && app.services.size() <= 0) {
18417 // If this is an isolated process, and there are no
18418 // services running in it, then the process is no longer
18419 // needed. We agressively kill these because we can by
18420 // definition not re-use the same process again, and it is
18421 // good to avoid having whatever code was running in them
18422 // left sitting around after no longer needed.
18423 app.kill("isolated not needed", true);
18426 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18427 && !app.killedByAm) {
18433 mNumServiceProcs = mNewNumServiceProcs;
18435 // Now determine the memory trimming level of background processes.
18436 // Unfortunately we need to start at the back of the list to do this
18437 // properly. We only do this if the number of background apps we
18438 // are managing to keep around is less than half the maximum we desire;
18439 // if we are keeping a good number around, we'll let them use whatever
18440 // memory they want.
18441 final int numCachedAndEmpty = numCached + numEmpty;
18443 if (numCached <= ProcessList.TRIM_CACHED_APPS
18444 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
18445 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
18446 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
18447 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
18448 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
18450 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
18453 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
18455 // We always allow the memory level to go up (better). We only allow it to go
18456 // down if we are in a state where that is allowed, *and* the total number of processes
18457 // has gone down since last time.
18458 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
18459 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
18460 + " last=" + mLastNumProcesses);
18461 if (memFactor > mLastMemoryLevel) {
18462 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
18463 memFactor = mLastMemoryLevel;
18464 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
18467 mLastMemoryLevel = memFactor;
18468 mLastNumProcesses = mLruProcesses.size();
18469 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
18470 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
18471 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
18472 if (mLowRamStartTime == 0) {
18473 mLowRamStartTime = now;
18477 switch (memFactor) {
18478 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
18479 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
18481 case ProcessStats.ADJ_MEM_FACTOR_LOW:
18482 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
18485 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
18488 int factor = numTrimming/3;
18490 if (mHomeProcess != null) minFactor++;
18491 if (mPreviousProcess != null) minFactor++;
18492 if (factor < minFactor) factor = minFactor;
18493 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
18494 for (int i=N-1; i>=0; i--) {
18495 ProcessRecord app = mLruProcesses.get(i);
18496 if (allChanged || app.procStateChanged) {
18497 setProcessTrackerStateLocked(app, trackerMemFactor, now);
18498 app.procStateChanged = false;
18500 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
18501 && !app.killedByAm) {
18502 if (app.trimMemoryLevel < curLevel && app.thread != null) {
18504 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18505 "Trimming memory of " + app.processName
18506 + " to " + curLevel);
18507 app.thread.scheduleTrimMemory(curLevel);
18508 } catch (RemoteException e) {
18511 // For now we won't do this; our memory trimming seems
18512 // to be good enough at this point that destroying
18513 // activities causes more harm than good.
18514 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
18515 && app != mHomeProcess && app != mPreviousProcess) {
18516 // Need to do this on its own message because the stack may not
18517 // be in a consistent state at this point.
18518 // For these apps we will also finish their activities
18519 // to help them free memory.
18520 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
18524 app.trimMemoryLevel = curLevel;
18526 if (step >= factor) {
18528 switch (curLevel) {
18529 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
18530 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
18532 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
18533 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18537 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18538 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
18539 && app.thread != null) {
18541 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18542 "Trimming memory of heavy-weight " + app.processName
18543 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18544 app.thread.scheduleTrimMemory(
18545 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
18546 } catch (RemoteException e) {
18549 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
18551 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18552 || app.systemNoUi) && app.pendingUiClean) {
18553 // If this application is now in the background and it
18554 // had done UI, then give it the special trim level to
18555 // have it free UI resources.
18556 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
18557 if (app.trimMemoryLevel < level && app.thread != null) {
18559 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18560 "Trimming memory of bg-ui " + app.processName
18562 app.thread.scheduleTrimMemory(level);
18563 } catch (RemoteException e) {
18566 app.pendingUiClean = false;
18568 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
18570 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18571 "Trimming memory of fg " + app.processName
18572 + " to " + fgTrimLevel);
18573 app.thread.scheduleTrimMemory(fgTrimLevel);
18574 } catch (RemoteException e) {
18577 app.trimMemoryLevel = fgTrimLevel;
18581 if (mLowRamStartTime != 0) {
18582 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
18583 mLowRamStartTime = 0;
18585 for (int i=N-1; i>=0; i--) {
18586 ProcessRecord app = mLruProcesses.get(i);
18587 if (allChanged || app.procStateChanged) {
18588 setProcessTrackerStateLocked(app, trackerMemFactor, now);
18589 app.procStateChanged = false;
18591 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18592 || app.systemNoUi) && app.pendingUiClean) {
18593 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
18594 && app.thread != null) {
18596 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
18597 "Trimming memory of ui hidden " + app.processName
18598 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18599 app.thread.scheduleTrimMemory(
18600 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
18601 } catch (RemoteException e) {
18604 app.pendingUiClean = false;
18606 app.trimMemoryLevel = 0;
18610 if (mAlwaysFinishActivities) {
18611 // Need to do this on its own message because the stack may not
18612 // be in a consistent state at this point.
18613 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
18617 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18620 if (mProcessStats.shouldWriteNowLocked(now)) {
18621 mHandler.post(new Runnable() {
18622 @Override public void run() {
18623 synchronized (ActivityManagerService.this) {
18624 mProcessStats.writeStateAsyncLocked();
18630 if (DEBUG_OOM_ADJ) {
18632 RuntimeException here = new RuntimeException("here");
18633 here.fillInStackTrace();
18634 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18636 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18641 final void trimApplications() {
18642 synchronized (this) {
18645 // First remove any unused application processes whose package
18646 // has been removed.
18647 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18648 final ProcessRecord app = mRemovedProcesses.get(i);
18649 if (app.activities.size() == 0
18650 && app.curReceiver == null && app.services.size() == 0) {
18652 TAG, "Exiting empty application process "
18653 + app.processName + " ("
18654 + (app.thread != null ? app.thread.asBinder() : null)
18656 if (app.pid > 0 && app.pid != MY_PID) {
18657 app.kill("empty", false);
18660 app.thread.scheduleExit();
18661 } catch (Exception e) {
18662 // Ignore exceptions.
18665 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
18666 mRemovedProcesses.remove(i);
18668 if (app.persistent) {
18669 addAppLocked(app.info, false, null /* ABI override */);
18674 // Now update the oom adj for all processes.
18675 updateOomAdjLocked();
18679 /** This method sends the specified signal to each of the persistent apps */
18680 public void signalPersistentProcesses(int sig) throws RemoteException {
18681 if (sig != Process.SIGNAL_USR1) {
18682 throw new SecurityException("Only SIGNAL_USR1 is allowed");
18685 synchronized (this) {
18686 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18687 != PackageManager.PERMISSION_GRANTED) {
18688 throw new SecurityException("Requires permission "
18689 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18692 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18693 ProcessRecord r = mLruProcesses.get(i);
18694 if (r.thread != null && r.persistent) {
18695 Process.sendSignal(r.pid, sig);
18701 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18702 if (proc == null || proc == mProfileProc) {
18703 proc = mProfileProc;
18704 profileType = mProfileType;
18705 clearProfilerLocked();
18707 if (proc == null) {
18711 proc.thread.profilerControl(false, null, profileType);
18712 } catch (RemoteException e) {
18713 throw new IllegalStateException("Process disappeared");
18717 private void clearProfilerLocked() {
18718 if (mProfileFd != null) {
18720 mProfileFd.close();
18721 } catch (IOException e) {
18724 mProfileApp = null;
18725 mProfileProc = null;
18726 mProfileFile = null;
18728 mAutoStopProfiler = false;
18729 mSamplingInterval = 0;
18732 public boolean profileControl(String process, int userId, boolean start,
18733 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18736 synchronized (this) {
18737 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18738 // its own permission.
18739 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18740 != PackageManager.PERMISSION_GRANTED) {
18741 throw new SecurityException("Requires permission "
18742 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18745 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18746 throw new IllegalArgumentException("null profile info or fd");
18749 ProcessRecord proc = null;
18750 if (process != null) {
18751 proc = findProcessLocked(process, userId, "profileControl");
18754 if (start && (proc == null || proc.thread == null)) {
18755 throw new IllegalArgumentException("Unknown process: " + process);
18759 stopProfilerLocked(null, 0);
18760 setProfileApp(proc.info, proc.processName, profilerInfo);
18761 mProfileProc = proc;
18762 mProfileType = profileType;
18763 ParcelFileDescriptor fd = profilerInfo.profileFd;
18766 } catch (IOException e) {
18769 profilerInfo.profileFd = fd;
18770 proc.thread.profilerControl(start, profilerInfo, profileType);
18774 stopProfilerLocked(proc, profileType);
18775 if (profilerInfo != null && profilerInfo.profileFd != null) {
18777 profilerInfo.profileFd.close();
18778 } catch (IOException e) {
18785 } catch (RemoteException e) {
18786 throw new IllegalStateException("Process disappeared");
18788 if (profilerInfo != null && profilerInfo.profileFd != null) {
18790 profilerInfo.profileFd.close();
18791 } catch (IOException e) {
18797 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18798 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18799 userId, true, ALLOW_FULL_ONLY, callName, null);
18800 ProcessRecord proc = null;
18802 int pid = Integer.parseInt(process);
18803 synchronized (mPidsSelfLocked) {
18804 proc = mPidsSelfLocked.get(pid);
18806 } catch (NumberFormatException e) {
18809 if (proc == null) {
18810 ArrayMap<String, SparseArray<ProcessRecord>> all
18811 = mProcessNames.getMap();
18812 SparseArray<ProcessRecord> procs = all.get(process);
18813 if (procs != null && procs.size() > 0) {
18814 proc = procs.valueAt(0);
18815 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18816 for (int i=1; i<procs.size(); i++) {
18817 ProcessRecord thisProc = procs.valueAt(i);
18818 if (thisProc.userId == userId) {
18830 public boolean dumpHeap(String process, int userId, boolean managed,
18831 String path, ParcelFileDescriptor fd) throws RemoteException {
18834 synchronized (this) {
18835 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18836 // its own permission (same as profileControl).
18837 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18838 != PackageManager.PERMISSION_GRANTED) {
18839 throw new SecurityException("Requires permission "
18840 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18844 throw new IllegalArgumentException("null fd");
18847 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18848 if (proc == null || proc.thread == null) {
18849 throw new IllegalArgumentException("Unknown process: " + process);
18852 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18853 if (!isDebuggable) {
18854 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18855 throw new SecurityException("Process not debuggable: " + proc);
18859 proc.thread.dumpHeap(managed, path, fd);
18863 } catch (RemoteException e) {
18864 throw new IllegalStateException("Process disappeared");
18869 } catch (IOException e) {
18875 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18876 public void monitor() {
18877 synchronized (this) { }
18880 void onCoreSettingsChange(Bundle settings) {
18881 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18882 ProcessRecord processRecord = mLruProcesses.get(i);
18884 if (processRecord.thread != null) {
18885 processRecord.thread.setCoreSettings(settings);
18887 } catch (RemoteException re) {
18893 // Multi-user methods
18896 * Start user, if its not already running, but don't bring it to foreground.
18899 public boolean startUserInBackground(final int userId) {
18900 return startUser(userId, /* foreground */ false);
18904 * Start user, if its not already running, and bring it to foreground.
18906 boolean startUserInForeground(final int userId, Dialog dlg) {
18907 boolean result = startUser(userId, /* foreground */ true);
18913 * Refreshes the list of users related to the current user when either a
18914 * user switch happens or when a new related user is started in the
18917 private void updateCurrentProfileIdsLocked() {
18918 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18919 mCurrentUserId, false /* enabledOnly */);
18920 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18921 for (int i = 0; i < currentProfileIds.length; i++) {
18922 currentProfileIds[i] = profiles.get(i).id;
18924 mCurrentProfileIds = currentProfileIds;
18926 synchronized (mUserProfileGroupIdsSelfLocked) {
18927 mUserProfileGroupIdsSelfLocked.clear();
18928 final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18929 for (int i = 0; i < users.size(); i++) {
18930 UserInfo user = users.get(i);
18931 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18932 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18938 private Set getProfileIdsLocked(int userId) {
18939 Set userIds = new HashSet<Integer>();
18940 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18941 userId, false /* enabledOnly */);
18942 for (UserInfo user : profiles) {
18943 userIds.add(Integer.valueOf(user.id));
18949 public boolean switchUser(final int userId) {
18950 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18952 synchronized (this) {
18953 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18954 if (userInfo == null) {
18955 Slog.w(TAG, "No user info for user #" + userId);
18958 if (userInfo.isManagedProfile()) {
18959 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18962 userName = userInfo.name;
18963 mTargetUserId = userId;
18965 mHandler.removeMessages(START_USER_SWITCH_MSG);
18966 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18970 private void showUserSwitchDialog(int userId, String userName) {
18971 // The dialog will show and then initiate the user switch by calling startUserInForeground
18972 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18973 true /* above system */);
18977 private boolean startUser(final int userId, final boolean foreground) {
18978 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18979 != PackageManager.PERMISSION_GRANTED) {
18980 String msg = "Permission Denial: switchUser() from pid="
18981 + Binder.getCallingPid()
18982 + ", uid=" + Binder.getCallingUid()
18983 + " requires " + INTERACT_ACROSS_USERS_FULL;
18985 throw new SecurityException(msg);
18988 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18990 final long ident = Binder.clearCallingIdentity();
18992 synchronized (this) {
18993 final int oldUserId = mCurrentUserId;
18994 if (oldUserId == userId) {
18998 mStackSupervisor.setLockTaskModeLocked(null, false, "startUser");
19000 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19001 if (userInfo == null) {
19002 Slog.w(TAG, "No user info for user #" + userId);
19005 if (foreground && userInfo.isManagedProfile()) {
19006 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19011 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19012 R.anim.screen_user_enter);
19015 boolean needStart = false;
19017 // If the user we are switching to is not currently started, then
19018 // we need to start it now.
19019 if (mStartedUsers.get(userId) == null) {
19020 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
19021 updateStartedUserArrayLocked();
19025 final Integer userIdInt = Integer.valueOf(userId);
19026 mUserLru.remove(userIdInt);
19027 mUserLru.add(userIdInt);
19030 mCurrentUserId = userId;
19031 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19032 updateCurrentProfileIdsLocked();
19033 mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19034 // Once the internal notion of the active user has switched, we lock the device
19035 // with the option to show the user switcher on the keyguard.
19036 mWindowManager.lockNow(null);
19038 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19039 updateCurrentProfileIdsLocked();
19040 mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19041 mUserLru.remove(currentUserIdInt);
19042 mUserLru.add(currentUserIdInt);
19045 final UserStartedState uss = mStartedUsers.get(userId);
19047 // Make sure user is in the started state. If it is currently
19048 // stopping, we need to knock that off.
19049 if (uss.mState == UserStartedState.STATE_STOPPING) {
19050 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19051 // so we can just fairly silently bring the user back from
19052 // the almost-dead.
19053 uss.mState = UserStartedState.STATE_RUNNING;
19054 updateStartedUserArrayLocked();
19056 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
19057 // This means ACTION_SHUTDOWN has been sent, so we will
19058 // need to treat this as a new boot of the user.
19059 uss.mState = UserStartedState.STATE_BOOTING;
19060 updateStartedUserArrayLocked();
19064 if (uss.mState == UserStartedState.STATE_BOOTING) {
19065 // Booting up a new user, need to tell system services about it.
19066 // Note that this is on the same handler as scheduling of broadcasts,
19067 // which is important because it needs to go first.
19068 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19072 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19074 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19075 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19076 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19077 oldUserId, userId, uss));
19078 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19079 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19083 // Send USER_STARTED broadcast
19084 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19085 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19086 | Intent.FLAG_RECEIVER_FOREGROUND);
19087 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19088 broadcastIntentLocked(null, null, intent,
19089 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19090 false, false, MY_PID, Process.SYSTEM_UID, userId);
19093 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19094 if (userId != UserHandle.USER_OWNER) {
19095 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19096 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19097 broadcastIntentLocked(null, null, intent, null,
19098 new IIntentReceiver.Stub() {
19099 public void performReceive(Intent intent, int resultCode,
19100 String data, Bundle extras, boolean ordered,
19101 boolean sticky, int sendingUser) {
19102 onUserInitialized(uss, foreground, oldUserId, userId);
19104 }, 0, null, null, null, AppOpsManager.OP_NONE,
19105 true, false, MY_PID, Process.SYSTEM_UID,
19107 uss.initializing = true;
19109 getUserManagerLocked().makeInitialized(userInfo.id);
19114 if (!uss.initializing) {
19115 moveUserToForeground(uss, oldUserId, userId);
19118 mStackSupervisor.startBackgroundUserLocked(userId, uss);
19122 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19123 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19124 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19125 broadcastIntentLocked(null, null, intent,
19126 null, new IIntentReceiver.Stub() {
19128 public void performReceive(Intent intent, int resultCode, String data,
19129 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
19130 throws RemoteException {
19133 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19134 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19138 Binder.restoreCallingIdentity(ident);
19144 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
19145 long ident = Binder.clearCallingIdentity();
19148 if (oldUserId >= 0) {
19149 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
19150 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
19151 int count = profiles.size();
19152 for (int i = 0; i < count; i++) {
19153 int profileUserId = profiles.get(i).id;
19154 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
19155 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19156 | Intent.FLAG_RECEIVER_FOREGROUND);
19157 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19158 broadcastIntentLocked(null, null, intent,
19159 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19160 false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19163 if (newUserId >= 0) {
19164 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
19165 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
19166 int count = profiles.size();
19167 for (int i = 0; i < count; i++) {
19168 int profileUserId = profiles.get(i).id;
19169 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
19170 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19171 | Intent.FLAG_RECEIVER_FOREGROUND);
19172 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
19173 broadcastIntentLocked(null, null, intent,
19174 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19175 false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
19177 intent = new Intent(Intent.ACTION_USER_SWITCHED);
19178 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19179 | Intent.FLAG_RECEIVER_FOREGROUND);
19180 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
19181 broadcastIntentLocked(null, null, intent,
19182 null, null, 0, null, null,
19183 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
19184 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19187 Binder.restoreCallingIdentity(ident);
19191 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
19192 final int newUserId) {
19193 final int N = mUserSwitchObservers.beginBroadcast();
19195 final IRemoteCallback callback = new IRemoteCallback.Stub() {
19198 public void sendResult(Bundle data) throws RemoteException {
19199 synchronized (ActivityManagerService.this) {
19200 if (mCurUserSwitchCallback == this) {
19203 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19209 synchronized (this) {
19210 uss.switching = true;
19211 mCurUserSwitchCallback = callback;
19213 for (int i=0; i<N; i++) {
19215 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
19216 newUserId, callback);
19217 } catch (RemoteException e) {
19221 synchronized (this) {
19222 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19225 mUserSwitchObservers.finishBroadcast();
19228 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19229 synchronized (this) {
19230 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
19231 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
19235 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
19236 mCurUserSwitchCallback = null;
19237 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19238 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
19239 oldUserId, newUserId, uss));
19242 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
19243 synchronized (this) {
19245 moveUserToForeground(uss, oldUserId, newUserId);
19249 completeSwitchAndInitalize(uss, newUserId, true, false);
19252 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
19253 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
19255 startHomeActivityLocked(newUserId, "moveUserToFroreground");
19257 mStackSupervisor.resumeTopActivitiesLocked();
19259 EventLogTags.writeAmSwitchUser(newUserId);
19260 getUserManagerLocked().userForeground(newUserId);
19261 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
19264 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
19265 completeSwitchAndInitalize(uss, newUserId, false, true);
19268 void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
19269 boolean clearInitializing, boolean clearSwitching) {
19270 boolean unfrozen = false;
19271 synchronized (this) {
19272 if (clearInitializing) {
19273 uss.initializing = false;
19274 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
19276 if (clearSwitching) {
19277 uss.switching = false;
19279 if (!uss.switching && !uss.initializing) {
19280 mWindowManager.stopFreezingScreen();
19285 final int N = mUserSwitchObservers.beginBroadcast();
19286 for (int i=0; i<N; i++) {
19288 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
19289 } catch (RemoteException e) {
19292 mUserSwitchObservers.finishBroadcast();
19294 stopGuestUserIfBackground();
19298 * Stops the guest user if it has gone to the background.
19300 private void stopGuestUserIfBackground() {
19301 synchronized (this) {
19302 final int num = mUserLru.size();
19303 for (int i = 0; i < num; i++) {
19304 Integer oldUserId = mUserLru.get(i);
19305 UserStartedState oldUss = mStartedUsers.get(oldUserId);
19306 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
19307 || oldUss.mState == UserStartedState.STATE_STOPPING
19308 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19311 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
19312 if (userInfo.isGuest()) {
19313 // This is a user to be stopped.
19314 stopUserLocked(oldUserId, null);
19321 void scheduleStartProfilesLocked() {
19322 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
19323 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
19324 DateUtils.SECOND_IN_MILLIS);
19328 void startProfilesLocked() {
19329 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
19330 List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19331 mCurrentUserId, false /* enabledOnly */);
19332 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
19333 for (UserInfo user : profiles) {
19334 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
19335 && user.id != mCurrentUserId) {
19339 final int n = toStart.size();
19341 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
19342 startUserInBackground(toStart.get(i).id);
19345 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
19349 void finishUserBoot(UserStartedState uss) {
19350 synchronized (this) {
19351 if (uss.mState == UserStartedState.STATE_BOOTING
19352 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
19353 uss.mState = UserStartedState.STATE_RUNNING;
19354 final int userId = uss.mHandle.getIdentifier();
19355 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
19356 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19357 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
19358 broadcastIntentLocked(null, null, intent,
19359 null, null, 0, null, null,
19360 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
19361 true, false, MY_PID, Process.SYSTEM_UID, userId);
19366 void finishUserSwitch(UserStartedState uss) {
19367 synchronized (this) {
19368 finishUserBoot(uss);
19370 startProfilesLocked();
19372 int num = mUserLru.size();
19374 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
19375 Integer oldUserId = mUserLru.get(i);
19376 UserStartedState oldUss = mStartedUsers.get(oldUserId);
19377 if (oldUss == null) {
19378 // Shouldn't happen, but be sane if it does.
19379 mUserLru.remove(i);
19383 if (oldUss.mState == UserStartedState.STATE_STOPPING
19384 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
19385 // This user is already stopping, doesn't count.
19390 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
19391 // Owner and current can't be stopped, but count as running.
19395 // This is a user to be stopped.
19396 stopUserLocked(oldUserId, null);
19404 public int stopUser(final int userId, final IStopUserCallback callback) {
19405 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19406 != PackageManager.PERMISSION_GRANTED) {
19407 String msg = "Permission Denial: switchUser() from pid="
19408 + Binder.getCallingPid()
19409 + ", uid=" + Binder.getCallingUid()
19410 + " requires " + INTERACT_ACROSS_USERS_FULL;
19412 throw new SecurityException(msg);
19415 throw new IllegalArgumentException("Can't stop primary user " + userId);
19417 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19418 synchronized (this) {
19419 return stopUserLocked(userId, callback);
19423 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
19424 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
19425 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
19426 return ActivityManager.USER_OP_IS_CURRENT;
19429 final UserStartedState uss = mStartedUsers.get(userId);
19431 // User is not started, nothing to do... but we do need to
19432 // callback if requested.
19433 if (callback != null) {
19434 mHandler.post(new Runnable() {
19436 public void run() {
19438 callback.userStopped(userId);
19439 } catch (RemoteException e) {
19444 return ActivityManager.USER_OP_SUCCESS;
19447 if (callback != null) {
19448 uss.mStopCallbacks.add(callback);
19451 if (uss.mState != UserStartedState.STATE_STOPPING
19452 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19453 uss.mState = UserStartedState.STATE_STOPPING;
19454 updateStartedUserArrayLocked();
19456 long ident = Binder.clearCallingIdentity();
19458 // We are going to broadcast ACTION_USER_STOPPING and then
19459 // once that is done send a final ACTION_SHUTDOWN and then
19461 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
19462 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19463 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19464 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
19465 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
19466 // This is the result receiver for the final shutdown broadcast.
19467 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
19469 public void performReceive(Intent intent, int resultCode, String data,
19470 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19471 finishUserStop(uss);
19474 // This is the result receiver for the initial stopping broadcast.
19475 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
19477 public void performReceive(Intent intent, int resultCode, String data,
19478 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
19480 synchronized (ActivityManagerService.this) {
19481 if (uss.mState != UserStartedState.STATE_STOPPING) {
19482 // Whoops, we are being started back up. Abort, abort!
19485 uss.mState = UserStartedState.STATE_SHUTDOWN;
19487 mBatteryStatsService.noteEvent(
19488 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
19489 Integer.toString(userId), userId);
19490 mSystemServiceManager.stopUser(userId);
19491 broadcastIntentLocked(null, null, shutdownIntent,
19492 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
19493 true, false, MY_PID, Process.SYSTEM_UID, userId);
19496 // Kick things off.
19497 broadcastIntentLocked(null, null, stoppingIntent,
19498 null, stoppingReceiver, 0, null, null,
19499 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
19500 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19502 Binder.restoreCallingIdentity(ident);
19506 return ActivityManager.USER_OP_SUCCESS;
19509 void finishUserStop(UserStartedState uss) {
19510 final int userId = uss.mHandle.getIdentifier();
19512 ArrayList<IStopUserCallback> callbacks;
19513 synchronized (this) {
19514 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
19515 if (mStartedUsers.get(userId) != uss) {
19517 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
19521 // User can no longer run.
19522 mStartedUsers.remove(userId);
19523 mUserLru.remove(Integer.valueOf(userId));
19524 updateStartedUserArrayLocked();
19526 // Clean up all state and processes associated with the user.
19527 // Kill all the processes for the user.
19528 forceStopUserLocked(userId, "finish user");
19531 // Explicitly remove the old information in mRecentTasks.
19532 removeRecentTasksForUserLocked(userId);
19535 for (int i=0; i<callbacks.size(); i++) {
19537 if (stopped) callbacks.get(i).userStopped(userId);
19538 else callbacks.get(i).userStopAborted(userId);
19539 } catch (RemoteException e) {
19544 mSystemServiceManager.cleanupUser(userId);
19545 synchronized (this) {
19546 mStackSupervisor.removeUserLocked(userId);
19552 public UserInfo getCurrentUser() {
19553 if ((checkCallingPermission(INTERACT_ACROSS_USERS)
19554 != PackageManager.PERMISSION_GRANTED) && (
19555 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19556 != PackageManager.PERMISSION_GRANTED)) {
19557 String msg = "Permission Denial: getCurrentUser() from pid="
19558 + Binder.getCallingPid()
19559 + ", uid=" + Binder.getCallingUid()
19560 + " requires " + INTERACT_ACROSS_USERS;
19562 throw new SecurityException(msg);
19564 synchronized (this) {
19565 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19566 return getUserManagerLocked().getUserInfo(userId);
19570 int getCurrentUserIdLocked() {
19571 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
19575 public boolean isUserRunning(int userId, boolean orStopped) {
19576 if (checkCallingPermission(INTERACT_ACROSS_USERS)
19577 != PackageManager.PERMISSION_GRANTED) {
19578 String msg = "Permission Denial: isUserRunning() from pid="
19579 + Binder.getCallingPid()
19580 + ", uid=" + Binder.getCallingUid()
19581 + " requires " + INTERACT_ACROSS_USERS;
19583 throw new SecurityException(msg);
19585 synchronized (this) {
19586 return isUserRunningLocked(userId, orStopped);
19590 boolean isUserRunningLocked(int userId, boolean orStopped) {
19591 UserStartedState state = mStartedUsers.get(userId);
19592 if (state == null) {
19598 return state.mState != UserStartedState.STATE_STOPPING
19599 && state.mState != UserStartedState.STATE_SHUTDOWN;
19603 public int[] getRunningUserIds() {
19604 if (checkCallingPermission(INTERACT_ACROSS_USERS)
19605 != PackageManager.PERMISSION_GRANTED) {
19606 String msg = "Permission Denial: isUserRunning() from pid="
19607 + Binder.getCallingPid()
19608 + ", uid=" + Binder.getCallingUid()
19609 + " requires " + INTERACT_ACROSS_USERS;
19611 throw new SecurityException(msg);
19613 synchronized (this) {
19614 return mStartedUserArray;
19618 private void updateStartedUserArrayLocked() {
19620 for (int i=0; i<mStartedUsers.size(); i++) {
19621 UserStartedState uss = mStartedUsers.valueAt(i);
19622 // This list does not include stopping users.
19623 if (uss.mState != UserStartedState.STATE_STOPPING
19624 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19628 mStartedUserArray = new int[num];
19630 for (int i=0; i<mStartedUsers.size(); i++) {
19631 UserStartedState uss = mStartedUsers.valueAt(i);
19632 if (uss.mState != UserStartedState.STATE_STOPPING
19633 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
19634 mStartedUserArray[num] = mStartedUsers.keyAt(i);
19641 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
19642 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19643 != PackageManager.PERMISSION_GRANTED) {
19644 String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19645 + Binder.getCallingPid()
19646 + ", uid=" + Binder.getCallingUid()
19647 + " requires " + INTERACT_ACROSS_USERS_FULL;
19649 throw new SecurityException(msg);
19652 mUserSwitchObservers.register(observer);
19656 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19657 mUserSwitchObservers.unregister(observer);
19660 private boolean userExists(int userId) {
19664 UserManagerService ums = getUserManagerLocked();
19665 return ums != null ? (ums.getUserInfo(userId) != null) : false;
19668 int[] getUsersLocked() {
19669 UserManagerService ums = getUserManagerLocked();
19670 return ums != null ? ums.getUserIds() : new int[] { 0 };
19673 UserManagerService getUserManagerLocked() {
19674 if (mUserManager == null) {
19675 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19676 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19678 return mUserManager;
19681 private int applyUserId(int uid, int userId) {
19682 return UserHandle.getUid(userId, uid);
19685 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19686 if (info == null) return null;
19687 ApplicationInfo newInfo = new ApplicationInfo(info);
19688 newInfo.uid = applyUserId(info.uid, userId);
19689 newInfo.dataDir = USER_DATA_DIR + userId + "/"
19690 + info.packageName;
19694 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19696 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19700 ActivityInfo info = new ActivityInfo(aInfo);
19701 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19705 private final class LocalService extends ActivityManagerInternal {
19707 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
19708 int targetUserId) {
19709 synchronized (ActivityManagerService.this) {
19710 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
19711 targetPkg, intent, null, targetUserId);
19716 public String checkContentProviderAccess(String authority, int userId) {
19717 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
19721 public void onWakefulnessChanged(int wakefulness) {
19722 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19726 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19727 String processName, String abiOverride, int uid, Runnable crashHandler) {
19728 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19729 processName, abiOverride, uid, crashHandler);
19734 * An implementation of IAppTask, that allows an app to manage its own tasks via
19735 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
19736 * only the process that calls getAppTasks() can call the AppTask methods.
19738 class AppTaskImpl extends IAppTask.Stub {
19739 private int mTaskId;
19740 private int mCallingUid;
19742 public AppTaskImpl(int taskId, int callingUid) {
19744 mCallingUid = callingUid;
19747 private void checkCaller() {
19748 if (mCallingUid != Binder.getCallingUid()) {
19749 throw new SecurityException("Caller " + mCallingUid
19750 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19755 public void finishAndRemoveTask() {
19758 synchronized (ActivityManagerService.this) {
19759 long origId = Binder.clearCallingIdentity();
19761 if (!removeTaskByIdLocked(mTaskId, false)) {
19762 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19765 Binder.restoreCallingIdentity(origId);
19771 public ActivityManager.RecentTaskInfo getTaskInfo() {
19774 synchronized (ActivityManagerService.this) {
19775 long origId = Binder.clearCallingIdentity();
19777 TaskRecord tr = recentTaskForIdLocked(mTaskId);
19779 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19781 return createRecentTaskInfoFromTaskRecord(tr);
19783 Binder.restoreCallingIdentity(origId);
19789 public void moveToFront() {
19791 // Will bring task to front if it already has a root activity.
19792 startActivityFromRecentsInner(mTaskId, null);
19796 public int startActivity(IBinder whoThread, String callingPackage,
19797 Intent intent, String resolvedType, Bundle options) {
19800 int callingUser = UserHandle.getCallingUserId();
19802 IApplicationThread appThread;
19803 synchronized (ActivityManagerService.this) {
19804 tr = recentTaskForIdLocked(mTaskId);
19806 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19808 appThread = ApplicationThreadNative.asInterface(whoThread);
19809 if (appThread == null) {
19810 throw new IllegalArgumentException("Bad app thread " + appThread);
19813 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19814 resolvedType, null, null, null, null, 0, 0, null, null,
19815 null, options, callingUser, null, tr);
19819 public void setExcludeFromRecents(boolean exclude) {
19822 synchronized (ActivityManagerService.this) {
19823 long origId = Binder.clearCallingIdentity();
19825 TaskRecord tr = recentTaskForIdLocked(mTaskId);
19827 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19829 Intent intent = tr.getBaseIntent();
19831 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19833 intent.setFlags(intent.getFlags()
19834 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19837 Binder.restoreCallingIdentity(origId);