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.content.pm.PackageManager.PERMISSION_GRANTED;
21 import com.android.internal.R;
22 import com.android.internal.os.BatteryStatsImpl;
23 import com.android.internal.os.ProcessStats;
24 import com.android.server.AttributeCache;
25 import com.android.server.IntentResolver;
26 import com.android.server.ProcessMap;
27 import com.android.server.SystemServer;
28 import com.android.server.Watchdog;
29 import com.android.server.am.ActivityStack.ActivityState;
30 import com.android.server.pm.UserManagerService;
31 import com.android.server.wm.WindowManagerService;
33 import dalvik.system.Zygote;
35 import android.app.Activity;
36 import android.app.ActivityManager;
37 import android.app.ActivityManagerNative;
38 import android.app.ActivityOptions;
39 import android.app.ActivityThread;
40 import android.app.AlertDialog;
41 import android.app.AppGlobals;
42 import android.app.ApplicationErrorReport;
43 import android.app.Dialog;
44 import android.app.IActivityController;
45 import android.app.IApplicationThread;
46 import android.app.IInstrumentationWatcher;
47 import android.app.INotificationManager;
48 import android.app.IProcessObserver;
49 import android.app.IServiceConnection;
50 import android.app.IStopUserCallback;
51 import android.app.IThumbnailReceiver;
52 import android.app.IUserSwitchObserver;
53 import android.app.Instrumentation;
54 import android.app.Notification;
55 import android.app.NotificationManager;
56 import android.app.PendingIntent;
57 import android.app.backup.IBackupManager;
58 import android.content.ActivityNotFoundException;
59 import android.content.BroadcastReceiver;
60 import android.content.ClipData;
61 import android.content.ComponentCallbacks2;
62 import android.content.ComponentName;
63 import android.content.ContentProvider;
64 import android.content.ContentResolver;
65 import android.content.Context;
66 import android.content.DialogInterface;
67 import android.content.IContentProvider;
68 import android.content.IIntentReceiver;
69 import android.content.IIntentSender;
70 import android.content.Intent;
71 import android.content.IntentFilter;
72 import android.content.IntentSender;
73 import android.content.pm.ActivityInfo;
74 import android.content.pm.ApplicationInfo;
75 import android.content.pm.ConfigurationInfo;
76 import android.content.pm.IPackageDataObserver;
77 import android.content.pm.IPackageManager;
78 import android.content.pm.InstrumentationInfo;
79 import android.content.pm.PackageInfo;
80 import android.content.pm.PackageManager;
81 import android.content.pm.UserInfo;
82 import android.content.pm.PackageManager.NameNotFoundException;
83 import android.content.pm.PathPermission;
84 import android.content.pm.ProviderInfo;
85 import android.content.pm.ResolveInfo;
86 import android.content.pm.ServiceInfo;
87 import android.content.res.CompatibilityInfo;
88 import android.content.res.Configuration;
89 import android.graphics.Bitmap;
90 import android.net.Proxy;
91 import android.net.ProxyProperties;
92 import android.net.Uri;
93 import android.os.Binder;
94 import android.os.Build;
95 import android.os.Bundle;
96 import android.os.Debug;
97 import android.os.DropBoxManager;
98 import android.os.Environment;
99 import android.os.FileObserver;
100 import android.os.FileUtils;
101 import android.os.Handler;
102 import android.os.IBinder;
103 import android.os.IPermissionController;
104 import android.os.IRemoteCallback;
105 import android.os.IUserManager;
106 import android.os.Looper;
107 import android.os.Message;
108 import android.os.Parcel;
109 import android.os.ParcelFileDescriptor;
110 import android.os.Process;
111 import android.os.RemoteCallbackList;
112 import android.os.RemoteException;
113 import android.os.SELinux;
114 import android.os.ServiceManager;
115 import android.os.StrictMode;
116 import android.os.SystemClock;
117 import android.os.SystemProperties;
118 import android.os.UpdateLock;
119 import android.os.UserHandle;
120 import android.provider.Settings;
121 import android.text.format.Time;
122 import android.util.EventLog;
123 import android.util.Log;
124 import android.util.Pair;
125 import android.util.PrintWriterPrinter;
126 import android.util.Slog;
127 import android.util.SparseArray;
128 import android.util.TimeUtils;
129 import android.view.Gravity;
130 import android.view.LayoutInflater;
131 import android.view.View;
132 import android.view.WindowManager;
133 import android.view.WindowManagerPolicy;
135 import java.io.BufferedInputStream;
136 import java.io.BufferedOutputStream;
137 import java.io.BufferedReader;
138 import java.io.DataInputStream;
139 import java.io.DataOutputStream;
141 import java.io.FileDescriptor;
142 import java.io.FileInputStream;
143 import java.io.FileNotFoundException;
144 import java.io.FileOutputStream;
145 import java.io.IOException;
146 import java.io.InputStreamReader;
147 import java.io.PrintWriter;
148 import java.io.StringWriter;
149 import java.lang.ref.WeakReference;
150 import java.util.ArrayList;
151 import java.util.Arrays;
152 import java.util.Collections;
153 import java.util.Comparator;
154 import java.util.HashMap;
155 import java.util.HashSet;
156 import java.util.Iterator;
157 import java.util.List;
158 import java.util.Locale;
159 import java.util.Map;
160 import java.util.Set;
161 import java.util.concurrent.atomic.AtomicBoolean;
162 import java.util.concurrent.atomic.AtomicLong;
164 public final class ActivityManagerService extends ActivityManagerNative
165 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
166 private static final String USER_DATA_DIR = "/data/user/";
167 static final String TAG = "ActivityManager";
168 static final String TAG_MU = "ActivityManagerServiceMU";
169 static final boolean DEBUG = false;
170 static final boolean localLOGV = DEBUG;
171 static final boolean DEBUG_SWITCH = localLOGV || false;
172 static final boolean DEBUG_TASKS = localLOGV || false;
173 static final boolean DEBUG_THUMBNAILS = localLOGV || false;
174 static final boolean DEBUG_PAUSE = localLOGV || false;
175 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
176 static final boolean DEBUG_TRANSITION = localLOGV || false;
177 static final boolean DEBUG_BROADCAST = localLOGV || false;
178 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
179 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
180 static final boolean DEBUG_SERVICE = localLOGV || false;
181 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
182 static final boolean DEBUG_VISBILITY = localLOGV || false;
183 static final boolean DEBUG_PROCESSES = localLOGV || false;
184 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
185 static final boolean DEBUG_CLEANUP = localLOGV || false;
186 static final boolean DEBUG_PROVIDER = localLOGV || false;
187 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
188 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
189 static final boolean DEBUG_RESULTS = localLOGV || false;
190 static final boolean DEBUG_BACKUP = localLOGV || false;
191 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
192 static final boolean DEBUG_POWER = localLOGV || false;
193 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
194 static final boolean DEBUG_MU = localLOGV || false;
195 static final boolean DEBUG_IMMERSIVE = localLOGV || false;
196 static final boolean VALIDATE_TOKENS = false;
197 static final boolean SHOW_ACTIVITY_START_TIME = true;
199 // Control over CPU and battery monitoring.
200 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
201 static final boolean MONITOR_CPU_USAGE = true;
202 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
203 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
204 static final boolean MONITOR_THREAD_CPU_USAGE = false;
206 // The flags that are set for all calls we make to the package manager.
207 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
209 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
211 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
213 // Maximum number of recent tasks that we can remember.
214 static final int MAX_RECENT_TASKS = 20;
216 // Amount of time after a call to stopAppSwitches() during which we will
217 // prevent further untrusted switches from happening.
218 static final long APP_SWITCH_DELAY_TIME = 5*1000;
220 // How long we wait for a launched process to attach to the activity manager
221 // before we decide it's never going to come up for real.
222 static final int PROC_START_TIMEOUT = 10*1000;
224 // How long we wait for a launched process to attach to the activity manager
225 // before we decide it's never going to come up for real, when the process was
226 // started with a wrapper for instrumentation (such as Valgrind) because it
227 // could take much longer than usual.
228 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
230 // How long to wait after going idle before forcing apps to GC.
231 static final int GC_TIMEOUT = 5*1000;
233 // The minimum amount of time between successive GC requests for a process.
234 static final int GC_MIN_INTERVAL = 60*1000;
236 // The rate at which we check for apps using excessive power -- 15 mins.
237 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
239 // The minimum sample duration we will allow before deciding we have
240 // enough data on wake locks to start killing things.
241 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
243 // The minimum sample duration we will allow before deciding we have
244 // enough data on CPU usage to start killing things.
245 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
247 // How long we allow a receiver to run before giving up on it.
248 static final int BROADCAST_FG_TIMEOUT = 10*1000;
249 static final int BROADCAST_BG_TIMEOUT = 60*1000;
251 // How long we wait until we timeout on key dispatching.
252 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
254 // How long we wait until we timeout on key dispatching during instrumentation.
255 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
257 // Amount of time we wait for observers to handle a user switch before
258 // giving up on them and unfreezing the screen.
259 static final int USER_SWITCH_TIMEOUT = 2*1000;
261 // Maximum number of users we allow to be running at a time.
262 static final int MAX_RUNNING_USERS = 3;
264 static final int MY_PID = Process.myPid();
266 static final String[] EMPTY_STRING_ARRAY = new String[0];
268 public ActivityStack mMainStack;
270 private final boolean mHeadless;
272 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
273 // default actuion automatically. Important for devices without direct input
275 private boolean mShowDialogs = true;
278 * Description of a request to start a new activity, which has been held
279 * due to app switches being disabled.
281 static class PendingActivityLaunch {
283 ActivityRecord sourceRecord;
287 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
288 = new ArrayList<PendingActivityLaunch>();
291 BroadcastQueue mFgBroadcastQueue;
292 BroadcastQueue mBgBroadcastQueue;
293 // Convenient for easy iteration over the queues. Foreground is first
294 // so that dispatch of foreground broadcasts gets precedence.
295 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
297 BroadcastQueue broadcastQueueForIntent(Intent intent) {
298 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
299 if (DEBUG_BACKGROUND_BROADCAST) {
300 Slog.i(TAG, "Broadcast intent " + intent + " on "
301 + (isFg ? "foreground" : "background")
304 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
307 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
308 for (BroadcastQueue queue : mBroadcastQueues) {
309 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
318 * Activity we have told the window manager to have key focus.
320 ActivityRecord mFocusedActivity = null;
322 * List of intents that were used to start the most recent tasks.
324 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
327 * Process management.
329 final ProcessList mProcessList = new ProcessList();
332 * All of the applications we currently have running organized by name.
333 * The keys are strings of the application package name (as
334 * returned by the package manager), and the keys are ApplicationRecord
337 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
340 * The currently running isolated processes.
342 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
345 * Counter for assigning isolated process uids, to avoid frequently reusing the
348 int mNextIsolatedProcessUid = 0;
351 * The currently running heavy-weight process, if any.
353 ProcessRecord mHeavyWeightProcess = null;
356 * The last time that various processes have crashed.
358 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
361 * Set of applications that we consider to be bad, and will reject
362 * incoming broadcasts from (which the user has no control over).
363 * Processes are added to this set when they have crashed twice within
364 * a minimum amount of time; they are removed from it when they are
365 * later restarted (hopefully due to some user action). The value is the
366 * time it was added to the list.
368 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
371 * All of the processes we currently have running organized by pid.
372 * The keys are the pid running the application.
374 * <p>NOTE: This object is protected by its own lock, NOT the global
375 * activity manager lock!
377 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
380 * All of the processes that have been forced to be foreground. The key
381 * is the pid of the caller who requested it (we hold a death
384 abstract class ForegroundToken implements IBinder.DeathRecipient {
388 final SparseArray<ForegroundToken> mForegroundProcesses
389 = new SparseArray<ForegroundToken>();
392 * List of records for processes that someone had tried to start before the
393 * system was ready. We don't start them at that point, but ensure they
394 * are started by the time booting is complete.
396 final ArrayList<ProcessRecord> mProcessesOnHold
397 = new ArrayList<ProcessRecord>();
400 * List of persistent applications that are in the process
403 final ArrayList<ProcessRecord> mPersistentStartingProcesses
404 = new ArrayList<ProcessRecord>();
407 * Processes that are being forcibly torn down.
409 final ArrayList<ProcessRecord> mRemovedProcesses
410 = new ArrayList<ProcessRecord>();
413 * List of running applications, sorted by recent usage.
414 * The first entry in the list is the least recently used.
415 * It contains ApplicationRecord objects. This list does NOT include
416 * any persistent application records (since we never want to exit them).
418 final ArrayList<ProcessRecord> mLruProcesses
419 = new ArrayList<ProcessRecord>();
422 * List of processes that should gc as soon as things are idle.
424 final ArrayList<ProcessRecord> mProcessesToGc
425 = new ArrayList<ProcessRecord>();
428 * This is the process holding what we currently consider to be
429 * the "home" activity.
431 ProcessRecord mHomeProcess;
434 * This is the process holding the activity the user last visited that
435 * is in a different process from the one they are currently in.
437 ProcessRecord mPreviousProcess;
440 * The time at which the previous process was last visible.
442 long mPreviousProcessVisibleTime;
445 * Which uses have been started, so are allowed to run code.
447 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
450 * LRU list of history of current users. Most recently current is at the end.
452 final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
455 * Constant array of the users that are currently started.
457 int[] mStartedUserArray = new int[] { 0 };
460 * Registered observers of the user switching mechanics.
462 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
463 = new RemoteCallbackList<IUserSwitchObserver>();
466 * Currently active user switch.
468 Object mCurUserSwitchCallback;
471 * Packages that the user has asked to have run in screen size
472 * compatibility mode instead of filling the screen.
474 final CompatModePackages mCompatModePackages;
477 * Set of PendingResultRecord objects that are currently active.
479 final HashSet mPendingResultRecords = new HashSet();
482 * Set of IntentSenderRecord objects that are currently active.
484 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
485 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
488 * Fingerprints (hashCode()) of stack traces that we've
489 * already logged DropBox entries for. Guarded by itself. If
490 * something (rogue user app) forces this over
491 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
493 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
494 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
497 * Strict Mode background batched logging state.
499 * The string buffer is guarded by itself, and its lock is also
500 * used to determine if another batched write is already
503 private final StringBuilder mStrictModeBuffer = new StringBuilder();
506 * Keeps track of all IIntentReceivers that have been registered for
507 * broadcasts. Hash keys are the receiver IBinder, hash value is
510 final HashMap mRegisteredReceivers = new HashMap();
513 * Resolver for broadcast intents to registered receivers.
514 * Holds BroadcastFilter (subclass of IntentFilter).
516 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
517 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
519 protected boolean allowFilterResult(
520 BroadcastFilter filter, List<BroadcastFilter> dest) {
521 IBinder target = filter.receiverList.receiver.asBinder();
522 for (int i=dest.size()-1; i>=0; i--) {
523 if (dest.get(i).receiverList.receiver.asBinder() == target) {
531 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
532 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
533 || userId == filter.owningUserId) {
534 return super.newResult(filter, match, userId);
540 protected BroadcastFilter[] newArray(int size) {
541 return new BroadcastFilter[size];
545 protected String packageForFilter(BroadcastFilter filter) {
546 return filter.packageName;
551 * State of all active sticky broadcasts per user. Keys are the action of the
552 * sticky Intent, values are an ArrayList of all broadcasted intents with
553 * that action (which should usually be one). The SparseArray is keyed
554 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
555 * for stickies that are sent to all users.
557 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
558 new SparseArray<HashMap<String, ArrayList<Intent>>>();
560 final ActiveServices mServices;
563 * Backup/restore process management
565 String mBackupAppName = null;
566 BackupRecord mBackupTarget = null;
569 * List of PendingThumbnailsRecord objects of clients who are still
570 * waiting to receive all of the thumbnails for a task.
572 final ArrayList mPendingThumbnails = new ArrayList();
575 * List of HistoryRecord objects that have been finished and must
576 * still report back to a pending thumbnail receiver.
578 final ArrayList mCancelledThumbnails = new ArrayList();
580 final ProviderMap mProviderMap;
583 * List of content providers who have clients waiting for them. The
584 * application is currently being launched and the provider will be
585 * removed from this list once it is published.
587 final ArrayList<ContentProviderRecord> mLaunchingProviders
588 = new ArrayList<ContentProviderRecord>();
591 * Global set of specific Uri permissions that have been granted.
593 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
594 = new SparseArray<HashMap<Uri, UriPermission>>();
596 CoreSettingsObserver mCoreSettingsObserver;
599 * Thread-local storage used to carry caller permissions over through
600 * indirect content-provider access.
601 * @see #ActivityManagerService.openContentUri()
603 private class Identity {
607 Identity(int _pid, int _uid) {
613 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
616 * All information we have collected about the runtime performance of
617 * any user id that can impact battery performance.
619 final BatteryStatsService mBatteryStatsService;
622 * information about component usage
624 final UsageStatsService mUsageStatsService;
627 * Current configuration information. HistoryRecord objects are given
628 * a reference to this object to indicate which configuration they are
629 * currently running in, so this object must be kept immutable.
631 Configuration mConfiguration = new Configuration();
634 * Current sequencing integer of the configuration, for skipping old
637 int mConfigurationSeq = 0;
640 * Hardware-reported OpenGLES version.
642 final int GL_ES_VERSION;
645 * List of initialization arguments to pass to all processes when binding applications to them.
646 * For example, references to the commonly used services.
648 HashMap<String, IBinder> mAppBindArgs;
651 * Temporary to avoid allocations. Protected by main lock.
653 final StringBuilder mStringBuilder = new StringBuilder(256);
656 * Used to control how we initialize the service.
658 boolean mStartRunning = false;
659 ComponentName mTopComponent;
662 boolean mProcessesReady = false;
663 boolean mSystemReady = false;
664 boolean mBooting = false;
665 boolean mWaitingUpdate = false;
666 boolean mDidUpdate = false;
667 boolean mOnBattery = false;
668 boolean mLaunchWarningShown = false;
674 boolean mCheckedForSetup;
677 * The time at which we will allow normal application switches again,
678 * after a call to {@link #stopAppSwitches()}.
680 long mAppSwitchesAllowedTime;
683 * This is set to true after the first switch after mAppSwitchesAllowedTime
684 * is set; any switches after that will clear the time.
686 boolean mDidAppSwitch;
689 * Last time (in realtime) at which we checked for power usage.
691 long mLastPowerCheckRealtime;
694 * Last time (in uptime) at which we checked for power usage.
696 long mLastPowerCheckUptime;
699 * Set while we are wanting to sleep, to prevent any
700 * activities from being started/resumed.
702 boolean mSleeping = false;
705 * State of external calls telling us if the device is asleep.
707 boolean mWentToSleep = false;
710 * State of external call telling us if the lock screen is shown.
712 boolean mLockScreenShown = false;
715 * Set if we are shutting down the system, similar to sleeping.
717 boolean mShuttingDown = false;
720 * Task identifier that activities are currently being started
721 * in. Incremented each time a new task is created.
722 * todo: Replace this with a TokenSpace class that generates non-repeating
723 * integers that won't wrap.
728 * Current sequence id for oom_adj computation traversal.
733 * Current sequence id for process LRU updating.
738 * Keep track of the non-hidden/empty process we last found, to help
739 * determine how to distribute hidden/empty processes next time.
741 int mNumNonHiddenProcs = 0;
744 * Keep track of the number of hidden procs, to balance oom adj
745 * distribution between those and empty procs.
747 int mNumHiddenProcs = 0;
750 * Keep track of the number of service processes we last found, to
751 * determine on the next iteration which should be B services.
753 int mNumServiceProcs = 0;
754 int mNewNumServiceProcs = 0;
757 * System monitoring: number of processes that died since the last
758 * N procs were started.
760 int[] mProcDeaths = new int[20];
763 * This is set if we had to do a delayed dexopt of an app before launching
764 * it, to increasing the ANR timeouts in that case.
768 String mDebugApp = null;
769 boolean mWaitForDebugger = false;
770 boolean mDebugTransient = false;
771 String mOrigDebugApp = null;
772 boolean mOrigWaitForDebugger = false;
773 boolean mAlwaysFinishActivities = false;
774 IActivityController mController = null;
775 String mProfileApp = null;
776 ProcessRecord mProfileProc = null;
778 ParcelFileDescriptor mProfileFd;
779 int mProfileType = 0;
780 boolean mAutoStopProfiler = false;
781 String mOpenGlTraceApp = null;
783 static class ProcessChangeItem {
784 static final int CHANGE_ACTIVITIES = 1<<0;
785 static final int CHANGE_IMPORTANCE= 1<<1;
790 boolean foregroundActivities;
793 final RemoteCallbackList<IProcessObserver> mProcessObservers
794 = new RemoteCallbackList<IProcessObserver>();
795 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
797 final ArrayList<ProcessChangeItem> mPendingProcessChanges
798 = new ArrayList<ProcessChangeItem>();
799 final ArrayList<ProcessChangeItem> mAvailProcessChanges
800 = new ArrayList<ProcessChangeItem>();
803 * Callback of last caller to {@link #requestPss}.
805 Runnable mRequestPssCallback;
808 * Remaining processes for which we are waiting results from the last
809 * call to {@link #requestPss}.
811 final ArrayList<ProcessRecord> mRequestPssList
812 = new ArrayList<ProcessRecord>();
815 * Runtime statistics collection thread. This object's lock is used to
816 * protect all related state.
818 final Thread mProcessStatsThread;
821 * Used to collect process stats when showing not responding dialog.
822 * Protected by mProcessStatsThread.
824 final ProcessStats mProcessStats = new ProcessStats(
825 MONITOR_THREAD_CPU_USAGE);
826 final AtomicLong mLastCpuTime = new AtomicLong(0);
827 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
829 long mLastWriteTime = 0;
832 * Used to retain an update lock when the foreground activity is in
835 final UpdateLock mUpdateLock = new UpdateLock("immersive");
838 * Set to true after the system has finished booting.
840 boolean mBooted = false;
842 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
843 int mProcessLimitOverride = -1;
845 WindowManagerService mWindowManager;
847 static ActivityManagerService mSelf;
848 static ActivityThread mSystemThread;
850 private int mCurrentUserId = 0;
851 private int[] mCurrentUserArray = new int[] { 0 };
852 private UserManagerService mUserManager;
854 private final class AppDeathRecipient implements IBinder.DeathRecipient {
855 final ProcessRecord mApp;
857 final IApplicationThread mAppThread;
859 AppDeathRecipient(ProcessRecord app, int pid,
860 IApplicationThread thread) {
861 if (localLOGV) Slog.v(
862 TAG, "New death recipient " + this
863 + " for thread " + thread.asBinder());
869 public void binderDied() {
870 if (localLOGV) Slog.v(
871 TAG, "Death received in " + this
872 + " for thread " + mAppThread.asBinder());
873 synchronized(ActivityManagerService.this) {
874 appDiedLocked(mApp, mPid, mAppThread);
879 static final int SHOW_ERROR_MSG = 1;
880 static final int SHOW_NOT_RESPONDING_MSG = 2;
881 static final int SHOW_FACTORY_ERROR_MSG = 3;
882 static final int UPDATE_CONFIGURATION_MSG = 4;
883 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
884 static final int WAIT_FOR_DEBUGGER_MSG = 6;
885 static final int SERVICE_TIMEOUT_MSG = 12;
886 static final int UPDATE_TIME_ZONE = 13;
887 static final int SHOW_UID_ERROR_MSG = 14;
888 static final int IM_FEELING_LUCKY_MSG = 15;
889 static final int PROC_START_TIMEOUT_MSG = 20;
890 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
891 static final int KILL_APPLICATION_MSG = 22;
892 static final int FINALIZE_PENDING_INTENT_MSG = 23;
893 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
894 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
895 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
896 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
897 static final int CLEAR_DNS_CACHE = 28;
898 static final int UPDATE_HTTP_PROXY = 29;
899 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
900 static final int DISPATCH_PROCESSES_CHANGED = 31;
901 static final int DISPATCH_PROCESS_DIED = 32;
902 static final int REPORT_MEM_USAGE = 33;
903 static final int REPORT_USER_SWITCH_MSG = 34;
904 static final int CONTINUE_USER_SWITCH_MSG = 35;
905 static final int USER_SWITCH_TIMEOUT_MSG = 36;
906 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
908 static final int FIRST_ACTIVITY_STACK_MSG = 100;
909 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
910 static final int FIRST_COMPAT_MODE_MSG = 300;
912 AlertDialog mUidAlert;
913 CompatModeDialog mCompatModeDialog;
914 long mLastMemUsageReportTime = 0;
916 final Handler mHandler = new Handler() {
918 // if (localLOGV) Slog.v(TAG, "Handler started!");
921 public void handleMessage(Message msg) {
923 case SHOW_ERROR_MSG: {
924 HashMap data = (HashMap) msg.obj;
925 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
926 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
927 synchronized (ActivityManagerService.this) {
928 ProcessRecord proc = (ProcessRecord)data.get("app");
929 AppErrorResult res = (AppErrorResult) data.get("result");
930 if (proc != null && proc.crashDialog != null) {
931 Slog.e(TAG, "App already has crash dialog: " + proc);
937 if (!showBackground && UserHandle.getAppId(proc.uid)
938 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
939 && proc.pid != MY_PID) {
940 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
946 if (mShowDialogs && !mSleeping && !mShuttingDown) {
947 Dialog d = new AppErrorDialog(mContext,
948 ActivityManagerService.this, res, proc);
950 proc.crashDialog = d;
952 // The device is asleep, so just pretend that the user
953 // saw a crash dialog and hit "force quit".
960 ensureBootCompleted();
962 case SHOW_NOT_RESPONDING_MSG: {
963 synchronized (ActivityManagerService.this) {
964 HashMap data = (HashMap) msg.obj;
965 ProcessRecord proc = (ProcessRecord)data.get("app");
966 if (proc != null && proc.anrDialog != null) {
967 Slog.e(TAG, "App already has anr dialog: " + proc);
971 Intent intent = new Intent("android.intent.action.ANR");
972 if (!mProcessesReady) {
973 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
974 | Intent.FLAG_RECEIVER_FOREGROUND);
976 broadcastIntentLocked(null, null, intent,
977 null, null, 0, null, null, null,
978 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
981 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
982 mContext, proc, (ActivityRecord)data.get("activity"),
987 // Just kill the app if there is no dialog to be shown.
988 killAppAtUsersRequest(proc, null);
992 ensureBootCompleted();
994 case SHOW_STRICT_MODE_VIOLATION_MSG: {
995 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
996 synchronized (ActivityManagerService.this) {
997 ProcessRecord proc = (ProcessRecord) data.get("app");
999 Slog.e(TAG, "App not found when showing strict mode dialog.");
1002 if (proc.crashDialog != null) {
1003 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1006 AppErrorResult res = (AppErrorResult) data.get("result");
1007 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1008 Dialog d = new StrictModeViolationDialog(mContext,
1009 ActivityManagerService.this, res, proc);
1011 proc.crashDialog = d;
1013 // The device is asleep, so just pretend that the user
1014 // saw a crash dialog and hit "force quit".
1018 ensureBootCompleted();
1020 case SHOW_FACTORY_ERROR_MSG: {
1021 Dialog d = new FactoryErrorDialog(
1022 mContext, msg.getData().getCharSequence("msg"));
1024 ensureBootCompleted();
1026 case UPDATE_CONFIGURATION_MSG: {
1027 final ContentResolver resolver = mContext.getContentResolver();
1028 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1030 case GC_BACKGROUND_PROCESSES_MSG: {
1031 synchronized (ActivityManagerService.this) {
1032 performAppGcsIfAppropriateLocked();
1035 case WAIT_FOR_DEBUGGER_MSG: {
1036 synchronized (ActivityManagerService.this) {
1037 ProcessRecord app = (ProcessRecord)msg.obj;
1038 if (msg.arg1 != 0) {
1039 if (!app.waitedForDebugger) {
1040 Dialog d = new AppWaitingForDebuggerDialog(
1041 ActivityManagerService.this,
1044 app.waitedForDebugger = true;
1048 if (app.waitDialog != null) {
1049 app.waitDialog.dismiss();
1050 app.waitDialog = null;
1055 case SERVICE_TIMEOUT_MSG: {
1058 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1060 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1063 mServices.serviceTimeout((ProcessRecord)msg.obj);
1065 case UPDATE_TIME_ZONE: {
1066 synchronized (ActivityManagerService.this) {
1067 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1068 ProcessRecord r = mLruProcesses.get(i);
1069 if (r.thread != null) {
1071 r.thread.updateTimeZone();
1072 } catch (RemoteException ex) {
1073 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1079 case CLEAR_DNS_CACHE: {
1080 synchronized (ActivityManagerService.this) {
1081 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1082 ProcessRecord r = mLruProcesses.get(i);
1083 if (r.thread != null) {
1085 r.thread.clearDnsCache();
1086 } catch (RemoteException ex) {
1087 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1093 case UPDATE_HTTP_PROXY: {
1094 ProxyProperties proxy = (ProxyProperties)msg.obj;
1097 String exclList = "";
1098 if (proxy != null) {
1099 host = proxy.getHost();
1100 port = Integer.toString(proxy.getPort());
1101 exclList = proxy.getExclusionList();
1103 synchronized (ActivityManagerService.this) {
1104 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1105 ProcessRecord r = mLruProcesses.get(i);
1106 if (r.thread != null) {
1108 r.thread.setHttpProxy(host, port, exclList);
1109 } catch (RemoteException ex) {
1110 Slog.w(TAG, "Failed to update http proxy for: " +
1111 r.info.processName);
1117 case SHOW_UID_ERROR_MSG: {
1118 String title = "System UIDs Inconsistent";
1119 String text = "UIDs on the system are inconsistent, you need to wipe your"
1120 + " data partition or your device will be unstable.";
1121 Log.e(TAG, title + ": " + text);
1123 // XXX This is a temporary dialog, no need to localize.
1124 AlertDialog d = new BaseErrorDialog(mContext);
1125 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1126 d.setCancelable(false);
1129 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1130 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1135 case IM_FEELING_LUCKY_MSG: {
1136 if (mUidAlert != null) {
1137 mUidAlert.dismiss();
1141 case PROC_START_TIMEOUT_MSG: {
1144 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1146 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1149 ProcessRecord app = (ProcessRecord)msg.obj;
1150 synchronized (ActivityManagerService.this) {
1151 processStartTimedOutLocked(app);
1154 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1155 synchronized (ActivityManagerService.this) {
1156 doPendingActivityLaunchesLocked(true);
1159 case KILL_APPLICATION_MSG: {
1160 synchronized (ActivityManagerService.this) {
1161 int appid = msg.arg1;
1162 boolean restart = (msg.arg2 == 1);
1163 String pkg = (String) msg.obj;
1164 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1165 UserHandle.USER_ALL);
1168 case FINALIZE_PENDING_INTENT_MSG: {
1169 ((PendingIntentRecord)msg.obj).completeFinalize();
1171 case POST_HEAVY_NOTIFICATION_MSG: {
1172 INotificationManager inm = NotificationManager.getService();
1177 ActivityRecord root = (ActivityRecord)msg.obj;
1178 ProcessRecord process = root.app;
1179 if (process == null) {
1184 Context context = mContext.createPackageContext(process.info.packageName, 0);
1185 String text = mContext.getString(R.string.heavy_weight_notification,
1186 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1187 Notification notification = new Notification();
1188 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1189 notification.when = 0;
1190 notification.flags = Notification.FLAG_ONGOING_EVENT;
1191 notification.tickerText = text;
1192 notification.defaults = 0; // please be quiet
1193 notification.sound = null;
1194 notification.vibrate = null;
1195 notification.setLatestEventInfo(context, text,
1196 mContext.getText(R.string.heavy_weight_notification_detail),
1197 PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1198 PendingIntent.FLAG_CANCEL_CURRENT, null,
1199 new UserHandle(root.userId)));
1202 int[] outId = new int[1];
1203 inm.enqueueNotificationWithTag("android", null,
1204 R.string.heavy_weight_notification,
1205 notification, outId, root.userId);
1206 } catch (RuntimeException e) {
1207 Slog.w(ActivityManagerService.TAG,
1208 "Error showing notification for heavy-weight app", e);
1209 } catch (RemoteException e) {
1211 } catch (NameNotFoundException e) {
1212 Slog.w(TAG, "Unable to create context for heavy notification", e);
1215 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1216 INotificationManager inm = NotificationManager.getService();
1221 inm.cancelNotificationWithTag("android", null,
1222 R.string.heavy_weight_notification, msg.arg1);
1223 } catch (RuntimeException e) {
1224 Slog.w(ActivityManagerService.TAG,
1225 "Error canceling notification for service", e);
1226 } catch (RemoteException e) {
1229 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1230 synchronized (ActivityManagerService.this) {
1231 checkExcessivePowerUsageLocked(true);
1232 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1233 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1234 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1237 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1238 synchronized (ActivityManagerService.this) {
1239 ActivityRecord ar = (ActivityRecord)msg.obj;
1240 if (mCompatModeDialog != null) {
1241 if (mCompatModeDialog.mAppInfo.packageName.equals(
1242 ar.info.applicationInfo.packageName)) {
1245 mCompatModeDialog.dismiss();
1246 mCompatModeDialog = null;
1248 if (ar != null && false) {
1249 if (mCompatModePackages.getPackageAskCompatModeLocked(
1251 int mode = mCompatModePackages.computeCompatModeLocked(
1252 ar.info.applicationInfo);
1253 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1254 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1255 mCompatModeDialog = new CompatModeDialog(
1256 ActivityManagerService.this, mContext,
1257 ar.info.applicationInfo);
1258 mCompatModeDialog.show();
1265 case DISPATCH_PROCESSES_CHANGED: {
1266 dispatchProcessesChanged();
1269 case DISPATCH_PROCESS_DIED: {
1270 final int pid = msg.arg1;
1271 final int uid = msg.arg2;
1272 dispatchProcessDied(pid, uid);
1275 case REPORT_MEM_USAGE: {
1276 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1277 if (!isDebuggable) {
1280 synchronized (ActivityManagerService.this) {
1281 long now = SystemClock.uptimeMillis();
1282 if (now < (mLastMemUsageReportTime+5*60*1000)) {
1283 // Don't report more than every 5 minutes to somewhat
1287 mLastMemUsageReportTime = now;
1289 Thread thread = new Thread() {
1290 @Override public void run() {
1291 StringBuilder dropBuilder = new StringBuilder(1024);
1292 StringBuilder logBuilder = new StringBuilder(1024);
1293 StringWriter oomSw = new StringWriter();
1294 PrintWriter oomPw = new PrintWriter(oomSw);
1295 StringWriter catSw = new StringWriter();
1296 PrintWriter catPw = new PrintWriter(catSw);
1297 String[] emptyArgs = new String[] { };
1298 StringBuilder tag = new StringBuilder(128);
1299 StringBuilder stack = new StringBuilder(128);
1300 tag.append("Low on memory -- ");
1301 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw,
1303 dropBuilder.append(stack);
1304 dropBuilder.append('\n');
1305 dropBuilder.append('\n');
1306 String oomString = oomSw.toString();
1307 dropBuilder.append(oomString);
1308 dropBuilder.append('\n');
1309 logBuilder.append(oomString);
1311 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1313 final InputStreamReader converter = new InputStreamReader(
1314 proc.getInputStream());
1315 BufferedReader in = new BufferedReader(converter);
1318 line = in.readLine();
1322 if (line.length() > 0) {
1323 logBuilder.append(line);
1324 logBuilder.append('\n');
1326 dropBuilder.append(line);
1327 dropBuilder.append('\n');
1330 } catch (IOException e) {
1332 synchronized (ActivityManagerService.this) {
1334 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1336 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1337 false, false, null);
1339 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1341 dropBuilder.append(catSw.toString());
1342 addErrorToDropBox("lowmem", null, "system_server", null,
1343 null, tag.toString(), dropBuilder.toString(), null, null);
1344 Slog.i(TAG, logBuilder.toString());
1345 synchronized (ActivityManagerService.this) {
1346 long now = SystemClock.uptimeMillis();
1347 if (mLastMemUsageReportTime < now) {
1348 mLastMemUsageReportTime = now;
1356 case REPORT_USER_SWITCH_MSG: {
1357 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1360 case CONTINUE_USER_SWITCH_MSG: {
1361 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1364 case USER_SWITCH_TIMEOUT_MSG: {
1365 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1368 case IMMERSIVE_MODE_LOCK_MSG: {
1369 final boolean nextState = (msg.arg1 != 0);
1370 if (mUpdateLock.isHeld() != nextState) {
1371 if (DEBUG_IMMERSIVE) {
1372 final ActivityRecord r = (ActivityRecord) msg.obj;
1373 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1376 mUpdateLock.acquire();
1378 mUpdateLock.release();
1387 public static void setSystemProcess() {
1389 ActivityManagerService m = mSelf;
1391 ServiceManager.addService("activity", m, true);
1392 ServiceManager.addService("meminfo", new MemBinder(m));
1393 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
1394 ServiceManager.addService("dbinfo", new DbBinder(m));
1395 if (MONITOR_CPU_USAGE) {
1396 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1398 ServiceManager.addService("permission", new PermissionController(m));
1400 ApplicationInfo info =
1401 mSelf.mContext.getPackageManager().getApplicationInfo(
1402 "android", STOCK_PM_FLAGS);
1403 mSystemThread.installSystemApplicationInfo(info);
1405 synchronized (mSelf) {
1406 ProcessRecord app = mSelf.newProcessRecordLocked(
1407 mSystemThread.getApplicationThread(), info,
1408 info.processName, false);
1409 app.persistent = true;
1411 app.maxAdj = ProcessList.SYSTEM_ADJ;
1412 mSelf.mProcessNames.put(app.processName, app.uid, app);
1413 synchronized (mSelf.mPidsSelfLocked) {
1414 mSelf.mPidsSelfLocked.put(app.pid, app);
1416 mSelf.updateLruProcessLocked(app, true);
1418 } catch (PackageManager.NameNotFoundException e) {
1419 throw new RuntimeException(
1420 "Unable to find android system package", e);
1424 public void setWindowManager(WindowManagerService wm) {
1425 mWindowManager = wm;
1428 public static final Context main(int factoryTest) {
1429 AThread thr = new AThread();
1432 synchronized (thr) {
1433 while (thr.mService == null) {
1436 } catch (InterruptedException e) {
1441 ActivityManagerService m = thr.mService;
1443 ActivityThread at = ActivityThread.systemMain();
1445 Context context = at.getSystemContext();
1446 context.setTheme(android.R.style.Theme_Holo);
1447 m.mContext = context;
1448 m.mFactoryTest = factoryTest;
1449 m.mMainStack = new ActivityStack(m, context, true);
1451 m.mBatteryStatsService.publish(context);
1452 m.mUsageStatsService.publish(context);
1454 synchronized (thr) {
1459 m.startRunning(null, null, null, null);
1464 public static ActivityManagerService self() {
1468 static class AThread extends Thread {
1469 ActivityManagerService mService;
1470 boolean mReady = false;
1473 super("ActivityManager");
1479 android.os.Process.setThreadPriority(
1480 android.os.Process.THREAD_PRIORITY_FOREGROUND);
1481 android.os.Process.setCanSelfBackground(false);
1483 ActivityManagerService m = new ActivityManagerService();
1485 synchronized (this) {
1490 synchronized (this) {
1494 } catch (InterruptedException e) {
1499 // For debug builds, log event loop stalls to dropbox for analysis.
1500 if (StrictMode.conditionallyEnableDebugLogging()) {
1501 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1508 static class MemBinder extends Binder {
1509 ActivityManagerService mActivityManagerService;
1510 MemBinder(ActivityManagerService activityManagerService) {
1511 mActivityManagerService = activityManagerService;
1515 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1516 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1517 != PackageManager.PERMISSION_GRANTED) {
1518 pw.println("Permission Denial: can't dump meminfo from from pid="
1519 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1520 + " without permission " + android.Manifest.permission.DUMP);
1524 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
1525 false, null, null, null);
1529 static class GraphicsBinder extends Binder {
1530 ActivityManagerService mActivityManagerService;
1531 GraphicsBinder(ActivityManagerService activityManagerService) {
1532 mActivityManagerService = activityManagerService;
1536 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1537 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1538 != PackageManager.PERMISSION_GRANTED) {
1539 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1540 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1541 + " without permission " + android.Manifest.permission.DUMP);
1545 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
1549 static class DbBinder extends Binder {
1550 ActivityManagerService mActivityManagerService;
1551 DbBinder(ActivityManagerService activityManagerService) {
1552 mActivityManagerService = activityManagerService;
1556 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1557 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1558 != PackageManager.PERMISSION_GRANTED) {
1559 pw.println("Permission Denial: can't dump dbinfo from from pid="
1560 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1561 + " without permission " + android.Manifest.permission.DUMP);
1565 mActivityManagerService.dumpDbInfo(fd, pw, args);
1569 static class CpuBinder extends Binder {
1570 ActivityManagerService mActivityManagerService;
1571 CpuBinder(ActivityManagerService activityManagerService) {
1572 mActivityManagerService = activityManagerService;
1576 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1577 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1578 != PackageManager.PERMISSION_GRANTED) {
1579 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1580 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1581 + " without permission " + android.Manifest.permission.DUMP);
1585 synchronized (mActivityManagerService.mProcessStatsThread) {
1586 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1587 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1588 SystemClock.uptimeMillis()));
1593 private ActivityManagerService() {
1594 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
1596 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1597 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1598 mBroadcastQueues[0] = mFgBroadcastQueue;
1599 mBroadcastQueues[1] = mBgBroadcastQueue;
1601 mServices = new ActiveServices(this);
1602 mProviderMap = new ProviderMap(this);
1604 File dataDir = Environment.getDataDirectory();
1605 File systemDir = new File(dataDir, "system");
1607 mBatteryStatsService = new BatteryStatsService(new File(
1608 systemDir, "batterystats.bin").toString());
1609 mBatteryStatsService.getActiveStatistics().readLocked();
1610 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1611 mOnBattery = DEBUG_POWER ? true
1612 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
1613 mBatteryStatsService.getActiveStatistics().setCallback(this);
1615 mUsageStatsService = new UsageStatsService(new File(
1616 systemDir, "usagestats").toString());
1617 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
1619 // User 0 is the first and only user that runs at boot.
1620 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1621 mUserLru.add(Integer.valueOf(0));
1622 updateStartedUserArrayLocked();
1624 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1625 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1627 mConfiguration.setToDefaults();
1628 mConfiguration.setLocale(Locale.getDefault());
1630 mConfigurationSeq = mConfiguration.seq = 1;
1631 mProcessStats.init();
1633 mCompatModePackages = new CompatModePackages(this, systemDir);
1635 // Add ourself to the Watchdog monitors.
1636 Watchdog.getInstance().addMonitor(this);
1638 mProcessStatsThread = new Thread("ProcessStats") {
1643 synchronized(this) {
1644 final long now = SystemClock.uptimeMillis();
1645 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
1646 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
1647 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
1648 // + ", write delay=" + nextWriteDelay);
1649 if (nextWriteDelay < nextCpuDelay) {
1650 nextCpuDelay = nextWriteDelay;
1652 if (nextCpuDelay > 0) {
1653 mProcessStatsMutexFree.set(true);
1654 this.wait(nextCpuDelay);
1657 } catch (InterruptedException e) {
1659 updateCpuStatsNow();
1660 } catch (Exception e) {
1661 Slog.e(TAG, "Unexpected exception collecting process stats", e);
1666 mProcessStatsThread.start();
1670 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1671 throws RemoteException {
1672 if (code == SYSPROPS_TRANSACTION) {
1673 // We need to tell all apps about the system property change.
1674 ArrayList<IBinder> procs = new ArrayList<IBinder>();
1675 synchronized(this) {
1676 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1677 final int NA = apps.size();
1678 for (int ia=0; ia<NA; ia++) {
1679 ProcessRecord app = apps.valueAt(ia);
1680 if (app.thread != null) {
1681 procs.add(app.thread.asBinder());
1687 int N = procs.size();
1688 for (int i=0; i<N; i++) {
1689 Parcel data2 = Parcel.obtain();
1691 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1692 } catch (RemoteException e) {
1698 return super.onTransact(code, data, reply, flags);
1699 } catch (RuntimeException e) {
1700 // The activity manager only throws security exceptions, so let's
1702 if (!(e instanceof SecurityException)) {
1703 Slog.e(TAG, "Activity Manager Crash", e);
1709 void updateCpuStats() {
1710 final long now = SystemClock.uptimeMillis();
1711 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1714 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1715 synchronized (mProcessStatsThread) {
1716 mProcessStatsThread.notify();
1721 void updateCpuStatsNow() {
1722 synchronized (mProcessStatsThread) {
1723 mProcessStatsMutexFree.set(false);
1724 final long now = SystemClock.uptimeMillis();
1725 boolean haveNewCpuStats = false;
1727 if (MONITOR_CPU_USAGE &&
1728 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1729 mLastCpuTime.set(now);
1730 haveNewCpuStats = true;
1731 mProcessStats.update();
1732 //Slog.i(TAG, mProcessStats.printCurrentState());
1733 //Slog.i(TAG, "Total CPU usage: "
1734 // + mProcessStats.getTotalCpuPercent() + "%");
1736 // Slog the cpu usage if the property is set.
1737 if ("true".equals(SystemProperties.get("events.cpu"))) {
1738 int user = mProcessStats.getLastUserTime();
1739 int system = mProcessStats.getLastSystemTime();
1740 int iowait = mProcessStats.getLastIoWaitTime();
1741 int irq = mProcessStats.getLastIrqTime();
1742 int softIrq = mProcessStats.getLastSoftIrqTime();
1743 int idle = mProcessStats.getLastIdleTime();
1745 int total = user + system + iowait + irq + softIrq + idle;
1746 if (total == 0) total = 1;
1748 EventLog.writeEvent(EventLogTags.CPU,
1749 ((user+system+iowait+irq+softIrq) * 100) / total,
1750 (user * 100) / total,
1751 (system * 100) / total,
1752 (iowait * 100) / total,
1753 (irq * 100) / total,
1754 (softIrq * 100) / total);
1758 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
1759 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
1760 synchronized(bstats) {
1761 synchronized(mPidsSelfLocked) {
1762 if (haveNewCpuStats) {
1764 int perc = bstats.startAddingCpuLocked();
1767 final int N = mProcessStats.countStats();
1768 for (int i=0; i<N; i++) {
1769 ProcessStats.Stats st = mProcessStats.getStats(i);
1773 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
1774 int otherUTime = (st.rel_utime*perc)/100;
1775 int otherSTime = (st.rel_stime*perc)/100;
1776 totalUTime += otherUTime;
1777 totalSTime += otherSTime;
1779 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
1780 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1781 st.rel_stime-otherSTime);
1782 ps.addSpeedStepTimes(cpuSpeedTimes);
1783 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
1785 BatteryStatsImpl.Uid.Proc ps =
1786 bstats.getProcessStatsLocked(st.name, st.pid);
1788 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1789 st.rel_stime-otherSTime);
1790 ps.addSpeedStepTimes(cpuSpeedTimes);
1794 bstats.finishAddingCpuLocked(perc, totalUTime,
1795 totalSTime, cpuSpeedTimes);
1800 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1801 mLastWriteTime = now;
1802 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
1809 public void batteryNeedsCpuUpdate() {
1810 updateCpuStatsNow();
1814 public void batteryPowerChanged(boolean onBattery) {
1815 // When plugging in, update the CPU stats first before changing
1817 updateCpuStatsNow();
1818 synchronized (this) {
1819 synchronized(mPidsSelfLocked) {
1820 mOnBattery = DEBUG_POWER ? true : onBattery;
1826 * Initialize the application bind args. These are passed to each
1827 * process when the bindApplication() IPC is sent to the process. They're
1828 * lazily setup to make sure the services are running when they're asked for.
1830 private HashMap<String, IBinder> getCommonServicesLocked() {
1831 if (mAppBindArgs == null) {
1832 mAppBindArgs = new HashMap<String, IBinder>();
1834 // Setup the application init args
1835 mAppBindArgs.put("package", ServiceManager.getService("package"));
1836 mAppBindArgs.put("window", ServiceManager.getService("window"));
1837 mAppBindArgs.put(Context.ALARM_SERVICE,
1838 ServiceManager.getService(Context.ALARM_SERVICE));
1840 return mAppBindArgs;
1843 final void setFocusedActivityLocked(ActivityRecord r) {
1844 if (mFocusedActivity != r) {
1845 mFocusedActivity = r;
1847 mWindowManager.setFocusedApp(r.appToken, true);
1849 applyUpdateLockStateLocked(r);
1853 final void applyUpdateLockStateLocked(ActivityRecord r) {
1854 // Modifications to the UpdateLock state are done on our handler, outside
1855 // the activity manager's locks. The new state is determined based on the
1856 // state *now* of the relevant activity record. The object is passed to
1857 // the handler solely for logging detail, not to be consulted/modified.
1858 final boolean nextState = r != null && r.immersive;
1859 mHandler.sendMessage(
1860 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
1863 private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
1864 // put it on the LRU to keep track of when it should be exited.
1865 int lrui = mLruProcesses.indexOf(app);
1866 if (lrui >= 0) mLruProcesses.remove(lrui);
1868 int i = mLruProcesses.size()-1;
1871 app.lruSeq = mLruSeq;
1873 // compute the new weight for this process.
1874 app.lastActivityTime = SystemClock.uptimeMillis();
1875 if (app.activities.size() > 0) {
1876 // If this process has activities, we more strongly want to keep
1878 app.lruWeight = app.lastActivityTime;
1879 } else if (app.pubProviders.size() > 0) {
1880 // If this process contains content providers, we want to keep
1881 // it a little more strongly.
1882 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
1883 // Also don't let it kick out the first few "real" hidden processes.
1884 skipTop = ProcessList.MIN_HIDDEN_APPS;
1886 // If this process doesn't have activities, we less strongly
1887 // want to keep it around, and generally want to avoid getting
1888 // in front of any very recently used activities.
1889 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
1890 // Also don't let it kick out the first few "real" hidden processes.
1891 skipTop = ProcessList.MIN_HIDDEN_APPS;
1895 ProcessRecord p = mLruProcesses.get(i);
1896 // If this app shouldn't be in front of the first N background
1897 // apps, then skip over that many that are currently hidden.
1898 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
1901 if (p.lruWeight <= app.lruWeight || i < bestPos) {
1902 mLruProcesses.add(i+1, app);
1908 mLruProcesses.add(0, app);
1911 // If the app is currently using a content provider or service,
1912 // bump those processes as well.
1913 if (app.connections.size() > 0) {
1914 for (ConnectionRecord cr : app.connections) {
1915 if (cr.binding != null && cr.binding.service != null
1916 && cr.binding.service.app != null
1917 && cr.binding.service.app.lruSeq != mLruSeq) {
1918 updateLruProcessInternalLocked(cr.binding.service.app, i+1);
1922 for (int j=app.conProviders.size()-1; j>=0; j--) {
1923 ContentProviderRecord cpr = app.conProviders.get(j).provider;
1924 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1925 updateLruProcessInternalLocked(cpr.proc, i+1);
1930 final void updateLruProcessLocked(ProcessRecord app,
1933 updateLruProcessInternalLocked(app, 0);
1935 //Slog.i(TAG, "Putting proc to front: " + app.processName);
1937 updateOomAdjLocked();
1941 final ProcessRecord getProcessRecordLocked(
1942 String processName, int uid) {
1943 if (uid == Process.SYSTEM_UID) {
1944 // The system gets to run in any process. If there are multiple
1945 // processes with the same uid, just pick the first (this
1946 // should never happen).
1947 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1949 if (procs == null) return null;
1950 final int N = procs.size();
1951 for (int i = 0; i < N; i++) {
1952 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1955 ProcessRecord proc = mProcessNames.get(processName, uid);
1959 void ensurePackageDexOpt(String packageName) {
1960 IPackageManager pm = AppGlobals.getPackageManager();
1962 if (pm.performDexOpt(packageName)) {
1965 } catch (RemoteException e) {
1969 boolean isNextTransitionForward() {
1970 int transit = mWindowManager.getPendingAppTransition();
1971 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1972 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1973 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1976 final ProcessRecord startProcessLocked(String processName,
1977 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
1978 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1982 app = getProcessRecordLocked(processName, info.uid);
1984 // If this is an isolated process, it can't re-use an existing process.
1987 // We don't have to do anything more if:
1988 // (1) There is an existing application record; and
1989 // (2) The caller doesn't think it is dead, OR there is no thread
1990 // object attached to it so we know it couldn't have crashed; and
1991 // (3) There is a pid assigned to it, so it is either starting or
1993 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
1994 + " app=" + app + " knownToBeDead=" + knownToBeDead
1995 + " thread=" + (app != null ? app.thread : null)
1996 + " pid=" + (app != null ? app.pid : -1));
1997 if (app != null && app.pid > 0) {
1998 if (!knownToBeDead || app.thread == null) {
1999 // We already have the app running, or are waiting for it to
2000 // come up (we have a pid but not yet its thread), so keep it.
2001 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2002 // If this is a new package in the process, add the package to the list
2003 app.addPackage(info.packageName);
2006 // An application record is attached to a previous process,
2008 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2009 handleAppDiedLocked(app, true, true);
2013 String hostingNameStr = hostingName != null
2014 ? hostingName.flattenToShortString() : null;
2017 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2018 // If we are in the background, then check to see if this process
2019 // is bad. If so, we will just silently fail.
2020 if (mBadProcesses.get(info.processName, info.uid) != null) {
2021 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2022 + "/" + info.processName);
2026 // When the user is explicitly starting a process, then clear its
2027 // crash count so that we won't make it bad until they see at
2028 // least one crash dialog again, and make the process good again
2029 // if it had been bad.
2030 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2031 + "/" + info.processName);
2032 mProcessCrashTimes.remove(info.processName, info.uid);
2033 if (mBadProcesses.get(info.processName, info.uid) != null) {
2034 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2035 UserHandle.getUserId(info.uid), info.uid,
2037 mBadProcesses.remove(info.processName, info.uid);
2046 app = newProcessRecordLocked(null, info, processName, isolated);
2048 Slog.w(TAG, "Failed making new process record for "
2049 + processName + "/" + info.uid + " isolated=" + isolated);
2052 mProcessNames.put(processName, app.uid, app);
2054 mIsolatedProcesses.put(app.uid, app);
2057 // If this is a new package in the process, add the package to the list
2058 app.addPackage(info.packageName);
2061 // If the system is not ready yet, then hold off on starting this
2062 // process until it is.
2063 if (!mProcessesReady
2064 && !isAllowedWhileBooting(info)
2065 && !allowWhileBooting) {
2066 if (!mProcessesOnHold.contains(app)) {
2067 mProcessesOnHold.add(app);
2069 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2073 startProcessLocked(app, hostingType, hostingNameStr);
2074 return (app.pid != 0) ? app : null;
2077 boolean isAllowedWhileBooting(ApplicationInfo ai) {
2078 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2081 private final void startProcessLocked(ProcessRecord app,
2082 String hostingType, String hostingNameStr) {
2083 if (app.pid > 0 && app.pid != MY_PID) {
2084 synchronized (mPidsSelfLocked) {
2085 mPidsSelfLocked.remove(app.pid);
2086 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2091 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2092 "startProcessLocked removing on hold: " + app);
2093 mProcessesOnHold.remove(app);
2097 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2104 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2105 if (!app.isolated) {
2106 int[] permGids = null;
2108 final PackageManager pm = mContext.getPackageManager();
2109 permGids = pm.getPackageGids(app.info.packageName);
2111 if (Environment.isExternalStorageEmulated()) {
2112 if (pm.checkPermission(
2113 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2114 app.info.packageName) == PERMISSION_GRANTED) {
2115 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2117 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2120 } catch (PackageManager.NameNotFoundException e) {
2121 Slog.w(TAG, "Unable to retrieve gids", e);
2125 * Add shared application GID so applications can share some
2126 * resources like shared libraries
2128 if (permGids == null) {
2131 gids = new int[permGids.length + 1];
2132 System.arraycopy(permGids, 0, gids, 1, permGids.length);
2134 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2136 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2137 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2138 && mTopComponent != null
2139 && app.processName.equals(mTopComponent.getPackageName())) {
2142 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2143 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2148 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2149 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2150 // Also turn on CheckJNI for debuggable apps. It's quite
2151 // awkward to turn on otherwise.
2152 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2154 // Run the app in safe mode if its manifest requests so or the
2155 // system is booted in safe mode.
2156 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2157 Zygote.systemInSafeMode == true) {
2158 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2160 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2161 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2163 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2164 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2166 if ("1".equals(SystemProperties.get("debug.assert"))) {
2167 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2170 // Start the process. It will either succeed and return a result containing
2171 // the PID of the new process, or else throw a RuntimeException.
2172 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2173 app.processName, uid, uid, gids, debugFlags, mountExternal,
2174 app.info.targetSdkVersion, null, null);
2176 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2178 if (bs.isOnBattery()) {
2179 app.batteryStats.incStartsLocked();
2183 EventLog.writeEvent(EventLogTags.AM_PROC_START,
2184 UserHandle.getUserId(uid), startResult.pid, uid,
2185 app.processName, hostingType,
2186 hostingNameStr != null ? hostingNameStr : "");
2188 if (app.persistent) {
2189 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
2192 StringBuilder buf = mStringBuilder;
2194 buf.append("Start proc ");
2195 buf.append(app.processName);
2196 buf.append(" for ");
2197 buf.append(hostingType);
2198 if (hostingNameStr != null) {
2200 buf.append(hostingNameStr);
2202 buf.append(": pid=");
2203 buf.append(startResult.pid);
2204 buf.append(" uid=");
2206 buf.append(" gids={");
2208 for (int gi=0; gi<gids.length; gi++) {
2209 if (gi != 0) buf.append(", ");
2210 buf.append(gids[gi]);
2215 Slog.i(TAG, buf.toString());
2216 app.setPid(startResult.pid);
2217 app.usingWrapper = startResult.usingWrapper;
2218 app.removed = false;
2219 synchronized (mPidsSelfLocked) {
2220 this.mPidsSelfLocked.put(startResult.pid, app);
2221 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2223 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2224 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
2226 } catch (RuntimeException e) {
2227 // XXX do better error recovery.
2229 Slog.e(TAG, "Failure starting process " + app.processName, e);
2233 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
2235 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2237 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2241 boolean startHomeActivityLocked(int userId) {
2243 // Added because none of the other calls to ensureBootCompleted seem to fire
2244 // when running headless.
2245 ensureBootCompleted();
2249 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2250 && mTopAction == null) {
2251 // We are running in factory test mode, but unable to find
2252 // the factory test app, so just sit around displaying the
2253 // error message and don't try to start anything.
2256 Intent intent = new Intent(
2258 mTopData != null ? Uri.parse(mTopData) : null);
2259 intent.setComponent(mTopComponent);
2260 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2261 intent.addCategory(Intent.CATEGORY_HOME);
2263 ActivityInfo aInfo =
2264 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
2265 if (aInfo != null) {
2266 intent.setComponent(new ComponentName(
2267 aInfo.applicationInfo.packageName, aInfo.name));
2268 // Don't do this if the home app is currently being
2270 aInfo = new ActivityInfo(aInfo);
2271 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
2272 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2273 aInfo.applicationInfo.uid);
2274 if (app == null || app.instrumentationClass == null) {
2275 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
2276 mMainStack.startActivityLocked(null, intent, null, aInfo,
2277 null, null, 0, 0, 0, 0, null, false, null);
2284 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2285 ActivityInfo ai = null;
2286 ComponentName comp = intent.getComponent();
2289 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2291 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2293 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2297 ai = info.activityInfo;
2300 } catch (RemoteException e) {
2308 * Starts the "new version setup screen" if appropriate.
2310 void startSetupActivityLocked() {
2311 // Only do this once per boot.
2312 if (mCheckedForSetup) {
2316 // We will show this screen if the current one is a different
2317 // version than the last one shown, and we are not running in
2318 // low-level factory test mode.
2319 final ContentResolver resolver = mContext.getContentResolver();
2320 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2321 Settings.Global.getInt(resolver,
2322 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
2323 mCheckedForSetup = true;
2325 // See if we should be showing the platform update setup UI.
2326 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2327 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2328 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2330 // We don't allow third party apps to replace this.
2331 ResolveInfo ri = null;
2332 for (int i=0; ris != null && i<ris.size(); i++) {
2333 if ((ris.get(i).activityInfo.applicationInfo.flags
2334 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2341 String vers = ri.activityInfo.metaData != null
2342 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2344 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2345 vers = ri.activityInfo.applicationInfo.metaData.getString(
2346 Intent.METADATA_SETUP_VERSION);
2348 String lastVers = Settings.Secure.getString(
2349 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2350 if (vers != null && !vers.equals(lastVers)) {
2351 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2352 intent.setComponent(new ComponentName(
2353 ri.activityInfo.packageName, ri.activityInfo.name));
2354 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2355 null, null, 0, 0, 0, 0, null, false, null);
2361 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
2362 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
2365 void enforceNotIsolatedCaller(String caller) {
2366 if (UserHandle.isIsolated(Binder.getCallingUid())) {
2367 throw new SecurityException("Isolated process not allowed to call " + caller);
2371 public int getFrontActivityScreenCompatMode() {
2372 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
2373 synchronized (this) {
2374 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2378 public void setFrontActivityScreenCompatMode(int mode) {
2379 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2380 "setFrontActivityScreenCompatMode");
2381 synchronized (this) {
2382 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2386 public int getPackageScreenCompatMode(String packageName) {
2387 enforceNotIsolatedCaller("getPackageScreenCompatMode");
2388 synchronized (this) {
2389 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2393 public void setPackageScreenCompatMode(String packageName, int mode) {
2394 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2395 "setPackageScreenCompatMode");
2396 synchronized (this) {
2397 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
2401 public boolean getPackageAskScreenCompat(String packageName) {
2402 enforceNotIsolatedCaller("getPackageAskScreenCompat");
2403 synchronized (this) {
2404 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2408 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2409 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2410 "setPackageAskScreenCompat");
2411 synchronized (this) {
2412 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2416 void reportResumedActivityLocked(ActivityRecord r) {
2417 //Slog.i(TAG, "**** REPORT RESUME: " + r);
2418 updateUsageStats(r, true);
2421 private void dispatchProcessesChanged() {
2423 synchronized (this) {
2424 N = mPendingProcessChanges.size();
2425 if (mActiveProcessChanges.length < N) {
2426 mActiveProcessChanges = new ProcessChangeItem[N];
2428 mPendingProcessChanges.toArray(mActiveProcessChanges);
2429 mAvailProcessChanges.addAll(mPendingProcessChanges);
2430 mPendingProcessChanges.clear();
2431 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2433 int i = mProcessObservers.beginBroadcast();
2436 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2437 if (observer != null) {
2439 for (int j=0; j<N; j++) {
2440 ProcessChangeItem item = mActiveProcessChanges[j];
2441 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2442 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2443 + item.pid + " uid=" + item.uid + ": "
2444 + item.foregroundActivities);
2445 observer.onForegroundActivitiesChanged(item.pid, item.uid,
2446 item.foregroundActivities);
2448 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2449 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2450 + item.pid + " uid=" + item.uid + ": " + item.importance);
2451 observer.onImportanceChanged(item.pid, item.uid,
2455 } catch (RemoteException e) {
2459 mProcessObservers.finishBroadcast();
2462 private void dispatchProcessDied(int pid, int uid) {
2463 int i = mProcessObservers.beginBroadcast();
2466 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2467 if (observer != null) {
2469 observer.onProcessDied(pid, uid);
2470 } catch (RemoteException e) {
2474 mProcessObservers.finishBroadcast();
2477 final void doPendingActivityLaunchesLocked(boolean doResume) {
2478 final int N = mPendingActivityLaunches.size();
2482 for (int i=0; i<N; i++) {
2483 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
2484 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
2485 pal.startFlags, doResume && i == (N-1), null);
2487 mPendingActivityLaunches.clear();
2490 public final int startActivity(IApplicationThread caller,
2491 Intent intent, String resolvedType, IBinder resultTo,
2492 String resultWho, int requestCode, int startFlags,
2493 String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
2494 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
2495 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
2498 public final int startActivityAsUser(IApplicationThread caller,
2499 Intent intent, String resolvedType, IBinder resultTo,
2500 String resultWho, int requestCode, int startFlags,
2501 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
2502 enforceNotIsolatedCaller("startActivity");
2503 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2504 false, true, "startActivity", null);
2505 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2506 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2507 null, null, options, userId);
2510 public final WaitResult startActivityAndWait(IApplicationThread caller,
2511 Intent intent, String resolvedType, IBinder resultTo,
2512 String resultWho, int requestCode, int startFlags, String profileFile,
2513 ParcelFileDescriptor profileFd, Bundle options, int userId) {
2514 enforceNotIsolatedCaller("startActivityAndWait");
2515 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2516 false, true, "startActivityAndWait", null);
2517 WaitResult res = new WaitResult();
2518 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2519 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2520 res, null, options, UserHandle.getCallingUserId());
2524 public final int startActivityWithConfig(IApplicationThread caller,
2525 Intent intent, String resolvedType, IBinder resultTo,
2526 String resultWho, int requestCode, int startFlags, Configuration config,
2527 Bundle options, int userId) {
2528 enforceNotIsolatedCaller("startActivityWithConfig");
2529 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2530 false, true, "startActivityWithConfig", null);
2531 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
2532 resultTo, resultWho, requestCode, startFlags,
2533 null, null, null, config, options, userId);
2537 public int startActivityIntentSender(IApplicationThread caller,
2538 IntentSender intent, Intent fillInIntent, String resolvedType,
2539 IBinder resultTo, String resultWho, int requestCode,
2540 int flagsMask, int flagsValues, Bundle options) {
2541 enforceNotIsolatedCaller("startActivityIntentSender");
2542 // Refuse possible leaked file descriptors
2543 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2544 throw new IllegalArgumentException("File descriptors passed in Intent");
2547 IIntentSender sender = intent.getTarget();
2548 if (!(sender instanceof PendingIntentRecord)) {
2549 throw new IllegalArgumentException("Bad PendingIntent object");
2552 PendingIntentRecord pir = (PendingIntentRecord)sender;
2554 synchronized (this) {
2555 // If this is coming from the currently resumed activity, it is
2556 // effectively saying that app switches are allowed at this point.
2557 if (mMainStack.mResumedActivity != null
2558 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
2559 Binder.getCallingUid()) {
2560 mAppSwitchesAllowedTime = 0;
2563 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2564 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
2568 public boolean startNextMatchingActivity(IBinder callingActivity,
2569 Intent intent, Bundle options) {
2570 // Refuse possible leaked file descriptors
2571 if (intent != null && intent.hasFileDescriptors() == true) {
2572 throw new IllegalArgumentException("File descriptors passed in Intent");
2575 synchronized (this) {
2576 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2578 ActivityOptions.abort(options);
2581 if (r.app == null || r.app.thread == null) {
2582 // The caller is not running... d'oh!
2583 ActivityOptions.abort(options);
2586 intent = new Intent(intent);
2587 // The caller is not allowed to change the data.
2588 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2589 // And we are resetting to find the next component...
2590 intent.setComponent(null);
2592 ActivityInfo aInfo = null;
2594 List<ResolveInfo> resolves =
2595 AppGlobals.getPackageManager().queryIntentActivities(
2596 intent, r.resolvedType,
2597 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2598 UserHandle.getCallingUserId());
2600 // Look for the original activity in the list...
2601 final int N = resolves != null ? resolves.size() : 0;
2602 for (int i=0; i<N; i++) {
2603 ResolveInfo rInfo = resolves.get(i);
2604 if (rInfo.activityInfo.packageName.equals(r.packageName)
2605 && rInfo.activityInfo.name.equals(r.info.name)) {
2606 // We found the current one... the next matching is
2610 aInfo = resolves.get(i).activityInfo;
2615 } catch (RemoteException e) {
2618 if (aInfo == null) {
2619 // Nobody who is next!
2620 ActivityOptions.abort(options);
2624 intent.setComponent(new ComponentName(
2625 aInfo.applicationInfo.packageName, aInfo.name));
2626 intent.setFlags(intent.getFlags()&~(
2627 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2628 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2629 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2630 Intent.FLAG_ACTIVITY_NEW_TASK));
2632 // Okay now we need to start the new activity, replacing the
2633 // currently running activity. This is a little tricky because
2634 // we want to start the new one as if the current one is finished,
2635 // but not finish the current one first so that there is no flicker.
2637 final boolean wasFinishing = r.finishing;
2640 // Propagate reply information over to the new activity.
2641 final ActivityRecord resultTo = r.resultTo;
2642 final String resultWho = r.resultWho;
2643 final int requestCode = r.requestCode;
2645 if (resultTo != null) {
2646 resultTo.removeResultsLocked(r, resultWho, requestCode);
2649 final long origId = Binder.clearCallingIdentity();
2650 int res = mMainStack.startActivityLocked(r.app.thread, intent,
2651 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2652 resultWho, requestCode, -1, r.launchedFromUid, 0,
2653 options, false, null);
2654 Binder.restoreCallingIdentity(origId);
2656 r.finishing = wasFinishing;
2657 if (res != ActivityManager.START_SUCCESS) {
2664 final int startActivityInPackage(int uid,
2665 Intent intent, String resolvedType, IBinder resultTo,
2666 String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2668 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2669 false, true, "startActivityInPackage", null);
2671 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2672 resultTo, resultWho, requestCode, startFlags,
2673 null, null, null, null, options, userId);
2677 public final int startActivities(IApplicationThread caller,
2678 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2680 enforceNotIsolatedCaller("startActivities");
2681 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2682 false, true, "startActivity", null);
2683 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
2688 final int startActivitiesInPackage(int uid,
2689 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2690 Bundle options, int userId) {
2692 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2693 false, true, "startActivityInPackage", null);
2694 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
2699 final void addRecentTaskLocked(TaskRecord task) {
2700 int N = mRecentTasks.size();
2701 // Quick case: check if the top-most recent task is the same.
2702 if (N > 0 && mRecentTasks.get(0) == task) {
2705 // Remove any existing entries that are the same kind of task.
2706 for (int i=0; i<N; i++) {
2707 TaskRecord tr = mRecentTasks.get(i);
2708 if (task.userId == tr.userId
2709 && ((task.affinity != null && task.affinity.equals(tr.affinity))
2710 || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
2711 mRecentTasks.remove(i);
2714 if (task.intent == null) {
2715 // If the new recent task we are adding is not fully
2716 // specified, then replace it with the existing recent task.
2721 if (N >= MAX_RECENT_TASKS) {
2722 mRecentTasks.remove(N-1);
2724 mRecentTasks.add(0, task);
2727 public void setRequestedOrientation(IBinder token,
2728 int requestedOrientation) {
2729 synchronized (this) {
2730 ActivityRecord r = mMainStack.isInStackLocked(token);
2734 final long origId = Binder.clearCallingIdentity();
2735 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
2736 Configuration config = mWindowManager.updateOrientationFromAppTokens(
2738 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
2739 if (config != null) {
2740 r.frozenBeforeDestroy = true;
2741 if (!updateConfigurationLocked(config, r, false, false)) {
2742 mMainStack.resumeTopActivityLocked(null);
2745 Binder.restoreCallingIdentity(origId);
2749 public int getRequestedOrientation(IBinder token) {
2750 synchronized (this) {
2751 ActivityRecord r = mMainStack.isInStackLocked(token);
2753 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2755 return mWindowManager.getAppOrientation(r.appToken);
2760 * This is the internal entry point for handling Activity.finish().
2762 * @param token The Binder token referencing the Activity we want to finish.
2763 * @param resultCode Result code, if any, from this Activity.
2764 * @param resultData Result data (Intent), if any, from this Activity.
2766 * @return Returns true if the activity successfully finished, or false if it is still running.
2768 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2769 // Refuse possible leaked file descriptors
2770 if (resultData != null && resultData.hasFileDescriptors() == true) {
2771 throw new IllegalArgumentException("File descriptors passed in Intent");
2774 synchronized(this) {
2775 if (mController != null) {
2776 // Find the first activity that is not finishing.
2777 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
2779 // ask watcher if this is allowed
2780 boolean resumeOK = true;
2782 resumeOK = mController.activityResuming(next.packageName);
2783 } catch (RemoteException e) {
2792 final long origId = Binder.clearCallingIdentity();
2793 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
2794 resultData, "app-request", true);
2795 Binder.restoreCallingIdentity(origId);
2800 public final void finishHeavyWeightApp() {
2801 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2802 != PackageManager.PERMISSION_GRANTED) {
2803 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2804 + Binder.getCallingPid()
2805 + ", uid=" + Binder.getCallingUid()
2806 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2808 throw new SecurityException(msg);
2811 synchronized(this) {
2812 if (mHeavyWeightProcess == null) {
2816 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
2817 mHeavyWeightProcess.activities);
2818 for (int i=0; i<activities.size(); i++) {
2819 ActivityRecord r = activities.get(i);
2821 int index = mMainStack.indexOfTokenLocked(r.appToken);
2823 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
2824 null, "finish-heavy", true);
2829 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2830 mHeavyWeightProcess.userId, 0));
2831 mHeavyWeightProcess = null;
2835 public void crashApplication(int uid, int initialPid, String packageName,
2837 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2838 != PackageManager.PERMISSION_GRANTED) {
2839 String msg = "Permission Denial: crashApplication() from pid="
2840 + Binder.getCallingPid()
2841 + ", uid=" + Binder.getCallingUid()
2842 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2844 throw new SecurityException(msg);
2847 synchronized(this) {
2848 ProcessRecord proc = null;
2850 // Figure out which process to kill. We don't trust that initialPid
2851 // still has any relation to current pids, so must scan through the
2853 synchronized (mPidsSelfLocked) {
2854 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2855 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2859 if (p.pid == initialPid) {
2863 for (String str : p.pkgList) {
2864 if (str.equals(packageName)) {
2872 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
2873 + " initialPid=" + initialPid
2874 + " packageName=" + packageName);
2878 if (proc.thread != null) {
2879 if (proc.pid == Process.myPid()) {
2880 Log.w(TAG, "crashApplication: trying to crash self!");
2883 long ident = Binder.clearCallingIdentity();
2885 proc.thread.scheduleCrash(message);
2886 } catch (RemoteException e) {
2888 Binder.restoreCallingIdentity(ident);
2893 public final void finishSubActivity(IBinder token, String resultWho,
2895 synchronized(this) {
2896 final long origId = Binder.clearCallingIdentity();
2897 mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
2898 Binder.restoreCallingIdentity(origId);
2902 public boolean finishActivityAffinity(IBinder token) {
2903 synchronized(this) {
2904 final long origId = Binder.clearCallingIdentity();
2905 boolean res = mMainStack.finishActivityAffinityLocked(token);
2906 Binder.restoreCallingIdentity(origId);
2911 public boolean willActivityBeVisible(IBinder token) {
2912 synchronized(this) {
2914 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2915 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
2916 if (r.appToken == token) {
2919 if (r.fullscreen && !r.finishing) {
2927 public void overridePendingTransition(IBinder token, String packageName,
2928 int enterAnim, int exitAnim) {
2929 synchronized(this) {
2930 ActivityRecord self = mMainStack.isInStackLocked(token);
2935 final long origId = Binder.clearCallingIdentity();
2937 if (self.state == ActivityState.RESUMED
2938 || self.state == ActivityState.PAUSING) {
2939 mWindowManager.overridePendingAppTransition(packageName,
2940 enterAnim, exitAnim, null);
2943 Binder.restoreCallingIdentity(origId);
2948 * Main function for removing an existing process from the activity manager
2949 * as a result of that process going away. Clears out all connections
2952 private final void handleAppDiedLocked(ProcessRecord app,
2953 boolean restarting, boolean allowRestart) {
2954 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
2956 mLruProcesses.remove(app);
2959 if (mProfileProc == app) {
2960 clearProfilerLocked();
2964 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2965 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
2966 "App died while pausing: " + mMainStack.mPausingActivity);
2967 mMainStack.mPausingActivity = null;
2969 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2970 mMainStack.mLastPausedActivity = null;
2973 // Remove this application's activities from active lists.
2974 boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
2976 app.activities.clear();
2978 if (app.instrumentationClass != null) {
2979 Slog.w(TAG, "Crash of app " + app.processName
2980 + " running instrumentation " + app.instrumentationClass);
2981 Bundle info = new Bundle();
2982 info.putString("shortMsg", "Process crashed.");
2983 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2987 if (!mMainStack.resumeTopActivityLocked(null)) {
2988 // If there was nothing to resume, and we are not already
2989 // restarting this process, but there is a visible activity that
2990 // is hosted by the process... then make sure all visible
2991 // activities are running, taking care of restarting this
2993 if (hasVisibleActivities) {
2994 mMainStack.ensureActivitiesVisibleLocked(null, 0);
3000 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3001 IBinder threadBinder = thread.asBinder();
3002 // Find the application record.
3003 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3004 ProcessRecord rec = mLruProcesses.get(i);
3005 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3012 final ProcessRecord getRecordForAppLocked(
3013 IApplicationThread thread) {
3014 if (thread == null) {
3018 int appIndex = getLRURecordIndexForAppLocked(thread);
3019 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3022 final void appDiedLocked(ProcessRecord app, int pid,
3023 IApplicationThread thread) {
3027 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3028 synchronized (stats) {
3029 stats.noteProcessDiedLocked(app.info.uid, pid);
3032 // Clean up already done if the process has been re-started.
3033 if (app.pid == pid && app.thread != null &&
3034 app.thread.asBinder() == thread.asBinder()) {
3035 if (!app.killedBackground) {
3036 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3039 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3040 if (DEBUG_CLEANUP) Slog.v(
3041 TAG, "Dying app: " + app + ", pid: " + pid
3042 + ", thread: " + thread.asBinder());
3043 boolean doLowMem = app.instrumentationClass == null;
3044 handleAppDiedLocked(app, false, true);
3047 // If there are no longer any background processes running,
3048 // and the app that died was not running instrumentation,
3049 // then tell everyone we are now low on memory.
3050 boolean haveBg = false;
3051 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3052 ProcessRecord rec = mLruProcesses.get(i);
3053 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3060 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
3061 long now = SystemClock.uptimeMillis();
3062 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3063 ProcessRecord rec = mLruProcesses.get(i);
3064 if (rec != app && rec.thread != null &&
3065 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3066 // The low memory report is overriding any current
3067 // state for a GC request. Make sure to do
3068 // heavy/important/visible/foreground processes first.
3069 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
3070 rec.lastRequestedGc = 0;
3072 rec.lastRequestedGc = rec.lastLowMemory;
3074 rec.reportLowMemory = true;
3075 rec.lastLowMemory = now;
3076 mProcessesToGc.remove(rec);
3077 addProcessToGcListLocked(rec);
3080 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
3081 scheduleAppGcsLocked();
3084 } else if (app.pid != pid) {
3085 // A new process has already been started.
3086 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3087 + ") has died and restarted (pid " + app.pid + ").");
3088 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
3089 } else if (DEBUG_PROCESSES) {
3090 Slog.d(TAG, "Received spurious death notification for thread "
3091 + thread.asBinder());
3096 * If a stack trace dump file is configured, dump process stack traces.
3097 * @param clearTraces causes the dump file to be erased prior to the new
3098 * traces being written, if true; when false, the new traces will be
3099 * appended to any existing file content.
3100 * @param firstPids of dalvik VM processes to dump stack traces for first
3101 * @param lastPids of dalvik VM processes to dump stack traces for last
3102 * @param nativeProcs optional list of native process names to dump stack crawls
3103 * @return file containing stack traces, or null if no dump file is configured
3105 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
3106 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3107 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3108 if (tracesPath == null || tracesPath.length() == 0) {
3112 File tracesFile = new File(tracesPath);
3114 File tracesDir = tracesFile.getParentFile();
3115 if (!tracesDir.exists()) {
3116 tracesFile.mkdirs();
3117 if (!SELinux.restorecon(tracesDir)) {
3121 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3123 if (clearTraces && tracesFile.exists()) tracesFile.delete();
3124 tracesFile.createNewFile();
3125 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3126 } catch (IOException e) {
3127 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
3131 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
3135 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
3136 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
3137 // Use a FileObserver to detect when traces finish writing.
3138 // The order of traces is considered important to maintain for legibility.
3139 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3140 public synchronized void onEvent(int event, String path) { notify(); }
3144 observer.startWatching();
3146 // First collect all of the stacks of the most important pids.
3147 if (firstPids != null) {
3149 int num = firstPids.size();
3150 for (int i = 0; i < num; i++) {
3151 synchronized (observer) {
3152 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3153 observer.wait(200); // Wait for write-close, give up after 200msec
3156 } catch (InterruptedException e) {
3161 // Next measure CPU usage.
3162 if (processStats != null) {
3163 processStats.init();
3165 processStats.update();
3167 synchronized (processStats) {
3168 processStats.wait(500); // measure over 1/2 second.
3170 } catch (InterruptedException e) {
3172 processStats.update();
3174 // We'll take the stack crawls of just the top apps using CPU.
3175 final int N = processStats.countWorkingStats();
3177 for (int i=0; i<N && numProcs<5; i++) {
3178 ProcessStats.Stats stats = processStats.getWorkingStats(i);
3179 if (lastPids.indexOfKey(stats.pid) >= 0) {
3182 synchronized (observer) {
3183 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3184 observer.wait(200); // Wait for write-close, give up after 200msec
3186 } catch (InterruptedException e) {
3195 observer.stopWatching();
3198 if (nativeProcs != null) {
3199 int[] pids = Process.getPidsForCommands(nativeProcs);
3201 for (int pid : pids) {
3202 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3208 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
3209 if (true || IS_USER_BUILD) {
3212 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3213 if (tracesPath == null || tracesPath.length() == 0) {
3217 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3218 StrictMode.allowThreadDiskWrites();
3220 final File tracesFile = new File(tracesPath);
3221 final File tracesDir = tracesFile.getParentFile();
3222 final File tracesTmp = new File(tracesDir, "__tmp__");
3224 if (!tracesDir.exists()) {
3225 tracesFile.mkdirs();
3226 if (!SELinux.restorecon(tracesDir.getPath())) {
3230 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3232 if (tracesFile.exists()) {
3234 tracesFile.renameTo(tracesTmp);
3236 StringBuilder sb = new StringBuilder();
3237 Time tobj = new Time();
3238 tobj.set(System.currentTimeMillis());
3239 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3241 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3242 sb.append(" since ");
3244 FileOutputStream fos = new FileOutputStream(tracesFile);
3245 fos.write(sb.toString().getBytes());
3247 fos.write("\n*** No application process!".getBytes());
3250 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3251 } catch (IOException e) {
3252 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3257 ArrayList<Integer> firstPids = new ArrayList<Integer>();
3258 firstPids.add(app.pid);
3259 dumpStackTraces(tracesPath, firstPids, null, null, null);
3262 File lastTracesFile = null;
3263 File curTracesFile = null;
3264 for (int i=9; i>=0; i--) {
3265 String name = String.format("slow%02d.txt", i);
3266 curTracesFile = new File(tracesDir, name);
3267 if (curTracesFile.exists()) {
3268 if (lastTracesFile != null) {
3269 curTracesFile.renameTo(lastTracesFile);
3271 curTracesFile.delete();
3274 lastTracesFile = curTracesFile;
3276 tracesFile.renameTo(curTracesFile);
3277 if (tracesTmp.exists()) {
3278 tracesTmp.renameTo(tracesFile);
3281 StrictMode.setThreadPolicy(oldPolicy);
3285 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3286 ActivityRecord parent, boolean aboveSystem, final String annotation) {
3287 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3288 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3290 if (mController != null) {
3292 // 0 == continue, -1 = kill process immediately
3293 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3294 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3295 } catch (RemoteException e) {
3300 long anrTime = SystemClock.uptimeMillis();
3301 if (MONITOR_CPU_USAGE) {
3302 updateCpuStatsNow();
3305 synchronized (this) {
3306 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3307 if (mShuttingDown) {
3308 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3310 } else if (app.notResponding) {
3311 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3313 } else if (app.crashing) {
3314 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3318 // In case we come through here for the same app before completing
3319 // this one, mark as anring now so we will bail out.
3320 app.notResponding = true;
3322 // Log the ANR to the event log.
3323 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3324 app.processName, app.info.flags, annotation);
3326 // Dump thread traces as quickly as we can, starting with "interesting" processes.
3327 firstPids.add(app.pid);
3329 int parentPid = app.pid;
3330 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
3331 if (parentPid != app.pid) firstPids.add(parentPid);
3333 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
3335 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3336 ProcessRecord r = mLruProcesses.get(i);
3337 if (r != null && r.thread != null) {
3339 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3343 lastPids.put(pid, Boolean.TRUE);
3350 // Log the ANR to the main log.
3351 StringBuilder info = new StringBuilder();
3353 info.append("ANR in ").append(app.processName);
3354 if (activity != null && activity.shortComponentName != null) {
3355 info.append(" (").append(activity.shortComponentName).append(")");
3358 if (annotation != null) {
3359 info.append("Reason: ").append(annotation).append("\n");
3361 if (parent != null && parent != activity) {
3362 info.append("Parent: ").append(parent.shortComponentName).append("\n");
3365 final ProcessStats processStats = new ProcessStats(true);
3367 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
3369 String cpuInfo = null;
3370 if (MONITOR_CPU_USAGE) {
3371 updateCpuStatsNow();
3372 synchronized (mProcessStatsThread) {
3373 cpuInfo = mProcessStats.printCurrentState(anrTime);
3375 info.append(processStats.printCurrentLoad());
3376 info.append(cpuInfo);
3379 info.append(processStats.printCurrentState(anrTime));
3381 Slog.e(TAG, info.toString());
3382 if (tracesFile == null) {
3383 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3384 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3387 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3388 cpuInfo, tracesFile, null);
3390 if (mController != null) {
3392 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3393 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
3395 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3398 } catch (RemoteException e) {
3403 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3404 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3405 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
3407 synchronized (this) {
3408 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
3409 Slog.w(TAG, "Killing " + app + ": background ANR");
3410 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
3411 app.processName, app.setAdj, "background ANR");
3412 Process.killProcessQuiet(app.pid);
3416 // Set the app's notResponding state, and look up the errorReportReceiver
3417 makeAppNotRespondingLocked(app,
3418 activity != null ? activity.shortComponentName : null,
3419 annotation != null ? "ANR " + annotation : "ANR",
3422 // Bring up the infamous App Not Responding dialog
3423 Message msg = Message.obtain();
3424 HashMap map = new HashMap();
3425 msg.what = SHOW_NOT_RESPONDING_MSG;
3427 msg.arg1 = aboveSystem ? 1 : 0;
3428 map.put("app", app);
3429 if (activity != null) {
3430 map.put("activity", activity);
3433 mHandler.sendMessage(msg);
3437 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3438 if (!mLaunchWarningShown) {
3439 mLaunchWarningShown = true;
3440 mHandler.post(new Runnable() {
3443 synchronized (ActivityManagerService.this) {
3444 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3446 mHandler.postDelayed(new Runnable() {
3449 synchronized (ActivityManagerService.this) {
3451 mLaunchWarningShown = false;
3461 public boolean clearApplicationUserData(final String packageName,
3462 final IPackageDataObserver observer, int userId) {
3463 enforceNotIsolatedCaller("clearApplicationUserData");
3464 int uid = Binder.getCallingUid();
3465 int pid = Binder.getCallingPid();
3466 userId = handleIncomingUser(pid, uid,
3467 userId, false, true, "clearApplicationUserData", null);
3468 long callingId = Binder.clearCallingIdentity();
3470 IPackageManager pm = AppGlobals.getPackageManager();
3472 synchronized(this) {
3474 pkgUid = pm.getPackageUid(packageName, userId);
3475 } catch (RemoteException e) {
3478 Slog.w(TAG, "Invalid packageName:" + packageName);
3481 if (uid == pkgUid || checkComponentPermission(
3482 android.Manifest.permission.CLEAR_APP_USER_DATA,
3484 == PackageManager.PERMISSION_GRANTED) {
3485 forceStopPackageLocked(packageName, pkgUid);
3487 throw new SecurityException(pid+" does not have permission:"+
3488 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3489 "for process:"+packageName);
3494 //clear application user data
3495 pm.clearApplicationUserData(packageName, observer, userId);
3496 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3497 Uri.fromParts("package", packageName, null));
3498 intent.putExtra(Intent.EXTRA_UID, pkgUid);
3499 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3500 null, null, 0, null, null, null, false, false, userId);
3501 } catch (RemoteException e) {
3504 Binder.restoreCallingIdentity(callingId);
3509 public void killBackgroundProcesses(final String packageName, int userId) {
3510 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3511 != PackageManager.PERMISSION_GRANTED &&
3512 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3513 != PackageManager.PERMISSION_GRANTED) {
3514 String msg = "Permission Denial: killBackgroundProcesses() from pid="
3515 + Binder.getCallingPid()
3516 + ", uid=" + Binder.getCallingUid()
3517 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3519 throw new SecurityException(msg);
3522 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3523 userId, true, true, "killBackgroundProcesses", null);
3524 long callingId = Binder.clearCallingIdentity();
3526 IPackageManager pm = AppGlobals.getPackageManager();
3527 synchronized(this) {
3530 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
3531 } catch (RemoteException e) {
3534 Slog.w(TAG, "Invalid packageName: " + packageName);
3537 killPackageProcessesLocked(packageName, appId, userId,
3538 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3541 Binder.restoreCallingIdentity(callingId);
3545 public void killAllBackgroundProcesses() {
3546 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3547 != PackageManager.PERMISSION_GRANTED) {
3548 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3549 + Binder.getCallingPid()
3550 + ", uid=" + Binder.getCallingUid()
3551 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3553 throw new SecurityException(msg);
3556 long callingId = Binder.clearCallingIdentity();
3558 synchronized(this) {
3559 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3560 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3561 final int NA = apps.size();
3562 for (int ia=0; ia<NA; ia++) {
3563 ProcessRecord app = apps.valueAt(ia);
3564 if (app.persistent) {
3565 // we don't kill persistent processes
3570 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3577 int N = procs.size();
3578 for (int i=0; i<N; i++) {
3579 removeProcessLocked(procs.get(i), false, true, "kill all background");
3583 Binder.restoreCallingIdentity(callingId);
3587 public void forceStopPackage(final String packageName, int userId) {
3588 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3589 != PackageManager.PERMISSION_GRANTED) {
3590 String msg = "Permission Denial: forceStopPackage() from pid="
3591 + Binder.getCallingPid()
3592 + ", uid=" + Binder.getCallingUid()
3593 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3595 throw new SecurityException(msg);
3597 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
3598 userId, true, true, "forceStopPackage", null);
3599 long callingId = Binder.clearCallingIdentity();
3601 IPackageManager pm = AppGlobals.getPackageManager();
3602 synchronized(this) {
3603 int[] users = userId == UserHandle.USER_ALL
3604 ? getUsersLocked() : new int[] { userId };
3605 for (int user : users) {
3608 pkgUid = pm.getPackageUid(packageName, user);
3609 } catch (RemoteException e) {
3612 Slog.w(TAG, "Invalid packageName: " + packageName);
3616 pm.setPackageStoppedState(packageName, true, user);
3617 } catch (RemoteException e) {
3618 } catch (IllegalArgumentException e) {
3619 Slog.w(TAG, "Failed trying to unstop package "
3620 + packageName + ": " + e);
3622 if (isUserRunningLocked(user, false)) {
3623 forceStopPackageLocked(packageName, pkgUid);
3628 Binder.restoreCallingIdentity(callingId);
3633 * The pkg name and app id have to be specified.
3635 public void killApplicationWithAppId(String pkg, int appid) {
3639 // Make sure the uid is valid.
3641 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
3644 int callerUid = Binder.getCallingUid();
3645 // Only the system server can kill an application
3646 if (callerUid == Process.SYSTEM_UID) {
3647 // Post an aysnc message to kill the application
3648 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3652 mHandler.sendMessage(msg);
3654 throw new SecurityException(callerUid + " cannot kill pkg: " +
3659 public void closeSystemDialogs(String reason) {
3660 enforceNotIsolatedCaller("closeSystemDialogs");
3662 final int pid = Binder.getCallingPid();
3663 final int uid = Binder.getCallingUid();
3664 final long origId = Binder.clearCallingIdentity();
3666 synchronized (this) {
3667 // Only allow this from foreground processes, so that background
3668 // applications can't abuse it to prevent system UI from being shown.
3669 if (uid >= Process.FIRST_APPLICATION_UID) {
3671 synchronized (mPidsSelfLocked) {
3672 proc = mPidsSelfLocked.get(pid);
3674 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3675 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3676 + " from background process " + proc);
3680 closeSystemDialogsLocked(reason);
3683 Binder.restoreCallingIdentity(origId);
3687 void closeSystemDialogsLocked(String reason) {
3688 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
3689 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3690 | Intent.FLAG_RECEIVER_FOREGROUND);
3691 if (reason != null) {
3692 intent.putExtra("reason", reason);
3694 mWindowManager.closeSystemDialogs(reason);
3696 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3697 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3698 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
3699 r.stack.finishActivityLocked(r, i,
3700 Activity.RESULT_CANCELED, null, "close-sys", true);
3704 broadcastIntentLocked(null, null, intent, null,
3705 null, 0, null, null, null, false, false, -1,
3706 Process.SYSTEM_UID, UserHandle.USER_ALL);
3709 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
3710 throws RemoteException {
3711 enforceNotIsolatedCaller("getProcessMemoryInfo");
3712 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3713 for (int i=pids.length-1; i>=0; i--) {
3714 infos[i] = new Debug.MemoryInfo();
3715 Debug.getMemoryInfo(pids[i], infos[i]);
3720 public long[] getProcessPss(int[] pids) throws RemoteException {
3721 enforceNotIsolatedCaller("getProcessPss");
3722 long[] pss = new long[pids.length];
3723 for (int i=pids.length-1; i>=0; i--) {
3724 pss[i] = Debug.getPss(pids[i]);
3729 public void killApplicationProcess(String processName, int uid) {
3730 if (processName == null) {
3734 int callerUid = Binder.getCallingUid();
3735 // Only the system server can kill an application
3736 if (callerUid == Process.SYSTEM_UID) {
3737 synchronized (this) {
3738 ProcessRecord app = getProcessRecordLocked(processName, uid);
3739 if (app != null && app.thread != null) {
3741 app.thread.scheduleSuicide();
3742 } catch (RemoteException e) {
3743 // If the other end already died, then our work here is done.
3746 Slog.w(TAG, "Process/uid not found attempting kill of "
3747 + processName + " / " + uid);
3751 throw new SecurityException(callerUid + " cannot kill app process: " +
3756 private void forceStopPackageLocked(final String packageName, int uid) {
3757 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3758 false, true, false, UserHandle.getUserId(uid));
3759 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3760 Uri.fromParts("package", packageName, null));
3761 if (!mProcessesReady) {
3762 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3763 | Intent.FLAG_RECEIVER_FOREGROUND);
3765 intent.putExtra(Intent.EXTRA_UID, uid);
3766 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
3767 broadcastIntentLocked(null, null, intent,
3768 null, null, 0, null, null, null,
3770 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
3773 private void forceStopUserLocked(int userId) {
3774 forceStopPackageLocked(null, -1, false, false, true, false, userId);
3775 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3776 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3777 | Intent.FLAG_RECEIVER_FOREGROUND);
3778 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3779 broadcastIntentLocked(null, null, intent,
3780 null, null, 0, null, null, null,
3782 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
3785 private final boolean killPackageProcessesLocked(String packageName, int appId,
3786 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3787 boolean doit, boolean evenPersistent, String reason) {
3788 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3790 // Remove all processes this package may have touched: all with the
3791 // same UID (except for the system or root user), and all whose name
3792 // matches the package name.
3793 final String procNamePrefix = packageName != null ? (packageName + ":") : null;
3794 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3795 final int NA = apps.size();
3796 for (int ia=0; ia<NA; ia++) {
3797 ProcessRecord app = apps.valueAt(ia);
3798 if (app.persistent && !evenPersistent) {
3799 // we don't kill persistent processes
3809 // Skip process if it doesn't meet our oom adj requirement.
3810 if (app.setAdj < minOomAdj) {
3814 // If no package is specified, we call all processes under the
3816 if (packageName == null) {
3817 if (app.userId != userId) {
3820 // Package has been specified, we want to hit all processes
3821 // that match it. We need to qualify this by the processes
3822 // that are running under the specified app and user ID.
3824 if (UserHandle.getAppId(app.uid) != appId) {
3827 if (userId != UserHandle.USER_ALL && app.userId != userId) {
3830 if (!app.pkgList.contains(packageName)) {
3835 // Process has passed all conditions, kill it!
3844 int N = procs.size();
3845 for (int i=0; i<N; i++) {
3846 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
3851 private final boolean forceStopPackageLocked(String name, int appId,
3852 boolean callerWillRestart, boolean purgeCache, boolean doit,
3853 boolean evenPersistent, int userId) {
3857 if (userId == UserHandle.USER_ALL && name == null) {
3858 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3861 if (appId < 0 && name != null) {
3863 appId = UserHandle.getAppId(
3864 AppGlobals.getPackageManager().getPackageUid(name, 0));
3865 } catch (RemoteException e) {
3871 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3872 + " user=" + userId);
3874 Slog.i(TAG, "Force stopping user " + userId);
3877 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3878 while (badApps.hasNext()) {
3879 SparseArray<Long> ba = badApps.next();
3880 for (i=ba.size()-1; i>=0; i--) {
3881 boolean remove = false;
3882 final int entUid = ba.keyAt(i);
3884 if (userId == UserHandle.USER_ALL) {
3885 if (UserHandle.getAppId(entUid) == appId) {
3889 if (entUid == UserHandle.getUid(userId, appId)) {
3893 } else if (UserHandle.getUserId(entUid) == userId) {
3900 if (ba.size() == 0) {
3906 boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3907 -100, callerWillRestart, true, doit, evenPersistent,
3908 name == null ? ("force stop user " + userId) : ("force stop " + name));
3910 TaskRecord lastTask = null;
3911 for (i=0; i<mMainStack.mHistory.size(); i++) {
3912 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
3913 final boolean samePackage = r.packageName.equals(name)
3914 || (name == null && r.userId == userId);
3915 if ((userId == UserHandle.USER_ALL || r.userId == userId)
3916 && (samePackage || r.task == lastTask)
3917 && (r.app == null || evenPersistent || !r.app.persistent)) {
3920 // If this activity is just finishing, then it is not
3921 // interesting as far as something to stop.
3926 didSomething = true;
3927 Slog.i(TAG, " Force finishing activity " + r);
3929 if (r.app != null) {
3930 r.app.removed = true;
3935 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3936 null, "force-stop", true)) {
3942 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3946 didSomething = true;
3950 // Remove all sticky broadcasts from this user.
3951 mStickyBroadcasts.remove(userId);
3954 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3955 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3956 userId, providers)) {
3960 didSomething = true;
3962 N = providers.size();
3963 for (i=0; i<N; i++) {
3964 removeDyingProviderLocked(null, providers.get(i), true);
3968 // Remove pending intents. For now we only do this when force
3969 // stopping users, because we have some problems when doing this
3970 // for packages -- app widgets are not currently cleaned up for
3971 // such packages, so they can be left with bad pending intents.
3972 if (mIntentSenderRecords.size() > 0) {
3973 Iterator<WeakReference<PendingIntentRecord>> it
3974 = mIntentSenderRecords.values().iterator();
3975 while (it.hasNext()) {
3976 WeakReference<PendingIntentRecord> wpir = it.next();
3981 PendingIntentRecord pir = wpir.get();
3987 // Stopping user, remove all objects for the user.
3988 if (pir.key.userId != userId) {
3989 // Not the same user, skip it.
3993 if (UserHandle.getAppId(pir.uid) != appId) {
3994 // Different app id, skip it.
3997 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
3998 // Different user, skip it.
4001 if (!pir.key.packageName.equals(name)) {
4002 // Different package, skip it.
4009 didSomething = true;
4011 pir.canceled = true;
4012 if (pir.key.activity != null) {
4013 pir.key.activity.pendingResults.remove(pir.ref);
4020 if (purgeCache && name != null) {
4021 AttributeCache ac = AttributeCache.instance();
4023 ac.removePackage(name);
4027 mMainStack.resumeTopActivityLocked(null);
4028 mMainStack.scheduleIdleLocked();
4032 return didSomething;
4035 private final boolean removeProcessLocked(ProcessRecord app,
4036 boolean callerWillRestart, boolean allowRestart, String reason) {
4037 final String name = app.processName;
4038 final int uid = app.uid;
4039 if (DEBUG_PROCESSES) Slog.d(
4040 TAG, "Force removing proc " + app.toShortString() + " (" + name
4043 mProcessNames.remove(name, uid);
4044 mIsolatedProcesses.remove(app.uid);
4045 if (mHeavyWeightProcess == app) {
4046 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4047 mHeavyWeightProcess.userId, 0));
4048 mHeavyWeightProcess = null;
4050 boolean needRestart = false;
4051 if (app.pid > 0 && app.pid != MY_PID) {
4053 synchronized (mPidsSelfLocked) {
4054 mPidsSelfLocked.remove(pid);
4055 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4057 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
4058 handleAppDiedLocked(app, true, allowRestart);
4059 mLruProcesses.remove(app);
4060 Process.killProcessQuiet(pid);
4062 if (app.persistent && !app.isolated) {
4063 if (!callerWillRestart) {
4064 addAppLocked(app.info, false);
4070 mRemovedProcesses.add(app);
4076 private final void processStartTimedOutLocked(ProcessRecord app) {
4077 final int pid = app.pid;
4078 boolean gone = false;
4079 synchronized (mPidsSelfLocked) {
4080 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4081 if (knownApp != null && knownApp.thread == null) {
4082 mPidsSelfLocked.remove(pid);
4088 Slog.w(TAG, "Process " + app + " failed to attach");
4089 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4090 pid, app.uid, app.processName);
4091 mProcessNames.remove(app.processName, app.uid);
4092 mIsolatedProcesses.remove(app.uid);
4093 if (mHeavyWeightProcess == app) {
4094 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4095 mHeavyWeightProcess.userId, 0));
4096 mHeavyWeightProcess = null;
4098 // Take care of any launching providers waiting for this process.
4099 checkAppInLaunchingProvidersLocked(app, true);
4100 // Take care of any services that are waiting for the process.
4101 mServices.processStartTimedOutLocked(app);
4102 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
4103 app.processName, app.setAdj, "start timeout");
4104 Process.killProcessQuiet(pid);
4105 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
4106 Slog.w(TAG, "Unattached app died before backup, skipping");
4108 IBackupManager bm = IBackupManager.Stub.asInterface(
4109 ServiceManager.getService(Context.BACKUP_SERVICE));
4110 bm.agentDisconnected(app.info.packageName);
4111 } catch (RemoteException e) {
4112 // Can't happen; the backup manager is local
4115 if (isPendingBroadcastProcessLocked(pid)) {
4116 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
4117 skipPendingBroadcastLocked(pid);
4120 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
4124 private final boolean attachApplicationLocked(IApplicationThread thread,
4127 // Find the application record that is being attached... either via
4128 // the pid if we are running in multiple processes, or just pull the
4129 // next app record if we are emulating process with anonymous threads.
4131 if (pid != MY_PID && pid >= 0) {
4132 synchronized (mPidsSelfLocked) {
4133 app = mPidsSelfLocked.get(pid);
4140 Slog.w(TAG, "No pending application record for pid " + pid
4141 + " (IApplicationThread " + thread + "); dropping process");
4142 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
4143 if (pid > 0 && pid != MY_PID) {
4144 Process.killProcessQuiet(pid);
4147 thread.scheduleExit();
4148 } catch (Exception e) {
4149 // Ignore exceptions.
4155 // If this application record is still attached to a previous
4156 // process, clean it up now.
4157 if (app.thread != null) {
4158 handleAppDiedLocked(app, true, true);
4161 // Tell the process all about itself.
4163 if (localLOGV) Slog.v(
4164 TAG, "Binding process pid " + pid + " to record " + app);
4166 String processName = app.processName;
4168 AppDeathRecipient adr = new AppDeathRecipient(
4170 thread.asBinder().linkToDeath(adr, 0);
4171 app.deathRecipient = adr;
4172 } catch (RemoteException e) {
4173 app.resetPackageList();
4174 startProcessLocked(app, "link fail", processName);
4178 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
4180 app.thread = thread;
4181 app.curAdj = app.setAdj = -100;
4182 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4183 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
4184 app.forcingToForeground = null;
4185 app.foregroundServices = false;
4186 app.hasShownUi = false;
4187 app.debugging = false;
4189 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4191 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
4192 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
4195 Slog.i(TAG, "Launching preboot mode app: " + app);
4198 if (localLOGV) Slog.v(
4199 TAG, "New app record " + app
4200 + " thread=" + thread.asBinder() + " pid=" + pid);
4202 int testMode = IApplicationThread.DEBUG_OFF;
4203 if (mDebugApp != null && mDebugApp.equals(processName)) {
4204 testMode = mWaitForDebugger
4205 ? IApplicationThread.DEBUG_WAIT
4206 : IApplicationThread.DEBUG_ON;
4207 app.debugging = true;
4208 if (mDebugTransient) {
4209 mDebugApp = mOrigDebugApp;
4210 mWaitForDebugger = mOrigWaitForDebugger;
4213 String profileFile = app.instrumentationProfileFile;
4214 ParcelFileDescriptor profileFd = null;
4215 boolean profileAutoStop = false;
4216 if (mProfileApp != null && mProfileApp.equals(processName)) {
4218 profileFile = mProfileFile;
4219 profileFd = mProfileFd;
4220 profileAutoStop = mAutoStopProfiler;
4222 boolean enableOpenGlTrace = false;
4223 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4224 enableOpenGlTrace = true;
4225 mOpenGlTraceApp = null;
4228 // If the app is being launched for restore or full backup, set it up specially
4229 boolean isRestrictedBackupMode = false;
4230 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4231 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
4232 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
4233 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4236 ensurePackageDexOpt(app.instrumentationInfo != null
4237 ? app.instrumentationInfo.packageName
4238 : app.info.packageName);
4239 if (app.instrumentationClass != null) {
4240 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
4242 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
4243 + processName + " with config " + mConfiguration);
4244 ApplicationInfo appInfo = app.instrumentationInfo != null
4245 ? app.instrumentationInfo : app.info;
4246 app.compat = compatibilityInfoForPackageLocked(appInfo);
4247 if (profileFd != null) {
4248 profileFd = profileFd.dup();
4250 thread.bindApplication(processName, appInfo, providers,
4251 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
4252 app.instrumentationArguments, app.instrumentationWatcher, testMode,
4253 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
4254 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
4255 mCoreSettingsObserver.getCoreSettingsLocked());
4256 updateLruProcessLocked(app, false);
4257 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
4258 } catch (Exception e) {
4259 // todo: Yikes! What should we do? For now we will try to
4260 // start another process, but that could easily get us in
4261 // an infinite loop of restarting processes...
4262 Slog.w(TAG, "Exception thrown during bind!", e);
4264 app.resetPackageList();
4265 app.unlinkDeathRecipient();
4266 startProcessLocked(app, "bind fail", processName);
4270 // Remove this record from the list of starting applications.
4271 mPersistentStartingProcesses.remove(app);
4272 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4273 "Attach application locked removing on hold: " + app);
4274 mProcessesOnHold.remove(app);
4276 boolean badApp = false;
4277 boolean didSomething = false;
4279 // See if the top visible activity is waiting to run in this process...
4280 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
4281 if (hr != null && normalMode) {
4282 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
4283 && processName.equals(hr.processName)) {
4286 Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4287 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
4288 didSomething = true;
4290 } catch (Exception e) {
4291 Slog.w(TAG, "Exception in new application when starting activity "
4292 + hr.intent.getComponent().flattenToShortString(), e);
4296 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
4300 // Find any services that should be running in this process...
4303 didSomething |= mServices.attachApplicationLocked(app, processName);
4304 } catch (Exception e) {
4309 // Check if a next-broadcast receiver is in this process...
4310 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
4312 didSomething = sendPendingBroadcastsLocked(app);
4313 } catch (Exception e) {
4314 // If the app died trying to launch the receiver we declare it 'bad'
4319 // Check whether the next backup agent is in this process...
4320 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
4321 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
4322 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
4324 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4325 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4326 mBackupTarget.backupMode);
4327 } catch (Exception e) {
4328 Slog.w(TAG, "Exception scheduling backup agent creation: ");
4329 e.printStackTrace();
4334 // todo: Also need to kill application to deal with all
4335 // kinds of exceptions.
4336 handleAppDiedLocked(app, false, true);
4340 if (!didSomething) {
4341 updateOomAdjLocked();
4347 public final void attachApplication(IApplicationThread thread) {
4348 synchronized (this) {
4349 int callingPid = Binder.getCallingPid();
4350 final long origId = Binder.clearCallingIdentity();
4351 attachApplicationLocked(thread, callingPid);
4352 Binder.restoreCallingIdentity(origId);
4356 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
4357 final long origId = Binder.clearCallingIdentity();
4358 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4359 if (stopProfiling) {
4360 synchronized (this) {
4361 if (mProfileProc == r.app) {
4362 if (mProfileFd != null) {
4365 } catch (IOException e) {
4367 clearProfilerLocked();
4372 Binder.restoreCallingIdentity(origId);
4375 void enableScreenAfterBoot() {
4376 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
4377 SystemClock.uptimeMillis());
4378 mWindowManager.enableScreenAfterBoot();
4380 synchronized (this) {
4381 updateEventDispatchingLocked();
4385 public void showBootMessage(final CharSequence msg, final boolean always) {
4386 enforceNotIsolatedCaller("showBootMessage");
4387 mWindowManager.showBootMessage(msg, always);
4390 public void dismissKeyguardOnNextActivity() {
4391 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
4392 final long token = Binder.clearCallingIdentity();
4394 synchronized (this) {
4395 if (mLockScreenShown) {
4396 mLockScreenShown = false;
4397 comeOutOfSleepIfNeededLocked();
4399 mMainStack.dismissKeyguardOnNextActivityLocked();
4402 Binder.restoreCallingIdentity(token);
4406 final void finishBooting() {
4407 IntentFilter pkgFilter = new IntentFilter();
4408 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4409 pkgFilter.addDataScheme("package");
4410 mContext.registerReceiver(new BroadcastReceiver() {
4412 public void onReceive(Context context, Intent intent) {
4413 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4415 for (String pkg : pkgs) {
4416 synchronized (ActivityManagerService.this) {
4417 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4418 setResultCode(Activity.RESULT_OK);
4427 synchronized (this) {
4428 // Ensure that any processes we had put on hold are now started
4430 final int NP = mProcessesOnHold.size();
4432 ArrayList<ProcessRecord> procs =
4433 new ArrayList<ProcessRecord>(mProcessesOnHold);
4434 for (int ip=0; ip<NP; ip++) {
4435 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4437 startProcessLocked(procs.get(ip), "on-hold", null);
4441 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
4442 // Start looking for apps that are abusing wake locks.
4443 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
4444 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
4445 // Tell anyone interested that we are done booting!
4446 SystemProperties.set("sys.boot_completed", "1");
4447 SystemProperties.set("dev.bootcomplete", "1");
4448 for (int i=0; i<mStartedUsers.size(); i++) {
4449 UserStartedState uss = mStartedUsers.valueAt(i);
4450 if (uss.mState == UserStartedState.STATE_BOOTING) {
4451 uss.mState = UserStartedState.STATE_RUNNING;
4452 final int userId = mStartedUsers.keyAt(i);
4453 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4454 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4455 broadcastIntentLocked(null, null, intent,
4456 null, null, 0, null, null,
4457 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4458 false, false, MY_PID, Process.SYSTEM_UID, userId);
4465 final void ensureBootCompleted() {
4467 boolean enableScreen;
4468 synchronized (this) {
4471 enableScreen = !mBooted;
4480 enableScreenAfterBoot();
4484 public final void activityResumed(IBinder token) {
4485 final long origId = Binder.clearCallingIdentity();
4486 mMainStack.activityResumed(token);
4487 Binder.restoreCallingIdentity(origId);
4490 public final void activityPaused(IBinder token) {
4491 final long origId = Binder.clearCallingIdentity();
4492 mMainStack.activityPaused(token, false);
4493 Binder.restoreCallingIdentity(origId);
4496 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4497 CharSequence description) {
4498 if (localLOGV) Slog.v(
4499 TAG, "Activity stopped: token=" + token);
4501 // Refuse possible leaked file descriptors
4502 if (icicle != null && icicle.hasFileDescriptors()) {
4503 throw new IllegalArgumentException("File descriptors passed in Bundle");
4506 ActivityRecord r = null;
4508 final long origId = Binder.clearCallingIdentity();
4510 synchronized (this) {
4511 r = mMainStack.isInStackLocked(token);
4513 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
4518 sendPendingThumbnail(r, null, null, null, false);
4523 Binder.restoreCallingIdentity(origId);
4526 public final void activityDestroyed(IBinder token) {
4527 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
4528 mMainStack.activityDestroyed(token);
4531 public String getCallingPackage(IBinder token) {
4532 synchronized (this) {
4533 ActivityRecord r = getCallingRecordLocked(token);
4534 return r != null && r.app != null ? r.info.packageName : null;
4538 public ComponentName getCallingActivity(IBinder token) {
4539 synchronized (this) {
4540 ActivityRecord r = getCallingRecordLocked(token);
4541 return r != null ? r.intent.getComponent() : null;
4545 private ActivityRecord getCallingRecordLocked(IBinder token) {
4546 ActivityRecord r = mMainStack.isInStackLocked(token);
4553 public ComponentName getActivityClassForToken(IBinder token) {
4554 synchronized(this) {
4555 ActivityRecord r = mMainStack.isInStackLocked(token);
4559 return r.intent.getComponent();
4563 public String getPackageForToken(IBinder token) {
4564 synchronized(this) {
4565 ActivityRecord r = mMainStack.isInStackLocked(token);
4569 return r.packageName;
4573 public IIntentSender getIntentSender(int type,
4574 String packageName, IBinder token, String resultWho,
4575 int requestCode, Intent[] intents, String[] resolvedTypes,
4576 int flags, Bundle options, int userId) {
4577 enforceNotIsolatedCaller("getIntentSender");
4578 // Refuse possible leaked file descriptors
4579 if (intents != null) {
4580 if (intents.length < 1) {
4581 throw new IllegalArgumentException("Intents array length must be >= 1");
4583 for (int i=0; i<intents.length; i++) {
4584 Intent intent = intents[i];
4585 if (intent != null) {
4586 if (intent.hasFileDescriptors()) {
4587 throw new IllegalArgumentException("File descriptors passed in Intent");
4589 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
4590 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4591 throw new IllegalArgumentException(
4592 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4594 intents[i] = new Intent(intent);
4597 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
4598 throw new IllegalArgumentException(
4599 "Intent array length does not match resolvedTypes length");
4602 if (options != null) {
4603 if (options.hasFileDescriptors()) {
4604 throw new IllegalArgumentException("File descriptors passed in options");
4608 synchronized(this) {
4609 int callingUid = Binder.getCallingUid();
4610 int origUserId = userId;
4611 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
4612 type == ActivityManager.INTENT_SENDER_BROADCAST, false,
4613 "getIntentSender", null);
4614 if (origUserId == UserHandle.USER_CURRENT) {
4615 // We don't want to evaluate this until the pending intent is
4616 // actually executed. However, we do want to always do the
4617 // security checking for it above.
4618 userId = UserHandle.USER_CURRENT;
4621 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
4622 int uid = AppGlobals.getPackageManager()
4623 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4624 if (!UserHandle.isSameApp(callingUid, uid)) {
4625 String msg = "Permission Denial: getIntentSender() from pid="
4626 + Binder.getCallingPid()
4627 + ", uid=" + Binder.getCallingUid()
4628 + ", (need uid=" + uid + ")"
4629 + " is not allowed to send as package " + packageName;
4631 throw new SecurityException(msg);
4635 return getIntentSenderLocked(type, packageName, callingUid, userId,
4636 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
4638 } catch (RemoteException e) {
4639 throw new SecurityException(e);
4644 IIntentSender getIntentSenderLocked(int type, String packageName,
4645 int callingUid, int userId, IBinder token, String resultWho,
4646 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4649 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
4650 ActivityRecord activity = null;
4651 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4652 activity = mMainStack.isInStackLocked(token);
4653 if (activity == null) {
4656 if (activity.finishing) {
4661 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4662 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4663 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4664 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4665 |PendingIntent.FLAG_UPDATE_CURRENT);
4667 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4668 type, packageName, activity, resultWho,
4669 requestCode, intents, resolvedTypes, flags, options, userId);
4670 WeakReference<PendingIntentRecord> ref;
4671 ref = mIntentSenderRecords.get(key);
4672 PendingIntentRecord rec = ref != null ? ref.get() : null;
4674 if (!cancelCurrent) {
4675 if (updateCurrent) {
4676 if (rec.key.requestIntent != null) {
4677 rec.key.requestIntent.replaceExtras(intents != null ?
4678 intents[intents.length - 1] : null);
4680 if (intents != null) {
4681 intents[intents.length-1] = rec.key.requestIntent;
4682 rec.key.allIntents = intents;
4683 rec.key.allResolvedTypes = resolvedTypes;
4685 rec.key.allIntents = null;
4686 rec.key.allResolvedTypes = null;
4691 rec.canceled = true;
4692 mIntentSenderRecords.remove(key);
4697 rec = new PendingIntentRecord(this, key, callingUid);
4698 mIntentSenderRecords.put(key, rec.ref);
4699 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
4700 if (activity.pendingResults == null) {
4701 activity.pendingResults
4702 = new HashSet<WeakReference<PendingIntentRecord>>();
4704 activity.pendingResults.add(rec.ref);
4709 public void cancelIntentSender(IIntentSender sender) {
4710 if (!(sender instanceof PendingIntentRecord)) {
4713 synchronized(this) {
4714 PendingIntentRecord rec = (PendingIntentRecord)sender;
4716 int uid = AppGlobals.getPackageManager()
4717 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4718 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
4719 String msg = "Permission Denial: cancelIntentSender() from pid="
4720 + Binder.getCallingPid()
4721 + ", uid=" + Binder.getCallingUid()
4722 + " is not allowed to cancel packges "
4723 + rec.key.packageName;
4725 throw new SecurityException(msg);
4727 } catch (RemoteException e) {
4728 throw new SecurityException(e);
4730 cancelIntentSenderLocked(rec, true);
4734 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4735 rec.canceled = true;
4736 mIntentSenderRecords.remove(rec.key);
4737 if (cleanActivity && rec.key.activity != null) {
4738 rec.key.activity.pendingResults.remove(rec.ref);
4742 public String getPackageForIntentSender(IIntentSender pendingResult) {
4743 if (!(pendingResult instanceof PendingIntentRecord)) {
4747 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4748 return res.key.packageName;
4749 } catch (ClassCastException e) {
4754 public int getUidForIntentSender(IIntentSender sender) {
4755 if (sender instanceof PendingIntentRecord) {
4757 PendingIntentRecord res = (PendingIntentRecord)sender;
4759 } catch (ClassCastException e) {
4765 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4766 if (!(pendingResult instanceof PendingIntentRecord)) {
4770 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4771 if (res.key.allIntents == null) {
4774 for (int i=0; i<res.key.allIntents.length; i++) {
4775 Intent intent = res.key.allIntents[i];
4776 if (intent.getPackage() != null && intent.getComponent() != null) {
4781 } catch (ClassCastException e) {
4786 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4787 if (!(pendingResult instanceof PendingIntentRecord)) {
4791 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4792 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4796 } catch (ClassCastException e) {
4801 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
4802 if (!(pendingResult instanceof PendingIntentRecord)) {
4806 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4807 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
4808 } catch (ClassCastException e) {
4813 public void setProcessLimit(int max) {
4814 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4815 "setProcessLimit()");
4816 synchronized (this) {
4817 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
4818 mProcessLimitOverride = max;
4823 public int getProcessLimit() {
4824 synchronized (this) {
4825 return mProcessLimitOverride;
4829 void foregroundTokenDied(ForegroundToken token) {
4830 synchronized (ActivityManagerService.this) {
4831 synchronized (mPidsSelfLocked) {
4833 = mForegroundProcesses.get(token.pid);
4837 mForegroundProcesses.remove(token.pid);
4838 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4842 pr.forcingToForeground = null;
4843 pr.foregroundServices = false;
4845 updateOomAdjLocked();
4849 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4850 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4851 "setProcessForeground()");
4852 synchronized(this) {
4853 boolean changed = false;
4855 synchronized (mPidsSelfLocked) {
4856 ProcessRecord pr = mPidsSelfLocked.get(pid);
4857 if (pr == null && isForeground) {
4858 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
4861 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4862 if (oldToken != null) {
4863 oldToken.token.unlinkToDeath(oldToken, 0);
4864 mForegroundProcesses.remove(pid);
4866 pr.forcingToForeground = null;
4870 if (isForeground && token != null) {
4871 ForegroundToken newToken = new ForegroundToken() {
4872 public void binderDied() {
4873 foregroundTokenDied(this);
4877 newToken.token = token;
4879 token.linkToDeath(newToken, 0);
4880 mForegroundProcesses.put(pid, newToken);
4881 pr.forcingToForeground = token;
4883 } catch (RemoteException e) {
4884 // If the process died while doing this, we will later
4885 // do the cleanup with the process death link.
4891 updateOomAdjLocked();
4896 // =========================================================
4898 // =========================================================
4900 static class PermissionController extends IPermissionController.Stub {
4901 ActivityManagerService mActivityManagerService;
4902 PermissionController(ActivityManagerService activityManagerService) {
4903 mActivityManagerService = activityManagerService;
4906 public boolean checkPermission(String permission, int pid, int uid) {
4907 return mActivityManagerService.checkPermission(permission, pid,
4908 uid) == PackageManager.PERMISSION_GRANTED;
4913 * This can be called with or without the global lock held.
4915 int checkComponentPermission(String permission, int pid, int uid,
4916 int owningUid, boolean exported) {
4917 // We might be performing an operation on behalf of an indirect binder
4918 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4919 // client identity accordingly before proceeding.
4920 Identity tlsIdentity = sCallerIdentity.get();
4921 if (tlsIdentity != null) {
4922 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
4923 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4924 uid = tlsIdentity.uid;
4925 pid = tlsIdentity.pid;
4928 if (pid == MY_PID) {
4929 return PackageManager.PERMISSION_GRANTED;
4932 return ActivityManager.checkComponentPermission(permission, uid,
4933 owningUid, exported);
4937 * As the only public entry point for permissions checking, this method
4938 * can enforce the semantic that requesting a check on a null global
4939 * permission is automatically denied. (Internally a null permission
4940 * string is used when calling {@link #checkComponentPermission} in cases
4941 * when only uid-based security is needed.)
4943 * This can be called with or without the global lock held.
4945 public int checkPermission(String permission, int pid, int uid) {
4946 if (permission == null) {
4947 return PackageManager.PERMISSION_DENIED;
4949 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
4953 * Binder IPC calls go through the public entry point.
4954 * This can be called with or without the global lock held.
4956 int checkCallingPermission(String permission) {
4957 return checkPermission(permission,
4958 Binder.getCallingPid(),
4959 UserHandle.getAppId(Binder.getCallingUid()));
4963 * This can be called with or without the global lock held.
4965 void enforceCallingPermission(String permission, String func) {
4966 if (checkCallingPermission(permission)
4967 == PackageManager.PERMISSION_GRANTED) {
4971 String msg = "Permission Denial: " + func + " from pid="
4972 + Binder.getCallingPid()
4973 + ", uid=" + Binder.getCallingUid()
4974 + " requires " + permission;
4976 throw new SecurityException(msg);
4980 * Determine if UID is holding permissions required to access {@link Uri} in
4981 * the given {@link ProviderInfo}. Final permission checking is always done
4982 * in {@link ContentProvider}.
4984 private final boolean checkHoldingPermissionsLocked(
4985 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4986 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4987 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
4989 if (pi.applicationInfo.uid == uid) {
4991 } else if (!pi.exported) {
4995 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4996 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4998 // check if target holds top-level <provider> permissions
4999 if (!readMet && pi.readPermission != null
5000 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5003 if (!writeMet && pi.writePermission != null
5004 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5008 // track if unprotected read/write is allowed; any denied
5009 // <path-permission> below removes this ability
5010 boolean allowDefaultRead = pi.readPermission == null;
5011 boolean allowDefaultWrite = pi.writePermission == null;
5013 // check if target holds any <path-permission> that match uri
5014 final PathPermission[] pps = pi.pathPermissions;
5016 final String path = uri.getPath();
5018 while (i > 0 && (!readMet || !writeMet)) {
5020 PathPermission pp = pps[i];
5021 if (pp.match(path)) {
5023 final String pprperm = pp.getReadPermission();
5024 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5025 + pprperm + " for " + pp.getPath()
5026 + ": match=" + pp.match(path)
5027 + " check=" + pm.checkUidPermission(pprperm, uid));
5028 if (pprperm != null) {
5029 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5032 allowDefaultRead = false;
5037 final String ppwperm = pp.getWritePermission();
5038 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5039 + ppwperm + " for " + pp.getPath()
5040 + ": match=" + pp.match(path)
5041 + " check=" + pm.checkUidPermission(ppwperm, uid));
5042 if (ppwperm != null) {
5043 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5046 allowDefaultWrite = false;
5054 // grant unprotected <provider> read/write, if not blocked by
5055 // <path-permission> above
5056 if (allowDefaultRead) readMet = true;
5057 if (allowDefaultWrite) writeMet = true;
5059 } catch (RemoteException e) {
5063 return readMet && writeMet;
5066 private final boolean checkUriPermissionLocked(Uri uri, int uid,
5068 // Root gets to do everything.
5072 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5073 if (perms == null) return false;
5074 UriPermission perm = perms.get(uri);
5075 if (perm == null) return false;
5076 return (modeFlags&perm.modeFlags) == modeFlags;
5079 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
5080 enforceNotIsolatedCaller("checkUriPermission");
5082 // Another redirected-binder-call permissions check as in
5083 // {@link checkComponentPermission}.
5084 Identity tlsIdentity = sCallerIdentity.get();
5085 if (tlsIdentity != null) {
5086 uid = tlsIdentity.uid;
5087 pid = tlsIdentity.pid;
5090 // Our own process gets to do everything.
5091 if (pid == MY_PID) {
5092 return PackageManager.PERMISSION_GRANTED;
5094 synchronized(this) {
5095 return checkUriPermissionLocked(uri, uid, modeFlags)
5096 ? PackageManager.PERMISSION_GRANTED
5097 : PackageManager.PERMISSION_DENIED;
5102 * Check if the targetPkg can be granted permission to access uri by
5103 * the callingUid using the given modeFlags. Throws a security exception
5104 * if callingUid is not allowed to do this. Returns the uid of the target
5105 * if the URI permission grant should be performed; returns -1 if it is not
5106 * needed (for example targetPkg already has permission to access the URI).
5107 * If you already know the uid of the target, you can supply it in
5108 * lastTargetUid else set that to -1.
5110 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
5111 Uri uri, int modeFlags, int lastTargetUid) {
5112 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5113 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5114 if (modeFlags == 0) {
5118 if (targetPkg != null) {
5119 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5120 "Checking grant " + targetPkg + " permission to " + uri);
5123 final IPackageManager pm = AppGlobals.getPackageManager();
5125 // If this is not a content: uri, we can't do anything with it.
5126 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
5127 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5128 "Can't grant URI permission for non-content URI: " + uri);
5132 String name = uri.getAuthority();
5133 ProviderInfo pi = null;
5134 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
5135 UserHandle.getUserId(callingUid));
5140 pi = pm.resolveContentProvider(name,
5141 PackageManager.GET_URI_PERMISSION_PATTERNS,
5142 UserHandle.getUserId(callingUid));
5143 } catch (RemoteException ex) {
5147 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
5151 int targetUid = lastTargetUid;
5152 if (targetUid < 0 && targetPkg != null) {
5154 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
5155 if (targetUid < 0) {
5156 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5157 "Can't grant URI permission no uid for: " + targetPkg);
5160 } catch (RemoteException ex) {
5165 if (targetUid >= 0) {
5166 // First... does the target actually need this permission?
5167 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5168 // No need to grant the target this permission.
5169 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5170 "Target " + targetPkg + " already has full permission to " + uri);
5174 // First... there is no target package, so can anyone access it?
5175 boolean allowed = pi.exported;
5176 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5177 if (pi.readPermission != null) {
5181 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5182 if (pi.writePermission != null) {
5191 // Second... is the provider allowing granting of URI permissions?
5192 if (!pi.grantUriPermissions) {
5193 throw new SecurityException("Provider " + pi.packageName
5195 + " does not allow granting of Uri permissions (uri "
5198 if (pi.uriPermissionPatterns != null) {
5199 final int N = pi.uriPermissionPatterns.length;
5200 boolean allowed = false;
5201 for (int i=0; i<N; i++) {
5202 if (pi.uriPermissionPatterns[i] != null
5203 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5209 throw new SecurityException("Provider " + pi.packageName
5211 + " does not allow granting of permission to path of Uri "
5216 // Third... does the caller itself have permission to access
5218 if (callingUid != Process.myUid()) {
5219 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5220 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5221 throw new SecurityException("Uid " + callingUid
5222 + " does not have permission to uri " + uri);
5230 public int checkGrantUriPermission(int callingUid, String targetPkg,
5231 Uri uri, int modeFlags) {
5232 enforceNotIsolatedCaller("checkGrantUriPermission");
5233 synchronized(this) {
5234 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5238 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5239 Uri uri, int modeFlags, UriPermissionOwner owner) {
5240 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5241 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5242 if (modeFlags == 0) {
5246 // So here we are: the caller has the assumed permission
5247 // to the uri, and the target doesn't. Let's now give this to
5250 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5251 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
5253 HashMap<Uri, UriPermission> targetUris
5254 = mGrantedUriPermissions.get(targetUid);
5255 if (targetUris == null) {
5256 targetUris = new HashMap<Uri, UriPermission>();
5257 mGrantedUriPermissions.put(targetUid, targetUris);
5260 UriPermission perm = targetUris.get(uri);
5262 perm = new UriPermission(targetUid, uri);
5263 targetUris.put(uri, perm);
5266 perm.modeFlags |= modeFlags;
5267 if (owner == null) {
5268 perm.globalModeFlags |= modeFlags;
5270 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5271 perm.readOwners.add(owner);
5272 owner.addReadPermission(perm);
5274 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5275 perm.writeOwners.add(owner);
5276 owner.addWritePermission(perm);
5281 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5282 int modeFlags, UriPermissionOwner owner) {
5283 if (targetPkg == null) {
5284 throw new NullPointerException("targetPkg");
5287 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
5288 if (targetUid < 0) {
5292 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5295 static class NeededUriGrants extends ArrayList<Uri> {
5296 final String targetPkg;
5297 final int targetUid;
5300 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5301 targetPkg = _targetPkg;
5302 targetUid = _targetUid;
5308 * Like checkGrantUriPermissionLocked, but takes an Intent.
5310 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5311 String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
5312 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5313 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5314 + " clip=" + (intent != null ? intent.getClipData() : null)
5315 + " from " + intent + "; flags=0x"
5316 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5318 if (targetPkg == null) {
5319 throw new NullPointerException("targetPkg");
5322 if (intent == null) {
5325 Uri data = intent.getData();
5326 ClipData clip = intent.getClipData();
5327 if (data == null && clip == null) {
5331 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5332 mode, needed != null ? needed.targetUid : -1);
5334 if (needed == null) {
5335 needed = new NeededUriGrants(targetPkg, target, mode);
5341 for (int i=0; i<clip.getItemCount(); i++) {
5342 Uri uri = clip.getItemAt(i).getUri();
5345 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5346 mode, needed != null ? needed.targetUid : -1);
5348 if (needed == null) {
5349 needed = new NeededUriGrants(targetPkg, target, mode);
5354 Intent clipIntent = clip.getItemAt(i).getIntent();
5355 if (clipIntent != null) {
5356 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5357 callingUid, targetPkg, clipIntent, mode, needed);
5358 if (newNeeded != null) {
5370 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5372 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5373 UriPermissionOwner owner) {
5374 if (needed != null) {
5375 for (int i=0; i<needed.size(); i++) {
5376 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5377 needed.get(i), needed.flags, owner);
5382 void grantUriPermissionFromIntentLocked(int callingUid,
5383 String targetPkg, Intent intent, UriPermissionOwner owner) {
5384 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
5385 intent, intent != null ? intent.getFlags() : 0, null);
5386 if (needed == null) {
5390 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
5393 public void grantUriPermission(IApplicationThread caller, String targetPkg,
5394 Uri uri, int modeFlags) {
5395 enforceNotIsolatedCaller("grantUriPermission");
5396 synchronized(this) {
5397 final ProcessRecord r = getRecordForAppLocked(caller);
5399 throw new SecurityException("Unable to find app for caller "
5401 + " when granting permission to uri " + uri);
5403 if (targetPkg == null) {
5404 throw new IllegalArgumentException("null target");
5407 throw new IllegalArgumentException("null uri");
5410 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
5415 void removeUriPermissionIfNeededLocked(UriPermission perm) {
5416 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5417 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5418 HashMap<Uri, UriPermission> perms
5419 = mGrantedUriPermissions.get(perm.uid);
5420 if (perms != null) {
5421 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5422 "Removing " + perm.uid + " permission to " + perm.uri);
5423 perms.remove(perm.uri);
5424 if (perms.size() == 0) {
5425 mGrantedUriPermissions.remove(perm.uid);
5431 private void revokeUriPermissionLocked(int callingUid, Uri uri,
5433 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5434 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5435 if (modeFlags == 0) {
5439 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5440 "Revoking all granted permissions to " + uri);
5442 final IPackageManager pm = AppGlobals.getPackageManager();
5444 final String authority = uri.getAuthority();
5445 ProviderInfo pi = null;
5446 int userId = UserHandle.getUserId(callingUid);
5447 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
5452 pi = pm.resolveContentProvider(authority,
5453 PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
5454 } catch (RemoteException ex) {
5458 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
5462 // Does the caller have this permission on the URI?
5463 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5464 // Right now, if you are not the original owner of the permission,
5465 // you are not allowed to revoke it.
5466 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5467 throw new SecurityException("Uid " + callingUid
5468 + " does not have permission to uri " + uri);
5472 // Go through all of the permissions and remove any that match.
5473 final List<String> SEGMENTS = uri.getPathSegments();
5474 if (SEGMENTS != null) {
5475 final int NS = SEGMENTS.size();
5476 int N = mGrantedUriPermissions.size();
5477 for (int i=0; i<N; i++) {
5478 HashMap<Uri, UriPermission> perms
5479 = mGrantedUriPermissions.valueAt(i);
5480 Iterator<UriPermission> it = perms.values().iterator();
5482 while (it.hasNext()) {
5483 UriPermission perm = it.next();
5484 Uri targetUri = perm.uri;
5485 if (!authority.equals(targetUri.getAuthority())) {
5488 List<String> targetSegments = targetUri.getPathSegments();
5489 if (targetSegments == null) {
5492 if (targetSegments.size() < NS) {
5495 for (int j=0; j<NS; j++) {
5496 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5500 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5501 "Revoking " + perm.uid + " permission to " + perm.uri);
5502 perm.clearModes(modeFlags);
5503 if (perm.modeFlags == 0) {
5507 if (perms.size() == 0) {
5508 mGrantedUriPermissions.remove(
5509 mGrantedUriPermissions.keyAt(i));
5517 public void revokeUriPermission(IApplicationThread caller, Uri uri,
5519 enforceNotIsolatedCaller("revokeUriPermission");
5520 synchronized(this) {
5521 final ProcessRecord r = getRecordForAppLocked(caller);
5523 throw new SecurityException("Unable to find app for caller "
5525 + " when revoking permission to uri " + uri);
5528 Slog.w(TAG, "revokeUriPermission: null uri");
5532 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5533 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5534 if (modeFlags == 0) {
5538 final IPackageManager pm = AppGlobals.getPackageManager();
5540 final String authority = uri.getAuthority();
5541 ProviderInfo pi = null;
5542 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
5547 pi = pm.resolveContentProvider(authority,
5548 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
5549 } catch (RemoteException ex) {
5553 Slog.w(TAG, "No content provider found for permission revoke: "
5554 + uri.toSafeString());
5558 revokeUriPermissionLocked(r.uid, uri, modeFlags);
5563 public IBinder newUriPermissionOwner(String name) {
5564 enforceNotIsolatedCaller("newUriPermissionOwner");
5565 synchronized(this) {
5566 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5567 return owner.getExternalTokenLocked();
5572 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5573 Uri uri, int modeFlags) {
5574 synchronized(this) {
5575 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5576 if (owner == null) {
5577 throw new IllegalArgumentException("Unknown owner: " + token);
5579 if (fromUid != Binder.getCallingUid()) {
5580 if (Binder.getCallingUid() != Process.myUid()) {
5581 // Only system code can grant URI permissions on behalf
5583 throw new SecurityException("nice try");
5586 if (targetPkg == null) {
5587 throw new IllegalArgumentException("null target");
5590 throw new IllegalArgumentException("null uri");
5593 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5598 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5599 synchronized(this) {
5600 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5601 if (owner == null) {
5602 throw new IllegalArgumentException("Unknown owner: " + token);
5606 owner.removeUriPermissionsLocked(mode);
5608 owner.removeUriPermissionLocked(uri, mode);
5613 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5614 synchronized (this) {
5616 who != null ? getRecordForAppLocked(who) : null;
5617 if (app == null) return;
5619 Message msg = Message.obtain();
5620 msg.what = WAIT_FOR_DEBUGGER_MSG;
5622 msg.arg1 = waiting ? 1 : 0;
5623 mHandler.sendMessage(msg);
5627 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
5628 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5629 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
5630 outInfo.availMem = Process.getFreeMemory();
5631 outInfo.totalMem = Process.getTotalMemory();
5632 outInfo.threshold = homeAppMem;
5633 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5634 outInfo.hiddenAppThreshold = hiddenAppMem;
5635 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
5636 ProcessList.SERVICE_ADJ);
5637 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5638 ProcessList.VISIBLE_APP_ADJ);
5639 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5640 ProcessList.FOREGROUND_APP_ADJ);
5643 // =========================================================
5645 // =========================================================
5647 public List getTasks(int maxNum, int flags,
5648 IThumbnailReceiver receiver) {
5649 ArrayList list = new ArrayList();
5651 PendingThumbnailsRecord pending = null;
5652 IApplicationThread topThumbnail = null;
5653 ActivityRecord topRecord = null;
5655 synchronized(this) {
5656 if (localLOGV) Slog.v(
5657 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5658 + ", receiver=" + receiver);
5660 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5661 != PackageManager.PERMISSION_GRANTED) {
5662 if (receiver != null) {
5663 // If the caller wants to wait for pending thumbnails,
5664 // it ain't gonna get them.
5666 receiver.finished();
5667 } catch (RemoteException ex) {
5670 String msg = "Permission Denial: getTasks() from pid="
5671 + Binder.getCallingPid()
5672 + ", uid=" + Binder.getCallingUid()
5673 + " requires " + android.Manifest.permission.GET_TASKS;
5675 throw new SecurityException(msg);
5678 int pos = mMainStack.mHistory.size()-1;
5679 ActivityRecord next =
5680 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5681 ActivityRecord top = null;
5682 TaskRecord curTask = null;
5683 int numActivities = 0;
5685 while (pos >= 0 && maxNum > 0) {
5686 final ActivityRecord r = next;
5688 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
5690 // Initialize state for next task if needed.
5692 (top.state == ActivityState.INITIALIZING
5693 && top.task == r.task)) {
5696 numActivities = numRunning = 0;
5699 // Add 'r' into the current task.
5701 if (r.app != null && r.app.thread != null) {
5705 if (localLOGV) Slog.v(
5706 TAG, r.intent.getComponent().flattenToShortString()
5707 + ": task=" + r.task);
5709 // If the next one is a different task, generate a new
5710 // TaskInfo entry for what we have.
5711 if (next == null || next.task != curTask) {
5712 ActivityManager.RunningTaskInfo ci
5713 = new ActivityManager.RunningTaskInfo();
5714 ci.id = curTask.taskId;
5715 ci.baseActivity = r.intent.getComponent();
5716 ci.topActivity = top.intent.getComponent();
5717 if (top.thumbHolder != null) {
5718 ci.description = top.thumbHolder.lastDescription;
5720 ci.numActivities = numActivities;
5721 ci.numRunning = numRunning;
5722 //System.out.println(
5723 // "#" + maxNum + ": " + " descr=" + ci.description);
5724 if (ci.thumbnail == null && receiver != null) {
5725 if (localLOGV) Slog.v(
5726 TAG, "State=" + top.state + "Idle=" + top.idle
5728 + " thr=" + (top.app != null ? top.app.thread : null));
5729 if (top.state == ActivityState.RESUMED
5730 || top.state == ActivityState.PAUSING) {
5731 if (top.idle && top.app != null
5732 && top.app.thread != null) {
5734 topThumbnail = top.app.thread;
5736 top.thumbnailNeeded = true;
5739 if (pending == null) {
5740 pending = new PendingThumbnailsRecord(receiver);
5742 pending.pendingRecords.add(top);
5750 if (pending != null) {
5751 mPendingThumbnails.add(pending);
5755 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
5757 if (topThumbnail != null) {
5758 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
5760 topThumbnail.requestThumbnail(topRecord.appToken);
5761 } catch (Exception e) {
5762 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
5763 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
5767 if (pending == null && receiver != null) {
5768 // In this case all thumbnails were available and the client
5769 // is being asked to be told when the remaining ones come in...
5770 // which is unusually, since the top-most currently running
5771 // activity should never have a canned thumbnail! Oh well.
5773 receiver.finished();
5774 } catch (RemoteException ex) {
5781 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5782 int flags, int userId) {
5783 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5784 false, true, "getRecentTasks", null);
5786 synchronized (this) {
5787 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5788 "getRecentTasks()");
5789 final boolean detailed = checkCallingPermission(
5790 android.Manifest.permission.GET_DETAILED_TASKS)
5791 == PackageManager.PERMISSION_GRANTED;
5793 IPackageManager pm = AppGlobals.getPackageManager();
5795 final int N = mRecentTasks.size();
5796 ArrayList<ActivityManager.RecentTaskInfo> res
5797 = new ArrayList<ActivityManager.RecentTaskInfo>(
5798 maxNum < N ? maxNum : N);
5799 for (int i=0; i<N && maxNum > 0; i++) {
5800 TaskRecord tr = mRecentTasks.get(i);
5801 // Only add calling user's recent tasks
5802 if (tr.userId != userId) continue;
5803 // Return the entry if desired by the caller. We always return
5804 // the first entry, because callers always expect this to be the
5805 // foreground app. We may filter others if the caller has
5806 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5807 // we should exclude the entry.
5810 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5811 || (tr.intent == null)
5812 || ((tr.intent.getFlags()
5813 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5814 ActivityManager.RecentTaskInfo rti
5815 = new ActivityManager.RecentTaskInfo();
5816 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
5817 rti.persistentId = tr.taskId;
5818 rti.baseIntent = new Intent(
5819 tr.intent != null ? tr.intent : tr.affinityIntent);
5821 rti.baseIntent.replaceExtras((Bundle)null);
5823 rti.origActivity = tr.origActivity;
5824 rti.description = tr.lastDescription;
5826 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5827 // Check whether this activity is currently available.
5829 if (rti.origActivity != null) {
5830 if (pm.getActivityInfo(rti.origActivity, 0, userId)
5834 } else if (rti.baseIntent != null) {
5835 if (pm.queryIntentActivities(rti.baseIntent,
5836 null, 0, userId) == null) {
5840 } catch (RemoteException e) {
5841 // Will never happen.
5853 private TaskRecord taskForIdLocked(int id) {
5854 final int N = mRecentTasks.size();
5855 for (int i=0; i<N; i++) {
5856 TaskRecord tr = mRecentTasks.get(i);
5857 if (tr.taskId == id) {
5864 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5865 synchronized (this) {
5866 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5867 "getTaskThumbnails()");
5868 TaskRecord tr = taskForIdLocked(id);
5870 return mMainStack.getTaskThumbnailsLocked(tr);
5876 public Bitmap getTaskTopThumbnail(int id) {
5877 synchronized (this) {
5878 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5879 "getTaskTopThumbnail()");
5880 TaskRecord tr = taskForIdLocked(id);
5882 return mMainStack.getTaskTopThumbnailLocked(tr);
5888 public boolean removeSubTask(int taskId, int subTaskIndex) {
5889 synchronized (this) {
5890 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5892 long ident = Binder.clearCallingIdentity();
5894 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5897 Binder.restoreCallingIdentity(ident);
5902 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5903 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
5904 Intent baseIntent = new Intent(
5905 tr.intent != null ? tr.intent : tr.affinityIntent);
5906 ComponentName component = baseIntent.getComponent();
5907 if (component == null) {
5908 Slog.w(TAG, "Now component for base intent of task: " + tr);
5912 // Find any running services associated with this app.
5913 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
5915 if (killProcesses) {
5916 // Find any running processes associated with this app.
5917 final String pkg = component.getPackageName();
5918 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5919 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5920 for (SparseArray<ProcessRecord> uids : pmap.values()) {
5921 for (int i=0; i<uids.size(); i++) {
5922 ProcessRecord proc = uids.valueAt(i);
5923 if (proc.userId != tr.userId) {
5926 if (!proc.pkgList.contains(pkg)) {
5933 // Kill the running processes.
5934 for (int i=0; i<procs.size(); i++) {
5935 ProcessRecord pr = procs.get(i);
5936 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5937 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5938 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
5939 pr.processName, pr.setAdj, "remove task");
5940 pr.killedBackground = true;
5941 Process.killProcessQuiet(pr.pid);
5943 pr.waitingToKill = "remove task";
5949 public boolean removeTask(int taskId, int flags) {
5950 synchronized (this) {
5951 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5953 long ident = Binder.clearCallingIdentity();
5955 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5958 mRecentTasks.remove(r.task);
5959 cleanUpRemovedTaskLocked(r.task, flags);
5962 TaskRecord tr = null;
5964 while (i < mRecentTasks.size()) {
5965 TaskRecord t = mRecentTasks.get(i);
5966 if (t.taskId == taskId) {
5973 if (tr.numActivities <= 0) {
5974 // Caller is just removing a recent task that is
5975 // not actively running. That is easy!
5976 mRecentTasks.remove(i);
5977 cleanUpRemovedTaskLocked(tr, flags);
5980 Slog.w(TAG, "removeTask: task " + taskId
5981 + " does not have activities to remove, "
5982 + " but numActivities=" + tr.numActivities
5988 Binder.restoreCallingIdentity(ident);
5994 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5996 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
5997 TaskRecord jt = startTask;
5999 // First look backwards
6000 for (j=startIndex-1; j>=0; j--) {
6001 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
6004 if (affinity.equals(jt.affinity)) {
6010 // Now look forwards
6011 final int N = mMainStack.mHistory.size();
6013 for (j=startIndex+1; j<N; j++) {
6014 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
6016 if (affinity.equals(jt.affinity)) {
6023 // Might it be at the top?
6024 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
6032 * TODO: Add mController hook
6034 public void moveTaskToFront(int task, int flags, Bundle options) {
6035 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6036 "moveTaskToFront()");
6038 synchronized(this) {
6039 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6040 Binder.getCallingUid(), "Task to front")) {
6041 ActivityOptions.abort(options);
6044 final long origId = Binder.clearCallingIdentity();
6046 TaskRecord tr = taskForIdLocked(task);
6048 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6049 mMainStack.mUserLeaving = true;
6051 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6052 // Caller wants the home activity moved with it. To accomplish this,
6053 // we'll just move the home task to the top first.
6054 mMainStack.moveHomeToFrontLocked();
6056 mMainStack.moveTaskToFrontLocked(tr, null, options);
6059 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6060 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
6061 if (hr.task.taskId == task) {
6062 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6063 mMainStack.mUserLeaving = true;
6065 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6066 // Caller wants the home activity moved with it. To accomplish this,
6067 // we'll just move the home task to the top first.
6068 mMainStack.moveHomeToFrontLocked();
6070 mMainStack.moveTaskToFrontLocked(hr.task, null, options);
6075 Binder.restoreCallingIdentity(origId);
6077 ActivityOptions.abort(options);
6081 public void moveTaskToBack(int task) {
6082 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6083 "moveTaskToBack()");
6085 synchronized(this) {
6086 if (mMainStack.mResumedActivity != null
6087 && mMainStack.mResumedActivity.task.taskId == task) {
6088 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6089 Binder.getCallingUid(), "Task to back")) {
6093 final long origId = Binder.clearCallingIdentity();
6094 mMainStack.moveTaskToBackLocked(task, null);
6095 Binder.restoreCallingIdentity(origId);
6100 * Moves an activity, and all of the other activities within the same task, to the bottom
6101 * of the history stack. The activity's order within the task is unchanged.
6103 * @param token A reference to the activity we wish to move
6104 * @param nonRoot If false then this only works if the activity is the root
6105 * of a task; if true it will work for any activity in a task.
6106 * @return Returns true if the move completed, false if not.
6108 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
6109 enforceNotIsolatedCaller("moveActivityTaskToBack");
6110 synchronized(this) {
6111 final long origId = Binder.clearCallingIdentity();
6112 int taskId = getTaskForActivityLocked(token, !nonRoot);
6114 return mMainStack.moveTaskToBackLocked(taskId, null);
6116 Binder.restoreCallingIdentity(origId);
6121 public void moveTaskBackwards(int task) {
6122 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6123 "moveTaskBackwards()");
6125 synchronized(this) {
6126 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6127 Binder.getCallingUid(), "Task backwards")) {
6130 final long origId = Binder.clearCallingIdentity();
6131 moveTaskBackwardsLocked(task);
6132 Binder.restoreCallingIdentity(origId);
6136 private final void moveTaskBackwardsLocked(int task) {
6137 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
6140 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6141 synchronized(this) {
6142 return getTaskForActivityLocked(token, onlyRoot);
6146 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
6147 final int N = mMainStack.mHistory.size();
6148 TaskRecord lastTask = null;
6149 for (int i=0; i<N; i++) {
6150 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
6151 if (r.appToken == token) {
6152 if (!onlyRoot || lastTask != r.task) {
6153 return r.task.taskId;
6163 // =========================================================
6165 // =========================================================
6167 public void reportThumbnail(IBinder token,
6168 Bitmap thumbnail, CharSequence description) {
6169 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6170 final long origId = Binder.clearCallingIdentity();
6171 sendPendingThumbnail(null, token, thumbnail, description, true);
6172 Binder.restoreCallingIdentity(origId);
6175 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
6176 Bitmap thumbnail, CharSequence description, boolean always) {
6177 TaskRecord task = null;
6178 ArrayList receivers = null;
6180 //System.out.println("Send pending thumbnail: " + r);
6182 synchronized(this) {
6184 r = mMainStack.isInStackLocked(token);
6189 if (thumbnail == null && r.thumbHolder != null) {
6190 thumbnail = r.thumbHolder.lastThumbnail;
6191 description = r.thumbHolder.lastDescription;
6193 if (thumbnail == null && !always) {
6194 // If there is no thumbnail, and this entry is not actually
6195 // going away, then abort for now and pick up the next
6196 // thumbnail we get.
6201 int N = mPendingThumbnails.size();
6204 PendingThumbnailsRecord pr =
6205 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6206 //System.out.println("Looking in " + pr.pendingRecords);
6207 if (pr.pendingRecords.remove(r)) {
6208 if (receivers == null) {
6209 receivers = new ArrayList();
6212 if (pr.pendingRecords.size() == 0) {
6214 mPendingThumbnails.remove(i);
6223 if (receivers != null) {
6224 final int N = receivers.size();
6225 for (int i=0; i<N; i++) {
6227 PendingThumbnailsRecord pr =
6228 (PendingThumbnailsRecord)receivers.get(i);
6229 pr.receiver.newThumbnail(
6230 task != null ? task.taskId : -1, thumbnail, description);
6232 pr.receiver.finished();
6234 } catch (Exception e) {
6235 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
6241 // =========================================================
6242 // CONTENT PROVIDERS
6243 // =========================================================
6245 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6246 List<ProviderInfo> providers = null;
6248 providers = AppGlobals.getPackageManager().
6249 queryContentProviders(app.processName, app.uid,
6250 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
6251 } catch (RemoteException ex) {
6254 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6255 int userId = app.userId;
6256 if (providers != null) {
6257 int N = providers.size();
6258 for (int i=0; i<N; i++) {
6260 (ProviderInfo)providers.get(i);
6261 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6262 cpi.name, cpi.flags);
6263 if (singleton && UserHandle.getUserId(app.uid) != 0) {
6264 // This is a singleton provider, but a user besides the
6265 // default user is asking to initialize a process it runs
6266 // in... well, no, it doesn't actually run in this process,
6267 // it runs in the process of the default user. Get rid of it.
6268 providers.remove(i);
6273 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6274 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
6276 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
6277 mProviderMap.putProviderByClass(comp, cpr);
6280 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
6281 app.pubProviders.put(cpi.name, cpr);
6282 app.addPackage(cpi.applicationInfo.packageName);
6283 ensurePackageDexOpt(cpi.applicationInfo.packageName);
6290 * Check if {@link ProcessRecord} has a possible chance at accessing the
6291 * given {@link ProviderInfo}. Final permission checking is always done
6292 * in {@link ContentProvider}.
6294 private final String checkContentProviderPermissionLocked(
6295 ProviderInfo cpi, ProcessRecord r) {
6296 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
6297 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
6298 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
6299 cpi.applicationInfo.uid, cpi.exported)
6300 == PackageManager.PERMISSION_GRANTED) {
6303 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
6304 cpi.applicationInfo.uid, cpi.exported)
6305 == PackageManager.PERMISSION_GRANTED) {
6309 PathPermission[] pps = cpi.pathPermissions;
6314 PathPermission pp = pps[i];
6315 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
6316 cpi.applicationInfo.uid, cpi.exported)
6317 == PackageManager.PERMISSION_GRANTED) {
6320 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
6321 cpi.applicationInfo.uid, cpi.exported)
6322 == PackageManager.PERMISSION_GRANTED) {
6328 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6329 if (perms != null) {
6330 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6331 if (uri.getKey().getAuthority().equals(cpi.authority)) {
6338 if (!cpi.exported) {
6339 msg = "Permission Denial: opening provider " + cpi.name
6340 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6341 + ", uid=" + callingUid + ") that is not exported from uid "
6342 + cpi.applicationInfo.uid;
6344 msg = "Permission Denial: opening provider " + cpi.name
6345 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6346 + ", uid=" + callingUid + ") requires "
6347 + cpi.readPermission + " or " + cpi.writePermission;
6353 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6354 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6356 for (int i=0; i<r.conProviders.size(); i++) {
6357 ContentProviderConnection conn = r.conProviders.get(i);
6358 if (conn.provider == cpr) {
6359 if (DEBUG_PROVIDER) Slog.v(TAG,
6360 "Adding provider requested by "
6361 + r.processName + " from process "
6362 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6363 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6366 conn.numStableIncs++;
6368 conn.unstableCount++;
6369 conn.numUnstableIncs++;
6374 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6376 conn.stableCount = 1;
6377 conn.numStableIncs = 1;
6379 conn.unstableCount = 1;
6380 conn.numUnstableIncs = 1;
6382 cpr.connections.add(conn);
6383 r.conProviders.add(conn);
6386 cpr.addExternalProcessHandleLocked(externalProcessToken);
6390 boolean decProviderCountLocked(ContentProviderConnection conn,
6391 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6393 cpr = conn.provider;
6394 if (DEBUG_PROVIDER) Slog.v(TAG,
6395 "Removing provider requested by "
6396 + conn.client.processName + " from process "
6397 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6398 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6402 conn.unstableCount--;
6404 if (conn.stableCount == 0 && conn.unstableCount == 0) {
6405 cpr.connections.remove(conn);
6406 conn.client.conProviders.remove(conn);
6411 cpr.removeExternalProcessHandleLocked(externalProcessToken);
6415 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
6416 String name, IBinder token, boolean stable, int userId) {
6417 ContentProviderRecord cpr;
6418 ContentProviderConnection conn = null;
6419 ProviderInfo cpi = null;
6421 synchronized(this) {
6422 ProcessRecord r = null;
6423 if (caller != null) {
6424 r = getRecordForAppLocked(caller);
6426 throw new SecurityException(
6427 "Unable to find app for caller " + caller
6428 + " (pid=" + Binder.getCallingPid()
6429 + ") when getting content provider " + name);
6433 // First check if this content provider has been published...
6434 cpr = mProviderMap.getProviderByName(name, userId);
6435 boolean providerRunning = cpr != null;
6436 if (providerRunning) {
6439 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6440 throw new SecurityException(msg);
6443 if (r != null && cpr.canRunHere(r)) {
6444 // This provider has been published or is in the process
6445 // of being published... but it is also allowed to run
6446 // in the caller's process, so don't make a connection
6447 // and just let the caller instantiate its own instance.
6448 ContentProviderHolder holder = cpr.newHolder(null);
6449 // don't give caller the provider object, it needs
6451 holder.provider = null;
6455 final long origId = Binder.clearCallingIdentity();
6457 // In this case the provider instance already exists, so we can
6458 // return it right away.
6459 conn = incProviderCountLocked(r, cpr, token, stable);
6460 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
6461 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
6462 // If this is a perceptible app accessing the provider,
6463 // make sure to count it as being accessed and thus
6464 // back up on the LRU list. This is good because
6465 // content providers are often expensive to start.
6466 updateLruProcessLocked(cpr.proc, false);
6470 if (cpr.proc != null) {
6472 if (cpr.name.flattenToShortString().equals(
6473 "com.android.providers.calendar/.CalendarProvider2")) {
6474 Slog.v(TAG, "****************** KILLING "
6475 + cpr.name.flattenToShortString());
6476 Process.killProcess(cpr.proc.pid);
6479 boolean success = updateOomAdjLocked(cpr.proc);
6480 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6481 // NOTE: there is still a race here where a signal could be
6482 // pending on the process even though we managed to update its
6483 // adj level. Not sure what to do about this, but at least
6484 // the race is now smaller.
6486 // Uh oh... it looks like the provider's process
6487 // has been killed on us. We need to wait for a new
6488 // process to be started, and make sure its death
6489 // doesn't kill our process.
6491 "Existing provider " + cpr.name.flattenToShortString()
6492 + " is crashing; detaching " + r);
6493 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
6494 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
6496 // This wasn't the last ref our process had on
6497 // the provider... we have now been killed, bail.
6500 providerRunning = false;
6505 Binder.restoreCallingIdentity(origId);
6509 if (!providerRunning) {
6511 cpi = AppGlobals.getPackageManager().
6512 resolveContentProvider(name,
6513 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
6514 } catch (RemoteException ex) {
6519 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6520 cpi.name, cpi.flags);
6524 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
6527 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6528 throw new SecurityException(msg);
6531 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
6532 && !cpi.processName.equals("system")) {
6533 // If this content provider does not run in the system
6534 // process, and the system is not yet ready to run other
6535 // processes, then fail fast instead of hanging.
6536 throw new IllegalArgumentException(
6537 "Attempt to launch content provider before system ready");
6540 // Make sure that the user who owns this provider is started. If not,
6541 // we don't want to allow it to run.
6542 if (mStartedUsers.get(userId) == null) {
6543 Slog.w(TAG, "Unable to launch app "
6544 + cpi.applicationInfo.packageName + "/"
6545 + cpi.applicationInfo.uid + " for provider "
6546 + name + ": user " + userId + " is stopped");
6550 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
6551 cpr = mProviderMap.getProviderByClass(comp, userId);
6552 final boolean firstClass = cpr == null;
6555 ApplicationInfo ai =
6556 AppGlobals.getPackageManager().
6558 cpi.applicationInfo.packageName,
6559 STOCK_PM_FLAGS, userId);
6561 Slog.w(TAG, "No package info for content provider "
6565 ai = getAppInfoForUser(ai, userId);
6566 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
6567 } catch (RemoteException ex) {
6568 // pm is in same process, this will never happen.
6572 if (r != null && cpr.canRunHere(r)) {
6573 // If this is a multiprocess provider, then just return its
6574 // info and allow the caller to instantiate it. Only do
6575 // this if the provider is the same user as the caller's
6576 // process, or can run as root (so can be in any process).
6577 return cpr.newHolder(null);
6580 if (DEBUG_PROVIDER) {
6581 RuntimeException e = new RuntimeException("here");
6582 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
6583 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
6586 // This is single process, and our app is now connecting to it.
6587 // See if we are already in the process of launching this
6589 final int N = mLaunchingProviders.size();
6591 for (i=0; i<N; i++) {
6592 if (mLaunchingProviders.get(i) == cpr) {
6597 // If the provider is not already being launched, then get it
6600 final long origId = Binder.clearCallingIdentity();
6603 // Content provider is now in use, its package can't be stopped.
6605 AppGlobals.getPackageManager().setPackageStoppedState(
6606 cpr.appInfo.packageName, false, userId);
6607 } catch (RemoteException e) {
6608 } catch (IllegalArgumentException e) {
6609 Slog.w(TAG, "Failed trying to unstop package "
6610 + cpr.appInfo.packageName + ": " + e);
6613 ProcessRecord proc = startProcessLocked(cpi.processName,
6614 cpr.appInfo, false, 0, "content provider",
6615 new ComponentName(cpi.applicationInfo.packageName,
6616 cpi.name), false, false);
6618 Slog.w(TAG, "Unable to launch app "
6619 + cpi.applicationInfo.packageName + "/"
6620 + cpi.applicationInfo.uid + " for provider "
6621 + name + ": process is bad");
6624 cpr.launchingApp = proc;
6625 mLaunchingProviders.add(cpr);
6627 Binder.restoreCallingIdentity(origId);
6631 // Make sure the provider is published (the same provider class
6632 // may be published under multiple names).
6634 mProviderMap.putProviderByClass(comp, cpr);
6637 mProviderMap.putProviderByName(name, cpr);
6638 conn = incProviderCountLocked(r, cpr, token, stable);
6640 conn.waiting = true;
6645 // Wait for the provider to be published...
6646 synchronized (cpr) {
6647 while (cpr.provider == null) {
6648 if (cpr.launchingApp == null) {
6649 Slog.w(TAG, "Unable to launch app "
6650 + cpi.applicationInfo.packageName + "/"
6651 + cpi.applicationInfo.uid + " for provider "
6652 + name + ": launching app became null");
6653 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
6654 UserHandle.getUserId(cpi.applicationInfo.uid),
6655 cpi.applicationInfo.packageName,
6656 cpi.applicationInfo.uid, name);
6661 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6662 + cpr.launchingApp);
6665 conn.waiting = true;
6668 } catch (InterruptedException ex) {
6671 conn.waiting = false;
6676 return cpr != null ? cpr.newHolder(conn) : null;
6679 public final ContentProviderHolder getContentProvider(
6680 IApplicationThread caller, String name, int userId, boolean stable) {
6681 enforceNotIsolatedCaller("getContentProvider");
6682 if (caller == null) {
6683 String msg = "null IApplicationThread when getting content provider "
6686 throw new SecurityException(msg);
6689 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6690 false, true, "getContentProvider", null);
6691 return getContentProviderImpl(caller, name, null, stable, userId);
6694 public ContentProviderHolder getContentProviderExternal(
6695 String name, int userId, IBinder token) {
6696 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6697 "Do not have permission in call getContentProviderExternal()");
6698 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
6699 false, true, "getContentProvider", null);
6700 return getContentProviderExternalUnchecked(name, token, userId);
6703 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6704 IBinder token, int userId) {
6705 return getContentProviderImpl(null, name, token, true, userId);
6709 * Drop a content provider from a ProcessRecord's bookkeeping
6712 public void removeContentProvider(IBinder connection, boolean stable) {
6713 enforceNotIsolatedCaller("removeContentProvider");
6714 synchronized (this) {
6715 ContentProviderConnection conn;
6717 conn = (ContentProviderConnection)connection;
6718 } catch (ClassCastException e) {
6719 String msg ="removeContentProvider: " + connection
6720 + " not a ContentProviderConnection";
6722 throw new IllegalArgumentException(msg);
6725 throw new NullPointerException("connection is null");
6727 if (decProviderCountLocked(conn, null, null, stable)) {
6728 updateOomAdjLocked();
6733 public void removeContentProviderExternal(String name, IBinder token) {
6734 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6735 "Do not have permission in call removeContentProviderExternal()");
6736 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
6739 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
6740 synchronized (this) {
6741 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
6743 //remove from mProvidersByClass
6744 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
6748 //update content provider record entry info
6749 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6750 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
6751 if (localCpr.hasExternalProcessHandles()) {
6752 if (localCpr.removeExternalProcessHandleLocked(token)) {
6753 updateOomAdjLocked();
6755 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6756 + " with no external reference for token: "
6760 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6761 + " with no external references.");
6766 public final void publishContentProviders(IApplicationThread caller,
6767 List<ContentProviderHolder> providers) {
6768 if (providers == null) {
6772 enforceNotIsolatedCaller("publishContentProviders");
6773 synchronized (this) {
6774 final ProcessRecord r = getRecordForAppLocked(caller);
6776 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
6778 throw new SecurityException(
6779 "Unable to find app for caller " + caller
6780 + " (pid=" + Binder.getCallingPid()
6781 + ") when publishing content providers");
6784 final long origId = Binder.clearCallingIdentity();
6786 final int N = providers.size();
6787 for (int i=0; i<N; i++) {
6788 ContentProviderHolder src = providers.get(i);
6789 if (src == null || src.info == null || src.provider == null) {
6792 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
6794 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
6796 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6797 mProviderMap.putProviderByClass(comp, dst);
6798 String names[] = dst.info.authority.split(";");
6799 for (int j = 0; j < names.length; j++) {
6800 mProviderMap.putProviderByName(names[j], dst);
6803 int NL = mLaunchingProviders.size();
6805 for (j=0; j<NL; j++) {
6806 if (mLaunchingProviders.get(j) == dst) {
6807 mLaunchingProviders.remove(j);
6812 synchronized (dst) {
6813 dst.provider = src.provider;
6817 updateOomAdjLocked(r);
6821 Binder.restoreCallingIdentity(origId);
6825 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6826 ContentProviderConnection conn;
6828 conn = (ContentProviderConnection)connection;
6829 } catch (ClassCastException e) {
6830 String msg ="refContentProvider: " + connection
6831 + " not a ContentProviderConnection";
6833 throw new IllegalArgumentException(msg);
6836 throw new NullPointerException("connection is null");
6839 synchronized (this) {
6841 conn.numStableIncs += stable;
6843 stable = conn.stableCount + stable;
6845 throw new IllegalStateException("stableCount < 0: " + stable);
6849 conn.numUnstableIncs += unstable;
6851 unstable = conn.unstableCount + unstable;
6853 throw new IllegalStateException("unstableCount < 0: " + unstable);
6856 if ((stable+unstable) <= 0) {
6857 throw new IllegalStateException("ref counts can't go to zero here: stable="
6858 + stable + " unstable=" + unstable);
6860 conn.stableCount = stable;
6861 conn.unstableCount = unstable;
6866 public void unstableProviderDied(IBinder connection) {
6867 ContentProviderConnection conn;
6869 conn = (ContentProviderConnection)connection;
6870 } catch (ClassCastException e) {
6871 String msg ="refContentProvider: " + connection
6872 + " not a ContentProviderConnection";
6874 throw new IllegalArgumentException(msg);
6877 throw new NullPointerException("connection is null");
6880 // Safely retrieve the content provider associated with the connection.
6881 IContentProvider provider;
6882 synchronized (this) {
6883 provider = conn.provider.provider;
6886 if (provider == null) {
6887 // Um, yeah, we're way ahead of you.
6891 // Make sure the caller is being honest with us.
6892 if (provider.asBinder().pingBinder()) {
6893 // Er, no, still looks good to us.
6894 synchronized (this) {
6895 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6896 + " says " + conn + " died, but we don't agree");
6901 // Well look at that! It's dead!
6902 synchronized (this) {
6903 if (conn.provider.provider != provider) {
6904 // But something changed... good enough.
6908 ProcessRecord proc = conn.provider.proc;
6909 if (proc == null || proc.thread == null) {
6910 // Seems like the process is already cleaned up.
6914 // As far as we're concerned, this is just like receiving a
6915 // death notification... just a bit prematurely.
6916 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6917 + ") early provider death");
6918 final long ident = Binder.clearCallingIdentity();
6920 appDiedLocked(proc, proc.pid, proc.thread);
6922 Binder.restoreCallingIdentity(ident);
6927 public static final void installSystemProviders() {
6928 List<ProviderInfo> providers;
6929 synchronized (mSelf) {
6930 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6931 providers = mSelf.generateApplicationProvidersLocked(app);
6932 if (providers != null) {
6933 for (int i=providers.size()-1; i>=0; i--) {
6934 ProviderInfo pi = (ProviderInfo)providers.get(i);
6935 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6936 Slog.w(TAG, "Not installing system proc provider " + pi.name
6937 + ": not system .apk");
6938 providers.remove(i);
6943 if (providers != null) {
6944 mSystemThread.installSystemProviders(providers);
6947 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
6949 mSelf.mUsageStatsService.monitorPackages();
6953 * Allows app to retrieve the MIME type of a URI without having permission
6954 * to access its content provider.
6956 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6958 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6959 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6961 public String getProviderMimeType(Uri uri, int userId) {
6962 enforceNotIsolatedCaller("getProviderMimeType");
6963 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
6964 userId, false, true, "getProviderMimeType", null);
6965 final String name = uri.getAuthority();
6966 final long ident = Binder.clearCallingIdentity();
6967 ContentProviderHolder holder = null;
6970 holder = getContentProviderExternalUnchecked(name, null, userId);
6971 if (holder != null) {
6972 return holder.provider.getType(uri);
6974 } catch (RemoteException e) {
6975 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6978 if (holder != null) {
6979 removeContentProviderExternalUnchecked(name, null, userId);
6981 Binder.restoreCallingIdentity(ident);
6987 // =========================================================
6988 // GLOBAL MANAGEMENT
6989 // =========================================================
6991 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6992 ApplicationInfo info, String customProcess, boolean isolated) {
6993 String proc = customProcess != null ? customProcess : info.processName;
6994 BatteryStatsImpl.Uid.Proc ps = null;
6995 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6998 int userId = UserHandle.getUserId(uid);
6999 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
7002 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
7003 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
7004 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
7006 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
7007 mNextIsolatedProcessUid++;
7008 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
7009 // No process for this uid, use it.
7013 if (stepsLeft <= 0) {
7018 synchronized (stats) {
7019 ps = stats.getProcessStatsLocked(info.uid, proc);
7021 return new ProcessRecord(ps, thread, info, proc, uid);
7024 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7027 app = getProcessRecordLocked(info.processName, info.uid);
7033 app = newProcessRecordLocked(null, info, null, isolated);
7034 mProcessNames.put(info.processName, app.uid, app);
7036 mIsolatedProcesses.put(app.uid, app);
7038 updateLruProcessLocked(app, true);
7041 // This package really, really can not be stopped.
7043 AppGlobals.getPackageManager().setPackageStoppedState(
7044 info.packageName, false, UserHandle.getUserId(app.uid));
7045 } catch (RemoteException e) {
7046 } catch (IllegalArgumentException e) {
7047 Slog.w(TAG, "Failed trying to unstop package "
7048 + info.packageName + ": " + e);
7051 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7052 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7053 app.persistent = true;
7054 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
7056 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7057 mPersistentStartingProcesses.add(app);
7058 startProcessLocked(app, "added application", app.processName);
7064 public void unhandledBack() {
7065 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7068 synchronized(this) {
7069 int count = mMainStack.mHistory.size();
7070 if (DEBUG_SWITCH) Slog.d(
7071 TAG, "Performing unhandledBack(): stack size = " + count);
7073 final long origId = Binder.clearCallingIdentity();
7074 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
7075 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
7076 Binder.restoreCallingIdentity(origId);
7081 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
7082 enforceNotIsolatedCaller("openContentUri");
7083 final int userId = UserHandle.getCallingUserId();
7084 String name = uri.getAuthority();
7085 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
7086 ParcelFileDescriptor pfd = null;
7088 // We record the binder invoker's uid in thread-local storage before
7089 // going to the content provider to open the file. Later, in the code
7090 // that handles all permissions checks, we look for this uid and use
7091 // that rather than the Activity Manager's own uid. The effect is that
7092 // we do the check against the caller's permissions even though it looks
7093 // to the content provider like the Activity Manager itself is making
7095 sCallerIdentity.set(new Identity(
7096 Binder.getCallingPid(), Binder.getCallingUid()));
7098 pfd = cph.provider.openFile(uri, "r");
7099 } catch (FileNotFoundException e) {
7100 // do nothing; pfd will be returned null
7102 // Ensure that whatever happens, we clean up the identity state
7103 sCallerIdentity.remove();
7106 // We've got the fd now, so we're done with the provider.
7107 removeContentProviderExternalUnchecked(name, null, userId);
7109 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
7114 // Actually is sleeping or shutting down or whatever else in the future
7115 // is an inactive state.
7116 public boolean isSleeping() {
7117 return mSleeping || mShuttingDown;
7120 public void goingToSleep() {
7121 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7122 != PackageManager.PERMISSION_GRANTED) {
7123 throw new SecurityException("Requires permission "
7124 + android.Manifest.permission.DEVICE_POWER);
7127 synchronized(this) {
7128 mWentToSleep = true;
7129 updateEventDispatchingLocked();
7133 mMainStack.stopIfSleepingLocked();
7135 // Initialize the wake times of all processes.
7136 checkExcessivePowerUsageLocked(false);
7137 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7138 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7139 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7144 public boolean shutdown(int timeout) {
7145 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7146 != PackageManager.PERMISSION_GRANTED) {
7147 throw new SecurityException("Requires permission "
7148 + android.Manifest.permission.SHUTDOWN);
7151 boolean timedout = false;
7153 synchronized(this) {
7154 mShuttingDown = true;
7155 updateEventDispatchingLocked();
7157 if (mMainStack.mResumedActivity != null) {
7158 mMainStack.stopIfSleepingLocked();
7159 final long endTime = System.currentTimeMillis() + timeout;
7160 while (mMainStack.mResumedActivity != null
7161 || mMainStack.mPausingActivity != null) {
7162 long delay = endTime - System.currentTimeMillis();
7164 Slog.w(TAG, "Activity manager shutdown timed out");
7170 } catch (InterruptedException e) {
7176 mUsageStatsService.shutdown();
7177 mBatteryStatsService.shutdown();
7182 public final void activitySlept(IBinder token) {
7183 if (localLOGV) Slog.v(
7184 TAG, "Activity slept: token=" + token);
7186 ActivityRecord r = null;
7188 final long origId = Binder.clearCallingIdentity();
7190 synchronized (this) {
7191 r = mMainStack.isInStackLocked(token);
7193 mMainStack.activitySleptLocked(r);
7197 Binder.restoreCallingIdentity(origId);
7200 private void comeOutOfSleepIfNeededLocked() {
7201 if (!mWentToSleep && !mLockScreenShown) {
7204 mMainStack.awakeFromSleepingLocked();
7205 mMainStack.resumeTopActivityLocked(null);
7210 public void wakingUp() {
7211 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7212 != PackageManager.PERMISSION_GRANTED) {
7213 throw new SecurityException("Requires permission "
7214 + android.Manifest.permission.DEVICE_POWER);
7217 synchronized(this) {
7218 mWentToSleep = false;
7219 updateEventDispatchingLocked();
7220 comeOutOfSleepIfNeededLocked();
7224 private void updateEventDispatchingLocked() {
7225 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7228 public void setLockScreenShown(boolean shown) {
7229 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7230 != PackageManager.PERMISSION_GRANTED) {
7231 throw new SecurityException("Requires permission "
7232 + android.Manifest.permission.DEVICE_POWER);
7235 synchronized(this) {
7236 mLockScreenShown = shown;
7237 comeOutOfSleepIfNeededLocked();
7241 public void stopAppSwitches() {
7242 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7243 != PackageManager.PERMISSION_GRANTED) {
7244 throw new SecurityException("Requires permission "
7245 + android.Manifest.permission.STOP_APP_SWITCHES);
7248 synchronized(this) {
7249 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7250 + APP_SWITCH_DELAY_TIME;
7251 mDidAppSwitch = false;
7252 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7253 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7254 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7258 public void resumeAppSwitches() {
7259 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7260 != PackageManager.PERMISSION_GRANTED) {
7261 throw new SecurityException("Requires permission "
7262 + android.Manifest.permission.STOP_APP_SWITCHES);
7265 synchronized(this) {
7266 // Note that we don't execute any pending app switches... we will
7267 // let those wait until either the timeout, or the next start
7268 // activity request.
7269 mAppSwitchesAllowedTime = 0;
7273 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7275 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7279 final int perm = checkComponentPermission(
7280 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
7281 callingUid, -1, true);
7282 if (perm == PackageManager.PERMISSION_GRANTED) {
7286 Slog.w(TAG, name + " request from " + callingUid + " stopped");
7290 public void setDebugApp(String packageName, boolean waitForDebugger,
7291 boolean persistent) {
7292 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7295 // Note that this is not really thread safe if there are multiple
7296 // callers into it at the same time, but that's not a situation we
7299 final ContentResolver resolver = mContext.getContentResolver();
7300 Settings.Global.putString(
7301 resolver, Settings.Global.DEBUG_APP,
7303 Settings.Global.putInt(
7304 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
7305 waitForDebugger ? 1 : 0);
7308 synchronized (this) {
7310 mOrigDebugApp = mDebugApp;
7311 mOrigWaitForDebugger = mWaitForDebugger;
7313 mDebugApp = packageName;
7314 mWaitForDebugger = waitForDebugger;
7315 mDebugTransient = !persistent;
7316 if (packageName != null) {
7317 final long origId = Binder.clearCallingIdentity();
7318 forceStopPackageLocked(packageName, -1, false, false, true, true,
7319 UserHandle.USER_ALL);
7320 Binder.restoreCallingIdentity(origId);
7325 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7326 synchronized (this) {
7327 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7328 if (!isDebuggable) {
7329 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7330 throw new SecurityException("Process not debuggable: " + app.packageName);
7334 mOpenGlTraceApp = processName;
7338 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7339 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7340 synchronized (this) {
7341 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7342 if (!isDebuggable) {
7343 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7344 throw new SecurityException("Process not debuggable: " + app.packageName);
7347 mProfileApp = processName;
7348 mProfileFile = profileFile;
7349 if (mProfileFd != null) {
7352 } catch (IOException e) {
7356 mProfileFd = profileFd;
7358 mAutoStopProfiler = autoStopProfiler;
7362 public void setAlwaysFinish(boolean enabled) {
7363 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7364 "setAlwaysFinish()");
7366 Settings.Global.putInt(
7367 mContext.getContentResolver(),
7368 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7370 synchronized (this) {
7371 mAlwaysFinishActivities = enabled;
7375 public void setActivityController(IActivityController controller) {
7376 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7377 "setActivityController()");
7378 synchronized (this) {
7379 mController = controller;
7383 public boolean isUserAMonkey() {
7384 // For now the fact that there is a controller implies
7385 // we have a monkey.
7386 synchronized (this) {
7387 return mController != null;
7391 public void requestBugReport() {
7392 // No permission check because this can't do anything harmful --
7393 // it will just eventually cause the user to be presented with
7394 // a UI to select where the bug report goes.
7395 SystemProperties.set("ctl.start", "bugreport");
7398 public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
7399 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7400 != PackageManager.PERMISSION_GRANTED) {
7401 throw new SecurityException("Requires permission "
7402 + android.Manifest.permission.FILTER_EVENTS);
7407 // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
7408 synchronized (this) {
7409 synchronized (mPidsSelfLocked) {
7410 proc = mPidsSelfLocked.get(pid);
7413 if (proc.debugging) {
7418 // Give more time since we were dexopting.
7423 if (proc.instrumentationClass != null) {
7424 Bundle info = new Bundle();
7425 info.putString("shortMsg", "keyDispatchingTimedOut");
7426 info.putString("longMsg", "Timed out while dispatching key event");
7427 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
7434 appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
7435 if (proc.instrumentationClass != null || proc.usingWrapper) {
7436 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
7440 return KEY_DISPATCHING_TIMEOUT;
7443 public void registerProcessObserver(IProcessObserver observer) {
7444 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7445 "registerProcessObserver()");
7446 synchronized (this) {
7447 mProcessObservers.register(observer);
7451 public void unregisterProcessObserver(IProcessObserver observer) {
7452 synchronized (this) {
7453 mProcessObservers.unregister(observer);
7457 public void setImmersive(IBinder token, boolean immersive) {
7458 synchronized(this) {
7459 final ActivityRecord r = mMainStack.isInStackLocked(token);
7461 throw new IllegalArgumentException();
7463 r.immersive = immersive;
7465 // update associated state if we're frontmost
7466 if (r == mFocusedActivity) {
7467 if (DEBUG_IMMERSIVE) {
7468 Slog.d(TAG, "Frontmost changed immersion: "+ r);
7470 applyUpdateLockStateLocked(r);
7475 public boolean isImmersive(IBinder token) {
7476 synchronized (this) {
7477 ActivityRecord r = mMainStack.isInStackLocked(token);
7479 throw new IllegalArgumentException();
7485 public boolean isTopActivityImmersive() {
7486 enforceNotIsolatedCaller("startActivity");
7487 synchronized (this) {
7488 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
7489 return (r != null) ? r.immersive : false;
7493 public final void enterSafeMode() {
7494 synchronized(this) {
7495 // It only makes sense to do this before the system is ready
7496 // and started launching other packages.
7497 if (!mSystemReady) {
7499 AppGlobals.getPackageManager().enterSafeMode();
7500 } catch (RemoteException e) {
7506 public final void showSafeModeOverlay() {
7507 View v = LayoutInflater.from(mContext).inflate(
7508 com.android.internal.R.layout.safe_mode, null);
7509 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7510 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7511 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7512 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7513 lp.gravity = Gravity.BOTTOM | Gravity.START;
7514 lp.format = v.getBackground().getOpacity();
7515 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7516 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7517 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
7518 ((WindowManager)mContext.getSystemService(
7519 Context.WINDOW_SERVICE)).addView(v, lp);
7522 public void noteWakeupAlarm(IIntentSender sender) {
7523 if (!(sender instanceof PendingIntentRecord)) {
7526 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7527 synchronized (stats) {
7528 if (mBatteryStatsService.isOnBattery()) {
7529 mBatteryStatsService.enforceCallingPermission();
7530 PendingIntentRecord rec = (PendingIntentRecord)sender;
7531 int MY_UID = Binder.getCallingUid();
7532 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7533 BatteryStatsImpl.Uid.Pkg pkg =
7534 stats.getPackageStatsLocked(uid, rec.key.packageName);
7535 pkg.incWakeupsLocked();
7540 public boolean killPids(int[] pids, String pReason, boolean secure) {
7541 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7542 throw new SecurityException("killPids only available to the system");
7544 String reason = (pReason == null) ? "Unknown" : pReason;
7545 // XXX Note: don't acquire main activity lock here, because the window
7546 // manager calls in with its locks held.
7548 boolean killed = false;
7549 synchronized (mPidsSelfLocked) {
7550 int[] types = new int[pids.length];
7552 for (int i=0; i<pids.length; i++) {
7553 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7555 int type = proc.setAdj;
7557 if (type > worstType) {
7563 // If the worst oom_adj is somewhere in the hidden proc LRU range,
7564 // then constrain it so we will kill all hidden procs.
7565 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7566 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
7567 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
7570 // If this is not a secure call, don't let it kill processes that
7572 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7573 worstType = ProcessList.SERVICE_ADJ;
7576 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
7577 for (int i=0; i<pids.length; i++) {
7578 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7582 int adj = proc.setAdj;
7583 if (adj >= worstType && !proc.killedBackground) {
7584 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7585 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
7586 proc.processName, adj, reason);
7588 proc.killedBackground = true;
7589 Process.killProcessQuiet(pids[i]);
7597 public boolean killProcessesBelowForeground(String reason) {
7598 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7599 throw new SecurityException("killProcessesBelowForeground() only available to system");
7602 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7605 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7606 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7607 throw new SecurityException("killProcessesBelowAdj() only available to system");
7610 boolean killed = false;
7611 synchronized (mPidsSelfLocked) {
7612 final int size = mPidsSelfLocked.size();
7613 for (int i = 0; i < size; i++) {
7614 final int pid = mPidsSelfLocked.keyAt(i);
7615 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7616 if (proc == null) continue;
7618 final int adj = proc.setAdj;
7619 if (adj > belowAdj && !proc.killedBackground) {
7620 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7621 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7622 proc.pid, proc.processName, adj, reason);
7624 proc.killedBackground = true;
7625 Process.killProcessQuiet(pid);
7632 public final void startRunning(String pkg, String cls, String action,
7634 synchronized(this) {
7635 if (mStartRunning) {
7638 mStartRunning = true;
7639 mTopComponent = pkg != null && cls != null
7640 ? new ComponentName(pkg, cls) : null;
7641 mTopAction = action != null ? action : Intent.ACTION_MAIN;
7643 if (!mSystemReady) {
7651 private void retrieveSettings() {
7652 final ContentResolver resolver = mContext.getContentResolver();
7653 String debugApp = Settings.Global.getString(
7654 resolver, Settings.Global.DEBUG_APP);
7655 boolean waitForDebugger = Settings.Global.getInt(
7656 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
7657 boolean alwaysFinishActivities = Settings.Global.getInt(
7658 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7660 Configuration configuration = new Configuration();
7661 Settings.System.getConfiguration(resolver, configuration);
7663 synchronized (this) {
7664 mDebugApp = mOrigDebugApp = debugApp;
7665 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7666 mAlwaysFinishActivities = alwaysFinishActivities;
7667 // This happens before any activities are started, so we can
7668 // change mConfiguration in-place.
7669 updateConfigurationLocked(configuration, null, false, true);
7670 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
7674 public boolean testIsSystemReady() {
7675 // no need to synchronize(this) just to read & return the value
7676 return mSystemReady;
7679 private static File getCalledPreBootReceiversFile() {
7680 File dataDir = Environment.getDataDirectory();
7681 File systemDir = new File(dataDir, "system");
7682 File fname = new File(systemDir, "called_pre_boots.dat");
7686 static final int LAST_DONE_VERSION = 10000;
7688 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7689 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7690 File file = getCalledPreBootReceiversFile();
7691 FileInputStream fis = null;
7693 fis = new FileInputStream(file);
7694 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
7695 int fvers = dis.readInt();
7696 if (fvers == LAST_DONE_VERSION) {
7697 String vers = dis.readUTF();
7698 String codename = dis.readUTF();
7699 String build = dis.readUTF();
7700 if (android.os.Build.VERSION.RELEASE.equals(vers)
7701 && android.os.Build.VERSION.CODENAME.equals(codename)
7702 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7703 int num = dis.readInt();
7706 String pkg = dis.readUTF();
7707 String cls = dis.readUTF();
7708 lastDoneReceivers.add(new ComponentName(pkg, cls));
7712 } catch (FileNotFoundException e) {
7713 } catch (IOException e) {
7714 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7719 } catch (IOException e) {
7723 return lastDoneReceivers;
7726 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7727 File file = getCalledPreBootReceiversFile();
7728 FileOutputStream fos = null;
7729 DataOutputStream dos = null;
7731 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7732 fos = new FileOutputStream(file);
7733 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
7734 dos.writeInt(LAST_DONE_VERSION);
7735 dos.writeUTF(android.os.Build.VERSION.RELEASE);
7736 dos.writeUTF(android.os.Build.VERSION.CODENAME);
7737 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
7738 dos.writeInt(list.size());
7739 for (int i=0; i<list.size(); i++) {
7740 dos.writeUTF(list.get(i).getPackageName());
7741 dos.writeUTF(list.get(i).getClassName());
7743 } catch (IOException e) {
7744 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7747 FileUtils.sync(fos);
7751 } catch (IOException e) {
7752 // TODO Auto-generated catch block
7753 e.printStackTrace();
7759 public void systemReady(final Runnable goingCallback) {
7760 synchronized(this) {
7762 if (goingCallback != null) goingCallback.run();
7766 // Check to see if there are any update receivers to run.
7768 if (mWaitingUpdate) {
7771 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7772 List<ResolveInfo> ris = null;
7774 ris = AppGlobals.getPackageManager().queryIntentReceivers(
7775 intent, null, 0, 0);
7776 } catch (RemoteException e) {
7779 for (int i=ris.size()-1; i>=0; i--) {
7780 if ((ris.get(i).activityInfo.applicationInfo.flags
7781 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7785 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
7787 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7789 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
7790 for (int i=0; i<ris.size(); i++) {
7791 ActivityInfo ai = ris.get(i).activityInfo;
7792 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7793 if (lastDoneReceivers.contains(comp)) {
7799 final int[] users = getUsersLocked();
7800 for (int i=0; i<ris.size(); i++) {
7801 ActivityInfo ai = ris.get(i).activityInfo;
7802 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7803 doneReceivers.add(comp);
7804 intent.setComponent(comp);
7805 for (int j=0; j<users.length; j++) {
7806 IIntentReceiver finisher = null;
7807 if (i == ris.size()-1 && j == users.length-1) {
7808 finisher = new IIntentReceiver.Stub() {
7809 public void performReceive(Intent intent, int resultCode,
7810 String data, Bundle extras, boolean ordered,
7811 boolean sticky, int sendingUser) {
7812 // The raw IIntentReceiver interface is called
7813 // with the AM lock held, so redispatch to
7814 // execute our code without the lock.
7815 mHandler.post(new Runnable() {
7817 synchronized (ActivityManagerService.this) {
7820 writeLastDonePreBootReceivers(doneReceivers);
7821 showBootMessage(mContext.getText(
7822 R.string.android_upgrading_complete),
7824 systemReady(goingCallback);
7830 Slog.i(TAG, "Sending system update to " + intent.getComponent()
7831 + " for user " + users[j]);
7832 broadcastIntentLocked(null, null, intent, null, finisher,
7833 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7835 if (finisher != null) {
7836 mWaitingUpdate = true;
7841 if (mWaitingUpdate) {
7847 mSystemReady = true;
7848 if (!mStartRunning) {
7853 ArrayList<ProcessRecord> procsToKill = null;
7854 synchronized(mPidsSelfLocked) {
7855 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7856 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7857 if (!isAllowedWhileBooting(proc.info)){
7858 if (procsToKill == null) {
7859 procsToKill = new ArrayList<ProcessRecord>();
7861 procsToKill.add(proc);
7866 synchronized(this) {
7867 if (procsToKill != null) {
7868 for (int i=procsToKill.size()-1; i>=0; i--) {
7869 ProcessRecord proc = procsToKill.get(i);
7870 Slog.i(TAG, "Removing system update proc: " + proc);
7871 removeProcessLocked(proc, true, false, "system update done");
7875 // Now that we have cleaned up any update processes, we
7876 // are ready to start launching real processes and know that
7877 // we won't trample on them any more.
7878 mProcessesReady = true;
7881 Slog.i(TAG, "System now ready");
7882 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
7883 SystemClock.uptimeMillis());
7885 synchronized(this) {
7886 // Make sure we have no pre-ready processes sitting around.
7888 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7889 ResolveInfo ri = mContext.getPackageManager()
7890 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
7892 CharSequence errorMsg = null;
7894 ActivityInfo ai = ri.activityInfo;
7895 ApplicationInfo app = ai.applicationInfo;
7896 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7897 mTopAction = Intent.ACTION_FACTORY_TEST;
7899 mTopComponent = new ComponentName(app.packageName,
7902 errorMsg = mContext.getResources().getText(
7903 com.android.internal.R.string.factorytest_not_system);
7906 errorMsg = mContext.getResources().getText(
7907 com.android.internal.R.string.factorytest_no_action);
7909 if (errorMsg != null) {
7912 mTopComponent = null;
7913 Message msg = Message.obtain();
7914 msg.what = SHOW_FACTORY_ERROR_MSG;
7915 msg.getData().putCharSequence("msg", errorMsg);
7916 mHandler.sendMessage(msg);
7923 if (goingCallback != null) goingCallback.run();
7925 synchronized (this) {
7926 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7928 List apps = AppGlobals.getPackageManager().
7929 getPersistentApplications(STOCK_PM_FLAGS);
7931 int N = apps.size();
7933 for (i=0; i<N; i++) {
7934 ApplicationInfo info
7935 = (ApplicationInfo)apps.get(i);
7937 !info.packageName.equals("android")) {
7938 addAppLocked(info, false);
7942 } catch (RemoteException ex) {
7943 // pm is in same process, this will never happen.
7947 // Start up initial activity.
7951 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
7952 Message msg = Message.obtain();
7953 msg.what = SHOW_UID_ERROR_MSG;
7954 mHandler.sendMessage(msg);
7956 } catch (RemoteException e) {
7959 long ident = Binder.clearCallingIdentity();
7961 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
7962 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7963 | Intent.FLAG_RECEIVER_FOREGROUND);
7964 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7965 broadcastIntentLocked(null, null, intent,
7966 null, null, 0, null, null, null,
7967 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
7968 intent = new Intent(Intent.ACTION_USER_STARTING);
7969 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7970 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7971 broadcastIntentLocked(null, null, intent,
7972 null, new IIntentReceiver.Stub() {
7974 public void performReceive(Intent intent, int resultCode, String data,
7975 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
7976 throws RemoteException {
7979 android.Manifest.permission.INTERACT_ACROSS_USERS,
7980 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
7982 Binder.restoreCallingIdentity(ident);
7984 mMainStack.resumeTopActivityLocked(null);
7985 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
7989 private boolean makeAppCrashingLocked(ProcessRecord app,
7990 String shortMsg, String longMsg, String stackTrace) {
7991 app.crashing = true;
7992 app.crashingReport = generateProcessError(app,
7993 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
7994 startAppProblemLocked(app);
7995 app.stopFreezingAllLocked();
7996 return handleAppCrashLocked(app);
7999 private void makeAppNotRespondingLocked(ProcessRecord app,
8000 String activity, String shortMsg, String longMsg) {
8001 app.notResponding = true;
8002 app.notRespondingReport = generateProcessError(app,
8003 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
8004 activity, shortMsg, longMsg, null);
8005 startAppProblemLocked(app);
8006 app.stopFreezingAllLocked();
8010 * Generate a process error record, suitable for attachment to a ProcessRecord.
8012 * @param app The ProcessRecord in which the error occurred.
8013 * @param condition Crashing, Application Not Responding, etc. Values are defined in
8014 * ActivityManager.AppErrorStateInfo
8015 * @param activity The activity associated with the crash, if known.
8016 * @param shortMsg Short message describing the crash.
8017 * @param longMsg Long message describing the crash.
8018 * @param stackTrace Full crash stack trace, may be null.
8020 * @return Returns a fully-formed AppErrorStateInfo record.
8022 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
8023 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
8024 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
8026 report.condition = condition;
8027 report.processName = app.processName;
8028 report.pid = app.pid;
8029 report.uid = app.info.uid;
8030 report.tag = activity;
8031 report.shortMsg = shortMsg;
8032 report.longMsg = longMsg;
8033 report.stackTrace = stackTrace;
8038 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
8039 synchronized (this) {
8040 app.crashing = false;
8041 app.crashingReport = null;
8042 app.notResponding = false;
8043 app.notRespondingReport = null;
8044 if (app.anrDialog == fromDialog) {
8045 app.anrDialog = null;
8047 if (app.waitDialog == fromDialog) {
8048 app.waitDialog = null;
8050 if (app.pid > 0 && app.pid != MY_PID) {
8051 handleAppCrashLocked(app);
8052 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
8053 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
8054 app.processName, app.setAdj, "user's request after error");
8055 Process.killProcessQuiet(app.pid);
8060 private boolean handleAppCrashLocked(ProcessRecord app) {
8062 Log.e(TAG, "handleAppCrashLocked: " + app.processName);
8065 long now = SystemClock.uptimeMillis();
8068 if (!app.isolated) {
8069 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8073 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
8074 // This process loses!
8075 Slog.w(TAG, "Process " + app.info.processName
8076 + " has crashed too many times: killing!");
8077 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
8078 app.userId, app.info.processName, app.uid);
8079 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8080 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
8082 Slog.w(TAG, " Force finishing activity "
8083 + r.intent.getComponent().flattenToShortString());
8084 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
8085 null, "crashed", false);
8088 if (!app.persistent) {
8089 // We don't want to start this process again until the user
8090 // explicitly does so... but for persistent process, we really
8091 // need to keep it running. If a persistent process is actually
8092 // repeatedly crashing, then badness for everyone.
8093 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
8094 app.info.processName);
8095 if (!app.isolated) {
8096 // XXX We don't have a way to mark isolated processes
8097 // as bad, since they don't have a peristent identity.
8098 mBadProcesses.put(app.info.processName, app.uid, now);
8099 mProcessCrashTimes.remove(app.info.processName, app.uid);
8103 // Don't let services in this process be restarted and potentially
8104 // annoy the user repeatedly. Unless it is persistent, since those
8105 // processes run critical code.
8106 removeProcessLocked(app, false, false, "crash");
8107 mMainStack.resumeTopActivityLocked(null);
8110 mMainStack.resumeTopActivityLocked(null);
8112 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
8113 if (r != null && r.app == app) {
8114 // If the top running activity is from this crashing
8115 // process, then terminate it to avoid getting in a loop.
8116 Slog.w(TAG, " Force finishing activity "
8117 + r.intent.getComponent().flattenToShortString());
8118 int index = mMainStack.indexOfActivityLocked(r);
8119 r.stack.finishActivityLocked(r, index,
8120 Activity.RESULT_CANCELED, null, "crashed", false);
8121 // Also terminate any activities below it that aren't yet
8122 // stopped, to avoid a situation where one will get
8123 // re-start our crashing activity once it gets resumed again.
8126 r = (ActivityRecord)mMainStack.mHistory.get(index);
8127 if (r.state == ActivityState.RESUMED
8128 || r.state == ActivityState.PAUSING
8129 || r.state == ActivityState.PAUSED) {
8130 if (!r.isHomeActivity || mHomeProcess != r.app) {
8131 Slog.w(TAG, " Force finishing activity "
8132 + r.intent.getComponent().flattenToShortString());
8133 r.stack.finishActivityLocked(r, index,
8134 Activity.RESULT_CANCELED, null, "crashed", false);
8141 // Bump up the crash count of any services currently running in the proc.
8142 if (app.services.size() != 0) {
8143 // Any services running in the application need to be placed
8144 // back in the pending list.
8145 Iterator<ServiceRecord> it = app.services.iterator();
8146 while (it.hasNext()) {
8147 ServiceRecord sr = it.next();
8152 // If the crashing process is what we consider to be the "home process" and it has been
8153 // replaced by a third-party app, clear the package preferred activities from packages
8154 // with a home activity running in the process to prevent a repeatedly crashing app
8155 // from blocking the user to manually clear the list.
8156 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8157 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8158 Iterator it = mHomeProcess.activities.iterator();
8159 while (it.hasNext()) {
8160 ActivityRecord r = (ActivityRecord)it.next();
8161 if (r.isHomeActivity) {
8162 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8164 ActivityThread.getPackageManager()
8165 .clearPackagePreferredActivities(r.packageName);
8166 } catch (RemoteException c) {
8167 // pm is in same process, this will never happen.
8173 if (!app.isolated) {
8174 // XXX Can't keep track of crash times for isolated processes,
8175 // because they don't have a perisistent identity.
8176 mProcessCrashTimes.put(app.info.processName, app.uid, now);
8182 void startAppProblemLocked(ProcessRecord app) {
8183 if (app.userId == mCurrentUserId) {
8184 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8185 mContext, app.info.packageName, app.info.flags);
8187 // If this app is not running under the current user, then we
8188 // can't give it a report button because that would require
8189 // launching the report UI under a different user.
8190 app.errorReportReceiver = null;
8192 skipCurrentReceiverLocked(app);
8195 void skipCurrentReceiverLocked(ProcessRecord app) {
8196 for (BroadcastQueue queue : mBroadcastQueues) {
8197 queue.skipCurrentReceiverLocked(app);
8202 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8203 * The application process will exit immediately after this call returns.
8204 * @param app object of the crashing app, null for the system server
8205 * @param crashInfo describing the exception
8207 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
8208 ProcessRecord r = findAppProcess(app, "Crash");
8209 final String processName = app == null ? "system_server"
8210 : (r == null ? "unknown" : r.processName);
8212 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
8213 UserHandle.getUserId(Binder.getCallingUid()), processName,
8214 r == null ? -1 : r.info.flags,
8215 crashInfo.exceptionClassName,
8216 crashInfo.exceptionMessage,
8217 crashInfo.throwFileName,
8218 crashInfo.throwLineNumber);
8220 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
8222 crashApplication(r, crashInfo);
8225 public void handleApplicationStrictModeViolation(
8228 StrictMode.ViolationInfo info) {
8229 ProcessRecord r = findAppProcess(app, "StrictMode");
8234 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
8235 Integer stackFingerprint = info.hashCode();
8236 boolean logIt = true;
8237 synchronized (mAlreadyLoggedViolatedStacks) {
8238 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8240 // TODO: sub-sample into EventLog for these, with
8241 // the info.durationMillis? Then we'd get
8242 // the relative pain numbers, without logging all
8243 // the stack traces repeatedly. We'd want to do
8244 // likewise in the client code, which also does
8245 // dup suppression, before the Binder call.
8247 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8248 mAlreadyLoggedViolatedStacks.clear();
8250 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8254 logStrictModeViolationToDropBox(r, info);
8258 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8259 AppErrorResult result = new AppErrorResult();
8260 synchronized (this) {
8261 final long origId = Binder.clearCallingIdentity();
8263 Message msg = Message.obtain();
8264 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8265 HashMap<String, Object> data = new HashMap<String, Object>();
8266 data.put("result", result);
8268 data.put("violationMask", violationMask);
8269 data.put("info", info);
8271 mHandler.sendMessage(msg);
8273 Binder.restoreCallingIdentity(origId);
8275 int res = result.get();
8276 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
8280 // Depending on the policy in effect, there could be a bunch of
8281 // these in quick succession so we try to batch these together to
8282 // minimize disk writes, number of dropbox entries, and maximize
8283 // compression, by having more fewer, larger records.
8284 private void logStrictModeViolationToDropBox(
8285 ProcessRecord process,
8286 StrictMode.ViolationInfo info) {
8290 final boolean isSystemApp = process == null ||
8291 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8292 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
8293 final String processName = process == null ? "unknown" : process.processName;
8294 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8295 final DropBoxManager dbox = (DropBoxManager)
8296 mContext.getSystemService(Context.DROPBOX_SERVICE);
8298 // Exit early if the dropbox isn't configured to accept this report type.
8299 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8301 boolean bufferWasEmpty;
8303 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8305 bufferWasEmpty = sb.length() == 0;
8306 appendDropBoxProcessHeaders(process, processName, sb);
8307 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8308 sb.append("System-App: ").append(isSystemApp).append("\n");
8309 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8310 if (info.violationNumThisLoop != 0) {
8311 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8313 if (info.numAnimationsRunning != 0) {
8314 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8316 if (info.broadcastIntentAction != null) {
8317 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8319 if (info.durationMillis != -1) {
8320 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
8322 if (info.numInstances != -1) {
8323 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8325 if (info.tags != null) {
8326 for (String tag : info.tags) {
8327 sb.append("Span-Tag: ").append(tag).append("\n");
8331 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8332 sb.append(info.crashInfo.stackTrace);
8336 // Only buffer up to ~64k. Various logging bits truncate
8338 needsFlush = (sb.length() > 64 * 1024);
8341 // Flush immediately if the buffer's grown too large, or this
8342 // is a non-system app. Non-system apps are isolated with a
8343 // different tag & policy and not batched.
8345 // Batching is useful during internal testing with
8346 // StrictMode settings turned up high. Without batching,
8347 // thousands of separate files could be created on boot.
8348 if (!isSystemApp || needsFlush) {
8349 new Thread("Error dump: " + dropboxTag) {
8354 report = sb.toString();
8355 sb.delete(0, sb.length());
8358 if (report.length() != 0) {
8359 dbox.addText(dropboxTag, report);
8366 // System app batching:
8367 if (!bufferWasEmpty) {
8368 // An existing dropbox-writing thread is outstanding, so
8369 // we don't need to start it up. The existing thread will
8370 // catch the buffer appends we just did.
8374 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8375 // (After this point, we shouldn't access AMS internal data structures.)
8376 new Thread("Error dump: " + dropboxTag) {
8379 // 5 second sleep to let stacks arrive and be batched together
8381 Thread.sleep(5000); // 5 seconds
8382 } catch (InterruptedException e) {}
8385 synchronized (mStrictModeBuffer) {
8386 errorReport = mStrictModeBuffer.toString();
8387 if (errorReport.length() == 0) {
8390 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8391 mStrictModeBuffer.trimToSize();
8393 dbox.addText(dropboxTag, errorReport);
8399 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8400 * @param app object of the crashing app, null for the system server
8401 * @param tag reported by the caller
8402 * @param crashInfo describing the context of the error
8403 * @return true if the process should exit immediately (WTF is fatal)
8405 public boolean handleApplicationWtf(IBinder app, String tag,
8406 ApplicationErrorReport.CrashInfo crashInfo) {
8407 ProcessRecord r = findAppProcess(app, "WTF");
8408 final String processName = app == null ? "system_server"
8409 : (r == null ? "unknown" : r.processName);
8411 EventLog.writeEvent(EventLogTags.AM_WTF,
8412 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
8414 r == null ? -1 : r.info.flags,
8415 tag, crashInfo.exceptionMessage);
8417 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
8419 if (r != null && r.pid != Process.myPid() &&
8420 Settings.Global.getInt(mContext.getContentResolver(),
8421 Settings.Global.WTF_IS_FATAL, 0) != 0) {
8422 crashApplication(r, crashInfo);
8430 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8431 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8433 private ProcessRecord findAppProcess(IBinder app, String reason) {
8438 synchronized (this) {
8439 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8440 final int NA = apps.size();
8441 for (int ia=0; ia<NA; ia++) {
8442 ProcessRecord p = apps.valueAt(ia);
8443 if (p.thread != null && p.thread.asBinder() == app) {
8449 Slog.w(TAG, "Can't find mystery application for " + reason
8450 + " from pid=" + Binder.getCallingPid()
8451 + " uid=" + Binder.getCallingUid() + ": " + app);
8457 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8458 * to append various headers to the dropbox log text.
8460 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8462 // Watchdog thread ends up invoking this function (with
8463 // a null ProcessRecord) to add the stack file to dropbox.
8464 // Do not acquire a lock on this (am) in such cases, as it
8465 // could cause a potential deadlock, if and when watchdog
8466 // is invoked due to unavailability of lock on am and it
8467 // would prevent watchdog from killing system_server.
8468 if (process == null) {
8469 sb.append("Process: ").append(processName).append("\n");
8472 // Note: ProcessRecord 'process' is guarded by the service
8473 // instance. (notably process.pkgList, which could otherwise change
8474 // concurrently during execution of this method)
8475 synchronized (this) {
8476 sb.append("Process: ").append(processName).append("\n");
8477 int flags = process.info.flags;
8478 IPackageManager pm = AppGlobals.getPackageManager();
8479 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8480 for (String pkg : process.pkgList) {
8481 sb.append("Package: ").append(pkg);
8483 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
8485 sb.append(" v").append(pi.versionCode);
8486 if (pi.versionName != null) {
8487 sb.append(" (").append(pi.versionName).append(")");
8490 } catch (RemoteException e) {
8491 Slog.e(TAG, "Error getting package info: " + pkg, e);
8498 private static String processClass(ProcessRecord process) {
8499 if (process == null || process.pid == MY_PID) {
8500 return "system_server";
8501 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8502 return "system_app";
8509 * Write a description of an error (crash, WTF, ANR) to the drop box.
8510 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8511 * @param process which caused the error, null means the system server
8512 * @param activity which triggered the error, null if unknown
8513 * @param parent activity related to the error, null if unknown
8514 * @param subject line related to the error, null if absent
8515 * @param report in long form describing the error, null if absent
8516 * @param logFile to include in the report, null if none
8517 * @param crashInfo giving an application stack trace, null if absent
8519 public void addErrorToDropBox(String eventType,
8520 ProcessRecord process, String processName, ActivityRecord activity,
8521 ActivityRecord parent, String subject,
8522 final String report, final File logFile,
8523 final ApplicationErrorReport.CrashInfo crashInfo) {
8524 // NOTE -- this must never acquire the ActivityManagerService lock,
8525 // otherwise the watchdog may be prevented from resetting the system.
8527 final String dropboxTag = processClass(process) + "_" + eventType;
8528 final DropBoxManager dbox = (DropBoxManager)
8529 mContext.getSystemService(Context.DROPBOX_SERVICE);
8531 // Exit early if the dropbox isn't configured to accept this report type.
8532 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8534 final StringBuilder sb = new StringBuilder(1024);
8535 appendDropBoxProcessHeaders(process, processName, sb);
8536 if (activity != null) {
8537 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8539 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8540 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8542 if (parent != null && parent != activity) {
8543 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8545 if (subject != null) {
8546 sb.append("Subject: ").append(subject).append("\n");
8548 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8549 if (Debug.isDebuggerConnected()) {
8550 sb.append("Debugger: Connected\n");
8554 // Do the rest in a worker thread to avoid blocking the caller on I/O
8555 // (After this point, we shouldn't access AMS internal data structures.)
8556 Thread worker = new Thread("Error dump: " + dropboxTag) {
8559 if (report != null) {
8562 if (logFile != null) {
8564 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8565 } catch (IOException e) {
8566 Slog.e(TAG, "Error reading " + logFile, e);
8569 if (crashInfo != null && crashInfo.stackTrace != null) {
8570 sb.append(crashInfo.stackTrace);
8573 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8574 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
8578 // Merge several logcat streams, and take the last N lines
8579 InputStreamReader input = null;
8581 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8582 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8583 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8585 try { logcat.getOutputStream().close(); } catch (IOException e) {}
8586 try { logcat.getErrorStream().close(); } catch (IOException e) {}
8587 input = new InputStreamReader(logcat.getInputStream());
8590 char[] buf = new char[8192];
8591 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8592 } catch (IOException e) {
8593 Slog.e(TAG, "Error running logcat", e);
8595 if (input != null) try { input.close(); } catch (IOException e) {}
8599 dbox.addText(dropboxTag, sb.toString());
8603 if (process == null) {
8604 // If process is null, we are being called from some internal code
8605 // and may be about to die -- run this synchronously.
8613 * Bring up the "unexpected error" dialog box for a crashing app.
8614 * Deal with edge cases (intercepts from instrumented applications,
8615 * ActivityController, error intent receivers, that sort of thing).
8616 * @param r the application crashing
8617 * @param crashInfo describing the failure
8619 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
8620 long timeMillis = System.currentTimeMillis();
8621 String shortMsg = crashInfo.exceptionClassName;
8622 String longMsg = crashInfo.exceptionMessage;
8623 String stackTrace = crashInfo.stackTrace;
8624 if (shortMsg != null && longMsg != null) {
8625 longMsg = shortMsg + ": " + longMsg;
8626 } else if (shortMsg != null) {
8630 AppErrorResult result = new AppErrorResult();
8631 synchronized (this) {
8632 if (mController != null) {
8634 String name = r != null ? r.processName : null;
8635 int pid = r != null ? r.pid : Binder.getCallingPid();
8636 if (!mController.appCrashed(name, pid,
8637 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
8638 Slog.w(TAG, "Force-killing crashed app " + name
8639 + " at watcher's request");
8640 Process.killProcess(pid);
8643 } catch (RemoteException e) {
8648 final long origId = Binder.clearCallingIdentity();
8650 // If this process is running instrumentation, finish it.
8651 if (r != null && r.instrumentationClass != null) {
8652 Slog.w(TAG, "Error in app " + r.processName
8653 + " running instrumentation " + r.instrumentationClass + ":");
8654 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
8655 if (longMsg != null) Slog.w(TAG, " " + longMsg);
8656 Bundle info = new Bundle();
8657 info.putString("shortMsg", shortMsg);
8658 info.putString("longMsg", longMsg);
8659 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8660 Binder.restoreCallingIdentity(origId);
8664 // If we can't identify the process or it's already exceeded its crash quota,
8665 // quit right away without showing a crash dialog.
8666 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
8667 Binder.restoreCallingIdentity(origId);
8671 Message msg = Message.obtain();
8672 msg.what = SHOW_ERROR_MSG;
8673 HashMap data = new HashMap();
8674 data.put("result", result);
8677 mHandler.sendMessage(msg);
8679 Binder.restoreCallingIdentity(origId);
8682 int res = result.get();
8684 Intent appErrorIntent = null;
8685 synchronized (this) {
8686 if (r != null && !r.isolated) {
8687 // XXX Can't keep track of crash time for isolated processes,
8688 // since they don't have a persistent identity.
8689 mProcessCrashTimes.put(r.info.processName, r.uid,
8690 SystemClock.uptimeMillis());
8692 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
8693 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
8697 if (appErrorIntent != null) {
8699 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
8700 } catch (ActivityNotFoundException e) {
8701 Slog.w(TAG, "bug report receiver dissappeared", e);
8706 Intent createAppErrorIntentLocked(ProcessRecord r,
8707 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8708 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
8709 if (report == null) {
8712 Intent result = new Intent(Intent.ACTION_APP_ERROR);
8713 result.setComponent(r.errorReportReceiver);
8714 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8715 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8719 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8720 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8721 if (r.errorReportReceiver == null) {
8725 if (!r.crashing && !r.notResponding) {
8729 ApplicationErrorReport report = new ApplicationErrorReport();
8730 report.packageName = r.info.packageName;
8731 report.installerPackageName = r.errorReportReceiver.getPackageName();
8732 report.processName = r.processName;
8733 report.time = timeMillis;
8734 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
8737 report.type = ApplicationErrorReport.TYPE_CRASH;
8738 report.crashInfo = crashInfo;
8739 } else if (r.notResponding) {
8740 report.type = ApplicationErrorReport.TYPE_ANR;
8741 report.anrInfo = new ApplicationErrorReport.AnrInfo();
8743 report.anrInfo.activity = r.notRespondingReport.tag;
8744 report.anrInfo.cause = r.notRespondingReport.shortMsg;
8745 report.anrInfo.info = r.notRespondingReport.longMsg;
8751 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
8752 enforceNotIsolatedCaller("getProcessesInErrorState");
8753 // assume our apps are happy - lazy create the list
8754 List<ActivityManager.ProcessErrorStateInfo> errList = null;
8756 final boolean allUsers = ActivityManager.checkUidPermission(
8757 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8758 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8759 int userId = UserHandle.getUserId(Binder.getCallingUid());
8761 synchronized (this) {
8763 // iterate across all processes
8764 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8765 ProcessRecord app = mLruProcesses.get(i);
8766 if (!allUsers && app.userId != userId) {
8769 if ((app.thread != null) && (app.crashing || app.notResponding)) {
8770 // This one's in trouble, so we'll generate a report for it
8771 // crashes are higher priority (in case there's a crash *and* an anr)
8772 ActivityManager.ProcessErrorStateInfo report = null;
8774 report = app.crashingReport;
8775 } else if (app.notResponding) {
8776 report = app.notRespondingReport;
8779 if (report != null) {
8780 if (errList == null) {
8781 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8783 errList.add(report);
8785 Slog.w(TAG, "Missing app error report, app = " + app.processName +
8786 " crashing = " + app.crashing +
8787 " notResponding = " + app.notResponding);
8796 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
8797 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8798 if (currApp != null) {
8799 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8801 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8802 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8803 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8804 } else if (adj >= ProcessList.HOME_APP_ADJ) {
8805 if (currApp != null) {
8808 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
8809 } else if (adj >= ProcessList.SERVICE_ADJ) {
8810 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8811 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8812 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8813 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8814 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8815 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8816 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8818 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8822 private void fillInProcMemInfo(ProcessRecord app,
8823 ActivityManager.RunningAppProcessInfo outInfo) {
8824 outInfo.pid = app.pid;
8825 outInfo.uid = app.info.uid;
8826 if (mHeavyWeightProcess == app) {
8827 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8829 if (app.persistent) {
8830 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8832 if (app.hasActivities) {
8833 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8835 outInfo.lastTrimLevel = app.trimMemoryLevel;
8836 int adj = app.curAdj;
8837 outInfo.importance = oomAdjToImportance(adj, outInfo);
8838 outInfo.importanceReasonCode = app.adjTypeCode;
8841 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
8842 enforceNotIsolatedCaller("getRunningAppProcesses");
8843 // Lazy instantiation of list
8844 List<ActivityManager.RunningAppProcessInfo> runList = null;
8845 final boolean allUsers = ActivityManager.checkUidPermission(
8846 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8847 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8848 int userId = UserHandle.getUserId(Binder.getCallingUid());
8849 synchronized (this) {
8850 // Iterate across all processes
8851 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8852 ProcessRecord app = mLruProcesses.get(i);
8853 if (!allUsers && app.userId != userId) {
8856 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8857 // Generate process state info for running application
8858 ActivityManager.RunningAppProcessInfo currApp =
8859 new ActivityManager.RunningAppProcessInfo(app.processName,
8860 app.pid, app.getPackageList());
8861 fillInProcMemInfo(app, currApp);
8862 if (app.adjSource instanceof ProcessRecord) {
8863 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
8864 currApp.importanceReasonImportance = oomAdjToImportance(
8865 app.adjSourceOom, null);
8866 } else if (app.adjSource instanceof ActivityRecord) {
8867 ActivityRecord r = (ActivityRecord)app.adjSource;
8868 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8870 if (app.adjTarget instanceof ComponentName) {
8871 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8873 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
8874 // + " lru=" + currApp.lru);
8875 if (runList == null) {
8876 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8878 runList.add(currApp);
8885 public List<ApplicationInfo> getRunningExternalApplications() {
8886 enforceNotIsolatedCaller("getRunningExternalApplications");
8887 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8888 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8889 if (runningApps != null && runningApps.size() > 0) {
8890 Set<String> extList = new HashSet<String>();
8891 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8892 if (app.pkgList != null) {
8893 for (String pkg : app.pkgList) {
8898 IPackageManager pm = AppGlobals.getPackageManager();
8899 for (String pkg : extList) {
8901 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
8902 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8905 } catch (RemoteException e) {
8913 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8914 enforceNotIsolatedCaller("getMyMemoryState");
8915 synchronized (this) {
8917 synchronized (mPidsSelfLocked) {
8918 proc = mPidsSelfLocked.get(Binder.getCallingPid());
8920 fillInProcMemInfo(proc, outInfo);
8925 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
8926 if (checkCallingPermission(android.Manifest.permission.DUMP)
8927 != PackageManager.PERMISSION_GRANTED) {
8928 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8929 + Binder.getCallingPid()
8930 + ", uid=" + Binder.getCallingUid()
8931 + " without permission "
8932 + android.Manifest.permission.DUMP);
8936 boolean dumpAll = false;
8937 boolean dumpClient = false;
8938 String dumpPackage = null;
8941 while (opti < args.length) {
8942 String opt = args[opti];
8943 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8947 if ("-a".equals(opt)) {
8949 } else if ("-c".equals(opt)) {
8951 } else if ("-h".equals(opt)) {
8952 pw.println("Activity manager dump options:");
8953 pw.println(" [-a] [-c] [-h] [cmd] ...");
8954 pw.println(" cmd may be one of:");
8955 pw.println(" a[ctivities]: activity stack state");
8956 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
8957 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
8958 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
8959 pw.println(" o[om]: out of memory management");
8960 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
8961 pw.println(" provider [COMP_SPEC]: provider client-side state");
8962 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
8963 pw.println(" service [COMP_SPEC]: service client-side state");
8964 pw.println(" package [PACKAGE_NAME]: all state related to given package");
8965 pw.println(" all: dump all activities");
8966 pw.println(" top: dump the top activity");
8967 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
8968 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
8969 pw.println(" a partial substring in a component name, a");
8970 pw.println(" hex object identifier.");
8971 pw.println(" -a: include all available server state.");
8972 pw.println(" -c: include client state.");
8975 pw.println("Unknown argument: " + opt + "; use -h for help");
8979 long origId = Binder.clearCallingIdentity();
8980 boolean more = false;
8981 // Is the caller requesting to dump a particular piece of data?
8982 if (opti < args.length) {
8983 String cmd = args[opti];
8985 if ("activities".equals(cmd) || "a".equals(cmd)) {
8986 synchronized (this) {
8987 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
8989 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
8992 if (opti >= args.length) {
8994 newArgs = EMPTY_STRING_ARRAY;
8998 newArgs = new String[args.length - opti];
8999 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9000 args.length - opti);
9002 synchronized (this) {
9003 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
9005 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
9008 if (opti >= args.length) {
9010 newArgs = EMPTY_STRING_ARRAY;
9014 newArgs = new String[args.length - opti];
9015 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9016 args.length - opti);
9018 synchronized (this) {
9019 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
9021 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
9024 if (opti >= args.length) {
9026 newArgs = EMPTY_STRING_ARRAY;
9030 newArgs = new String[args.length - opti];
9031 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9032 args.length - opti);
9034 synchronized (this) {
9035 dumpProcessesLocked(fd, pw, args, opti, true, name);
9037 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
9038 synchronized (this) {
9039 dumpOomLocked(fd, pw, args, opti, true);
9041 } else if ("provider".equals(cmd)) {
9044 if (opti >= args.length) {
9046 newArgs = EMPTY_STRING_ARRAY;
9050 newArgs = new String[args.length - opti];
9051 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9053 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
9054 pw.println("No providers match: " + name);
9055 pw.println("Use -h for help.");
9057 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
9058 synchronized (this) {
9059 dumpProvidersLocked(fd, pw, args, opti, true, null);
9061 } else if ("service".equals(cmd)) {
9064 if (opti >= args.length) {
9066 newArgs = EMPTY_STRING_ARRAY;
9070 newArgs = new String[args.length - opti];
9071 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9072 args.length - opti);
9074 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
9075 pw.println("No services match: " + name);
9076 pw.println("Use -h for help.");
9078 } else if ("package".equals(cmd)) {
9080 if (opti >= args.length) {
9081 pw.println("package: no package name specified");
9082 pw.println("Use -h for help.");
9084 dumpPackage = args[opti];
9086 newArgs = new String[args.length - opti];
9087 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9088 args.length - opti);
9093 } else if ("services".equals(cmd) || "s".equals(cmd)) {
9094 synchronized (this) {
9095 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
9098 // Dumping a single activity?
9099 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9100 pw.println("Bad activity command, or no activities match: " + cmd);
9101 pw.println("Use -h for help.");
9105 Binder.restoreCallingIdentity(origId);
9110 // No piece of data specified, dump everything.
9111 synchronized (this) {
9113 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9118 pw.println("-------------------------------------------------------------------------------");
9120 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9125 pw.println("-------------------------------------------------------------------------------");
9127 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9132 pw.println("-------------------------------------------------------------------------------");
9134 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9139 pw.println("-------------------------------------------------------------------------------");
9141 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
9146 pw.println("-------------------------------------------------------------------------------");
9148 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
9150 Binder.restoreCallingIdentity(origId);
9153 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9154 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
9155 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9156 pw.println(" Main stack:");
9157 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
9160 pw.println(" Running activities (most recent first):");
9161 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
9163 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
9165 pw.println(" Activities waiting for another to become visible:");
9166 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
9167 !dumpAll, false, dumpPackage);
9169 if (mMainStack.mStoppingActivities.size() > 0) {
9171 pw.println(" Activities waiting to stop:");
9172 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
9173 !dumpAll, false, dumpPackage);
9175 if (mMainStack.mGoingToSleepActivities.size() > 0) {
9177 pw.println(" Activities waiting to sleep:");
9178 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
9179 !dumpAll, false, dumpPackage);
9181 if (mMainStack.mFinishingActivities.size() > 0) {
9183 pw.println(" Activities waiting to finish:");
9184 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
9185 !dumpAll, false, dumpPackage);
9189 if (mMainStack.mPausingActivity != null) {
9190 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
9192 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
9193 pw.println(" mFocusedActivity: " + mFocusedActivity);
9195 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9196 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
9197 pw.println(" mDismissKeyguardOnNextActivity: "
9198 + mMainStack.mDismissKeyguardOnNextActivity);
9201 if (mRecentTasks.size() > 0) {
9203 pw.println(" Recent tasks:");
9205 final int N = mRecentTasks.size();
9206 for (int i=0; i<N; i++) {
9207 TaskRecord tr = mRecentTasks.get(i);
9208 if (dumpPackage != null) {
9209 if (tr.realActivity == null ||
9210 !dumpPackage.equals(tr.realActivity)) {
9214 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
9217 mRecentTasks.get(i).dump(pw, " ");
9224 pw.println(" mCurTask: " + mCurTask);
9230 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9231 int opti, boolean dumpAll, String dumpPackage) {
9232 boolean needSep = false;
9235 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9238 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9239 final int NA = procs.size();
9240 for (int ia=0; ia<NA; ia++) {
9241 ProcessRecord r = procs.valueAt(ia);
9242 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9246 pw.println(" All known processes:");
9249 pw.print(r.persistent ? " *PERS*" : " *APP*");
9250 pw.print(" UID "); pw.print(procs.keyAt(ia));
9251 pw.print(" "); pw.println(r);
9260 if (mIsolatedProcesses.size() > 0) {
9261 if (needSep) pw.println(" ");
9263 pw.println(" Isolated process list (sorted by uid):");
9264 for (int i=0; i<mIsolatedProcesses.size(); i++) {
9265 ProcessRecord r = mIsolatedProcesses.valueAt(i);
9266 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9269 pw.println(String.format("%sIsolated #%2d: %s",
9270 " ", i, r.toString()));
9274 if (mLruProcesses.size() > 0) {
9275 if (needSep) pw.println(" ");
9277 pw.println(" Process LRU list (sorted by oom_adj):");
9278 dumpProcessOomList(pw, this, mLruProcesses, " ",
9279 "Proc", "PERS", false, dumpPackage);
9284 synchronized (mPidsSelfLocked) {
9285 boolean printed = false;
9286 for (int i=0; i<mPidsSelfLocked.size(); i++) {
9287 ProcessRecord r = mPidsSelfLocked.valueAt(i);
9288 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9292 if (needSep) pw.println(" ");
9294 pw.println(" PID mappings:");
9297 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9298 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
9303 if (mForegroundProcesses.size() > 0) {
9304 synchronized (mPidsSelfLocked) {
9305 boolean printed = false;
9306 for (int i=0; i<mForegroundProcesses.size(); i++) {
9307 ProcessRecord r = mPidsSelfLocked.get(
9308 mForegroundProcesses.valueAt(i).pid);
9309 if (dumpPackage != null && (r == null
9310 || !dumpPackage.equals(r.info.packageName))) {
9314 if (needSep) pw.println(" ");
9316 pw.println(" Foreground Processes:");
9319 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
9320 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9325 if (mPersistentStartingProcesses.size() > 0) {
9326 if (needSep) pw.println(" ");
9328 pw.println(" Persisent processes that are starting:");
9329 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
9330 "Starting Norm", "Restarting PERS", dumpPackage);
9333 if (mRemovedProcesses.size() > 0) {
9334 if (needSep) pw.println(" ");
9336 pw.println(" Processes that are being removed:");
9337 dumpProcessList(pw, this, mRemovedProcesses, " ",
9338 "Removed Norm", "Removed PERS", dumpPackage);
9341 if (mProcessesOnHold.size() > 0) {
9342 if (needSep) pw.println(" ");
9344 pw.println(" Processes that are on old until the system is ready:");
9345 dumpProcessList(pw, this, mProcessesOnHold, " ",
9346 "OnHold Norm", "OnHold PERS", dumpPackage);
9349 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
9351 if (mProcessCrashTimes.getMap().size() > 0) {
9352 boolean printed = false;
9353 long now = SystemClock.uptimeMillis();
9354 for (Map.Entry<String, SparseArray<Long>> procs
9355 : mProcessCrashTimes.getMap().entrySet()) {
9356 String pname = procs.getKey();
9357 SparseArray<Long> uids = procs.getValue();
9358 final int N = uids.size();
9359 for (int i=0; i<N; i++) {
9360 int puid = uids.keyAt(i);
9361 ProcessRecord r = mProcessNames.get(pname, puid);
9362 if (dumpPackage != null && (r == null
9363 || !dumpPackage.equals(r.info.packageName))) {
9367 if (needSep) pw.println(" ");
9369 pw.println(" Time since processes crashed:");
9372 pw.print(" Process "); pw.print(pname);
9373 pw.print(" uid "); pw.print(puid);
9374 pw.print(": last crashed ");
9375 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9381 if (mBadProcesses.getMap().size() > 0) {
9382 boolean printed = false;
9383 for (Map.Entry<String, SparseArray<Long>> procs
9384 : mBadProcesses.getMap().entrySet()) {
9385 String pname = procs.getKey();
9386 SparseArray<Long> uids = procs.getValue();
9387 final int N = uids.size();
9388 for (int i=0; i<N; i++) {
9389 int puid = uids.keyAt(i);
9390 ProcessRecord r = mProcessNames.get(pname, puid);
9391 if (dumpPackage != null && (r == null
9392 || !dumpPackage.equals(r.info.packageName))) {
9396 if (needSep) pw.println(" ");
9398 pw.println(" Bad processes:");
9400 pw.print(" Bad process "); pw.print(pname);
9401 pw.print(" uid "); pw.print(puid);
9402 pw.print(": crashed at time ");
9403 pw.println(uids.valueAt(i));
9409 pw.println(" mStartedUsers:");
9410 for (int i=0; i<mStartedUsers.size(); i++) {
9411 UserStartedState uss = mStartedUsers.valueAt(i);
9412 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
9413 pw.print(": "); uss.dump("", pw);
9415 pw.print(" mStartedUserArray: [");
9416 for (int i=0; i<mStartedUserArray.length; i++) {
9417 if (i > 0) pw.print(", ");
9418 pw.print(mStartedUserArray[i]);
9421 pw.print(" mUserLru: [");
9422 for (int i=0; i<mUserLru.size(); i++) {
9423 if (i > 0) pw.print(", ");
9424 pw.print(mUserLru.get(i));
9428 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9430 pw.println(" mHomeProcess: " + mHomeProcess);
9431 pw.println(" mPreviousProcess: " + mPreviousProcess);
9433 StringBuilder sb = new StringBuilder(128);
9434 sb.append(" mPreviousProcessVisibleTime: ");
9435 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9438 if (mHeavyWeightProcess != null) {
9439 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9441 pw.println(" mConfiguration: " + mConfiguration);
9443 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
9444 if (mCompatModePackages.getPackages().size() > 0) {
9445 boolean printed = false;
9446 for (Map.Entry<String, Integer> entry
9447 : mCompatModePackages.getPackages().entrySet()) {
9448 String pkg = entry.getKey();
9449 int mode = entry.getValue();
9450 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9454 pw.println(" mScreenCompatPackages:");
9457 pw.print(" "); pw.print(pkg); pw.print(": ");
9458 pw.print(mode); pw.println();
9462 if (mSleeping || mWentToSleep || mLockScreenShown) {
9463 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9464 + " mLockScreenShown " + mLockScreenShown);
9466 if (mShuttingDown) {
9467 pw.println(" mShuttingDown=" + mShuttingDown);
9469 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9470 || mOrigWaitForDebugger) {
9471 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9472 + " mDebugTransient=" + mDebugTransient
9473 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9475 if (mOpenGlTraceApp != null) {
9476 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
9478 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9479 || mProfileFd != null) {
9480 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9481 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9482 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
9483 + mAutoStopProfiler);
9485 if (mAlwaysFinishActivities || mController != null) {
9486 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
9487 + " mController=" + mController);
9490 pw.println(" Total persistent processes: " + numPers);
9491 pw.println(" mStartRunning=" + mStartRunning
9492 + " mProcessesReady=" + mProcessesReady
9493 + " mSystemReady=" + mSystemReady);
9494 pw.println(" mBooting=" + mBooting
9495 + " mBooted=" + mBooted
9496 + " mFactoryTest=" + mFactoryTest);
9497 pw.print(" mLastPowerCheckRealtime=");
9498 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9500 pw.print(" mLastPowerCheckUptime=");
9501 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9503 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
9504 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
9505 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
9506 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs
9507 + " mNumHiddenProcs=" + mNumHiddenProcs
9508 + " mNumServiceProcs=" + mNumServiceProcs
9509 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
9515 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
9516 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
9517 if (mProcessesToGc.size() > 0) {
9518 boolean printed = false;
9519 long now = SystemClock.uptimeMillis();
9520 for (int i=0; i<mProcessesToGc.size(); i++) {
9521 ProcessRecord proc = mProcessesToGc.get(i);
9522 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9526 if (needSep) pw.println(" ");
9528 pw.println(" Processes that are waiting to GC:");
9531 pw.print(" Process "); pw.println(proc);
9532 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
9533 pw.print(", last gced=");
9534 pw.print(now-proc.lastRequestedGc);
9535 pw.print(" ms ago, last lowMem=");
9536 pw.print(now-proc.lastLowMemory);
9537 pw.println(" ms ago");
9544 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9545 int opti, boolean dumpAll) {
9546 boolean needSep = false;
9548 if (mLruProcesses.size() > 0) {
9549 if (needSep) pw.println(" ");
9551 pw.println(" OOM levels:");
9552 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
9553 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
9554 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9555 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9556 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9557 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9558 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
9559 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
9560 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
9561 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
9562 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
9563 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
9564 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
9566 if (needSep) pw.println(" ");
9568 pw.println(" Process OOM control:");
9569 dumpProcessOomList(pw, this, mLruProcesses, " ",
9570 "Proc", "PERS", true, null);
9574 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
9577 pw.println(" mHomeProcess: " + mHomeProcess);
9578 pw.println(" mPreviousProcess: " + mPreviousProcess);
9579 if (mHeavyWeightProcess != null) {
9580 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9587 * There are three ways to call this:
9588 * - no provider specified: dump all the providers
9589 * - a flattened component name that matched an existing provider was specified as the
9590 * first arg: dump that one provider
9591 * - the first arg isn't the flattened component name of an existing provider:
9592 * dump all providers whose component contains the first arg as a substring
9594 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9595 int opti, boolean dumpAll) {
9596 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
9599 static class ItemMatcher {
9600 ArrayList<ComponentName> components;
9601 ArrayList<String> strings;
9602 ArrayList<Integer> objects;
9609 void build(String name) {
9610 ComponentName componentName = ComponentName.unflattenFromString(name);
9611 if (componentName != null) {
9612 if (components == null) {
9613 components = new ArrayList<ComponentName>();
9615 components.add(componentName);
9619 // Not a '/' separated full component name; maybe an object ID?
9621 objectId = Integer.parseInt(name, 16);
9622 if (objects == null) {
9623 objects = new ArrayList<Integer>();
9625 objects.add(objectId);
9627 } catch (RuntimeException e) {
9628 // Not an integer; just do string match.
9629 if (strings == null) {
9630 strings = new ArrayList<String>();
9638 int build(String[] args, int opti) {
9639 for (; opti<args.length; opti++) {
9640 String name = args[opti];
9641 if ("--".equals(name)) {
9649 boolean match(Object object, ComponentName comp) {
9653 if (components != null) {
9654 for (int i=0; i<components.size(); i++) {
9655 if (components.get(i).equals(comp)) {
9660 if (objects != null) {
9661 for (int i=0; i<objects.size(); i++) {
9662 if (System.identityHashCode(object) == objects.get(i)) {
9667 if (strings != null) {
9668 String flat = comp.flattenToString();
9669 for (int i=0; i<strings.size(); i++) {
9670 if (flat.contains(strings.get(i))) {
9680 * There are three things that cmd can be:
9681 * - a flattened component name that matches an existing activity
9682 * - the cmd arg isn't the flattened component name of an existing activity:
9683 * dump all activity whose component contains the cmd as a substring
9684 * - A hex number of the ActivityRecord object instance.
9686 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9687 int opti, boolean dumpAll) {
9688 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
9690 if ("all".equals(name)) {
9691 synchronized (this) {
9692 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9696 } else if ("top".equals(name)) {
9697 synchronized (this) {
9698 final int N = mMainStack.mHistory.size();
9700 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9704 ItemMatcher matcher = new ItemMatcher();
9705 matcher.build(name);
9707 synchronized (this) {
9708 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
9709 if (matcher.match(r1, r1.intent.getComponent())) {
9716 if (activities.size() <= 0) {
9720 String[] newArgs = new String[args.length - opti];
9721 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9723 TaskRecord lastTask = null;
9724 boolean needSep = false;
9725 for (int i=activities.size()-1; i>=0; i--) {
9726 ActivityRecord r = (ActivityRecord)activities.get(i);
9731 synchronized (this) {
9732 if (lastTask != r.task) {
9734 pw.print("TASK "); pw.print(lastTask.affinity);
9735 pw.print(" id="); pw.println(lastTask.taskId);
9737 lastTask.dump(pw, " ");
9741 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
9747 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9748 * there is a thread associated with the activity.
9750 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
9751 final ActivityRecord r, String[] args, boolean dumpAll) {
9752 String innerPrefix = prefix + " ";
9753 synchronized (this) {
9754 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9755 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9757 if (r.app != null) pw.println(r.app.pid);
9758 else pw.println("(not running)");
9760 r.dump(pw, innerPrefix);
9763 if (r.app != null && r.app.thread != null) {
9764 // flush anything that is already in the PrintWriter since the thread is going
9765 // to write to the file descriptor directly
9768 TransferPipe tp = new TransferPipe();
9770 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9771 r.appToken, innerPrefix, args);
9776 } catch (IOException e) {
9777 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9778 } catch (RemoteException e) {
9779 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9784 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9785 int opti, boolean dumpAll, String dumpPackage) {
9786 boolean needSep = false;
9787 boolean onlyHistory = false;
9789 if ("history".equals(dumpPackage)) {
9790 if (opti < args.length && "-s".equals(args[opti])) {
9797 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
9798 if (!onlyHistory && dumpAll) {
9799 if (mRegisteredReceivers.size() > 0) {
9800 boolean printed = false;
9801 Iterator it = mRegisteredReceivers.values().iterator();
9802 while (it.hasNext()) {
9803 ReceiverList r = (ReceiverList)it.next();
9804 if (dumpPackage != null && (r.app == null ||
9805 !dumpPackage.equals(r.app.info.packageName))) {
9809 pw.println(" Registered Receivers:");
9813 pw.print(" * "); pw.println(r);
9818 if (mReceiverResolver.dump(pw, needSep ?
9819 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
9820 " ", dumpPackage, false)) {
9825 for (BroadcastQueue q : mBroadcastQueues) {
9826 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
9831 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
9832 for (int user=0; user<mStickyBroadcasts.size(); user++) {
9837 pw.print(" Sticky broadcasts for user ");
9838 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9839 StringBuilder sb = new StringBuilder(128);
9840 for (Map.Entry<String, ArrayList<Intent>> ent
9841 : mStickyBroadcasts.valueAt(user).entrySet()) {
9842 pw.print(" * Sticky action "); pw.print(ent.getKey());
9845 ArrayList<Intent> intents = ent.getValue();
9846 final int N = intents.size();
9847 for (int i=0; i<N; i++) {
9849 sb.append(" Intent: ");
9850 intents.get(i).toShortString(sb, false, true, false, false);
9851 pw.println(sb.toString());
9852 Bundle bundle = intents.get(i).getExtras();
9853 if (bundle != null) {
9855 pw.println(bundle.toString());
9865 if (!onlyHistory && dumpAll) {
9867 for (BroadcastQueue queue : mBroadcastQueues) {
9868 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
9869 + queue.mBroadcastsScheduled);
9871 pw.println(" mHandler:");
9872 mHandler.dump(new PrintWriterPrinter(pw), " ");
9879 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9880 int opti, boolean dumpAll, String dumpPackage) {
9881 boolean needSep = true;
9883 ItemMatcher matcher = new ItemMatcher();
9884 matcher.build(args, opti);
9886 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9888 mProviderMap.dumpProvidersLocked(pw, dumpAll);
9890 if (mLaunchingProviders.size() > 0) {
9891 boolean printed = false;
9892 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
9893 ContentProviderRecord r = mLaunchingProviders.get(i);
9894 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9898 if (needSep) pw.println(" ");
9900 pw.println(" Launching content providers:");
9903 pw.print(" Launching #"); pw.print(i); pw.print(": ");
9908 if (mGrantedUriPermissions.size() > 0) {
9909 if (needSep) pw.println();
9911 pw.println("Granted Uri Permissions:");
9912 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9913 int uid = mGrantedUriPermissions.keyAt(i);
9914 HashMap<Uri, UriPermission> perms
9915 = mGrantedUriPermissions.valueAt(i);
9916 pw.print(" * UID "); pw.print(uid);
9917 pw.println(" holds:");
9918 for (UriPermission perm : perms.values()) {
9919 pw.print(" "); pw.println(perm);
9931 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9932 int opti, boolean dumpAll, String dumpPackage) {
9933 boolean needSep = false;
9935 if (mIntentSenderRecords.size() > 0) {
9936 boolean printed = false;
9937 Iterator<WeakReference<PendingIntentRecord>> it
9938 = mIntentSenderRecords.values().iterator();
9939 while (it.hasNext()) {
9940 WeakReference<PendingIntentRecord> ref = it.next();
9941 PendingIntentRecord rec = ref != null ? ref.get(): null;
9942 if (dumpPackage != null && (rec == null
9943 || !dumpPackage.equals(rec.key.packageName))) {
9947 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9952 pw.print(" * "); pw.println(rec);
9957 pw.print(" * "); pw.println(ref);
9965 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
9966 String prefix, String label, boolean complete, boolean brief, boolean client,
9967 String dumpPackage) {
9968 TaskRecord lastTask = null;
9969 boolean needNL = false;
9970 final String innerPrefix = prefix + " ";
9971 final String[] args = new String[0];
9972 for (int i=list.size()-1; i>=0; i--) {
9973 final ActivityRecord r = (ActivityRecord)list.get(i);
9974 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9977 final boolean full = !brief && (complete || !r.isInHistory());
9982 if (lastTask != r.task) {
9985 pw.print(full ? "* " : " ");
9986 pw.println(lastTask);
9988 lastTask.dump(pw, prefix + " ");
9989 } else if (complete) {
9990 // Complete + brief == give a summary. Isn't that obvious?!?
9991 if (lastTask.intent != null) {
9992 pw.print(prefix); pw.print(" ");
9993 pw.println(lastTask.intent.toInsecureStringWithClip());
9997 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
9998 pw.print(" #"); pw.print(i); pw.print(": ");
10001 r.dump(pw, innerPrefix);
10002 } else if (complete) {
10003 // Complete + brief == give a summary. Isn't that obvious?!?
10004 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
10005 if (r.app != null) {
10006 pw.print(innerPrefix); pw.println(r.app);
10009 if (client && r.app != null && r.app.thread != null) {
10010 // flush anything that is already in the PrintWriter since the thread is going
10011 // to write to the file descriptor directly
10014 TransferPipe tp = new TransferPipe();
10016 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
10017 r.appToken, innerPrefix, args);
10018 // Short timeout, since blocking here can
10019 // deadlock with the application.
10024 } catch (IOException e) {
10025 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
10026 } catch (RemoteException e) {
10027 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
10034 private static String buildOomTag(String prefix, String space, int val, int base) {
10036 if (space == null) return prefix;
10037 return prefix + " ";
10039 return prefix + "+" + Integer.toString(val-base);
10042 private static final int dumpProcessList(PrintWriter pw,
10043 ActivityManagerService service, List list,
10044 String prefix, String normalLabel, String persistentLabel,
10045 String dumpPackage) {
10047 final int N = list.size()-1;
10048 for (int i=N; i>=0; i--) {
10049 ProcessRecord r = (ProcessRecord)list.get(i);
10050 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10053 pw.println(String.format("%s%s #%2d: %s",
10054 prefix, (r.persistent ? persistentLabel : normalLabel),
10056 if (r.persistent) {
10063 private static final boolean dumpProcessOomList(PrintWriter pw,
10064 ActivityManagerService service, List<ProcessRecord> origList,
10065 String prefix, String normalLabel, String persistentLabel,
10066 boolean inclDetails, String dumpPackage) {
10068 ArrayList<Pair<ProcessRecord, Integer>> list
10069 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10070 for (int i=0; i<origList.size(); i++) {
10071 ProcessRecord r = origList.get(i);
10072 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10075 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10078 if (list.size() <= 0) {
10082 Comparator<Pair<ProcessRecord, Integer>> comparator
10083 = new Comparator<Pair<ProcessRecord, Integer>>() {
10085 public int compare(Pair<ProcessRecord, Integer> object1,
10086 Pair<ProcessRecord, Integer> object2) {
10087 if (object1.first.setAdj != object2.first.setAdj) {
10088 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10090 if (object1.second.intValue() != object2.second.intValue()) {
10091 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10097 Collections.sort(list, comparator);
10099 final long curRealtime = SystemClock.elapsedRealtime();
10100 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10101 final long curUptime = SystemClock.uptimeMillis();
10102 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10104 for (int i=list.size()-1; i>=0; i--) {
10105 ProcessRecord r = list.get(i).first;
10107 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
10108 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
10109 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10110 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
10111 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10112 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
10113 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10114 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
10115 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10116 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
10117 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
10118 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
10119 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10120 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10121 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10122 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10123 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10124 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10125 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10126 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
10127 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10128 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
10129 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10130 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
10132 oomAdj = Integer.toString(r.setAdj);
10135 switch (r.setSchedGroup) {
10136 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10139 case Process.THREAD_GROUP_DEFAULT:
10143 schedGroup = Integer.toString(r.setSchedGroup);
10147 if (r.foregroundActivities) {
10149 } else if (r.foregroundServices) {
10154 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
10155 prefix, (r.persistent ? persistentLabel : normalLabel),
10156 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10157 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
10158 if (r.adjSource != null || r.adjTarget != null) {
10161 if (r.adjTarget instanceof ComponentName) {
10162 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10163 } else if (r.adjTarget != null) {
10164 pw.print(r.adjTarget.toString());
10166 pw.print("{null}");
10169 if (r.adjSource instanceof ProcessRecord) {
10171 pw.print(((ProcessRecord)r.adjSource).toShortString());
10173 } else if (r.adjSource != null) {
10174 pw.println(r.adjSource.toString());
10176 pw.println("{null}");
10182 pw.print("oom: max="); pw.print(r.maxAdj);
10183 pw.print(" hidden="); pw.print(r.hiddenAdj);
10184 pw.print(" client="); pw.print(r.clientHiddenAdj);
10185 pw.print(" empty="); pw.print(r.emptyAdj);
10186 pw.print(" curRaw="); pw.print(r.curRawAdj);
10187 pw.print(" setRaw="); pw.print(r.setRawAdj);
10188 pw.print(" cur="); pw.print(r.curAdj);
10189 pw.print(" set="); pw.println(r.setAdj);
10192 pw.print("keeping="); pw.print(r.keeping);
10193 pw.print(" hidden="); pw.print(r.hidden);
10194 pw.print(" empty="); pw.print(r.empty);
10195 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
10198 if (r.lastWakeTime != 0) {
10200 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10201 synchronized (stats) {
10202 wtime = stats.getProcessWakeTime(r.info.uid,
10203 r.pid, curRealtime);
10205 long timeUsed = wtime - r.lastWakeTime;
10208 pw.print("keep awake over ");
10209 TimeUtils.formatDuration(realtimeSince, pw);
10210 pw.print(" used ");
10211 TimeUtils.formatDuration(timeUsed, pw);
10213 pw.print((timeUsed*100)/realtimeSince);
10216 if (r.lastCpuTime != 0) {
10217 long timeUsed = r.curCpuTime - r.lastCpuTime;
10220 pw.print("run cpu over ");
10221 TimeUtils.formatDuration(uptimeSince, pw);
10222 pw.print(" used ");
10223 TimeUtils.formatDuration(timeUsed, pw);
10225 pw.print((timeUsed*100)/uptimeSince);
10234 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
10235 ArrayList<ProcessRecord> procs;
10236 synchronized (this) {
10237 if (args != null && args.length > start
10238 && args[start].charAt(0) != '-') {
10239 procs = new ArrayList<ProcessRecord>();
10242 pid = Integer.parseInt(args[start]);
10243 } catch (NumberFormatException e) {
10246 for (int i=mLruProcesses.size()-1; i>=0; i--) {
10247 ProcessRecord proc = mLruProcesses.get(i);
10248 if (proc.pid == pid) {
10250 } else if (proc.processName.equals(args[start])) {
10254 if (procs.size() <= 0) {
10255 pw.println("No process found for: " + args[start]);
10259 procs = new ArrayList<ProcessRecord>(mLruProcesses);
10265 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10266 PrintWriter pw, String[] args) {
10267 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10268 if (procs == null) {
10272 long uptime = SystemClock.uptimeMillis();
10273 long realtime = SystemClock.elapsedRealtime();
10274 pw.println("Applications Graphics Acceleration Info:");
10275 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10277 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10278 ProcessRecord r = procs.get(i);
10279 if (r.thread != null) {
10280 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10283 TransferPipe tp = new TransferPipe();
10285 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10290 } catch (IOException e) {
10291 pw.println("Failure while dumping the app: " + r);
10293 } catch (RemoteException e) {
10294 pw.println("Got a RemoteException while dumping the app " + r);
10301 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10302 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10303 if (procs == null) {
10307 pw.println("Applications Database Info:");
10309 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10310 ProcessRecord r = procs.get(i);
10311 if (r.thread != null) {
10312 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10315 TransferPipe tp = new TransferPipe();
10317 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10322 } catch (IOException e) {
10323 pw.println("Failure while dumping the app: " + r);
10325 } catch (RemoteException e) {
10326 pw.println("Got a RemoteException while dumping the app " + r);
10333 final static class MemItem {
10334 final String label;
10335 final String shortLabel;
10338 ArrayList<MemItem> subitems;
10340 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
10342 shortLabel = _shortLabel;
10348 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
10351 Collections.sort(items, new Comparator<MemItem>() {
10353 public int compare(MemItem lhs, MemItem rhs) {
10354 if (lhs.pss < rhs.pss) {
10356 } else if (lhs.pss > rhs.pss) {
10364 for (int i=0; i<items.size(); i++) {
10365 MemItem mi = items.get(i);
10366 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
10367 if (mi.subitems != null) {
10368 dumpMemItems(pw, prefix + " ", mi.subitems, true);
10373 // These are in KB.
10374 static final long[] DUMP_MEM_BUCKETS = new long[] {
10375 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10376 120*1024, 160*1024, 200*1024,
10377 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10378 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10381 static final void appendMemBucket(StringBuilder out, long memKB, String label,
10382 boolean stackLike) {
10383 int start = label.lastIndexOf('.');
10384 if (start >= 0) start++;
10386 int end = label.length();
10387 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10388 if (DUMP_MEM_BUCKETS[i] >= memKB) {
10389 long bucket = DUMP_MEM_BUCKETS[i]/1024;
10390 out.append(bucket);
10391 out.append(stackLike ? "MB." : "MB ");
10392 out.append(label, start, end);
10396 out.append(memKB/1024);
10397 out.append(stackLike ? "MB." : "MB ");
10398 out.append(label, start, end);
10401 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10402 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10403 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10404 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10405 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10407 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10408 "System", "Persistent", "Foreground",
10409 "Visible", "Perceptible", "Heavy Weight",
10410 "Backup", "A Services", "Home", "Previous",
10411 "B Services", "Background"
10414 final void dumpApplicationMemoryUsage(FileDescriptor fd,
10415 PrintWriter pw, String prefix, String[] args, boolean brief,
10416 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
10417 boolean dumpAll = false;
10418 boolean oomOnly = false;
10421 while (opti < args.length) {
10422 String opt = args[opti];
10423 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10427 if ("-a".equals(opt)) {
10429 } else if ("--oom".equals(opt)) {
10431 } else if ("-h".equals(opt)) {
10432 pw.println("meminfo dump options: [-a] [--oom] [process]");
10433 pw.println(" -a: include all available information for each process.");
10434 pw.println(" --oom: only show processes organized by oom adj.");
10435 pw.println("If [process] is specified it can be the name or ");
10436 pw.println("pid of a specific process to dump.");
10439 pw.println("Unknown argument: " + opt + "; use -h for help");
10443 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
10444 if (procs == null) {
10448 final boolean isCheckinRequest = scanArgs(args, "--checkin");
10449 long uptime = SystemClock.uptimeMillis();
10450 long realtime = SystemClock.elapsedRealtime();
10452 if (procs.size() == 1 || isCheckinRequest) {
10456 if (isCheckinRequest) {
10457 // short checkin version
10458 pw.println(uptime + "," + realtime);
10461 pw.println("Applications Memory Usage (kB):");
10462 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10465 String[] innerArgs = new String[args.length-opti];
10466 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10468 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10469 long nativePss=0, dalvikPss=0, otherPss=0;
10470 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10472 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10473 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10474 new ArrayList[DUMP_MEM_OOM_LABEL.length];
10478 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10479 ProcessRecord r = procs.get(i);
10480 if (r.thread != null) {
10481 if (!isCheckinRequest && dumpAll) {
10482 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10485 Debug.MemoryInfo mi = null;
10488 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10489 } catch (RemoteException e) {
10490 if (!isCheckinRequest) {
10491 pw.println("Got RemoteException!");
10496 mi = new Debug.MemoryInfo();
10497 Debug.getMemoryInfo(r.pid, mi);
10500 if (!isCheckinRequest && mi != null) {
10501 long myTotalPss = mi.getTotalPss();
10502 totalPss += myTotalPss;
10503 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
10504 r.processName, myTotalPss, 0);
10505 procMems.add(pssItem);
10507 nativePss += mi.nativePss;
10508 dalvikPss += mi.dalvikPss;
10509 otherPss += mi.otherPss;
10510 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10511 long mem = mi.getOtherPss(j);
10516 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
10517 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10518 || oomIndex == (oomPss.length-1)) {
10519 oomPss[oomIndex] += myTotalPss;
10520 if (oomProcs[oomIndex] == null) {
10521 oomProcs[oomIndex] = new ArrayList<MemItem>();
10523 oomProcs[oomIndex].add(pssItem);
10531 if (!isCheckinRequest && procs.size() > 1) {
10532 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10534 catMems.add(new MemItem("Native", "Native", nativePss, -1));
10535 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10536 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
10537 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10538 String label = Debug.MemoryInfo.getOtherLabel(j);
10539 catMems.add(new MemItem(label, label, miscPss[j], j));
10542 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10543 for (int j=0; j<oomPss.length; j++) {
10544 if (oomPss[j] != 0) {
10545 String label = DUMP_MEM_OOM_LABEL[j];
10546 MemItem item = new MemItem(label, label, oomPss[j],
10547 DUMP_MEM_OOM_ADJ[j]);
10548 item.subitems = oomProcs[j];
10553 if (outTag != null || outStack != null) {
10554 if (outTag != null) {
10555 appendMemBucket(outTag, totalPss, "total", false);
10557 if (outStack != null) {
10558 appendMemBucket(outStack, totalPss, "total", true);
10560 boolean firstLine = true;
10561 for (int i=0; i<oomMems.size(); i++) {
10562 MemItem miCat = oomMems.get(i);
10563 if (miCat.subitems == null || miCat.subitems.size() < 1) {
10566 if (miCat.id < ProcessList.SERVICE_ADJ
10567 || miCat.id == ProcessList.HOME_APP_ADJ
10568 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
10569 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10570 outTag.append(" / ");
10572 if (outStack != null) {
10573 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10575 outStack.append(":");
10578 outStack.append("\n\t at ");
10580 outStack.append("$");
10583 for (int j=0; j<miCat.subitems.size(); j++) {
10584 MemItem mi = miCat.subitems.get(j);
10586 if (outTag != null) {
10587 outTag.append(" ");
10589 if (outStack != null) {
10590 outStack.append("$");
10593 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10594 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10596 if (outStack != null) {
10597 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10600 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10601 outStack.append("(");
10602 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10603 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10604 outStack.append(DUMP_MEM_OOM_LABEL[k]);
10605 outStack.append(":");
10606 outStack.append(DUMP_MEM_OOM_ADJ[k]);
10609 outStack.append(")");
10615 if (!brief && !oomOnly) {
10617 pw.println("Total PSS by process:");
10618 dumpMemItems(pw, " ", procMems, true);
10621 pw.println("Total PSS by OOM adjustment:");
10622 dumpMemItems(pw, " ", oomMems, false);
10624 PrintWriter out = categoryPw != null ? categoryPw : pw;
10626 out.println("Total PSS by category:");
10627 dumpMemItems(out, " ", catMems, true);
10630 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
10631 final int[] SINGLE_LONG_FORMAT = new int[] {
10632 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10634 long[] longOut = new long[1];
10635 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10636 SINGLE_LONG_FORMAT, null, longOut, null);
10637 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10639 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10640 SINGLE_LONG_FORMAT, null, longOut, null);
10641 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10643 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10644 SINGLE_LONG_FORMAT, null, longOut, null);
10645 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10647 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10648 SINGLE_LONG_FORMAT, null, longOut, null);
10649 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10650 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10651 pw.print(shared); pw.println(" kB");
10652 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; ");
10653 pw.print(voltile); pw.println(" kB volatile");
10658 * Searches array of arguments for the specified string
10659 * @param args array of argument strings
10660 * @param value value to search for
10661 * @return true if the value is contained in the array
10663 private static boolean scanArgs(String[] args, String value) {
10664 if (args != null) {
10665 for (String arg : args) {
10666 if (value.equals(arg)) {
10674 private final boolean removeDyingProviderLocked(ProcessRecord proc,
10675 ContentProviderRecord cpr, boolean always) {
10676 final boolean inLaunching = mLaunchingProviders.contains(cpr);
10678 if (!inLaunching || always) {
10679 synchronized (cpr) {
10680 cpr.launchingApp = null;
10683 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
10684 String names[] = cpr.info.authority.split(";");
10685 for (int j = 0; j < names.length; j++) {
10686 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
10690 for (int i=0; i<cpr.connections.size(); i++) {
10691 ContentProviderConnection conn = cpr.connections.get(i);
10692 if (conn.waiting) {
10693 // If this connection is waiting for the provider, then we don't
10694 // need to mess with its process unless we are always removing
10695 // or for some reason the provider is not currently launching.
10696 if (inLaunching && !always) {
10700 ProcessRecord capp = conn.client;
10702 if (conn.stableCount > 0) {
10703 if (!capp.persistent && capp.thread != null
10705 && capp.pid != MY_PID) {
10706 Slog.i(TAG, "Kill " + capp.processName
10707 + " (pid " + capp.pid + "): provider " + cpr.info.name
10708 + " in dying process " + (proc != null ? proc.processName : "??"));
10709 EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
10710 capp.processName, capp.setAdj, "dying provider "
10711 + cpr.name.toShortString());
10712 Process.killProcessQuiet(capp.pid);
10714 } else if (capp.thread != null && conn.provider.provider != null) {
10716 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10717 } catch (RemoteException e) {
10719 // In the protocol here, we don't expect the client to correctly
10720 // clean up this connection, we'll just remove it.
10721 cpr.connections.remove(i);
10722 conn.client.conProviders.remove(conn);
10726 if (inLaunching && always) {
10727 mLaunchingProviders.remove(cpr);
10729 return inLaunching;
10733 * Main code for cleaning up a process when it has gone away. This is
10734 * called both as a result of the process dying, or directly when stopping
10735 * a process when running in single process mode.
10737 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
10738 boolean restarting, boolean allowRestart, int index) {
10740 mLruProcesses.remove(index);
10743 mProcessesToGc.remove(app);
10745 // Dismiss any open dialogs.
10746 if (app.crashDialog != null) {
10747 app.crashDialog.dismiss();
10748 app.crashDialog = null;
10750 if (app.anrDialog != null) {
10751 app.anrDialog.dismiss();
10752 app.anrDialog = null;
10754 if (app.waitDialog != null) {
10755 app.waitDialog.dismiss();
10756 app.waitDialog = null;
10759 app.crashing = false;
10760 app.notResponding = false;
10762 app.resetPackageList();
10763 app.unlinkDeathRecipient();
10765 app.forcingToForeground = null;
10766 app.foregroundServices = false;
10767 app.foregroundActivities = false;
10768 app.hasShownUi = false;
10769 app.hasAboveClient = false;
10771 mServices.killServicesLocked(app, allowRestart);
10773 boolean restart = false;
10775 // Remove published content providers.
10776 if (!app.pubProviders.isEmpty()) {
10777 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
10778 while (it.hasNext()) {
10779 ContentProviderRecord cpr = it.next();
10781 final boolean always = app.bad || !allowRestart;
10782 if (removeDyingProviderLocked(app, cpr, always) || always) {
10783 // We left the provider in the launching list, need to
10788 cpr.provider = null;
10791 app.pubProviders.clear();
10794 // Take care of any launching providers waiting for this process.
10795 if (checkAppInLaunchingProvidersLocked(app, false)) {
10799 // Unregister from connected content providers.
10800 if (!app.conProviders.isEmpty()) {
10801 for (int i=0; i<app.conProviders.size(); i++) {
10802 ContentProviderConnection conn = app.conProviders.get(i);
10803 conn.provider.connections.remove(conn);
10805 app.conProviders.clear();
10808 // At this point there may be remaining entries in mLaunchingProviders
10809 // where we were the only one waiting, so they are no longer of use.
10810 // Look for these and clean up if found.
10811 // XXX Commented out for now. Trying to figure out a way to reproduce
10812 // the actual situation to identify what is actually going on.
10814 for (int i=0; i<mLaunchingProviders.size(); i++) {
10815 ContentProviderRecord cpr = (ContentProviderRecord)
10816 mLaunchingProviders.get(i);
10817 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
10818 synchronized (cpr) {
10819 cpr.launchingApp = null;
10826 skipCurrentReceiverLocked(app);
10828 // Unregister any receivers.
10829 if (app.receivers.size() > 0) {
10830 Iterator<ReceiverList> it = app.receivers.iterator();
10831 while (it.hasNext()) {
10832 removeReceiverLocked(it.next());
10834 app.receivers.clear();
10837 // If the app is undergoing backup, tell the backup manager about it
10838 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
10839 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
10840 + mBackupTarget.appInfo + " died during backup");
10842 IBackupManager bm = IBackupManager.Stub.asInterface(
10843 ServiceManager.getService(Context.BACKUP_SERVICE));
10844 bm.agentDisconnected(app.info.packageName);
10845 } catch (RemoteException e) {
10846 // can't happen; backup manager is local
10850 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10851 ProcessChangeItem item = mPendingProcessChanges.get(i);
10852 if (item.pid == app.pid) {
10853 mPendingProcessChanges.remove(i);
10854 mAvailProcessChanges.add(item);
10857 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
10859 // If the caller is restarting this app, then leave it in its
10860 // current lists and let the caller take care of it.
10865 if (!app.persistent || app.isolated) {
10866 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
10867 "Removing non-persistent process during cleanup: " + app);
10868 mProcessNames.remove(app.processName, app.uid);
10869 mIsolatedProcesses.remove(app.uid);
10870 if (mHeavyWeightProcess == app) {
10871 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10872 mHeavyWeightProcess.userId, 0));
10873 mHeavyWeightProcess = null;
10875 } else if (!app.removed) {
10876 // This app is persistent, so we need to keep its record around.
10877 // If it is not already on the pending app list, add it there
10878 // and start a new process for it.
10879 if (mPersistentStartingProcesses.indexOf(app) < 0) {
10880 mPersistentStartingProcesses.add(app);
10884 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
10885 "Clean-up removing on hold: " + app);
10886 mProcessesOnHold.remove(app);
10888 if (app == mHomeProcess) {
10889 mHomeProcess = null;
10891 if (app == mPreviousProcess) {
10892 mPreviousProcess = null;
10895 if (restart && !app.isolated) {
10896 // We have components that still need to be running in the
10897 // process, so re-launch it.
10898 mProcessNames.put(app.processName, app.uid, app);
10899 startProcessLocked(app, "restart", app.processName);
10900 } else if (app.pid > 0 && app.pid != MY_PID) {
10902 synchronized (mPidsSelfLocked) {
10903 mPidsSelfLocked.remove(app.pid);
10904 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10910 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10911 // Look through the content providers we are waiting to have launched,
10912 // and if any run in this process then either schedule a restart of
10913 // the process or kill the client waiting for it if this process has
10915 int NL = mLaunchingProviders.size();
10916 boolean restart = false;
10917 for (int i=0; i<NL; i++) {
10918 ContentProviderRecord cpr = mLaunchingProviders.get(i);
10919 if (cpr.launchingApp == app) {
10920 if (!alwaysBad && !app.bad) {
10923 removeDyingProviderLocked(app, cpr, true);
10924 // cpr should have been removed from mLaunchingProviders
10925 NL = mLaunchingProviders.size();
10933 // =========================================================
10935 // =========================================================
10937 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10939 enforceNotIsolatedCaller("getServices");
10940 synchronized (this) {
10941 return mServices.getRunningServiceInfoLocked(maxNum, flags);
10945 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10946 enforceNotIsolatedCaller("getRunningServiceControlPanel");
10947 synchronized (this) {
10948 return mServices.getRunningServiceControlPanelLocked(name);
10952 public ComponentName startService(IApplicationThread caller, Intent service,
10953 String resolvedType, int userId) {
10954 enforceNotIsolatedCaller("startService");
10955 // Refuse possible leaked file descriptors
10956 if (service != null && service.hasFileDescriptors() == true) {
10957 throw new IllegalArgumentException("File descriptors passed in Intent");
10961 Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
10962 synchronized(this) {
10963 final int callingPid = Binder.getCallingPid();
10964 final int callingUid = Binder.getCallingUid();
10965 checkValidCaller(callingUid, userId);
10966 final long origId = Binder.clearCallingIdentity();
10967 ComponentName res = mServices.startServiceLocked(caller, service,
10968 resolvedType, callingPid, callingUid, userId);
10969 Binder.restoreCallingIdentity(origId);
10974 ComponentName startServiceInPackage(int uid,
10975 Intent service, String resolvedType, int userId) {
10976 synchronized(this) {
10978 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
10979 final long origId = Binder.clearCallingIdentity();
10980 ComponentName res = mServices.startServiceLocked(null, service,
10981 resolvedType, -1, uid, userId);
10982 Binder.restoreCallingIdentity(origId);
10987 public int stopService(IApplicationThread caller, Intent service,
10988 String resolvedType, int userId) {
10989 enforceNotIsolatedCaller("stopService");
10990 // Refuse possible leaked file descriptors
10991 if (service != null && service.hasFileDescriptors() == true) {
10992 throw new IllegalArgumentException("File descriptors passed in Intent");
10995 checkValidCaller(Binder.getCallingUid(), userId);
10997 synchronized(this) {
10998 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
11002 public IBinder peekService(Intent service, String resolvedType) {
11003 enforceNotIsolatedCaller("peekService");
11004 // Refuse possible leaked file descriptors
11005 if (service != null && service.hasFileDescriptors() == true) {
11006 throw new IllegalArgumentException("File descriptors passed in Intent");
11008 synchronized(this) {
11009 return mServices.peekServiceLocked(service, resolvedType);
11013 public boolean stopServiceToken(ComponentName className, IBinder token,
11015 synchronized(this) {
11016 return mServices.stopServiceTokenLocked(className, token, startId);
11020 public void setServiceForeground(ComponentName className, IBinder token,
11021 int id, Notification notification, boolean removeNotification) {
11022 synchronized(this) {
11023 mServices.setServiceForegroundLocked(className, token, id, notification,
11024 removeNotification);
11028 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
11029 boolean requireFull, String name, String callerPackage) {
11030 final int callingUserId = UserHandle.getUserId(callingUid);
11031 if (callingUserId != userId) {
11032 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
11033 if ((requireFull || checkComponentPermission(
11034 android.Manifest.permission.INTERACT_ACROSS_USERS,
11035 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
11036 && checkComponentPermission(
11037 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11038 callingPid, callingUid, -1, true)
11039 != PackageManager.PERMISSION_GRANTED) {
11040 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
11041 // In this case, they would like to just execute as their
11042 // owner user instead of failing.
11043 userId = callingUserId;
11045 StringBuilder builder = new StringBuilder(128);
11046 builder.append("Permission Denial: ");
11047 builder.append(name);
11048 if (callerPackage != null) {
11049 builder.append(" from ");
11050 builder.append(callerPackage);
11052 builder.append(" asks to run as user ");
11053 builder.append(userId);
11054 builder.append(" but is calling from user ");
11055 builder.append(UserHandle.getUserId(callingUid));
11056 builder.append("; this requires ");
11057 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
11058 if (!requireFull) {
11059 builder.append(" or ");
11060 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
11062 String msg = builder.toString();
11064 throw new SecurityException(msg);
11068 if (userId == UserHandle.USER_CURRENT
11069 || userId == UserHandle.USER_CURRENT_OR_SELF) {
11070 // Note that we may be accessing this outside of a lock...
11071 // shouldn't be a big deal, if this is being called outside
11072 // of a locked context there is intrinsically a race with
11073 // the value the caller will receive and someone else changing it.
11074 userId = mCurrentUserId;
11076 if (!allowAll && userId < 0) {
11077 throw new IllegalArgumentException(
11078 "Call does not support special user #" + userId);
11084 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
11085 String className, int flags) {
11086 boolean result = false;
11087 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11088 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
11089 if (ActivityManager.checkUidPermission(
11090 android.Manifest.permission.INTERACT_ACROSS_USERS,
11091 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
11092 ComponentName comp = new ComponentName(aInfo.packageName, className);
11093 String msg = "Permission Denial: Component " + comp.flattenToShortString()
11094 + " requests FLAG_SINGLE_USER, but app does not hold "
11095 + android.Manifest.permission.INTERACT_ACROSS_USERS;
11097 throw new SecurityException(msg);
11101 } else if (componentProcessName == aInfo.packageName) {
11102 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11103 } else if ("system".equals(componentProcessName)) {
11107 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11108 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
11113 public int bindService(IApplicationThread caller, IBinder token,
11114 Intent service, String resolvedType,
11115 IServiceConnection connection, int flags, int userId) {
11116 enforceNotIsolatedCaller("bindService");
11117 // Refuse possible leaked file descriptors
11118 if (service != null && service.hasFileDescriptors() == true) {
11119 throw new IllegalArgumentException("File descriptors passed in Intent");
11122 synchronized(this) {
11123 return mServices.bindServiceLocked(caller, token, service, resolvedType,
11124 connection, flags, userId);
11128 public boolean unbindService(IServiceConnection connection) {
11129 synchronized (this) {
11130 return mServices.unbindServiceLocked(connection);
11134 public void publishService(IBinder token, Intent intent, IBinder service) {
11135 // Refuse possible leaked file descriptors
11136 if (intent != null && intent.hasFileDescriptors() == true) {
11137 throw new IllegalArgumentException("File descriptors passed in Intent");
11140 synchronized(this) {
11141 if (!(token instanceof ServiceRecord)) {
11142 throw new IllegalArgumentException("Invalid service token");
11144 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
11148 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11149 // Refuse possible leaked file descriptors
11150 if (intent != null && intent.hasFileDescriptors() == true) {
11151 throw new IllegalArgumentException("File descriptors passed in Intent");
11154 synchronized(this) {
11155 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
11159 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
11160 synchronized(this) {
11161 if (!(token instanceof ServiceRecord)) {
11162 throw new IllegalArgumentException("Invalid service token");
11164 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
11168 // =========================================================
11169 // BACKUP AND RESTORE
11170 // =========================================================
11172 // Cause the target app to be launched if necessary and its backup agent
11173 // instantiated. The backup agent will invoke backupAgentCreated() on the
11174 // activity manager to announce its creation.
11175 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
11176 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
11177 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
11179 synchronized(this) {
11180 // !!! TODO: currently no check here that we're already bound
11181 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11182 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11183 synchronized (stats) {
11184 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11187 // Backup agent is now in use, its package can't be stopped.
11189 AppGlobals.getPackageManager().setPackageStoppedState(
11190 app.packageName, false, UserHandle.getUserId(app.uid));
11191 } catch (RemoteException e) {
11192 } catch (IllegalArgumentException e) {
11193 Slog.w(TAG, "Failed trying to unstop package "
11194 + app.packageName + ": " + e);
11197 BackupRecord r = new BackupRecord(ss, app, backupMode);
11198 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11199 ? new ComponentName(app.packageName, app.backupAgentName)
11200 : new ComponentName("android", "FullBackupAgent");
11201 // startProcessLocked() returns existing proc's record if it's already running
11202 ProcessRecord proc = startProcessLocked(app.processName, app,
11203 false, 0, "backup", hostingName, false, false);
11204 if (proc == null) {
11205 Slog.e(TAG, "Unable to start backup agent process " + r);
11211 mBackupAppName = app.packageName;
11213 // Try not to kill the process during backup
11214 updateOomAdjLocked(proc);
11216 // If the process is already attached, schedule the creation of the backup agent now.
11217 // If it is not yet live, this will be done when it attaches to the framework.
11218 if (proc.thread != null) {
11219 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
11221 proc.thread.scheduleCreateBackupAgent(app,
11222 compatibilityInfoForPackageLocked(app), backupMode);
11223 } catch (RemoteException e) {
11224 // Will time out on the backup manager side
11227 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
11229 // Invariants: at this point, the target app process exists and the application
11230 // is either already running or in the process of coming up. mBackupTarget and
11231 // mBackupAppName describe the app, so that when it binds back to the AM we
11232 // know that it's scheduled for a backup-agent operation.
11239 public void clearPendingBackup() {
11240 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
11241 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
11243 synchronized (this) {
11244 mBackupTarget = null;
11245 mBackupAppName = null;
11249 // A backup agent has just come up
11250 public void backupAgentCreated(String agentPackageName, IBinder agent) {
11251 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
11254 synchronized(this) {
11255 if (!agentPackageName.equals(mBackupAppName)) {
11256 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
11261 long oldIdent = Binder.clearCallingIdentity();
11263 IBackupManager bm = IBackupManager.Stub.asInterface(
11264 ServiceManager.getService(Context.BACKUP_SERVICE));
11265 bm.agentConnected(agentPackageName, agent);
11266 } catch (RemoteException e) {
11267 // can't happen; the backup manager service is local
11268 } catch (Exception e) {
11269 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11270 e.printStackTrace();
11272 Binder.restoreCallingIdentity(oldIdent);
11276 // done with this agent
11277 public void unbindBackupAgent(ApplicationInfo appInfo) {
11278 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
11279 if (appInfo == null) {
11280 Slog.w(TAG, "unbind backup agent for null app");
11284 synchronized(this) {
11286 if (mBackupAppName == null) {
11287 Slog.w(TAG, "Unbinding backup agent with no active backup");
11291 if (!mBackupAppName.equals(appInfo.packageName)) {
11292 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11296 // Not backing this app up any more; reset its OOM adjustment
11297 final ProcessRecord proc = mBackupTarget.app;
11298 updateOomAdjLocked(proc);
11300 // If the app crashed during backup, 'thread' will be null here
11301 if (proc.thread != null) {
11303 proc.thread.scheduleDestroyBackupAgent(appInfo,
11304 compatibilityInfoForPackageLocked(appInfo));
11305 } catch (Exception e) {
11306 Slog.e(TAG, "Exception when unbinding backup agent:");
11307 e.printStackTrace();
11311 mBackupTarget = null;
11312 mBackupAppName = null;
11316 // =========================================================
11318 // =========================================================
11320 private final List getStickiesLocked(String action, IntentFilter filter,
11321 List cur, int userId) {
11322 final ContentResolver resolver = mContext.getContentResolver();
11323 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11324 if (stickies == null) {
11327 final ArrayList<Intent> list = stickies.get(action);
11328 if (list == null) {
11331 int N = list.size();
11332 for (int i=0; i<N; i++) {
11333 Intent intent = list.get(i);
11334 if (filter.match(resolver, intent, true, TAG) >= 0) {
11336 cur = new ArrayList<Intent>();
11344 boolean isPendingBroadcastProcessLocked(int pid) {
11345 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11346 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11349 void skipPendingBroadcastLocked(int pid) {
11350 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11351 for (BroadcastQueue queue : mBroadcastQueues) {
11352 queue.skipPendingBroadcastLocked(pid);
11356 // The app just attached; send any pending broadcasts that it should receive
11357 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11358 boolean didSomething = false;
11359 for (BroadcastQueue queue : mBroadcastQueues) {
11360 didSomething |= queue.sendPendingBroadcastsLocked(app);
11362 return didSomething;
11365 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
11366 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
11367 enforceNotIsolatedCaller("registerReceiver");
11370 synchronized(this) {
11371 ProcessRecord callerApp = null;
11372 if (caller != null) {
11373 callerApp = getRecordForAppLocked(caller);
11374 if (callerApp == null) {
11375 throw new SecurityException(
11376 "Unable to find app for caller " + caller
11377 + " (pid=" + Binder.getCallingPid()
11378 + ") when registering receiver " + receiver);
11380 if (callerApp.info.uid != Process.SYSTEM_UID &&
11381 !callerApp.pkgList.contains(callerPackage)) {
11382 throw new SecurityException("Given caller package " + callerPackage
11383 + " is not running in process " + callerApp);
11385 callingUid = callerApp.info.uid;
11386 callingPid = callerApp.pid;
11388 callerPackage = null;
11389 callingUid = Binder.getCallingUid();
11390 callingPid = Binder.getCallingPid();
11393 userId = this.handleIncomingUser(callingPid, callingUid, userId,
11394 true, true, "registerReceiver", callerPackage);
11396 List allSticky = null;
11398 // Look for any matching sticky broadcasts...
11399 Iterator actions = filter.actionsIterator();
11400 if (actions != null) {
11401 while (actions.hasNext()) {
11402 String action = (String)actions.next();
11403 allSticky = getStickiesLocked(action, filter, allSticky,
11404 UserHandle.USER_ALL);
11405 allSticky = getStickiesLocked(action, filter, allSticky,
11406 UserHandle.getUserId(callingUid));
11409 allSticky = getStickiesLocked(null, filter, allSticky,
11410 UserHandle.USER_ALL);
11411 allSticky = getStickiesLocked(null, filter, allSticky,
11412 UserHandle.getUserId(callingUid));
11415 // The first sticky in the list is returned directly back to
11417 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11419 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
11422 if (receiver == null) {
11427 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11429 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11431 if (rl.app != null) {
11432 rl.app.receivers.add(rl);
11435 receiver.asBinder().linkToDeath(rl, 0);
11436 } catch (RemoteException e) {
11439 rl.linkedToDeath = true;
11441 mRegisteredReceivers.put(receiver.asBinder(), rl);
11442 } else if (rl.uid != callingUid) {
11443 throw new IllegalArgumentException(
11444 "Receiver requested to register for uid " + callingUid
11445 + " was previously registered for uid " + rl.uid);
11446 } else if (rl.pid != callingPid) {
11447 throw new IllegalArgumentException(
11448 "Receiver requested to register for pid " + callingPid
11449 + " was previously registered for pid " + rl.pid);
11450 } else if (rl.userId != userId) {
11451 throw new IllegalArgumentException(
11452 "Receiver requested to register for user " + userId
11453 + " was previously registered for user " + rl.userId);
11455 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
11456 permission, callingUid, userId);
11458 if (!bf.debugCheck()) {
11459 Slog.w(TAG, "==> For Dynamic broadast");
11461 mReceiverResolver.addFilter(bf);
11463 // Enqueue broadcasts for all existing stickies that match
11465 if (allSticky != null) {
11466 ArrayList receivers = new ArrayList();
11469 int N = allSticky.size();
11470 for (int i=0; i<N; i++) {
11471 Intent intent = (Intent)allSticky.get(i);
11472 BroadcastQueue queue = broadcastQueueForIntent(intent);
11473 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
11474 null, -1, -1, null, receivers, null, 0, null, null,
11475 false, true, true, -1);
11476 queue.enqueueParallelBroadcastLocked(r);
11477 queue.scheduleBroadcastsLocked();
11485 public void unregisterReceiver(IIntentReceiver receiver) {
11486 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
11488 final long origId = Binder.clearCallingIdentity();
11490 boolean doTrim = false;
11492 synchronized(this) {
11494 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11496 if (rl.curBroadcast != null) {
11497 BroadcastRecord r = rl.curBroadcast;
11498 final boolean doNext = finishReceiverLocked(
11499 receiver.asBinder(), r.resultCode, r.resultData,
11500 r.resultExtras, r.resultAbort, true);
11503 r.queue.processNextBroadcast(false);
11507 if (rl.app != null) {
11508 rl.app.receivers.remove(rl);
11510 removeReceiverLocked(rl);
11511 if (rl.linkedToDeath) {
11512 rl.linkedToDeath = false;
11513 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11518 // If we actually concluded any broadcasts, we might now be able
11519 // to trim the recipients' apps from our working set
11521 trimApplications();
11526 Binder.restoreCallingIdentity(origId);
11530 void removeReceiverLocked(ReceiverList rl) {
11531 mRegisteredReceivers.remove(rl.receiver.asBinder());
11533 for (int i=0; i<N; i++) {
11534 mReceiverResolver.removeFilter(rl.get(i));
11538 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
11539 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11540 ProcessRecord r = mLruProcesses.get(i);
11541 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
11543 r.thread.dispatchPackageBroadcast(cmd, packages);
11544 } catch (RemoteException ex) {
11550 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11552 List<ResolveInfo> receivers = null;
11554 HashSet<ComponentName> singleUserReceivers = null;
11555 boolean scannedFirstReceivers = false;
11556 for (int user : users) {
11557 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11558 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11559 if (user != 0 && newReceivers != null) {
11560 // If this is not the primary user, we need to check for
11561 // any receivers that should be filtered out.
11562 for (int i=0; i<newReceivers.size(); i++) {
11563 ResolveInfo ri = newReceivers.get(i);
11564 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
11565 newReceivers.remove(i);
11570 if (newReceivers != null && newReceivers.size() == 0) {
11571 newReceivers = null;
11573 if (receivers == null) {
11574 receivers = newReceivers;
11575 } else if (newReceivers != null) {
11576 // We need to concatenate the additional receivers
11577 // found with what we have do far. This would be easy,
11578 // but we also need to de-dup any receivers that are
11580 if (!scannedFirstReceivers) {
11581 // Collect any single user receivers we had already retrieved.
11582 scannedFirstReceivers = true;
11583 for (int i=0; i<receivers.size(); i++) {
11584 ResolveInfo ri = receivers.get(i);
11585 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11586 ComponentName cn = new ComponentName(
11587 ri.activityInfo.packageName, ri.activityInfo.name);
11588 if (singleUserReceivers == null) {
11589 singleUserReceivers = new HashSet<ComponentName>();
11591 singleUserReceivers.add(cn);
11595 // Add the new results to the existing results, tracking
11596 // and de-dupping single user receivers.
11597 for (int i=0; i<newReceivers.size(); i++) {
11598 ResolveInfo ri = newReceivers.get(i);
11599 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11600 ComponentName cn = new ComponentName(
11601 ri.activityInfo.packageName, ri.activityInfo.name);
11602 if (singleUserReceivers == null) {
11603 singleUserReceivers = new HashSet<ComponentName>();
11605 if (!singleUserReceivers.contains(cn)) {
11606 singleUserReceivers.add(cn);
11615 } catch (RemoteException ex) {
11616 // pm is in same process, this will never happen.
11621 private final int broadcastIntentLocked(ProcessRecord callerApp,
11622 String callerPackage, Intent intent, String resolvedType,
11623 IIntentReceiver resultTo, int resultCode, String resultData,
11624 Bundle map, String requiredPermission,
11625 boolean ordered, boolean sticky, int callingPid, int callingUid,
11627 intent = new Intent(intent);
11629 // By default broadcasts do not go to stopped apps.
11630 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11632 if (DEBUG_BROADCAST_LIGHT) Slog.v(
11633 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11634 + " ordered=" + ordered + " userid=" + userId);
11635 if ((resultTo != null) && !ordered) {
11636 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
11639 userId = handleIncomingUser(callingPid, callingUid, userId,
11640 true, false, "broadcast", callerPackage);
11642 // Make sure that the user who is receiving this broadcast is started.
11643 // If not, we will just skip it.
11644 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
11645 if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11646 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11647 Slog.w(TAG, "Skipping broadcast of " + intent
11648 + ": user " + userId + " is stopped");
11649 return ActivityManager.BROADCAST_SUCCESS;
11654 * Prevent non-system code (defined here to be non-persistent
11655 * processes) from sending protected broadcasts.
11657 int callingAppId = UserHandle.getAppId(callingUid);
11658 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11659 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
11662 } else if (callerApp == null || !callerApp.persistent) {
11664 if (AppGlobals.getPackageManager().isProtectedBroadcast(
11665 intent.getAction())) {
11666 String msg = "Permission Denial: not allowed to send broadcast "
11667 + intent.getAction() + " from pid="
11668 + callingPid + ", uid=" + callingUid;
11670 throw new SecurityException(msg);
11672 } catch (RemoteException e) {
11673 Slog.w(TAG, "Remote exception", e);
11674 return ActivityManager.BROADCAST_SUCCESS;
11678 // Handle special intents: if this broadcast is from the package
11679 // manager about a package being removed, we need to remove all of
11680 // its activities from the history stack.
11681 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
11682 intent.getAction());
11683 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11684 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
11685 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
11687 if (checkComponentPermission(
11688 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
11689 callingPid, callingUid, -1, true)
11690 == PackageManager.PERMISSION_GRANTED) {
11692 final Bundle intentExtras = intent.getExtras();
11693 final int uid = intentExtras != null
11694 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11696 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11697 synchronized (bs) {
11698 bs.removeUidStatsLocked(uid);
11702 // If resources are unavailable just force stop all
11703 // those packages and flush the attribute cache as well.
11704 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
11705 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11706 if (list != null && (list.length > 0)) {
11707 for (String pkg : list) {
11708 forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
11710 sendPackageBroadcastLocked(
11711 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
11714 Uri data = intent.getData();
11716 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11717 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11718 forceStopPackageLocked(ssp,
11719 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11722 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
11723 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11724 new String[] {ssp}, userId);
11730 String msg = "Permission Denial: " + intent.getAction()
11731 + " broadcast from " + callerPackage + " (pid=" + callingPid
11732 + ", uid=" + callingUid + ")"
11734 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
11736 throw new SecurityException(msg);
11739 // Special case for adding a package: by default turn on compatibility
11741 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
11742 Uri data = intent.getData();
11744 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11745 mCompatModePackages.handlePackageAddedLocked(ssp,
11746 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
11751 * If this is the time zone changed action, queue up a message that will reset the timezone
11752 * of all currently running processes. This message will get queued up before the broadcast
11755 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11756 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11759 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11760 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11763 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11764 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11765 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11768 // Add to the sticky list if requested.
11770 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11771 callingPid, callingUid)
11772 != PackageManager.PERMISSION_GRANTED) {
11773 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11774 + callingPid + ", uid=" + callingUid
11775 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
11777 throw new SecurityException(msg);
11779 if (requiredPermission != null) {
11780 Slog.w(TAG, "Can't broadcast sticky intent " + intent
11781 + " and enforce permission " + requiredPermission);
11782 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11784 if (intent.getComponent() != null) {
11785 throw new SecurityException(
11786 "Sticky broadcasts can't target a specific component");
11788 // We use userId directly here, since the "all" target is maintained
11789 // as a separate set of sticky broadcasts.
11790 if (userId != UserHandle.USER_ALL) {
11791 // But first, if this is not a broadcast to all users, then
11792 // make sure it doesn't conflict with an existing broadcast to
11794 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11795 UserHandle.USER_ALL);
11796 if (stickies != null) {
11797 ArrayList<Intent> list = stickies.get(intent.getAction());
11798 if (list != null) {
11799 int N = list.size();
11801 for (i=0; i<N; i++) {
11802 if (intent.filterEquals(list.get(i))) {
11803 throw new IllegalArgumentException(
11804 "Sticky broadcast " + intent + " for user "
11805 + userId + " conflicts with existing global broadcast");
11811 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11812 if (stickies == null) {
11813 stickies = new HashMap<String, ArrayList<Intent>>();
11814 mStickyBroadcasts.put(userId, stickies);
11816 ArrayList<Intent> list = stickies.get(intent.getAction());
11817 if (list == null) {
11818 list = new ArrayList<Intent>();
11819 stickies.put(intent.getAction(), list);
11821 int N = list.size();
11823 for (i=0; i<N; i++) {
11824 if (intent.filterEquals(list.get(i))) {
11825 // This sticky already exists, replace it.
11826 list.set(i, new Intent(intent));
11831 list.add(new Intent(intent));
11836 if (userId == UserHandle.USER_ALL) {
11837 // Caller wants broadcast to go to all started users.
11838 users = mStartedUserArray;
11840 // Caller wants broadcast to go to one specific user.
11841 users = new int[] {userId};
11844 // Figure out who all will receive this broadcast.
11845 List receivers = null;
11846 List<BroadcastFilter> registeredReceivers = null;
11847 // Need to resolve the intent to interested receivers...
11848 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11850 receivers = collectReceiverComponents(intent, resolvedType, users);
11852 if (intent.getComponent() == null) {
11853 registeredReceivers = mReceiverResolver.queryIntent(intent,
11854 resolvedType, false, userId);
11857 final boolean replacePending =
11858 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11860 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
11861 + " replacePending=" + replacePending);
11863 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11864 if (!ordered && NR > 0) {
11865 // If we are not serializing this broadcast, then send the
11866 // registered receivers separately so they don't wait for the
11867 // components to be launched.
11868 final BroadcastQueue queue = broadcastQueueForIntent(intent);
11869 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11870 callerPackage, callingPid, callingUid, requiredPermission,
11871 registeredReceivers, resultTo, resultCode, resultData, map,
11872 ordered, sticky, false, userId);
11873 if (DEBUG_BROADCAST) Slog.v(
11874 TAG, "Enqueueing parallel broadcast " + r);
11875 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
11877 queue.enqueueParallelBroadcastLocked(r);
11878 queue.scheduleBroadcastsLocked();
11880 registeredReceivers = null;
11884 // Merge into one list.
11886 if (receivers != null) {
11887 // A special case for PACKAGE_ADDED: do not allow the package
11888 // being added to see this broadcast. This prevents them from
11889 // using this as a back door to get run as soon as they are
11890 // installed. Maybe in the future we want to have a special install
11891 // broadcast or such for apps, but we'd like to deliberately make
11893 String skipPackages[] = null;
11894 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11895 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11896 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
11897 Uri data = intent.getData();
11898 if (data != null) {
11899 String pkgName = data.getSchemeSpecificPart();
11900 if (pkgName != null) {
11901 skipPackages = new String[] { pkgName };
11904 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
11905 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11907 if (skipPackages != null && (skipPackages.length > 0)) {
11908 for (String skipPackage : skipPackages) {
11909 if (skipPackage != null) {
11910 int NT = receivers.size();
11911 for (int it=0; it<NT; it++) {
11912 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11913 if (curt.activityInfo.packageName.equals(skipPackage)) {
11914 receivers.remove(it);
11923 int NT = receivers != null ? receivers.size() : 0;
11925 ResolveInfo curt = null;
11926 BroadcastFilter curr = null;
11927 while (it < NT && ir < NR) {
11928 if (curt == null) {
11929 curt = (ResolveInfo)receivers.get(it);
11931 if (curr == null) {
11932 curr = registeredReceivers.get(ir);
11934 if (curr.getPriority() >= curt.priority) {
11935 // Insert this broadcast record into the final list.
11936 receivers.add(it, curr);
11942 // Skip to the next ResolveInfo in the final list.
11949 if (receivers == null) {
11950 receivers = new ArrayList();
11952 receivers.add(registeredReceivers.get(ir));
11956 if ((receivers != null && receivers.size() > 0)
11957 || resultTo != null) {
11958 BroadcastQueue queue = broadcastQueueForIntent(intent);
11959 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
11960 callerPackage, callingPid, callingUid, requiredPermission,
11961 receivers, resultTo, resultCode, resultData, map, ordered,
11962 sticky, false, userId);
11963 if (DEBUG_BROADCAST) Slog.v(
11964 TAG, "Enqueueing ordered broadcast " + r
11965 + ": prev had " + queue.mOrderedBroadcasts.size());
11966 if (DEBUG_BROADCAST) {
11967 int seq = r.intent.getIntExtra("seq", -1);
11968 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
11970 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
11972 queue.enqueueOrderedBroadcastLocked(r);
11973 queue.scheduleBroadcastsLocked();
11977 return ActivityManager.BROADCAST_SUCCESS;
11980 final Intent verifyBroadcastLocked(Intent intent) {
11981 // Refuse possible leaked file descriptors
11982 if (intent != null && intent.hasFileDescriptors() == true) {
11983 throw new IllegalArgumentException("File descriptors passed in Intent");
11986 int flags = intent.getFlags();
11988 if (!mProcessesReady) {
11989 // if the caller really truly claims to know what they're doing, go
11990 // ahead and allow the broadcast without launching any receivers
11991 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11992 intent = new Intent(intent);
11993 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11994 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11995 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11996 + " before boot completion");
11997 throw new IllegalStateException("Cannot broadcast before boot completed");
12001 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12002 throw new IllegalArgumentException(
12003 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12009 public final int broadcastIntent(IApplicationThread caller,
12010 Intent intent, String resolvedType, IIntentReceiver resultTo,
12011 int resultCode, String resultData, Bundle map,
12012 String requiredPermission, boolean serialized, boolean sticky, int userId) {
12013 enforceNotIsolatedCaller("broadcastIntent");
12014 synchronized(this) {
12015 intent = verifyBroadcastLocked(intent);
12017 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12018 final int callingPid = Binder.getCallingPid();
12019 final int callingUid = Binder.getCallingUid();
12020 final long origId = Binder.clearCallingIdentity();
12021 int res = broadcastIntentLocked(callerApp,
12022 callerApp != null ? callerApp.info.packageName : null,
12023 intent, resolvedType, resultTo,
12024 resultCode, resultData, map, requiredPermission, serialized, sticky,
12025 callingPid, callingUid, userId);
12026 Binder.restoreCallingIdentity(origId);
12031 int broadcastIntentInPackage(String packageName, int uid,
12032 Intent intent, String resolvedType, IIntentReceiver resultTo,
12033 int resultCode, String resultData, Bundle map,
12034 String requiredPermission, boolean serialized, boolean sticky, int userId) {
12035 synchronized(this) {
12036 intent = verifyBroadcastLocked(intent);
12038 final long origId = Binder.clearCallingIdentity();
12039 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12040 resultTo, resultCode, resultData, map, requiredPermission,
12041 serialized, sticky, -1, uid, userId);
12042 Binder.restoreCallingIdentity(origId);
12047 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
12048 // Refuse possible leaked file descriptors
12049 if (intent != null && intent.hasFileDescriptors() == true) {
12050 throw new IllegalArgumentException("File descriptors passed in Intent");
12053 userId = handleIncomingUser(Binder.getCallingPid(),
12054 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
12056 synchronized(this) {
12057 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12058 != PackageManager.PERMISSION_GRANTED) {
12059 String msg = "Permission Denial: unbroadcastIntent() from pid="
12060 + Binder.getCallingPid()
12061 + ", uid=" + Binder.getCallingUid()
12062 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
12064 throw new SecurityException(msg);
12066 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12067 if (stickies != null) {
12068 ArrayList<Intent> list = stickies.get(intent.getAction());
12069 if (list != null) {
12070 int N = list.size();
12072 for (i=0; i<N; i++) {
12073 if (intent.filterEquals(list.get(i))) {
12078 if (list.size() <= 0) {
12079 stickies.remove(intent.getAction());
12082 if (stickies.size() <= 0) {
12083 mStickyBroadcasts.remove(userId);
12089 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12090 String resultData, Bundle resultExtras, boolean resultAbort,
12091 boolean explicit) {
12092 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
12094 Slog.w(TAG, "finishReceiver called but not found on queue");
12098 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
12102 public void finishReceiver(IBinder who, int resultCode, String resultData,
12103 Bundle resultExtras, boolean resultAbort) {
12104 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
12106 // Refuse possible leaked file descriptors
12107 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12108 throw new IllegalArgumentException("File descriptors passed in Bundle");
12111 final long origId = Binder.clearCallingIdentity();
12113 boolean doNext = false;
12114 BroadcastRecord r = null;
12116 synchronized(this) {
12117 r = broadcastRecordForReceiverLocked(who);
12119 doNext = r.queue.finishReceiverLocked(r, resultCode,
12120 resultData, resultExtras, resultAbort, true);
12125 r.queue.processNextBroadcast(false);
12127 trimApplications();
12129 Binder.restoreCallingIdentity(origId);
12133 // =========================================================
12135 // =========================================================
12137 public boolean startInstrumentation(ComponentName className,
12138 String profileFile, int flags, Bundle arguments,
12139 IInstrumentationWatcher watcher, int userId) {
12140 enforceNotIsolatedCaller("startInstrumentation");
12141 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
12142 userId, false, true, "startInstrumentation", null);
12143 // Refuse possible leaked file descriptors
12144 if (arguments != null && arguments.hasFileDescriptors()) {
12145 throw new IllegalArgumentException("File descriptors passed in Bundle");
12148 synchronized(this) {
12149 InstrumentationInfo ii = null;
12150 ApplicationInfo ai = null;
12152 ii = mContext.getPackageManager().getInstrumentationInfo(
12153 className, STOCK_PM_FLAGS);
12154 ai = AppGlobals.getPackageManager().getApplicationInfo(
12155 ii.targetPackage, STOCK_PM_FLAGS, userId);
12156 } catch (PackageManager.NameNotFoundException e) {
12157 } catch (RemoteException e) {
12160 reportStartInstrumentationFailure(watcher, className,
12161 "Unable to find instrumentation info for: " + className);
12165 reportStartInstrumentationFailure(watcher, className,
12166 "Unable to find instrumentation target package: " + ii.targetPackage);
12170 int match = mContext.getPackageManager().checkSignatures(
12171 ii.targetPackage, ii.packageName);
12172 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12173 String msg = "Permission Denial: starting instrumentation "
12174 + className + " from pid="
12175 + Binder.getCallingPid()
12176 + ", uid=" + Binder.getCallingPid()
12177 + " not allowed because package " + ii.packageName
12178 + " does not have a signature matching the target "
12179 + ii.targetPackage;
12180 reportStartInstrumentationFailure(watcher, className, msg);
12181 throw new SecurityException(msg);
12184 final long origId = Binder.clearCallingIdentity();
12185 // Instrumentation can kill and relaunch even persistent processes
12186 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
12187 ProcessRecord app = addAppLocked(ai, false);
12188 app.instrumentationClass = className;
12189 app.instrumentationInfo = ai;
12190 app.instrumentationProfileFile = profileFile;
12191 app.instrumentationArguments = arguments;
12192 app.instrumentationWatcher = watcher;
12193 app.instrumentationResultClass = className;
12194 Binder.restoreCallingIdentity(origId);
12201 * Report errors that occur while attempting to start Instrumentation. Always writes the
12202 * error to the logs, but if somebody is watching, send the report there too. This enables
12203 * the "am" command to report errors with more information.
12205 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12206 * @param cn The component name of the instrumentation.
12207 * @param report The error report.
12209 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12210 ComponentName cn, String report) {
12211 Slog.w(TAG, report);
12213 if (watcher != null) {
12214 Bundle results = new Bundle();
12215 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12216 results.putString("Error", report);
12217 watcher.instrumentationStatus(cn, -1, results);
12219 } catch (RemoteException e) {
12224 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12225 if (app.instrumentationWatcher != null) {
12227 // NOTE: IInstrumentationWatcher *must* be oneway here
12228 app.instrumentationWatcher.instrumentationFinished(
12229 app.instrumentationClass,
12232 } catch (RemoteException e) {
12235 app.instrumentationWatcher = null;
12236 app.instrumentationClass = null;
12237 app.instrumentationInfo = null;
12238 app.instrumentationProfileFile = null;
12239 app.instrumentationArguments = null;
12241 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
12244 public void finishInstrumentation(IApplicationThread target,
12245 int resultCode, Bundle results) {
12246 int userId = UserHandle.getCallingUserId();
12247 // Refuse possible leaked file descriptors
12248 if (results != null && results.hasFileDescriptors()) {
12249 throw new IllegalArgumentException("File descriptors passed in Intent");
12252 synchronized(this) {
12253 ProcessRecord app = getRecordForAppLocked(target);
12255 Slog.w(TAG, "finishInstrumentation: no app for " + target);
12258 final long origId = Binder.clearCallingIdentity();
12259 finishInstrumentationLocked(app, resultCode, results);
12260 Binder.restoreCallingIdentity(origId);
12264 // =========================================================
12266 // =========================================================
12268 public ConfigurationInfo getDeviceConfigurationInfo() {
12269 ConfigurationInfo config = new ConfigurationInfo();
12270 synchronized (this) {
12271 config.reqTouchScreen = mConfiguration.touchscreen;
12272 config.reqKeyboardType = mConfiguration.keyboard;
12273 config.reqNavigation = mConfiguration.navigation;
12274 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12275 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
12276 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12278 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12279 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
12280 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12282 config.reqGlEsVersion = GL_ES_VERSION;
12287 public Configuration getConfiguration() {
12289 synchronized(this) {
12290 ci = new Configuration(mConfiguration);
12295 public void updatePersistentConfiguration(Configuration values) {
12296 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12297 "updateConfiguration()");
12298 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12299 "updateConfiguration()");
12300 if (values == null) {
12301 throw new NullPointerException("Configuration must not be null");
12304 synchronized(this) {
12305 final long origId = Binder.clearCallingIdentity();
12306 updateConfigurationLocked(values, null, true, false);
12307 Binder.restoreCallingIdentity(origId);
12311 public void updateConfiguration(Configuration values) {
12312 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12313 "updateConfiguration()");
12315 synchronized(this) {
12316 if (values == null && mWindowManager != null) {
12317 // sentinel: fetch the current configuration from the window manager
12318 values = mWindowManager.computeNewConfiguration();
12321 if (mWindowManager != null) {
12322 mProcessList.applyDisplaySize(mWindowManager);
12325 final long origId = Binder.clearCallingIdentity();
12326 if (values != null) {
12327 Settings.System.clearConfiguration(values);
12329 updateConfigurationLocked(values, null, false, false);
12330 Binder.restoreCallingIdentity(origId);
12335 * Do either or both things: (1) change the current configuration, and (2)
12336 * make sure the given activity is running with the (now) current
12337 * configuration. Returns true if the activity has been left running, or
12338 * false if <var>starting</var> is being destroyed to match the new
12340 * @param persistent TODO
12342 boolean updateConfigurationLocked(Configuration values,
12343 ActivityRecord starting, boolean persistent, boolean initLocale) {
12344 // do nothing if we are headless
12345 if (mHeadless) return true;
12349 boolean kept = true;
12351 if (values != null) {
12352 Configuration newConfig = new Configuration(mConfiguration);
12353 changes = newConfig.updateFrom(values);
12354 if (changes != 0) {
12355 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
12356 Slog.i(TAG, "Updating configuration to: " + values);
12359 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
12361 if (values.locale != null && !initLocale) {
12362 saveLocaleLocked(values.locale,
12363 !values.locale.equals(mConfiguration.locale),
12364 values.userSetLocale);
12367 mConfigurationSeq++;
12368 if (mConfigurationSeq <= 0) {
12369 mConfigurationSeq = 1;
12371 newConfig.seq = mConfigurationSeq;
12372 mConfiguration = newConfig;
12373 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
12375 final Configuration configCopy = new Configuration(mConfiguration);
12377 // TODO: If our config changes, should we auto dismiss any currently
12378 // showing dialogs?
12379 mShowDialogs = shouldShowDialogs(newConfig);
12381 AttributeCache ac = AttributeCache.instance();
12383 ac.updateConfiguration(configCopy);
12386 // Make sure all resources in our process are updated
12387 // right now, so that anyone who is going to retrieve
12388 // resource values after we return will be sure to get
12389 // the new ones. This is especially important during
12390 // boot, where the first config change needs to guarantee
12391 // all resources have that config before following boot
12392 // code is executed.
12393 mSystemThread.applyConfigurationToResources(configCopy);
12395 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
12396 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12397 msg.obj = new Configuration(configCopy);
12398 mHandler.sendMessage(msg);
12401 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12402 ProcessRecord app = mLruProcesses.get(i);
12404 if (app.thread != null) {
12405 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
12406 + app.processName + " new config " + mConfiguration);
12407 app.thread.scheduleConfigurationChanged(configCopy);
12409 } catch (Exception e) {
12412 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
12413 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12414 | Intent.FLAG_RECEIVER_REPLACE_PENDING
12415 | Intent.FLAG_RECEIVER_FOREGROUND);
12416 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12417 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12418 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12419 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
12420 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12421 broadcastIntentLocked(null, null, intent,
12422 null, null, 0, null, null,
12423 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12428 if (changes != 0 && starting == null) {
12429 // If the configuration changed, and the caller is not already
12430 // in the process of starting an activity, then find the top
12431 // activity to check if its configuration needs to change.
12432 starting = mMainStack.topRunningActivityLocked(null);
12435 if (starting != null) {
12436 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
12437 // And we need to make sure at this point that all other activities
12438 // are made visible with the correct configuration.
12439 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
12442 if (values != null && mWindowManager != null) {
12443 mWindowManager.setNewConfiguration(mConfiguration);
12450 * Decide based on the configuration whether we should shouw the ANR,
12451 * crash, etc dialogs. The idea is that if there is no affordnace to
12452 * press the on-screen buttons, we shouldn't show the dialog.
12454 * A thought: SystemUI might also want to get told about this, the Power
12455 * dialog / global actions also might want different behaviors.
12457 private static final boolean shouldShowDialogs(Configuration config) {
12458 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12459 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12463 * Save the locale. You must be inside a synchronized (this) block.
12465 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12467 SystemProperties.set("user.language", l.getLanguage());
12468 SystemProperties.set("user.region", l.getCountry());
12472 SystemProperties.set("persist.sys.language", l.getLanguage());
12473 SystemProperties.set("persist.sys.country", l.getCountry());
12474 SystemProperties.set("persist.sys.localevar", l.getVariant());
12479 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12480 ActivityRecord srec = ActivityRecord.forToken(token);
12481 return srec != null && srec.task.affinity != null &&
12482 srec.task.affinity.equals(destAffinity);
12485 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12486 Intent resultData) {
12487 ComponentName dest = destIntent.getComponent();
12489 synchronized (this) {
12490 ActivityRecord srec = ActivityRecord.forToken(token);
12491 if (srec == null) {
12494 ArrayList<ActivityRecord> history = srec.stack.mHistory;
12495 final int start = history.indexOf(srec);
12497 // Current activity is not in history stack; do nothing.
12500 int finishTo = start - 1;
12501 ActivityRecord parent = null;
12502 boolean foundParentInTask = false;
12503 if (dest != null) {
12504 TaskRecord tr = srec.task;
12505 for (int i = start - 1; i >= 0; i--) {
12506 ActivityRecord r = history.get(i);
12507 if (tr != r.task) {
12508 // Couldn't find parent in the same task; stop at the one above this.
12509 // (Root of current task; in-app "home" behavior)
12510 // Always at least finish the current activity.
12511 finishTo = Math.min(start - 1, i + 1);
12512 parent = history.get(finishTo);
12514 } else if (r.info.packageName.equals(dest.getPackageName()) &&
12515 r.info.name.equals(dest.getClassName())) {
12518 foundParentInTask = true;
12524 if (mController != null) {
12525 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12526 if (next != null) {
12527 // ask watcher if this is allowed
12528 boolean resumeOK = true;
12530 resumeOK = mController.activityResuming(next.packageName);
12531 } catch (RemoteException e) {
12532 mController = null;
12540 final long origId = Binder.clearCallingIdentity();
12541 for (int i = start; i > finishTo; i--) {
12542 ActivityRecord r = history.get(i);
12543 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12544 "navigate-up", true);
12545 // Only return the supplied result for the first activity finished
12546 resultCode = Activity.RESULT_CANCELED;
12550 if (parent != null && foundParentInTask) {
12551 final int parentLaunchMode = parent.info.launchMode;
12552 final int destIntentFlags = destIntent.getFlags();
12553 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12554 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12555 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12556 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
12557 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
12560 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
12561 destIntent.getComponent(), 0, srec.userId);
12562 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12563 null, aInfo, parent.appToken, null,
12564 0, -1, parent.launchedFromUid, 0, null, true, null);
12565 foundParentInTask = res == ActivityManager.START_SUCCESS;
12566 } catch (RemoteException e) {
12567 foundParentInTask = false;
12569 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12570 resultData, "navigate-up", true);
12573 Binder.restoreCallingIdentity(origId);
12574 return foundParentInTask;
12578 public int getLaunchedFromUid(IBinder activityToken) {
12579 ActivityRecord srec = ActivityRecord.forToken(activityToken);
12580 if (srec == null) {
12583 return srec.launchedFromUid;
12586 // =========================================================
12587 // LIFETIME MANAGEMENT
12588 // =========================================================
12590 // Returns which broadcast queue the app is the current [or imminent] receiver
12591 // on, or 'null' if the app is not an active broadcast recipient.
12592 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12593 BroadcastRecord r = app.curReceiver;
12598 // It's not the current receiver, but it might be starting up to become one
12599 synchronized (this) {
12600 for (BroadcastQueue queue : mBroadcastQueues) {
12601 r = queue.mPendingBroadcast;
12602 if (r != null && r.curApp == app) {
12603 // found it; report which queue it's in
12612 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
12613 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
12614 if (mAdjSeq == app.adjSeq) {
12615 // This adjustment has already been computed. If we are calling
12616 // from the top, we may have already computed our adjustment with
12617 // an earlier hidden adjustment that isn't really for us... if
12618 // so, use the new hidden adjustment.
12619 if (!recursed && app.hidden) {
12620 if (app.hasActivities) {
12621 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12622 } else if (app.hasClientActivities) {
12623 app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12625 app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12628 return app.curRawAdj;
12631 if (app.thread == null) {
12632 app.adjSeq = mAdjSeq;
12633 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12634 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
12637 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12638 app.adjSource = null;
12639 app.adjTarget = null;
12641 app.hidden = false;
12642 app.hasClientActivities = false;
12644 final int activitiesSize = app.activities.size();
12646 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
12647 // The max adjustment doesn't allow this app to be anything
12648 // below foreground, so it is not worth doing work for it.
12649 app.adjType = "fixed";
12650 app.adjSeq = mAdjSeq;
12651 app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
12652 app.hasActivities = false;
12653 app.foregroundActivities = false;
12654 app.keeping = true;
12655 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
12656 // System process can do UI, and when they do we want to have
12657 // them trim their memory after the user leaves the UI. To
12658 // facilitate this, here we need to determine whether or not it
12659 // is currently showing UI.
12660 app.systemNoUi = true;
12661 if (app == TOP_APP) {
12662 app.systemNoUi = false;
12663 app.hasActivities = true;
12664 } else if (activitiesSize > 0) {
12665 for (int j = 0; j < activitiesSize; j++) {
12666 final ActivityRecord r = app.activities.get(j);
12668 app.systemNoUi = false;
12670 if (r.app == app) {
12671 app.hasActivities = true;
12675 return (app.curAdj=app.maxAdj);
12678 app.keeping = false;
12679 app.systemNoUi = false;
12680 app.hasActivities = false;
12682 // Determine the importance of the process, starting with most
12683 // important to least, and assign an appropriate OOM adjustment.
12686 boolean foregroundActivities = false;
12687 boolean interesting = false;
12688 BroadcastQueue queue;
12689 if (app == TOP_APP) {
12690 // The last app on the list is the foreground app.
12691 adj = ProcessList.FOREGROUND_APP_ADJ;
12692 schedGroup = Process.THREAD_GROUP_DEFAULT;
12693 app.adjType = "top-activity";
12694 foregroundActivities = true;
12695 interesting = true;
12696 app.hasActivities = true;
12697 } else if (app.instrumentationClass != null) {
12698 // Don't want to kill running instrumentation.
12699 adj = ProcessList.FOREGROUND_APP_ADJ;
12700 schedGroup = Process.THREAD_GROUP_DEFAULT;
12701 app.adjType = "instrumentation";
12702 interesting = true;
12703 } else if ((queue = isReceivingBroadcast(app)) != null) {
12704 // An app that is currently receiving a broadcast also
12705 // counts as being in the foreground for OOM killer purposes.
12706 // It's placed in a sched group based on the nature of the
12707 // broadcast as reflected by which queue it's active in.
12708 adj = ProcessList.FOREGROUND_APP_ADJ;
12709 schedGroup = (queue == mFgBroadcastQueue)
12710 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
12711 app.adjType = "broadcast";
12712 } else if (app.executingServices.size() > 0) {
12713 // An app that is currently executing a service callback also
12714 // counts as being in the foreground.
12715 adj = ProcessList.FOREGROUND_APP_ADJ;
12716 schedGroup = Process.THREAD_GROUP_DEFAULT;
12717 app.adjType = "exec-service";
12719 // Assume process is hidden (has activities); we will correct
12720 // later if this is not the case.
12722 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12724 app.adjType = "bg-act";
12727 boolean hasStoppingActivities = false;
12729 // Examine all activities if not already foreground.
12730 if (!foregroundActivities && activitiesSize > 0) {
12731 for (int j = 0; j < activitiesSize; j++) {
12732 final ActivityRecord r = app.activities.get(j);
12734 // App has a visible activity; only upgrade adjustment.
12735 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12736 adj = ProcessList.VISIBLE_APP_ADJ;
12737 app.adjType = "visible";
12739 schedGroup = Process.THREAD_GROUP_DEFAULT;
12740 app.hidden = false;
12741 app.hasActivities = true;
12742 foregroundActivities = true;
12744 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
12745 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12746 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12747 app.adjType = "pausing";
12749 app.hidden = false;
12750 foregroundActivities = true;
12751 } else if (r.state == ActivityState.STOPPING) {
12752 // We will apply the actual adjustment later, because
12753 // we want to allow this process to immediately go through
12754 // any memory trimming that is in effect.
12755 app.hidden = false;
12756 foregroundActivities = true;
12757 hasStoppingActivities = true;
12759 if (r.app == app) {
12760 app.hasActivities = true;
12765 if (adj == hiddenAdj && !app.hasActivities) {
12766 if (app.hasClientActivities) {
12767 adj = clientHiddenAdj;
12768 app.adjType = "bg-client-act";
12770 // Whoops, this process is completely empty as far as we know
12774 app.adjType = "bg-empty";
12778 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12779 if (app.foregroundServices) {
12780 // The user is aware of this app, so make it visible.
12781 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12782 app.hidden = false;
12783 app.adjType = "fg-service";
12784 schedGroup = Process.THREAD_GROUP_DEFAULT;
12785 } else if (app.forcingToForeground != null) {
12786 // The user is aware of this app, so make it visible.
12787 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12788 app.hidden = false;
12789 app.adjType = "force-fg";
12790 app.adjSource = app.forcingToForeground;
12791 schedGroup = Process.THREAD_GROUP_DEFAULT;
12795 if (app.foregroundServices) {
12796 interesting = true;
12799 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
12800 // We don't want to kill the current heavy-weight process.
12801 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
12802 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12803 app.hidden = false;
12804 app.adjType = "heavy";
12807 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
12808 // This process is hosting what we currently consider to be the
12809 // home app, so we don't want to let it go into the background.
12810 adj = ProcessList.HOME_APP_ADJ;
12811 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12812 app.hidden = false;
12813 app.adjType = "home";
12816 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12817 && app.activities.size() > 0) {
12818 // This was the previous process that showed UI to the user.
12819 // We want to try to keep it around more aggressively, to give
12820 // a good experience around switching between two apps.
12821 adj = ProcessList.PREVIOUS_APP_ADJ;
12822 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12823 app.hidden = false;
12824 app.adjType = "previous";
12827 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12828 + " reason=" + app.adjType);
12830 // By default, we use the computed adjustment. It may be changed if
12831 // there are applications dependent on our services or providers, but
12832 // this gives us a baseline and makes sure we don't get into an
12833 // infinite recursion.
12834 app.adjSeq = mAdjSeq;
12835 app.curRawAdj = app.nonStoppingAdj = adj;
12837 if (mBackupTarget != null && app == mBackupTarget.app) {
12838 // If possible we want to avoid killing apps while they're being backed up
12839 if (adj > ProcessList.BACKUP_APP_ADJ) {
12840 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
12841 adj = ProcessList.BACKUP_APP_ADJ;
12842 app.adjType = "backup";
12843 app.hidden = false;
12847 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12848 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12849 final long now = SystemClock.uptimeMillis();
12850 // This process is more important if the top activity is
12851 // bound to the service.
12852 Iterator<ServiceRecord> jt = app.services.iterator();
12853 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12854 ServiceRecord s = jt.next();
12855 if (s.startRequested) {
12856 if (app.hasShownUi && app != mHomeProcess) {
12857 // If this process has shown some UI, let it immediately
12858 // go to the LRU list because it may be pretty heavy with
12859 // UI stuff. We'll tag it with a label just to help
12860 // debug and understand what is going on.
12861 if (adj > ProcessList.SERVICE_ADJ) {
12862 app.adjType = "started-bg-ui-services";
12865 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12866 // This service has seen some activity within
12867 // recent memory, so we will keep its process ahead
12868 // of the background processes.
12869 if (adj > ProcessList.SERVICE_ADJ) {
12870 adj = ProcessList.SERVICE_ADJ;
12871 app.adjType = "started-services";
12872 app.hidden = false;
12875 // If we have let the service slide into the background
12876 // state, still have some text describing what it is doing
12877 // even though the service no longer has an impact.
12878 if (adj > ProcessList.SERVICE_ADJ) {
12879 app.adjType = "started-bg-services";
12882 // Don't kill this process because it is doing work; it
12883 // has said it is doing work.
12884 app.keeping = true;
12886 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12887 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
12888 Iterator<ArrayList<ConnectionRecord>> kt
12889 = s.connections.values().iterator();
12890 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
12891 ArrayList<ConnectionRecord> clist = kt.next();
12892 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
12893 // XXX should compute this based on the max of
12894 // all connected clients.
12895 ConnectionRecord cr = clist.get(i);
12896 if (cr.binding.client == app) {
12897 // Binding to ourself is not interesting.
12900 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
12901 ProcessRecord client = cr.binding.client;
12902 int clientAdj = adj;
12903 int myHiddenAdj = hiddenAdj;
12904 if (myHiddenAdj > client.hiddenAdj) {
12905 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12906 myHiddenAdj = client.hiddenAdj;
12908 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12911 int myClientHiddenAdj = clientHiddenAdj;
12912 if (myClientHiddenAdj > client.clientHiddenAdj) {
12913 if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12914 myClientHiddenAdj = client.clientHiddenAdj;
12916 myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12919 int myEmptyAdj = emptyAdj;
12920 if (myEmptyAdj > client.emptyAdj) {
12921 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12922 myEmptyAdj = client.emptyAdj;
12924 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12927 clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12928 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
12929 String adjType = null;
12930 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12931 // Not doing bind OOM management, so treat
12932 // this guy more like a started service.
12933 if (app.hasShownUi && app != mHomeProcess) {
12934 // If this process has shown some UI, let it immediately
12935 // go to the LRU list because it may be pretty heavy with
12936 // UI stuff. We'll tag it with a label just to help
12937 // debug and understand what is going on.
12938 if (adj > clientAdj) {
12939 adjType = "bound-bg-ui-services";
12941 app.hidden = false;
12944 if (now >= (s.lastActivity
12945 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
12946 // This service has not seen activity within
12947 // recent memory, so allow it to drop to the
12948 // LRU list if there is no other reason to keep
12949 // it around. We'll also tag it with a label just
12950 // to help debug and undertand what is going on.
12951 if (adj > clientAdj) {
12952 adjType = "bound-bg-services";
12957 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12958 if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
12959 // If this connection is keeping the service
12960 // created, then we want to try to better follow
12961 // its memory management semantics for activities.
12962 // That is, if it is sitting in the background
12963 // LRU list as a hidden process (with activities),
12964 // we don't want the service it is connected to
12965 // to go into the empty LRU and quickly get killed,
12966 // because I'll we'll do is just end up restarting
12968 app.hasClientActivities |= client.hasActivities;
12971 if (adj > clientAdj) {
12972 // If this process has recently shown UI, and
12973 // the process that is binding to it is less
12974 // important than being visible, then we don't
12975 // care about the binding as much as we care
12976 // about letting this process get into the LRU
12977 // list to be killed and restarted if needed for
12979 if (app.hasShownUi && app != mHomeProcess
12980 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12981 adjType = "bound-bg-ui-services";
12983 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12984 |Context.BIND_IMPORTANT)) != 0) {
12986 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12987 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12988 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12989 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12990 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
12993 app.pendingUiClean = true;
12994 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12995 adj = ProcessList.VISIBLE_APP_ADJ;
12998 if (!client.hidden) {
12999 app.hidden = false;
13001 if (client.keeping) {
13002 app.keeping = true;
13004 adjType = "service";
13007 if (adjType != null) {
13008 app.adjType = adjType;
13009 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13010 .REASON_SERVICE_IN_USE;
13011 app.adjSource = cr.binding.client;
13012 app.adjSourceOom = clientAdj;
13013 app.adjTarget = s.name;
13015 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13016 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13017 schedGroup = Process.THREAD_GROUP_DEFAULT;
13021 final ActivityRecord a = cr.activity;
13022 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13023 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
13024 (a.visible || a.state == ActivityState.RESUMED
13025 || a.state == ActivityState.PAUSING)) {
13026 adj = ProcessList.FOREGROUND_APP_ADJ;
13027 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13028 schedGroup = Process.THREAD_GROUP_DEFAULT;
13030 app.hidden = false;
13031 app.adjType = "service";
13032 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13033 .REASON_SERVICE_IN_USE;
13035 app.adjSourceOom = adj;
13036 app.adjTarget = s.name;
13044 // Finally, if this process has active services running in it, we
13045 // would like to avoid killing it unless it would prevent the current
13046 // application from running. By default we put the process in
13047 // with the rest of the background processes; as we scan through
13048 // its services we may bump it up from there.
13049 if (adj > hiddenAdj) {
13051 app.hidden = false;
13052 app.adjType = "bg-services";
13056 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13057 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13058 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
13059 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
13060 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
13061 ContentProviderRecord cpr = jt.next();
13062 for (int i = cpr.connections.size()-1;
13063 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13064 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
13066 ContentProviderConnection conn = cpr.connections.get(i);
13067 ProcessRecord client = conn.client;
13068 if (client == app) {
13069 // Being our own client is not interesting.
13072 int myHiddenAdj = hiddenAdj;
13073 if (myHiddenAdj > client.hiddenAdj) {
13074 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
13075 myHiddenAdj = client.hiddenAdj;
13077 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13080 int myClientHiddenAdj = clientHiddenAdj;
13081 if (myClientHiddenAdj > client.clientHiddenAdj) {
13082 if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
13083 myClientHiddenAdj = client.clientHiddenAdj;
13085 myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13088 int myEmptyAdj = emptyAdj;
13089 if (myEmptyAdj > client.emptyAdj) {
13090 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
13091 myEmptyAdj = client.emptyAdj;
13093 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
13096 int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
13097 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
13098 if (adj > clientAdj) {
13099 if (app.hasShownUi && app != mHomeProcess
13100 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13101 app.adjType = "bg-ui-provider";
13103 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13104 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13105 app.adjType = "provider";
13107 if (!client.hidden) {
13108 app.hidden = false;
13110 if (client.keeping) {
13111 app.keeping = true;
13113 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13114 .REASON_PROVIDER_IN_USE;
13115 app.adjSource = client;
13116 app.adjSourceOom = clientAdj;
13117 app.adjTarget = cpr.name;
13119 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13120 schedGroup = Process.THREAD_GROUP_DEFAULT;
13123 // If the provider has external (non-framework) process
13124 // dependencies, ensure that its adjustment is at least
13125 // FOREGROUND_APP_ADJ.
13126 if (cpr.hasExternalProcessHandles()) {
13127 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13128 adj = ProcessList.FOREGROUND_APP_ADJ;
13129 schedGroup = Process.THREAD_GROUP_DEFAULT;
13130 app.hidden = false;
13131 app.keeping = true;
13132 app.adjType = "provider";
13133 app.adjTarget = cpr.name;
13139 if (adj == ProcessList.SERVICE_ADJ) {
13141 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13142 mNewNumServiceProcs++;
13144 if (app.serviceb) {
13145 adj = ProcessList.SERVICE_B_ADJ;
13148 app.serviceb = false;
13151 app.nonStoppingAdj = adj;
13153 if (hasStoppingActivities) {
13154 // Only upgrade adjustment.
13155 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13156 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13157 app.adjType = "stopping";
13161 app.curRawAdj = adj;
13163 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
13164 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13165 if (adj > app.maxAdj) {
13167 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
13168 schedGroup = Process.THREAD_GROUP_DEFAULT;
13171 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13172 app.keeping = true;
13175 if (app.hasAboveClient) {
13176 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13177 // then we need to drop its adjustment to be lower than the service's
13178 // in order to honor the request. We want to drop it by one adjustment
13179 // level... but there is special meaning applied to various levels so
13180 // we will skip some of them.
13181 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
13182 // System process will not get dropped, ever
13183 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13184 adj = ProcessList.VISIBLE_APP_ADJ;
13185 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13186 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13187 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13188 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13189 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
13194 int importance = app.memImportance;
13195 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13197 app.curSchedGroup = schedGroup;
13198 if (!interesting) {
13199 // For this reporting, if there is not something explicitly
13200 // interesting in this process then we will push it to the
13201 // background importance.
13202 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13203 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13204 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13205 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13206 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13207 } else if (adj >= ProcessList.HOME_APP_ADJ) {
13208 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13209 } else if (adj >= ProcessList.SERVICE_ADJ) {
13210 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13211 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13212 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13213 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13214 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13215 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13216 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13217 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13218 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13220 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13224 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13225 if (foregroundActivities != app.foregroundActivities) {
13226 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13228 if (changes != 0) {
13229 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13230 app.memImportance = importance;
13231 app.foregroundActivities = foregroundActivities;
13232 int i = mPendingProcessChanges.size()-1;
13233 ProcessChangeItem item = null;
13235 item = mPendingProcessChanges.get(i);
13236 if (item.pid == app.pid) {
13237 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13243 // No existing item in pending changes; need a new one.
13244 final int NA = mAvailProcessChanges.size();
13246 item = mAvailProcessChanges.remove(NA-1);
13247 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13249 item = new ProcessChangeItem();
13250 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13253 item.pid = app.pid;
13254 item.uid = app.info.uid;
13255 if (mPendingProcessChanges.size() == 0) {
13256 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13257 "*** Enqueueing dispatch processes changed!");
13258 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13260 mPendingProcessChanges.add(item);
13262 item.changes |= changes;
13263 item.importance = importance;
13264 item.foregroundActivities = foregroundActivities;
13265 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13266 + Integer.toHexString(System.identityHashCode(item))
13267 + " " + app.toShortString() + ": changes=" + item.changes
13268 + " importance=" + item.importance
13269 + " foreground=" + item.foregroundActivities
13270 + " type=" + app.adjType + " source=" + app.adjSource
13271 + " target=" + app.adjTarget);
13274 return app.curRawAdj;
13278 * Ask a given process to GC right now.
13280 final void performAppGcLocked(ProcessRecord app) {
13282 app.lastRequestedGc = SystemClock.uptimeMillis();
13283 if (app.thread != null) {
13284 if (app.reportLowMemory) {
13285 app.reportLowMemory = false;
13286 app.thread.scheduleLowMemory();
13288 app.thread.processInBackground();
13291 } catch (Exception e) {
13297 * Returns true if things are idle enough to perform GCs.
13299 private final boolean canGcNowLocked() {
13300 boolean processingBroadcasts = false;
13301 for (BroadcastQueue q : mBroadcastQueues) {
13302 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13303 processingBroadcasts = true;
13306 return !processingBroadcasts
13307 && (mSleeping || (mMainStack.mResumedActivity != null &&
13308 mMainStack.mResumedActivity.idle));
13312 * Perform GCs on all processes that are waiting for it, but only
13313 * if things are idle.
13315 final void performAppGcsLocked() {
13316 final int N = mProcessesToGc.size();
13320 if (canGcNowLocked()) {
13321 while (mProcessesToGc.size() > 0) {
13322 ProcessRecord proc = mProcessesToGc.remove(0);
13323 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
13324 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13325 <= SystemClock.uptimeMillis()) {
13326 // To avoid spamming the system, we will GC processes one
13327 // at a time, waiting a few seconds between each.
13328 performAppGcLocked(proc);
13329 scheduleAppGcsLocked();
13332 // It hasn't been long enough since we last GCed this
13333 // process... put it in the list to wait for its time.
13334 addProcessToGcListLocked(proc);
13340 scheduleAppGcsLocked();
13345 * If all looks good, perform GCs on all processes waiting for them.
13347 final void performAppGcsIfAppropriateLocked() {
13348 if (canGcNowLocked()) {
13349 performAppGcsLocked();
13352 // Still not idle, wait some more.
13353 scheduleAppGcsLocked();
13357 * Schedule the execution of all pending app GCs.
13359 final void scheduleAppGcsLocked() {
13360 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
13362 if (mProcessesToGc.size() > 0) {
13363 // Schedule a GC for the time to the next process.
13364 ProcessRecord proc = mProcessesToGc.get(0);
13365 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13367 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
13368 long now = SystemClock.uptimeMillis();
13369 if (when < (now+GC_TIMEOUT)) {
13370 when = now + GC_TIMEOUT;
13372 mHandler.sendMessageAtTime(msg, when);
13377 * Add a process to the array of processes waiting to be GCed. Keeps the
13378 * list in sorted order by the last GC time. The process can't already be
13381 final void addProcessToGcListLocked(ProcessRecord proc) {
13382 boolean added = false;
13383 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13384 if (mProcessesToGc.get(i).lastRequestedGc <
13385 proc.lastRequestedGc) {
13387 mProcessesToGc.add(i+1, proc);
13392 mProcessesToGc.add(0, proc);
13397 * Set up to ask a process to GC itself. This will either do it
13398 * immediately, or put it on the list of processes to gc the next
13399 * time things are idle.
13401 final void scheduleAppGcLocked(ProcessRecord app) {
13402 long now = SystemClock.uptimeMillis();
13403 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
13406 if (!mProcessesToGc.contains(app)) {
13407 addProcessToGcListLocked(app);
13408 scheduleAppGcsLocked();
13412 final void checkExcessivePowerUsageLocked(boolean doKills) {
13413 updateCpuStatsNow();
13415 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13416 boolean doWakeKills = doKills;
13417 boolean doCpuKills = doKills;
13418 if (mLastPowerCheckRealtime == 0) {
13419 doWakeKills = false;
13421 if (mLastPowerCheckUptime == 0) {
13422 doCpuKills = false;
13424 if (stats.isScreenOn()) {
13425 doWakeKills = false;
13427 final long curRealtime = SystemClock.elapsedRealtime();
13428 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13429 final long curUptime = SystemClock.uptimeMillis();
13430 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13431 mLastPowerCheckRealtime = curRealtime;
13432 mLastPowerCheckUptime = curUptime;
13433 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13434 doWakeKills = false;
13436 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13437 doCpuKills = false;
13439 int i = mLruProcesses.size();
13442 ProcessRecord app = mLruProcesses.get(i);
13443 if (!app.keeping) {
13445 synchronized (stats) {
13446 wtime = stats.getProcessWakeTime(app.info.uid,
13447 app.pid, curRealtime);
13449 long wtimeUsed = wtime - app.lastWakeTime;
13450 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13452 StringBuilder sb = new StringBuilder(128);
13453 sb.append("Wake for ");
13454 app.toShortString(sb);
13455 sb.append(": over ");
13456 TimeUtils.formatDuration(realtimeSince, sb);
13457 sb.append(" used ");
13458 TimeUtils.formatDuration(wtimeUsed, sb);
13460 sb.append((wtimeUsed*100)/realtimeSince);
13462 Slog.i(TAG, sb.toString());
13464 sb.append("CPU for ");
13465 app.toShortString(sb);
13466 sb.append(": over ");
13467 TimeUtils.formatDuration(uptimeSince, sb);
13468 sb.append(" used ");
13469 TimeUtils.formatDuration(cputimeUsed, sb);
13471 sb.append((cputimeUsed*100)/uptimeSince);
13473 Slog.i(TAG, sb.toString());
13475 // If a process has held a wake lock for more
13476 // than 50% of the time during this period,
13477 // that sounds bad. Kill!
13478 if (doWakeKills && realtimeSince > 0
13479 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13480 synchronized (stats) {
13481 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13482 realtimeSince, wtimeUsed);
13484 Slog.w(TAG, "Excessive wake lock in " + app.processName
13485 + " (pid " + app.pid + "): held " + wtimeUsed
13486 + " during " + realtimeSince);
13487 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13488 app.processName, app.setAdj, "excessive wake lock");
13489 Process.killProcessQuiet(app.pid);
13490 } else if (doCpuKills && uptimeSince > 0
13491 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13492 synchronized (stats) {
13493 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13494 uptimeSince, cputimeUsed);
13496 Slog.w(TAG, "Excessive CPU in " + app.processName
13497 + " (pid " + app.pid + "): used " + cputimeUsed
13498 + " during " + uptimeSince);
13499 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13500 app.processName, app.setAdj, "excessive cpu");
13501 Process.killProcessQuiet(app.pid);
13503 app.lastWakeTime = wtime;
13504 app.lastCpuTime = app.curCpuTime;
13510 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13511 int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
13512 app.hiddenAdj = hiddenAdj;
13513 app.clientHiddenAdj = clientHiddenAdj;
13514 app.emptyAdj = emptyAdj;
13516 if (app.thread == null) {
13520 final boolean wasKeeping = app.keeping;
13522 boolean success = true;
13524 computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
13526 if (app.curRawAdj != app.setRawAdj) {
13527 if (wasKeeping && !app.keeping) {
13528 // This app is no longer something we want to keep. Note
13529 // its current wake lock time to later know to kill it if
13530 // it is not behaving well.
13531 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13532 synchronized (stats) {
13533 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13534 app.pid, SystemClock.elapsedRealtime());
13536 app.lastCpuTime = app.curCpuTime;
13539 app.setRawAdj = app.curRawAdj;
13542 if (app.curAdj != app.setAdj) {
13543 if (Process.setOomAdj(app.pid, app.curAdj)) {
13544 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13545 TAG, "Set " + app.pid + " " + app.processName +
13546 " adj " + app.curAdj + ": " + app.adjType);
13547 app.setAdj = app.curAdj;
13550 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
13553 if (app.setSchedGroup != app.curSchedGroup) {
13554 app.setSchedGroup = app.curSchedGroup;
13555 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13556 "Setting process group of " + app.processName
13557 + " to " + app.curSchedGroup);
13558 if (app.waitingToKill != null &&
13559 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13560 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13561 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13562 app.processName, app.setAdj, app.waitingToKill);
13563 app.killedBackground = true;
13564 Process.killProcessQuiet(app.pid);
13568 long oldId = Binder.clearCallingIdentity();
13570 Process.setProcessGroup(app.pid, app.curSchedGroup);
13571 } catch (Exception e) {
13572 Slog.w(TAG, "Failed setting process group of " + app.pid
13573 + " to " + app.curSchedGroup);
13574 e.printStackTrace();
13576 Binder.restoreCallingIdentity(oldId);
13579 if (app.thread != null) {
13581 app.thread.setSchedulingGroup(app.curSchedGroup);
13582 } catch (RemoteException e) {
13591 private final ActivityRecord resumedAppLocked() {
13592 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
13593 if (resumedActivity == null || resumedActivity.app == null) {
13594 resumedActivity = mMainStack.mPausingActivity;
13595 if (resumedActivity == null || resumedActivity.app == null) {
13596 resumedActivity = mMainStack.topRunningActivityLocked(null);
13599 return resumedActivity;
13602 final boolean updateOomAdjLocked(ProcessRecord app) {
13603 final ActivityRecord TOP_ACT = resumedAppLocked();
13604 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13605 int curAdj = app.curAdj;
13606 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13607 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13611 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13612 app.emptyAdj, TOP_APP, false);
13613 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13614 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
13615 if (nowHidden != wasHidden) {
13616 // Changed to/from hidden state, so apps after it in the LRU
13617 // list may also be changed.
13618 updateOomAdjLocked();
13623 final void updateOomAdjLocked() {
13624 final ActivityRecord TOP_ACT = resumedAppLocked();
13625 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13626 final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
13629 RuntimeException e = new RuntimeException();
13630 e.fillInStackTrace();
13631 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
13635 mNewNumServiceProcs = 0;
13637 final int emptyProcessLimit;
13638 final int hiddenProcessLimit;
13639 if (mProcessLimit <= 0) {
13640 emptyProcessLimit = hiddenProcessLimit = 0;
13641 } else if (mProcessLimit == 1) {
13642 emptyProcessLimit = 1;
13643 hiddenProcessLimit = 0;
13645 emptyProcessLimit = (mProcessLimit*2)/3;
13646 hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13649 // Let's determine how many processes we have running vs.
13650 // how many slots we have for background processes; we may want
13651 // to put multiple processes in a slot of there are enough of
13653 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13654 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13655 int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13656 if (numEmptyProcs > hiddenProcessLimit) {
13657 // If there are more empty processes than our limit on hidden
13658 // processes, then use the hidden process limit for the factor.
13659 // This ensures that the really old empty processes get pushed
13660 // down to the bottom, so if we are running low on memory we will
13661 // have a better chance at keeping around more hidden processes
13662 // instead of a gazillion empty processes.
13663 numEmptyProcs = hiddenProcessLimit;
13665 int emptyFactor = numEmptyProcs/numSlots;
13666 if (emptyFactor < 1) emptyFactor = 1;
13667 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13668 if (hiddenFactor < 1) hiddenFactor = 1;
13669 int stepHidden = 0;
13673 int numTrimming = 0;
13675 mNumNonHiddenProcs = 0;
13676 mNumHiddenProcs = 0;
13678 // First update the OOM adjustment for each of the
13679 // application processes based on their current state.
13680 int i = mLruProcesses.size();
13681 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13682 int nextHiddenAdj = curHiddenAdj+1;
13683 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13684 int nextEmptyAdj = curEmptyAdj+2;
13685 int curClientHiddenAdj = curEmptyAdj;
13688 ProcessRecord app = mLruProcesses.get(i);
13689 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
13690 updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
13691 if (!app.killedBackground) {
13692 if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13693 // This process was assigned as a hidden process... step the
13696 if (curHiddenAdj != nextHiddenAdj) {
13698 if (stepHidden >= hiddenFactor) {
13700 curHiddenAdj = nextHiddenAdj;
13701 nextHiddenAdj += 2;
13702 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13703 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13705 if (curClientHiddenAdj <= curHiddenAdj) {
13706 curClientHiddenAdj = curHiddenAdj + 1;
13707 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13708 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13714 if (numHidden > hiddenProcessLimit) {
13715 Slog.i(TAG, "No longer want " + app.processName
13716 + " (pid " + app.pid + "): hidden #" + numHidden);
13717 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13718 app.processName, app.setAdj, "too many background");
13719 app.killedBackground = true;
13720 Process.killProcessQuiet(app.pid);
13722 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
13723 // This process has a client that has activities. We will have
13724 // given it the current hidden adj; here we will just leave it
13725 // without stepping the hidden adj.
13726 curClientHiddenAdj++;
13727 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13728 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13731 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13732 // This process was assigned as an empty process... step the
13734 if (curEmptyAdj != nextEmptyAdj) {
13736 if (stepEmpty >= emptyFactor) {
13738 curEmptyAdj = nextEmptyAdj;
13740 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13741 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13745 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13746 mNumNonHiddenProcs++;
13748 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13749 && !app.hasClientActivities) {
13750 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
13751 && app.lastActivityTime < oldTime) {
13752 Slog.i(TAG, "No longer want " + app.processName
13753 + " (pid " + app.pid + "): empty for "
13754 + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
13756 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13757 app.processName, app.setAdj, "old background process");
13758 app.killedBackground = true;
13759 Process.killProcessQuiet(app.pid);
13762 if (numEmpty > emptyProcessLimit) {
13763 Slog.i(TAG, "No longer want " + app.processName
13764 + " (pid " + app.pid + "): empty #" + numEmpty);
13765 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13766 app.processName, app.setAdj, "too many background");
13767 app.killedBackground = true;
13768 Process.killProcessQuiet(app.pid);
13773 if (app.isolated && app.services.size() <= 0) {
13774 // If this is an isolated process, and there are no
13775 // services running in it, then the process is no longer
13776 // needed. We agressively kill these because we can by
13777 // definition not re-use the same process again, and it is
13778 // good to avoid having whatever code was running in them
13779 // left sitting around after no longer needed.
13780 Slog.i(TAG, "Isolated process " + app.processName
13781 + " (pid " + app.pid + ") no longer needed");
13782 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13783 app.processName, app.setAdj, "isolated not needed");
13784 app.killedBackground = true;
13785 Process.killProcessQuiet(app.pid);
13787 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13788 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13789 && !app.killedBackground) {
13795 mNumServiceProcs = mNewNumServiceProcs;
13797 // Now determine the memory trimming level of background processes.
13798 // Unfortunately we need to start at the back of the list to do this
13799 // properly. We only do this if the number of background apps we
13800 // are managing to keep around is less than half the maximum we desire;
13801 // if we are keeping a good number around, we'll let them use whatever
13802 // memory they want.
13803 if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
13804 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
13805 final int numHiddenAndEmpty = numHidden + numEmpty;
13806 final int N = mLruProcesses.size();
13807 int factor = numTrimming/3;
13809 if (mHomeProcess != null) minFactor++;
13810 if (mPreviousProcess != null) minFactor++;
13811 if (factor < minFactor) factor = minFactor;
13814 if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
13815 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
13816 } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
13817 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13819 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13821 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
13822 for (i=0; i<N; i++) {
13823 ProcessRecord app = mLruProcesses.get(i);
13824 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13825 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13826 && !app.killedBackground) {
13827 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13829 app.thread.scheduleTrimMemory(curLevel);
13830 } catch (RemoteException e) {
13833 // For now we won't do this; our memory trimming seems
13834 // to be good enough at this point that destroying
13835 // activities causes more harm than good.
13836 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13837 && app != mHomeProcess && app != mPreviousProcess) {
13838 // Need to do this on its own message because the stack may not
13839 // be in a consistent state at this point.
13840 // For these apps we will also finish their activities
13841 // to help them free memory.
13842 mMainStack.scheduleDestroyActivities(app, false, "trim");
13846 app.trimMemoryLevel = curLevel;
13848 if (step >= factor) {
13850 switch (curLevel) {
13851 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13852 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
13854 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13855 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13859 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13860 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
13861 && app.thread != null) {
13863 app.thread.scheduleTrimMemory(
13864 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
13865 } catch (RemoteException e) {
13868 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
13870 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13871 && app.pendingUiClean) {
13872 // If this application is now in the background and it
13873 // had done UI, then give it the special trim level to
13874 // have it free UI resources.
13875 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13876 if (app.trimMemoryLevel < level && app.thread != null) {
13878 app.thread.scheduleTrimMemory(level);
13879 } catch (RemoteException e) {
13882 app.pendingUiClean = false;
13884 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
13886 app.thread.scheduleTrimMemory(fgTrimLevel);
13887 } catch (RemoteException e) {
13890 app.trimMemoryLevel = fgTrimLevel;
13894 final int N = mLruProcesses.size();
13895 for (i=0; i<N; i++) {
13896 ProcessRecord app = mLruProcesses.get(i);
13897 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
13898 && app.pendingUiClean) {
13899 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13900 && app.thread != null) {
13902 app.thread.scheduleTrimMemory(
13903 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13904 } catch (RemoteException e) {
13907 app.pendingUiClean = false;
13909 app.trimMemoryLevel = 0;
13913 if (mAlwaysFinishActivities) {
13914 // Need to do this on its own message because the stack may not
13915 // be in a consistent state at this point.
13916 mMainStack.scheduleDestroyActivities(null, false, "always-finish");
13920 final void trimApplications() {
13921 synchronized (this) {
13924 // First remove any unused application processes whose package
13925 // has been removed.
13926 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13927 final ProcessRecord app = mRemovedProcesses.get(i);
13928 if (app.activities.size() == 0
13929 && app.curReceiver == null && app.services.size() == 0) {
13931 TAG, "Exiting empty application process "
13932 + app.processName + " ("
13933 + (app.thread != null ? app.thread.asBinder() : null)
13935 if (app.pid > 0 && app.pid != MY_PID) {
13936 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13937 app.processName, app.setAdj, "empty");
13938 Process.killProcessQuiet(app.pid);
13941 app.thread.scheduleExit();
13942 } catch (Exception e) {
13943 // Ignore exceptions.
13946 cleanUpApplicationRecordLocked(app, false, true, -1);
13947 mRemovedProcesses.remove(i);
13949 if (app.persistent) {
13950 if (app.persistent) {
13951 addAppLocked(app.info, false);
13957 // Now update the oom adj for all processes.
13958 updateOomAdjLocked();
13962 /** This method sends the specified signal to each of the persistent apps */
13963 public void signalPersistentProcesses(int sig) throws RemoteException {
13964 if (sig != Process.SIGNAL_USR1) {
13965 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13968 synchronized (this) {
13969 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13970 != PackageManager.PERMISSION_GRANTED) {
13971 throw new SecurityException("Requires permission "
13972 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13975 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13976 ProcessRecord r = mLruProcesses.get(i);
13977 if (r.thread != null && r.persistent) {
13978 Process.sendSignal(r.pid, sig);
13984 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13985 if (proc == null || proc == mProfileProc) {
13986 proc = mProfileProc;
13987 path = mProfileFile;
13988 profileType = mProfileType;
13989 clearProfilerLocked();
13991 if (proc == null) {
13995 proc.thread.profilerControl(false, path, null, profileType);
13996 } catch (RemoteException e) {
13997 throw new IllegalStateException("Process disappeared");
14001 private void clearProfilerLocked() {
14002 if (mProfileFd != null) {
14004 mProfileFd.close();
14005 } catch (IOException e) {
14008 mProfileApp = null;
14009 mProfileProc = null;
14010 mProfileFile = null;
14012 mAutoStopProfiler = false;
14015 public boolean profileControl(String process, int userId, boolean start,
14016 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
14019 synchronized (this) {
14020 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14021 // its own permission.
14022 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14023 != PackageManager.PERMISSION_GRANTED) {
14024 throw new SecurityException("Requires permission "
14025 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14028 if (start && fd == null) {
14029 throw new IllegalArgumentException("null fd");
14032 ProcessRecord proc = null;
14033 if (process != null) {
14034 proc = findProcessLocked(process, userId, "profileControl");
14037 if (start && (proc == null || proc.thread == null)) {
14038 throw new IllegalArgumentException("Unknown process: " + process);
14042 stopProfilerLocked(null, null, 0);
14043 setProfileApp(proc.info, proc.processName, path, fd, false);
14044 mProfileProc = proc;
14045 mProfileType = profileType;
14048 } catch (IOException e) {
14051 proc.thread.profilerControl(start, path, fd, profileType);
14055 stopProfilerLocked(proc, path, profileType);
14059 } catch (IOException e) {
14066 } catch (RemoteException e) {
14067 throw new IllegalStateException("Process disappeared");
14072 } catch (IOException e) {
14078 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
14079 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14080 userId, true, true, callName, null);
14081 ProcessRecord proc = null;
14083 int pid = Integer.parseInt(process);
14084 synchronized (mPidsSelfLocked) {
14085 proc = mPidsSelfLocked.get(pid);
14087 } catch (NumberFormatException e) {
14090 if (proc == null) {
14091 HashMap<String, SparseArray<ProcessRecord>> all
14092 = mProcessNames.getMap();
14093 SparseArray<ProcessRecord> procs = all.get(process);
14094 if (procs != null && procs.size() > 0) {
14095 proc = procs.valueAt(0);
14096 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
14097 for (int i=1; i<procs.size(); i++) {
14098 ProcessRecord thisProc = procs.valueAt(i);
14099 if (thisProc.userId == userId) {
14111 public boolean dumpHeap(String process, int userId, boolean managed,
14112 String path, ParcelFileDescriptor fd) throws RemoteException {
14115 synchronized (this) {
14116 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14117 // its own permission (same as profileControl).
14118 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14119 != PackageManager.PERMISSION_GRANTED) {
14120 throw new SecurityException("Requires permission "
14121 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14125 throw new IllegalArgumentException("null fd");
14128 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
14129 if (proc == null || proc.thread == null) {
14130 throw new IllegalArgumentException("Unknown process: " + process);
14133 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14134 if (!isDebuggable) {
14135 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14136 throw new SecurityException("Process not debuggable: " + proc);
14140 proc.thread.dumpHeap(managed, path, fd);
14144 } catch (RemoteException e) {
14145 throw new IllegalStateException("Process disappeared");
14150 } catch (IOException e) {
14156 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14157 public void monitor() {
14158 synchronized (this) { }
14161 void onCoreSettingsChange(Bundle settings) {
14162 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14163 ProcessRecord processRecord = mLruProcesses.get(i);
14165 if (processRecord.thread != null) {
14166 processRecord.thread.setCoreSettings(settings);
14168 } catch (RemoteException re) {
14174 // Multi-user methods
14177 public boolean switchUser(final int userId) {
14178 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14179 != PackageManager.PERMISSION_GRANTED) {
14180 String msg = "Permission Denial: switchUser() from pid="
14181 + Binder.getCallingPid()
14182 + ", uid=" + Binder.getCallingUid()
14183 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14185 throw new SecurityException(msg);
14188 final long ident = Binder.clearCallingIdentity();
14190 synchronized (this) {
14191 final int oldUserId = mCurrentUserId;
14192 if (oldUserId == userId) {
14196 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14197 if (userInfo == null) {
14198 Slog.w(TAG, "No user info for user #" + userId);
14202 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14203 R.anim.screen_user_enter);
14205 boolean needStart = false;
14207 // If the user we are switching to is not currently started, then
14208 // we need to start it now.
14209 if (mStartedUsers.get(userId) == null) {
14210 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
14211 updateStartedUserArrayLocked();
14215 mCurrentUserId = userId;
14216 mCurrentUserArray = new int[] { userId };
14217 final Integer userIdInt = Integer.valueOf(userId);
14218 mUserLru.remove(userIdInt);
14219 mUserLru.add(userIdInt);
14221 mWindowManager.setCurrentUser(userId);
14223 // Once the internal notion of the active user has switched, we lock the device
14224 // with the option to show the user switcher on the keyguard.
14225 mWindowManager.lockNow(null);
14227 final UserStartedState uss = mStartedUsers.get(userId);
14229 // Make sure user is in the started state. If it is currently
14230 // stopping, we need to knock that off.
14231 if (uss.mState == UserStartedState.STATE_STOPPING) {
14232 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
14233 // so we can just fairly silently bring the user back from
14234 // the almost-dead.
14235 uss.mState = UserStartedState.STATE_RUNNING;
14236 updateStartedUserArrayLocked();
14238 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
14239 // This means ACTION_SHUTDOWN has been sent, so we will
14240 // need to treat this as a new boot of the user.
14241 uss.mState = UserStartedState.STATE_BOOTING;
14242 updateStartedUserArrayLocked();
14246 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14247 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14248 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14249 oldUserId, userId, uss));
14250 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14251 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
14253 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14254 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14255 | Intent.FLAG_RECEIVER_FOREGROUND);
14256 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14257 broadcastIntentLocked(null, null, intent,
14258 null, null, 0, null, null, null,
14259 false, false, MY_PID, Process.SYSTEM_UID, userId);
14262 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14264 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
14265 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14266 broadcastIntentLocked(null, null, intent, null,
14267 new IIntentReceiver.Stub() {
14268 public void performReceive(Intent intent, int resultCode,
14269 String data, Bundle extras, boolean ordered,
14270 boolean sticky, int sendingUser) {
14271 userInitialized(uss, userId);
14273 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14275 uss.initializing = true;
14277 getUserManagerLocked().makeInitialized(userInfo.id);
14281 boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14282 if (!haveActivities) {
14283 startHomeActivityLocked(userId);
14286 EventLogTags.writeAmSwitchUser(userId);
14287 getUserManagerLocked().userForeground(userId);
14288 sendUserSwitchBroadcastsLocked(oldUserId, userId);
14290 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
14291 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14292 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14293 broadcastIntentLocked(null, null, intent,
14294 null, new IIntentReceiver.Stub() {
14296 public void performReceive(Intent intent, int resultCode, String data,
14297 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14298 throws RemoteException {
14301 android.Manifest.permission.INTERACT_ACROSS_USERS,
14302 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14306 Binder.restoreCallingIdentity(ident);
14312 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14313 long ident = Binder.clearCallingIdentity();
14316 if (oldUserId >= 0) {
14317 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
14318 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14319 | Intent.FLAG_RECEIVER_FOREGROUND);
14320 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14321 broadcastIntentLocked(null, null, intent,
14322 null, null, 0, null, null, null,
14323 false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14325 if (newUserId >= 0) {
14326 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
14327 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14328 | Intent.FLAG_RECEIVER_FOREGROUND);
14329 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14330 broadcastIntentLocked(null, null, intent,
14331 null, null, 0, null, null, null,
14332 false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14333 intent = new Intent(Intent.ACTION_USER_SWITCHED);
14334 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14335 | Intent.FLAG_RECEIVER_FOREGROUND);
14336 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14337 broadcastIntentLocked(null, null, intent,
14338 null, null, 0, null, null,
14339 android.Manifest.permission.MANAGE_USERS,
14340 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14343 Binder.restoreCallingIdentity(ident);
14347 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14348 final int newUserId) {
14349 final int N = mUserSwitchObservers.beginBroadcast();
14351 final IRemoteCallback callback = new IRemoteCallback.Stub() {
14354 public void sendResult(Bundle data) throws RemoteException {
14355 synchronized (ActivityManagerService.this) {
14356 if (mCurUserSwitchCallback == this) {
14359 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14365 synchronized (this) {
14366 uss.switching = true;
14367 mCurUserSwitchCallback = callback;
14369 for (int i=0; i<N; i++) {
14371 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14372 newUserId, callback);
14373 } catch (RemoteException e) {
14377 synchronized (this) {
14378 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14381 mUserSwitchObservers.finishBroadcast();
14384 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14385 synchronized (this) {
14386 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14387 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14391 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14392 mCurUserSwitchCallback = null;
14393 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14394 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14395 oldUserId, newUserId, uss));
14398 void userInitialized(UserStartedState uss, int newUserId) {
14399 completeSwitchAndInitalize(uss, newUserId, true, false);
14402 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14403 completeSwitchAndInitalize(uss, newUserId, false, true);
14406 void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
14407 boolean clearInitializing, boolean clearSwitching) {
14408 boolean unfrozen = false;
14409 synchronized (this) {
14410 if (clearInitializing) {
14411 uss.initializing = false;
14412 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
14414 if (clearSwitching) {
14415 uss.switching = false;
14417 if (!uss.switching && !uss.initializing) {
14418 mWindowManager.stopFreezingScreen();
14423 final int N = mUserSwitchObservers.beginBroadcast();
14424 for (int i=0; i<N; i++) {
14426 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14427 } catch (RemoteException e) {
14430 mUserSwitchObservers.finishBroadcast();
14434 void finishUserSwitch(UserStartedState uss) {
14435 synchronized (this) {
14436 if (uss.mState == UserStartedState.STATE_BOOTING
14437 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14438 uss.mState = UserStartedState.STATE_RUNNING;
14439 final int userId = uss.mHandle.getIdentifier();
14440 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14441 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14442 broadcastIntentLocked(null, null, intent,
14443 null, null, 0, null, null,
14444 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
14445 false, false, MY_PID, Process.SYSTEM_UID, userId);
14447 int num = mUserLru.size();
14449 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14450 Integer oldUserId = mUserLru.get(i);
14451 UserStartedState oldUss = mStartedUsers.get(oldUserId);
14452 if (oldUss == null) {
14453 // Shouldn't happen, but be sane if it does.
14454 mUserLru.remove(i);
14458 if (oldUss.mState == UserStartedState.STATE_STOPPING
14459 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
14460 // This user is already stopping, doesn't count.
14465 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14466 // Owner and current can't be stopped, but count as running.
14470 // This is a user to be stopped.
14471 stopUserLocked(oldUserId, null);
14479 public int stopUser(final int userId, final IStopUserCallback callback) {
14480 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14481 != PackageManager.PERMISSION_GRANTED) {
14482 String msg = "Permission Denial: switchUser() from pid="
14483 + Binder.getCallingPid()
14484 + ", uid=" + Binder.getCallingUid()
14485 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14487 throw new SecurityException(msg);
14490 throw new IllegalArgumentException("Can't stop primary user " + userId);
14492 synchronized (this) {
14493 return stopUserLocked(userId, callback);
14497 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14498 if (mCurrentUserId == userId) {
14499 return ActivityManager.USER_OP_IS_CURRENT;
14502 final UserStartedState uss = mStartedUsers.get(userId);
14504 // User is not started, nothing to do... but we do need to
14505 // callback if requested.
14506 if (callback != null) {
14507 mHandler.post(new Runnable() {
14509 public void run() {
14511 callback.userStopped(userId);
14512 } catch (RemoteException e) {
14517 return ActivityManager.USER_OP_SUCCESS;
14520 if (callback != null) {
14521 uss.mStopCallbacks.add(callback);
14524 if (uss.mState != UserStartedState.STATE_STOPPING
14525 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14526 uss.mState = UserStartedState.STATE_STOPPING;
14527 updateStartedUserArrayLocked();
14529 long ident = Binder.clearCallingIdentity();
14531 // We are going to broadcast ACTION_USER_STOPPING and then
14532 // once that is done send a final ACTION_SHUTDOWN and then
14534 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
14535 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14536 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14537 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
14538 // This is the result receiver for the final shutdown broadcast.
14539 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
14541 public void performReceive(Intent intent, int resultCode, String data,
14542 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14543 finishUserStop(uss);
14546 // This is the result receiver for the initial stopping broadcast.
14547 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
14549 public void performReceive(Intent intent, int resultCode, String data,
14550 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14552 synchronized (ActivityManagerService.this) {
14553 if (uss.mState != UserStartedState.STATE_STOPPING) {
14554 // Whoops, we are being started back up. Abort, abort!
14557 uss.mState = UserStartedState.STATE_SHUTDOWN;
14559 broadcastIntentLocked(null, null, shutdownIntent,
14560 null, shutdownReceiver, 0, null, null, null,
14561 true, false, MY_PID, Process.SYSTEM_UID, userId);
14564 // Kick things off.
14565 broadcastIntentLocked(null, null, stoppingIntent,
14566 null, stoppingReceiver, 0, null, null,
14567 android.Manifest.permission.INTERACT_ACROSS_USERS,
14568 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14570 Binder.restoreCallingIdentity(ident);
14574 return ActivityManager.USER_OP_SUCCESS;
14577 void finishUserStop(UserStartedState uss) {
14578 final int userId = uss.mHandle.getIdentifier();
14580 ArrayList<IStopUserCallback> callbacks;
14581 synchronized (this) {
14582 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
14583 if (mStartedUsers.get(userId) != uss) {
14585 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
14589 // User can no longer run.
14590 mStartedUsers.remove(userId);
14591 mUserLru.remove(Integer.valueOf(userId));
14592 updateStartedUserArrayLocked();
14594 // Clean up all state and processes associated with the user.
14595 // Kill all the processes for the user.
14596 forceStopUserLocked(userId);
14597 AttributeCache ac = AttributeCache.instance();
14599 ac.removeUser(userId);
14604 for (int i=0; i<callbacks.size(); i++) {
14606 if (stopped) callbacks.get(i).userStopped(userId);
14607 else callbacks.get(i).userStopAborted(userId);
14608 } catch (RemoteException e) {
14614 public UserInfo getCurrentUser() {
14615 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14616 != PackageManager.PERMISSION_GRANTED) && (
14617 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14618 != PackageManager.PERMISSION_GRANTED)) {
14619 String msg = "Permission Denial: getCurrentUser() from pid="
14620 + Binder.getCallingPid()
14621 + ", uid=" + Binder.getCallingUid()
14622 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14624 throw new SecurityException(msg);
14626 synchronized (this) {
14627 return getUserManagerLocked().getUserInfo(mCurrentUserId);
14631 int getCurrentUserIdLocked() {
14632 return mCurrentUserId;
14636 public boolean isUserRunning(int userId, boolean orStopped) {
14637 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14638 != PackageManager.PERMISSION_GRANTED) {
14639 String msg = "Permission Denial: isUserRunning() from pid="
14640 + Binder.getCallingPid()
14641 + ", uid=" + Binder.getCallingUid()
14642 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14644 throw new SecurityException(msg);
14646 synchronized (this) {
14647 return isUserRunningLocked(userId, orStopped);
14651 boolean isUserRunningLocked(int userId, boolean orStopped) {
14652 UserStartedState state = mStartedUsers.get(userId);
14653 if (state == null) {
14659 return state.mState != UserStartedState.STATE_STOPPING
14660 && state.mState != UserStartedState.STATE_SHUTDOWN;
14664 public int[] getRunningUserIds() {
14665 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14666 != PackageManager.PERMISSION_GRANTED) {
14667 String msg = "Permission Denial: isUserRunning() from pid="
14668 + Binder.getCallingPid()
14669 + ", uid=" + Binder.getCallingUid()
14670 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14672 throw new SecurityException(msg);
14674 synchronized (this) {
14675 return mStartedUserArray;
14679 private void updateStartedUserArrayLocked() {
14681 for (int i=0; i<mStartedUsers.size(); i++) {
14682 UserStartedState uss = mStartedUsers.valueAt(i);
14683 // This list does not include stopping users.
14684 if (uss.mState != UserStartedState.STATE_STOPPING
14685 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14689 mStartedUserArray = new int[num];
14691 for (int i=0; i<mStartedUsers.size(); i++) {
14692 UserStartedState uss = mStartedUsers.valueAt(i);
14693 if (uss.mState != UserStartedState.STATE_STOPPING
14694 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14695 mStartedUserArray[num] = mStartedUsers.keyAt(i);
14702 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14703 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14704 != PackageManager.PERMISSION_GRANTED) {
14705 String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14706 + Binder.getCallingPid()
14707 + ", uid=" + Binder.getCallingUid()
14708 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14710 throw new SecurityException(msg);
14713 mUserSwitchObservers.register(observer);
14717 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14718 mUserSwitchObservers.unregister(observer);
14721 private boolean userExists(int userId) {
14725 UserManagerService ums = getUserManagerLocked();
14726 return ums != null ? (ums.getUserInfo(userId) != null) : false;
14729 int[] getUsersLocked() {
14730 UserManagerService ums = getUserManagerLocked();
14731 return ums != null ? ums.getUserIds() : new int[] { 0 };
14734 UserManagerService getUserManagerLocked() {
14735 if (mUserManager == null) {
14736 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14737 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
14739 return mUserManager;
14742 private void checkValidCaller(int uid, int userId) {
14743 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
14745 throw new SecurityException("Caller uid=" + uid
14746 + " is not privileged to communicate with user=" + userId);
14749 private int applyUserId(int uid, int userId) {
14750 return UserHandle.getUid(userId, uid);
14753 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
14754 if (info == null) return null;
14755 ApplicationInfo newInfo = new ApplicationInfo(info);
14756 newInfo.uid = applyUserId(info.uid, userId);
14757 newInfo.dataDir = USER_DATA_DIR + userId + "/"
14758 + info.packageName;
14762 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
14764 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
14768 ActivityInfo info = new ActivityInfo(aInfo);
14769 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);