2 * Copyright (C) 2006-2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.am;
19 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24 import static com.android.internal.util.XmlUtils.readIntAttribute;
25 import static com.android.internal.util.XmlUtils.readLongAttribute;
26 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27 import static com.android.internal.util.XmlUtils.writeIntAttribute;
28 import static com.android.internal.util.XmlUtils.writeLongAttribute;
29 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31 import static org.xmlpull.v1.XmlPullParser.START_TAG;
32 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
34 import android.Manifest;
35 import android.app.AppOpsManager;
36 import android.app.ApplicationThreadNative;
37 import android.app.IActivityContainer;
38 import android.app.IActivityContainerCallback;
39 import android.app.IAppTask;
40 import android.app.ProfilerInfo;
41 import android.app.admin.DevicePolicyManager;
42 import android.app.usage.UsageEvents;
43 import android.app.usage.UsageStatsManagerInternal;
44 import android.appwidget.AppWidgetManager;
45 import android.content.res.Resources;
46 import android.graphics.Bitmap;
47 import android.graphics.Point;
48 import android.graphics.Rect;
49 import android.os.BatteryStats;
50 import android.os.PersistableBundle;
51 import android.os.storage.IMountService;
52 import android.os.storage.StorageManager;
53 import android.service.voice.IVoiceInteractionSession;
54 import android.util.ArrayMap;
55 import android.util.ArraySet;
56 import android.util.SparseIntArray;
58 import android.view.Display;
59 import com.android.internal.R;
60 import com.android.internal.annotations.GuardedBy;
61 import com.android.internal.app.IAppOpsService;
62 import com.android.internal.app.IVoiceInteractor;
63 import com.android.internal.app.ProcessMap;
64 import com.android.internal.app.ProcessStats;
65 import com.android.internal.content.PackageMonitor;
66 import com.android.internal.os.BackgroundThread;
67 import com.android.internal.os.BatteryStatsImpl;
68 import com.android.internal.os.ProcessCpuTracker;
69 import com.android.internal.os.TransferPipe;
70 import com.android.internal.os.Zygote;
71 import com.android.internal.util.FastPrintWriter;
72 import com.android.internal.util.FastXmlSerializer;
73 import com.android.internal.util.MemInfoReader;
74 import com.android.internal.util.Preconditions;
75 import com.android.server.AppOpsService;
76 import com.android.server.AttributeCache;
77 import com.android.server.IntentResolver;
78 import com.android.server.LocalServices;
79 import com.android.server.ServiceThread;
80 import com.android.server.SystemService;
81 import com.android.server.SystemServiceManager;
82 import com.android.server.Watchdog;
83 import com.android.server.am.ActivityStack.ActivityState;
84 import com.android.server.firewall.IntentFirewall;
85 import com.android.server.pm.UserManagerService;
86 import com.android.server.wm.AppTransition;
87 import com.android.server.wm.WindowManagerService;
88 import com.google.android.collect.Lists;
89 import com.google.android.collect.Maps;
91 import libcore.io.IoUtils;
93 import org.xmlpull.v1.XmlPullParser;
94 import org.xmlpull.v1.XmlPullParserException;
95 import org.xmlpull.v1.XmlSerializer;
97 import android.app.Activity;
98 import android.app.ActivityManager;
99 import android.app.ActivityManager.RunningTaskInfo;
100 import android.app.ActivityManager.StackInfo;
101 import android.app.ActivityManagerInternal;
102 import android.app.ActivityManagerNative;
103 import android.app.ActivityOptions;
104 import android.app.ActivityThread;
105 import android.app.AlertDialog;
106 import android.app.AppGlobals;
107 import android.app.ApplicationErrorReport;
108 import android.app.Dialog;
109 import android.app.IActivityController;
110 import android.app.IApplicationThread;
111 import android.app.IInstrumentationWatcher;
112 import android.app.INotificationManager;
113 import android.app.IProcessObserver;
114 import android.app.IServiceConnection;
115 import android.app.IStopUserCallback;
116 import android.app.IUiAutomationConnection;
117 import android.app.IUserSwitchObserver;
118 import android.app.Instrumentation;
119 import android.app.Notification;
120 import android.app.NotificationManager;
121 import android.app.PendingIntent;
122 import android.app.backup.IBackupManager;
123 import android.content.ActivityNotFoundException;
124 import android.content.BroadcastReceiver;
125 import android.content.ClipData;
126 import android.content.ComponentCallbacks2;
127 import android.content.ComponentName;
128 import android.content.ContentProvider;
129 import android.content.ContentResolver;
130 import android.content.Context;
131 import android.content.DialogInterface;
132 import android.content.IContentProvider;
133 import android.content.IIntentReceiver;
134 import android.content.IIntentSender;
135 import android.content.Intent;
136 import android.content.IntentFilter;
137 import android.content.IntentSender;
138 import android.content.pm.ActivityInfo;
139 import android.content.pm.ApplicationInfo;
140 import android.content.pm.ConfigurationInfo;
141 import android.content.pm.IPackageDataObserver;
142 import android.content.pm.IPackageManager;
143 import android.content.pm.InstrumentationInfo;
144 import android.content.pm.PackageInfo;
145 import android.content.pm.PackageManager;
146 import android.content.pm.ParceledListSlice;
147 import android.content.pm.UserInfo;
148 import android.content.pm.PackageManager.NameNotFoundException;
149 import android.content.pm.PathPermission;
150 import android.content.pm.ProviderInfo;
151 import android.content.pm.ResolveInfo;
152 import android.content.pm.ServiceInfo;
153 import android.content.res.CompatibilityInfo;
154 import android.content.res.Configuration;
155 import android.net.Proxy;
156 import android.net.ProxyInfo;
157 import android.net.Uri;
158 import android.os.Binder;
159 import android.os.Build;
160 import android.os.Bundle;
161 import android.os.Debug;
162 import android.os.DropBoxManager;
163 import android.os.Environment;
164 import android.os.FactoryTest;
165 import android.os.FileObserver;
166 import android.os.FileUtils;
167 import android.os.Handler;
168 import android.os.IBinder;
169 import android.os.IPermissionController;
170 import android.os.IRemoteCallback;
171 import android.os.IUserManager;
172 import android.os.Looper;
173 import android.os.Message;
174 import android.os.Parcel;
175 import android.os.ParcelFileDescriptor;
176 import android.os.PowerManagerInternal;
177 import android.os.Process;
178 import android.os.RemoteCallbackList;
179 import android.os.RemoteException;
180 import android.os.SELinux;
181 import android.os.ServiceManager;
182 import android.os.StrictMode;
183 import android.os.SystemClock;
184 import android.os.SystemProperties;
185 import android.os.UpdateLock;
186 import android.os.UserHandle;
187 import android.os.UserManager;
188 import android.provider.Settings;
189 import android.text.format.DateUtils;
190 import android.text.format.Time;
191 import android.util.AtomicFile;
192 import android.util.EventLog;
193 import android.util.Log;
194 import android.util.Pair;
195 import android.util.PrintWriterPrinter;
196 import android.util.Slog;
197 import android.util.SparseArray;
198 import android.util.TimeUtils;
199 import android.util.Xml;
200 import android.view.Gravity;
201 import android.view.LayoutInflater;
202 import android.view.View;
203 import android.view.WindowManager;
204 import dalvik.system.VMRuntime;
206 import java.io.BufferedInputStream;
207 import java.io.BufferedOutputStream;
208 import java.io.DataInputStream;
209 import java.io.DataOutputStream;
211 import java.io.FileDescriptor;
212 import java.io.FileInputStream;
213 import java.io.FileNotFoundException;
214 import java.io.FileOutputStream;
215 import java.io.IOException;
216 import java.io.InputStreamReader;
217 import java.io.PrintWriter;
218 import java.io.StringWriter;
219 import java.lang.ref.WeakReference;
220 import java.util.ArrayList;
221 import java.util.Arrays;
222 import java.util.Collections;
223 import java.util.Comparator;
224 import java.util.HashMap;
225 import java.util.HashSet;
226 import java.util.Iterator;
227 import java.util.List;
228 import java.util.Locale;
229 import java.util.Map;
230 import java.util.Set;
231 import java.util.concurrent.atomic.AtomicBoolean;
232 import java.util.concurrent.atomic.AtomicLong;
234 public final class ActivityManagerService extends ActivityManagerNative
235 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
237 private static final String USER_DATA_DIR = "/data/user/";
238 // File that stores last updated system version and called preboot receivers
239 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
241 static final String TAG = "ActivityManager";
242 static final String TAG_MU = "ActivityManagerServiceMU";
243 static final boolean DEBUG = false;
244 static final boolean localLOGV = DEBUG;
245 static final boolean DEBUG_BACKUP = localLOGV || false;
246 static final boolean DEBUG_BROADCAST = localLOGV || false;
247 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
248 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
249 static final boolean DEBUG_CLEANUP = localLOGV || false;
250 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
251 static final boolean DEBUG_FOCUS = false;
252 static final boolean DEBUG_IMMERSIVE = localLOGV || false;
253 static final boolean DEBUG_MU = localLOGV || false;
254 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
255 static final boolean DEBUG_LRU = localLOGV || false;
256 static final boolean DEBUG_PAUSE = localLOGV || false;
257 static final boolean DEBUG_POWER = localLOGV || false;
258 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
259 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
260 static final boolean DEBUG_PROCESSES = localLOGV || false;
261 static final boolean DEBUG_PROVIDER = localLOGV || false;
262 static final boolean DEBUG_RESULTS = localLOGV || false;
263 static final boolean DEBUG_SERVICE = localLOGV || false;
264 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
265 static final boolean DEBUG_STACK = localLOGV || false;
266 static final boolean DEBUG_SWITCH = localLOGV || false;
267 static final boolean DEBUG_TASKS = localLOGV || false;
268 static final boolean DEBUG_THUMBNAILS = localLOGV || false;
269 static final boolean DEBUG_TRANSITION = localLOGV || false;
270 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
271 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
272 static final boolean DEBUG_VISBILITY = localLOGV || false;
273 static final boolean DEBUG_PSS = localLOGV || false;
274 static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
275 static final boolean DEBUG_RECENTS = localLOGV || false;
276 static final boolean VALIDATE_TOKENS = false;
277 static final boolean SHOW_ACTIVITY_START_TIME = true;
279 // Control over CPU and battery monitoring.
280 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
281 static final boolean MONITOR_CPU_USAGE = true;
282 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
283 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
284 static final boolean MONITOR_THREAD_CPU_USAGE = false;
286 // The flags that are set for all calls we make to the package manager.
287 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
289 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
291 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
293 // Maximum number recent bitmaps to keep in memory.
294 static final int MAX_RECENT_BITMAPS = 5;
296 // Amount of time after a call to stopAppSwitches() during which we will
297 // prevent further untrusted switches from happening.
298 static final long APP_SWITCH_DELAY_TIME = 5*1000;
300 // How long we wait for a launched process to attach to the activity manager
301 // before we decide it's never going to come up for real.
302 static final int PROC_START_TIMEOUT = 10*1000;
304 // How long we wait for a launched process to attach to the activity manager
305 // before we decide it's never going to come up for real, when the process was
306 // started with a wrapper for instrumentation (such as Valgrind) because it
307 // could take much longer than usual.
308 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
310 // How long to wait after going idle before forcing apps to GC.
311 static final int GC_TIMEOUT = 5*1000;
313 // The minimum amount of time between successive GC requests for a process.
314 static final int GC_MIN_INTERVAL = 60*1000;
316 // The minimum amount of time between successive PSS requests for a process.
317 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
319 // The minimum amount of time between successive PSS requests for a process
320 // when the request is due to the memory state being lowered.
321 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
323 // The rate at which we check for apps using excessive power -- 15 mins.
324 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
326 // The minimum sample duration we will allow before deciding we have
327 // enough data on wake locks to start killing things.
328 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
330 // The minimum sample duration we will allow before deciding we have
331 // enough data on CPU usage to start killing things.
332 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
334 // How long we allow a receiver to run before giving up on it.
335 static final int BROADCAST_FG_TIMEOUT = 10*1000;
336 static final int BROADCAST_BG_TIMEOUT = 60*1000;
338 // How long we wait until we timeout on key dispatching.
339 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
341 // How long we wait until we timeout on key dispatching during instrumentation.
342 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
344 // Amount of time we wait for observers to handle a user switch before
345 // giving up on them and unfreezing the screen.
346 static final int USER_SWITCH_TIMEOUT = 2*1000;
348 // Maximum number of users we allow to be running at a time.
349 static final int MAX_RUNNING_USERS = 3;
351 // How long to wait in getAssistContextExtras for the activity and foreground services
352 // to respond with the result.
353 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
355 // Maximum number of persisted Uri grants a package is allowed
356 static final int MAX_PERSISTED_URI_GRANTS = 128;
358 static final int MY_PID = Process.myPid();
360 static final String[] EMPTY_STRING_ARRAY = new String[0];
362 // How many bytes to write into the dropbox log before truncating
363 static final int DROPBOX_MAX_SIZE = 256 * 1024;
365 // Access modes for handleIncomingUser.
366 static final int ALLOW_NON_FULL = 0;
367 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
368 static final int ALLOW_FULL_ONLY = 2;
370 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
372 /** All system services */
373 SystemServiceManager mSystemServiceManager;
375 /** Run all ActivityStacks through this */
376 ActivityStackSupervisor mStackSupervisor;
378 public IntentFirewall mIntentFirewall;
380 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
381 // default actuion automatically. Important for devices without direct input
383 private boolean mShowDialogs = true;
385 BroadcastQueue mFgBroadcastQueue;
386 BroadcastQueue mBgBroadcastQueue;
387 // Convenient for easy iteration over the queues. Foreground is first
388 // so that dispatch of foreground broadcasts gets precedence.
389 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
391 BroadcastQueue broadcastQueueForIntent(Intent intent) {
392 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
393 if (DEBUG_BACKGROUND_BROADCAST) {
394 Slog.i(TAG, "Broadcast intent " + intent + " on "
395 + (isFg ? "foreground" : "background")
398 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
401 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
402 for (BroadcastQueue queue : mBroadcastQueues) {
403 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
412 * Activity we have told the window manager to have key focus.
414 ActivityRecord mFocusedActivity = null;
417 * List of intents that were used to start the most recent tasks.
419 ArrayList<TaskRecord> mRecentTasks;
420 ArrayList<TaskRecord> mTmpRecents = new ArrayList<TaskRecord>();
423 * For addAppTask: cached of the last activity component that was added.
425 ComponentName mLastAddedTaskComponent;
428 * For addAppTask: cached of the last activity uid that was added.
430 int mLastAddedTaskUid;
433 * For addAppTask: cached of the last ActivityInfo that was added.
435 ActivityInfo mLastAddedTaskActivity;
437 public class PendingAssistExtras extends Binder implements Runnable {
438 public final ActivityRecord activity;
439 public final Bundle extras;
440 public final Intent intent;
441 public final String hint;
442 public final int userHandle;
443 public boolean haveResult = false;
444 public Bundle result = null;
445 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
446 String _hint, int _userHandle) {
447 activity = _activity;
451 userHandle = _userHandle;
455 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
456 synchronized (this) {
463 final ArrayList<PendingAssistExtras> mPendingAssistExtras
464 = new ArrayList<PendingAssistExtras>();
467 * Process management.
469 final ProcessList mProcessList = new ProcessList();
472 * All of the applications we currently have running organized by name.
473 * The keys are strings of the application package name (as
474 * returned by the package manager), and the keys are ApplicationRecord
477 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
480 * Tracking long-term execution of processes to look for abuse and other
483 final ProcessStatsService mProcessStats;
486 * The currently running isolated processes.
488 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
491 * Counter for assigning isolated process uids, to avoid frequently reusing the
494 int mNextIsolatedProcessUid = 0;
497 * The currently running heavy-weight process, if any.
499 ProcessRecord mHeavyWeightProcess = null;
502 * The last time that various processes have crashed.
504 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
507 * Information about a process that is currently marked as bad.
509 static final class BadProcessInfo {
510 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
512 this.shortMsg = shortMsg;
513 this.longMsg = longMsg;
518 final String shortMsg;
519 final String longMsg;
524 * Set of applications that we consider to be bad, and will reject
525 * incoming broadcasts from (which the user has no control over).
526 * Processes are added to this set when they have crashed twice within
527 * a minimum amount of time; they are removed from it when they are
528 * later restarted (hopefully due to some user action). The value is the
529 * time it was added to the list.
531 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
534 * All of the processes we currently have running organized by pid.
535 * The keys are the pid running the application.
537 * <p>NOTE: This object is protected by its own lock, NOT the global
538 * activity manager lock!
540 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
543 * All of the processes that have been forced to be foreground. The key
544 * is the pid of the caller who requested it (we hold a death
547 abstract class ForegroundToken implements IBinder.DeathRecipient {
551 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
554 * List of records for processes that someone had tried to start before the
555 * system was ready. We don't start them at that point, but ensure they
556 * are started by the time booting is complete.
558 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
561 * List of persistent applications that are in the process
564 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
567 * Processes that are being forcibly torn down.
569 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
572 * List of running applications, sorted by recent usage.
573 * The first entry in the list is the least recently used.
575 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
578 * Where in mLruProcesses that the processes hosting activities start.
580 int mLruProcessActivityStart = 0;
583 * Where in mLruProcesses that the processes hosting services start.
584 * This is after (lower index) than mLruProcessesActivityStart.
586 int mLruProcessServiceStart = 0;
589 * List of processes that should gc as soon as things are idle.
591 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
594 * Processes we want to collect PSS data from.
596 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
599 * Last time we requested PSS data of all processes.
601 long mLastFullPssTime = SystemClock.uptimeMillis();
604 * If set, the next time we collect PSS data we should do a full collection
605 * with data from native processes and the kernel.
607 boolean mFullPssPending = false;
610 * This is the process holding what we currently consider to be
611 * the "home" activity.
613 ProcessRecord mHomeProcess;
616 * This is the process holding the activity the user last visited that
617 * is in a different process from the one they are currently in.
619 ProcessRecord mPreviousProcess;
622 * The time at which the previous process was last visible.
624 long mPreviousProcessVisibleTime;
627 * Which uses have been started, so are allowed to run code.
629 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
632 * LRU list of history of current users. Most recently current is at the end.
634 final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
637 * Constant array of the users that are currently started.
639 int[] mStartedUserArray = new int[] { 0 };
642 * Registered observers of the user switching mechanics.
644 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
645 = new RemoteCallbackList<IUserSwitchObserver>();
648 * Currently active user switch.
650 Object mCurUserSwitchCallback;
653 * Packages that the user has asked to have run in screen size
654 * compatibility mode instead of filling the screen.
656 final CompatModePackages mCompatModePackages;
659 * Set of IntentSenderRecord objects that are currently active.
661 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
662 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
665 * Fingerprints (hashCode()) of stack traces that we've
666 * already logged DropBox entries for. Guarded by itself. If
667 * something (rogue user app) forces this over
668 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
670 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
671 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
674 * Strict Mode background batched logging state.
676 * The string buffer is guarded by itself, and its lock is also
677 * used to determine if another batched write is already
680 private final StringBuilder mStrictModeBuffer = new StringBuilder();
683 * Keeps track of all IIntentReceivers that have been registered for
684 * broadcasts. Hash keys are the receiver IBinder, hash value is
687 final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
688 new HashMap<IBinder, ReceiverList>();
691 * Resolver for broadcast intents to registered receivers.
692 * Holds BroadcastFilter (subclass of IntentFilter).
694 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
695 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
697 protected boolean allowFilterResult(
698 BroadcastFilter filter, List<BroadcastFilter> dest) {
699 IBinder target = filter.receiverList.receiver.asBinder();
700 for (int i=dest.size()-1; i>=0; i--) {
701 if (dest.get(i).receiverList.receiver.asBinder() == target) {
709 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
710 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
711 || userId == filter.owningUserId) {
712 return super.newResult(filter, match, userId);
718 protected BroadcastFilter[] newArray(int size) {
719 return new BroadcastFilter[size];
723 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
724 return packageName.equals(filter.packageName);
729 * State of all active sticky broadcasts per user. Keys are the action of the
730 * sticky Intent, values are an ArrayList of all broadcasted intents with
731 * that action (which should usually be one). The SparseArray is keyed
732 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
733 * for stickies that are sent to all users.
735 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
736 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
738 final ActiveServices mServices;
741 * Backup/restore process management
743 String mBackupAppName = null;
744 BackupRecord mBackupTarget = null;
746 final ProviderMap mProviderMap;
749 * List of content providers who have clients waiting for them. The
750 * application is currently being launched and the provider will be
751 * removed from this list once it is published.
753 final ArrayList<ContentProviderRecord> mLaunchingProviders
754 = new ArrayList<ContentProviderRecord>();
757 * File storing persisted {@link #mGrantedUriPermissions}.
759 private final AtomicFile mGrantFile;
761 /** XML constants used in {@link #mGrantFile} */
762 private static final String TAG_URI_GRANTS = "uri-grants";
763 private static final String TAG_URI_GRANT = "uri-grant";
764 private static final String ATTR_USER_HANDLE = "userHandle";
765 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
766 private static final String ATTR_TARGET_USER_ID = "targetUserId";
767 private static final String ATTR_SOURCE_PKG = "sourcePkg";
768 private static final String ATTR_TARGET_PKG = "targetPkg";
769 private static final String ATTR_URI = "uri";
770 private static final String ATTR_MODE_FLAGS = "modeFlags";
771 private static final String ATTR_CREATED_TIME = "createdTime";
772 private static final String ATTR_PREFIX = "prefix";
775 * Global set of specific {@link Uri} permissions that have been granted.
776 * This optimized lookup structure maps from {@link UriPermission#targetUid}
777 * to {@link UriPermission#uri} to {@link UriPermission}.
780 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
781 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
783 public static class GrantUri {
784 public final int sourceUserId;
785 public final Uri uri;
786 public boolean prefix;
788 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
789 this.sourceUserId = sourceUserId;
791 this.prefix = prefix;
795 public int hashCode() {
796 return toString().hashCode();
800 public boolean equals(Object o) {
801 if (o instanceof GrantUri) {
802 GrantUri other = (GrantUri) o;
803 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
804 && prefix == other.prefix;
810 public String toString() {
811 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
812 if (prefix) result += " [prefix]";
816 public String toSafeString() {
817 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
818 if (prefix) result += " [prefix]";
822 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
823 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
824 ContentProvider.getUriWithoutUserId(uri), false);
828 CoreSettingsObserver mCoreSettingsObserver;
831 * Thread-local storage used to carry caller permissions over through
832 * indirect content-provider access.
834 private class Identity {
838 Identity(int _pid, int _uid) {
844 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
847 * All information we have collected about the runtime performance of
848 * any user id that can impact battery performance.
850 final BatteryStatsService mBatteryStatsService;
853 * Information about component usage
855 UsageStatsManagerInternal mUsageStatsService;
858 * Information about and control over application operations
860 final AppOpsService mAppOpsService;
863 * Save recent tasks information across reboots.
865 final TaskPersister mTaskPersister;
868 * Current configuration information. HistoryRecord objects are given
869 * a reference to this object to indicate which configuration they are
870 * currently running in, so this object must be kept immutable.
872 Configuration mConfiguration = new Configuration();
875 * Current sequencing integer of the configuration, for skipping old
878 int mConfigurationSeq = 0;
881 * Hardware-reported OpenGLES version.
883 final int GL_ES_VERSION;
886 * List of initialization arguments to pass to all processes when binding applications to them.
887 * For example, references to the commonly used services.
889 HashMap<String, IBinder> mAppBindArgs;
892 * Temporary to avoid allocations. Protected by main lock.
894 final StringBuilder mStringBuilder = new StringBuilder(256);
897 * Used to control how we initialize the service.
899 ComponentName mTopComponent;
900 String mTopAction = Intent.ACTION_MAIN;
902 boolean mProcessesReady = false;
903 boolean mSystemReady = false;
904 boolean mBooting = false;
905 boolean mCallFinishBooting = false;
906 boolean mBootAnimationComplete = false;
907 boolean mWaitingUpdate = false;
908 boolean mDidUpdate = false;
909 boolean mOnBattery = false;
910 boolean mLaunchWarningShown = false;
916 boolean mCheckedForSetup;
919 * The time at which we will allow normal application switches again,
920 * after a call to {@link #stopAppSwitches()}.
922 long mAppSwitchesAllowedTime;
925 * This is set to true after the first switch after mAppSwitchesAllowedTime
926 * is set; any switches after that will clear the time.
928 boolean mDidAppSwitch;
931 * Last time (in realtime) at which we checked for power usage.
933 long mLastPowerCheckRealtime;
936 * Last time (in uptime) at which we checked for power usage.
938 long mLastPowerCheckUptime;
941 * Set while we are wanting to sleep, to prevent any
942 * activities from being started/resumed.
944 private boolean mSleeping = false;
947 * Set while we are running a voice interaction. This overrides
948 * sleeping while it is active.
950 private boolean mRunningVoice = false;
953 * State of external calls telling us if the device is awake or asleep.
955 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
958 * State of external call telling us if the lock screen is shown.
960 private boolean mLockScreenShown = false;
963 * Set if we are shutting down the system, similar to sleeping.
965 boolean mShuttingDown = false;
968 * Current sequence id for oom_adj computation traversal.
973 * Current sequence id for process LRU updating.
978 * Keep track of the non-cached/empty process we last found, to help
979 * determine how to distribute cached/empty processes next time.
981 int mNumNonCachedProcs = 0;
984 * Keep track of the number of cached hidden procs, to balance oom adj
985 * distribution between those and empty procs.
987 int mNumCachedHiddenProcs = 0;
990 * Keep track of the number of service processes we last found, to
991 * determine on the next iteration which should be B services.
993 int mNumServiceProcs = 0;
994 int mNewNumAServiceProcs = 0;
995 int mNewNumServiceProcs = 0;
998 * Allow the current computed overall memory level of the system to go down?
999 * This is set to false when we are killing processes for reasons other than
1000 * memory management, so that the now smaller process list will not be taken as
1001 * an indication that memory is tighter.
1003 boolean mAllowLowerMemLevel = false;
1006 * The last computed memory level, for holding when we are in a state that
1007 * processes are going away for other reasons.
1009 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1012 * The last total number of process we have, to determine if changes actually look
1013 * like a shrinking number of process due to lower RAM.
1015 int mLastNumProcesses;
1018 * The uptime of the last time we performed idle maintenance.
1020 long mLastIdleTime = SystemClock.uptimeMillis();
1023 * Total time spent with RAM that has been added in the past since the last idle time.
1025 long mLowRamTimeSinceLastIdle = 0;
1028 * If RAM is currently low, when that horrible situation started.
1030 long mLowRamStartTime = 0;
1033 * For reporting to battery stats the current top application.
1035 private String mCurResumedPackage = null;
1036 private int mCurResumedUid = -1;
1039 * For reporting to battery stats the apps currently running foreground
1040 * service. The ProcessMap is package/uid tuples; each of these contain
1041 * an array of the currently foreground processes.
1043 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1044 = new ProcessMap<ArrayList<ProcessRecord>>();
1047 * This is set if we had to do a delayed dexopt of an app before launching
1048 * it, to increase the ANR timeouts in that case.
1053 * Set if the systemServer made a call to enterSafeMode.
1057 String mDebugApp = null;
1058 boolean mWaitForDebugger = false;
1059 boolean mDebugTransient = false;
1060 String mOrigDebugApp = null;
1061 boolean mOrigWaitForDebugger = false;
1062 boolean mAlwaysFinishActivities = false;
1063 IActivityController mController = null;
1064 String mProfileApp = null;
1065 ProcessRecord mProfileProc = null;
1066 String mProfileFile;
1067 ParcelFileDescriptor mProfileFd;
1068 int mSamplingInterval = 0;
1069 boolean mAutoStopProfiler = false;
1070 int mProfileType = 0;
1071 String mOpenGlTraceApp = null;
1073 static class ProcessChangeItem {
1074 static final int CHANGE_ACTIVITIES = 1<<0;
1075 static final int CHANGE_PROCESS_STATE = 1<<1;
1080 boolean foregroundActivities;
1083 final RemoteCallbackList<IProcessObserver> mProcessObservers
1084 = new RemoteCallbackList<IProcessObserver>();
1085 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1087 final ArrayList<ProcessChangeItem> mPendingProcessChanges
1088 = new ArrayList<ProcessChangeItem>();
1089 final ArrayList<ProcessChangeItem> mAvailProcessChanges
1090 = new ArrayList<ProcessChangeItem>();
1093 * Runtime CPU use collection thread. This object's lock is used to
1094 * perform synchronization with the thread (notifying it to run).
1096 final Thread mProcessCpuThread;
1099 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1100 * Must acquire this object's lock when accessing it.
1101 * NOTE: this lock will be held while doing long operations (trawling
1102 * through all processes in /proc), so it should never be acquired by
1103 * any critical paths such as when holding the main activity manager lock.
1105 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1106 MONITOR_THREAD_CPU_USAGE);
1107 final AtomicLong mLastCpuTime = new AtomicLong(0);
1108 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1110 long mLastWriteTime = 0;
1113 * Used to retain an update lock when the foreground activity is in
1116 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1119 * Set to true after the system has finished booting.
1121 boolean mBooted = false;
1123 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1124 int mProcessLimitOverride = -1;
1126 WindowManagerService mWindowManager;
1128 final ActivityThread mSystemThread;
1130 // Holds the current foreground user's id
1131 int mCurrentUserId = 0;
1132 // Holds the target user's id during a user switch
1133 int mTargetUserId = UserHandle.USER_NULL;
1134 // If there are multiple profiles for the current user, their ids are here
1135 // Currently only the primary user can have managed profiles
1136 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1139 * Mapping from each known user ID to the profile group ID it is associated with.
1141 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1143 private UserManagerService mUserManager;
1145 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1146 final ProcessRecord mApp;
1148 final IApplicationThread mAppThread;
1150 AppDeathRecipient(ProcessRecord app, int pid,
1151 IApplicationThread thread) {
1152 if (localLOGV) Slog.v(
1153 TAG, "New death recipient " + this
1154 + " for thread " + thread.asBinder());
1157 mAppThread = thread;
1161 public void binderDied() {
1162 if (localLOGV) Slog.v(
1163 TAG, "Death received in " + this
1164 + " for thread " + mAppThread.asBinder());
1165 synchronized(ActivityManagerService.this) {
1166 appDiedLocked(mApp, mPid, mAppThread);
1171 static final int SHOW_ERROR_MSG = 1;
1172 static final int SHOW_NOT_RESPONDING_MSG = 2;
1173 static final int SHOW_FACTORY_ERROR_MSG = 3;
1174 static final int UPDATE_CONFIGURATION_MSG = 4;
1175 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1176 static final int WAIT_FOR_DEBUGGER_MSG = 6;
1177 static final int SERVICE_TIMEOUT_MSG = 12;
1178 static final int UPDATE_TIME_ZONE = 13;
1179 static final int SHOW_UID_ERROR_MSG = 14;
1180 static final int IM_FEELING_LUCKY_MSG = 15;
1181 static final int PROC_START_TIMEOUT_MSG = 20;
1182 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1183 static final int KILL_APPLICATION_MSG = 22;
1184 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1185 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1186 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1187 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1188 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1189 static final int CLEAR_DNS_CACHE_MSG = 28;
1190 static final int UPDATE_HTTP_PROXY_MSG = 29;
1191 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1192 static final int DISPATCH_PROCESSES_CHANGED = 31;
1193 static final int DISPATCH_PROCESS_DIED = 32;
1194 static final int REPORT_MEM_USAGE_MSG = 33;
1195 static final int REPORT_USER_SWITCH_MSG = 34;
1196 static final int CONTINUE_USER_SWITCH_MSG = 35;
1197 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1198 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1199 static final int PERSIST_URI_GRANTS_MSG = 38;
1200 static final int REQUEST_ALL_PSS_MSG = 39;
1201 static final int START_PROFILES_MSG = 40;
1202 static final int UPDATE_TIME = 41;
1203 static final int SYSTEM_USER_START_MSG = 42;
1204 static final int SYSTEM_USER_CURRENT_MSG = 43;
1205 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1206 static final int FINISH_BOOTING_MSG = 45;
1207 static final int START_USER_SWITCH_MSG = 46;
1208 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1210 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1211 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1212 static final int FIRST_COMPAT_MODE_MSG = 300;
1213 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1215 AlertDialog mUidAlert;
1216 CompatModeDialog mCompatModeDialog;
1217 long mLastMemUsageReportTime = 0;
1219 private LockToAppRequestDialog mLockToAppRequest;
1222 * Flag whether the current user is a "monkey", i.e. whether
1223 * the UI is driven by a UI automation tool.
1225 private boolean mUserIsMonkey;
1227 /** Flag whether the device has a Recents UI */
1228 boolean mHasRecents;
1230 /** The dimensions of the thumbnails in the Recents UI. */
1231 int mThumbnailWidth;
1232 int mThumbnailHeight;
1234 final ServiceThread mHandlerThread;
1235 final MainHandler mHandler;
1237 final class MainHandler extends Handler {
1238 public MainHandler(Looper looper) {
1239 super(looper, null, true);
1243 public void handleMessage(Message msg) {
1245 case SHOW_ERROR_MSG: {
1246 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1247 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1248 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1249 synchronized (ActivityManagerService.this) {
1250 ProcessRecord proc = (ProcessRecord)data.get("app");
1251 AppErrorResult res = (AppErrorResult) data.get("result");
1252 if (proc != null && proc.crashDialog != null) {
1253 Slog.e(TAG, "App already has crash dialog: " + proc);
1259 boolean isBackground = (UserHandle.getAppId(proc.uid)
1260 >= Process.FIRST_APPLICATION_UID
1261 && proc.pid != MY_PID);
1262 for (int userId : mCurrentProfileIds) {
1263 isBackground &= (proc.userId != userId);
1265 if (isBackground && !showBackground) {
1266 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1272 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1273 Dialog d = new AppErrorDialog(mContext,
1274 ActivityManagerService.this, res, proc);
1276 proc.crashDialog = d;
1278 // The device is asleep, so just pretend that the user
1279 // saw a crash dialog and hit "force quit".
1286 ensureBootCompleted();
1288 case SHOW_NOT_RESPONDING_MSG: {
1289 synchronized (ActivityManagerService.this) {
1290 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1291 ProcessRecord proc = (ProcessRecord)data.get("app");
1292 if (proc != null && proc.anrDialog != null) {
1293 Slog.e(TAG, "App already has anr dialog: " + proc);
1297 Intent intent = new Intent("android.intent.action.ANR");
1298 if (!mProcessesReady) {
1299 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1300 | Intent.FLAG_RECEIVER_FOREGROUND);
1302 broadcastIntentLocked(null, null, intent,
1303 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1304 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1307 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1308 mContext, proc, (ActivityRecord)data.get("activity"),
1313 // Just kill the app if there is no dialog to be shown.
1314 killAppAtUsersRequest(proc, null);
1318 ensureBootCompleted();
1320 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1321 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1322 synchronized (ActivityManagerService.this) {
1323 ProcessRecord proc = (ProcessRecord) data.get("app");
1325 Slog.e(TAG, "App not found when showing strict mode dialog.");
1328 if (proc.crashDialog != null) {
1329 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1332 AppErrorResult res = (AppErrorResult) data.get("result");
1333 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1334 Dialog d = new StrictModeViolationDialog(mContext,
1335 ActivityManagerService.this, res, proc);
1337 proc.crashDialog = d;
1339 // The device is asleep, so just pretend that the user
1340 // saw a crash dialog and hit "force quit".
1344 ensureBootCompleted();
1346 case SHOW_FACTORY_ERROR_MSG: {
1347 Dialog d = new FactoryErrorDialog(
1348 mContext, msg.getData().getCharSequence("msg"));
1350 ensureBootCompleted();
1352 case UPDATE_CONFIGURATION_MSG: {
1353 final ContentResolver resolver = mContext.getContentResolver();
1354 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1356 case GC_BACKGROUND_PROCESSES_MSG: {
1357 synchronized (ActivityManagerService.this) {
1358 performAppGcsIfAppropriateLocked();
1361 case WAIT_FOR_DEBUGGER_MSG: {
1362 synchronized (ActivityManagerService.this) {
1363 ProcessRecord app = (ProcessRecord)msg.obj;
1364 if (msg.arg1 != 0) {
1365 if (!app.waitedForDebugger) {
1366 Dialog d = new AppWaitingForDebuggerDialog(
1367 ActivityManagerService.this,
1370 app.waitedForDebugger = true;
1374 if (app.waitDialog != null) {
1375 app.waitDialog.dismiss();
1376 app.waitDialog = null;
1381 case SERVICE_TIMEOUT_MSG: {
1384 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1386 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1389 mServices.serviceTimeout((ProcessRecord)msg.obj);
1391 case UPDATE_TIME_ZONE: {
1392 synchronized (ActivityManagerService.this) {
1393 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1394 ProcessRecord r = mLruProcesses.get(i);
1395 if (r.thread != null) {
1397 r.thread.updateTimeZone();
1398 } catch (RemoteException ex) {
1399 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1405 case CLEAR_DNS_CACHE_MSG: {
1406 synchronized (ActivityManagerService.this) {
1407 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1408 ProcessRecord r = mLruProcesses.get(i);
1409 if (r.thread != null) {
1411 r.thread.clearDnsCache();
1412 } catch (RemoteException ex) {
1413 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1419 case UPDATE_HTTP_PROXY_MSG: {
1420 ProxyInfo proxy = (ProxyInfo)msg.obj;
1423 String exclList = "";
1424 Uri pacFileUrl = Uri.EMPTY;
1425 if (proxy != null) {
1426 host = proxy.getHost();
1427 port = Integer.toString(proxy.getPort());
1428 exclList = proxy.getExclusionListAsString();
1429 pacFileUrl = proxy.getPacFileUrl();
1431 synchronized (ActivityManagerService.this) {
1432 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1433 ProcessRecord r = mLruProcesses.get(i);
1434 if (r.thread != null) {
1436 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1437 } catch (RemoteException ex) {
1438 Slog.w(TAG, "Failed to update http proxy for: " +
1439 r.info.processName);
1445 case SHOW_UID_ERROR_MSG: {
1446 String title = "System UIDs Inconsistent";
1447 String text = "UIDs on the system are inconsistent, you need to wipe your"
1448 + " data partition or your device will be unstable.";
1449 Log.e(TAG, title + ": " + text);
1451 // XXX This is a temporary dialog, no need to localize.
1452 AlertDialog d = new BaseErrorDialog(mContext);
1453 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1454 d.setCancelable(false);
1457 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1458 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1463 case IM_FEELING_LUCKY_MSG: {
1464 if (mUidAlert != null) {
1465 mUidAlert.dismiss();
1469 case PROC_START_TIMEOUT_MSG: {
1472 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1474 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1477 ProcessRecord app = (ProcessRecord)msg.obj;
1478 synchronized (ActivityManagerService.this) {
1479 processStartTimedOutLocked(app);
1482 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1483 synchronized (ActivityManagerService.this) {
1484 mStackSupervisor.doPendingActivityLaunchesLocked(true);
1487 case KILL_APPLICATION_MSG: {
1488 synchronized (ActivityManagerService.this) {
1489 int appid = msg.arg1;
1490 boolean restart = (msg.arg2 == 1);
1491 Bundle bundle = (Bundle)msg.obj;
1492 String pkg = bundle.getString("pkg");
1493 String reason = bundle.getString("reason");
1494 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1495 false, UserHandle.USER_ALL, reason);
1498 case FINALIZE_PENDING_INTENT_MSG: {
1499 ((PendingIntentRecord)msg.obj).completeFinalize();
1501 case POST_HEAVY_NOTIFICATION_MSG: {
1502 INotificationManager inm = NotificationManager.getService();
1507 ActivityRecord root = (ActivityRecord)msg.obj;
1508 ProcessRecord process = root.app;
1509 if (process == null) {
1514 Context context = mContext.createPackageContext(process.info.packageName, 0);
1515 String text = mContext.getString(R.string.heavy_weight_notification,
1516 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1517 Notification notification = new Notification();
1518 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1519 notification.when = 0;
1520 notification.flags = Notification.FLAG_ONGOING_EVENT;
1521 notification.tickerText = text;
1522 notification.defaults = 0; // please be quiet
1523 notification.sound = null;
1524 notification.vibrate = null;
1525 notification.color = mContext.getResources().getColor(
1526 com.android.internal.R.color.system_notification_accent_color);
1527 notification.setLatestEventInfo(context, text,
1528 mContext.getText(R.string.heavy_weight_notification_detail),
1529 PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1530 PendingIntent.FLAG_CANCEL_CURRENT, null,
1531 new UserHandle(root.userId)));
1534 int[] outId = new int[1];
1535 inm.enqueueNotificationWithTag("android", "android", null,
1536 R.string.heavy_weight_notification,
1537 notification, outId, root.userId);
1538 } catch (RuntimeException e) {
1539 Slog.w(ActivityManagerService.TAG,
1540 "Error showing notification for heavy-weight app", e);
1541 } catch (RemoteException e) {
1543 } catch (NameNotFoundException e) {
1544 Slog.w(TAG, "Unable to create context for heavy notification", e);
1547 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1548 INotificationManager inm = NotificationManager.getService();
1553 inm.cancelNotificationWithTag("android", null,
1554 R.string.heavy_weight_notification, msg.arg1);
1555 } catch (RuntimeException e) {
1556 Slog.w(ActivityManagerService.TAG,
1557 "Error canceling notification for service", e);
1558 } catch (RemoteException e) {
1561 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1562 synchronized (ActivityManagerService.this) {
1563 checkExcessivePowerUsageLocked(true);
1564 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1565 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1566 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1569 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1570 synchronized (ActivityManagerService.this) {
1571 ActivityRecord ar = (ActivityRecord)msg.obj;
1572 if (mCompatModeDialog != null) {
1573 if (mCompatModeDialog.mAppInfo.packageName.equals(
1574 ar.info.applicationInfo.packageName)) {
1577 mCompatModeDialog.dismiss();
1578 mCompatModeDialog = null;
1580 if (ar != null && false) {
1581 if (mCompatModePackages.getPackageAskCompatModeLocked(
1583 int mode = mCompatModePackages.computeCompatModeLocked(
1584 ar.info.applicationInfo);
1585 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1586 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1587 mCompatModeDialog = new CompatModeDialog(
1588 ActivityManagerService.this, mContext,
1589 ar.info.applicationInfo);
1590 mCompatModeDialog.show();
1597 case DISPATCH_PROCESSES_CHANGED: {
1598 dispatchProcessesChanged();
1601 case DISPATCH_PROCESS_DIED: {
1602 final int pid = msg.arg1;
1603 final int uid = msg.arg2;
1604 dispatchProcessDied(pid, uid);
1607 case REPORT_MEM_USAGE_MSG: {
1608 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1609 Thread thread = new Thread() {
1610 @Override public void run() {
1611 final SparseArray<ProcessMemInfo> infoMap
1612 = new SparseArray<ProcessMemInfo>(memInfos.size());
1613 for (int i=0, N=memInfos.size(); i<N; i++) {
1614 ProcessMemInfo mi = memInfos.get(i);
1615 infoMap.put(mi.pid, mi);
1617 updateCpuStatsNow();
1618 synchronized (mProcessCpuTracker) {
1619 final int N = mProcessCpuTracker.countStats();
1620 for (int i=0; i<N; i++) {
1621 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1623 long pss = Debug.getPss(st.pid, null);
1625 if (infoMap.indexOfKey(st.pid) < 0) {
1626 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1627 ProcessList.NATIVE_ADJ, -1, "native", null);
1637 for (int i=0, N=memInfos.size(); i<N; i++) {
1638 ProcessMemInfo mi = memInfos.get(i);
1640 mi.pss = Debug.getPss(mi.pid, null);
1644 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1645 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1646 if (lhs.oomAdj != rhs.oomAdj) {
1647 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1649 if (lhs.pss != rhs.pss) {
1650 return lhs.pss < rhs.pss ? 1 : -1;
1656 StringBuilder tag = new StringBuilder(128);
1657 StringBuilder stack = new StringBuilder(128);
1658 tag.append("Low on memory -- ");
1659 appendMemBucket(tag, totalPss, "total", false);
1660 appendMemBucket(stack, totalPss, "total", true);
1662 StringBuilder logBuilder = new StringBuilder(1024);
1663 logBuilder.append("Low on memory:\n");
1665 boolean firstLine = true;
1666 int lastOomAdj = Integer.MIN_VALUE;
1667 for (int i=0, N=memInfos.size(); i<N; i++) {
1668 ProcessMemInfo mi = memInfos.get(i);
1670 if (mi.oomAdj != ProcessList.NATIVE_ADJ
1671 && (mi.oomAdj < ProcessList.SERVICE_ADJ
1672 || mi.oomAdj == ProcessList.HOME_APP_ADJ
1673 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1674 if (lastOomAdj != mi.oomAdj) {
1675 lastOomAdj = mi.oomAdj;
1676 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1679 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1684 stack.append("\n\t at ");
1692 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1693 appendMemBucket(tag, mi.pss, mi.name, false);
1695 appendMemBucket(stack, mi.pss, mi.name, true);
1696 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1697 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1699 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1700 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1701 stack.append(DUMP_MEM_OOM_LABEL[k]);
1703 stack.append(DUMP_MEM_OOM_ADJ[k]);
1710 logBuilder.append(" ");
1711 logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1712 logBuilder.append(' ');
1713 logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1714 logBuilder.append(' ');
1715 ProcessList.appendRamKb(logBuilder, mi.pss);
1716 logBuilder.append(" kB: ");
1717 logBuilder.append(mi.name);
1718 logBuilder.append(" (");
1719 logBuilder.append(mi.pid);
1720 logBuilder.append(") ");
1721 logBuilder.append(mi.adjType);
1722 logBuilder.append('\n');
1723 if (mi.adjReason != null) {
1724 logBuilder.append(" ");
1725 logBuilder.append(mi.adjReason);
1726 logBuilder.append('\n');
1730 logBuilder.append(" ");
1731 ProcessList.appendRamKb(logBuilder, totalPss);
1732 logBuilder.append(" kB: TOTAL\n");
1734 long[] infos = new long[Debug.MEMINFO_COUNT];
1735 Debug.getMemInfo(infos);
1736 logBuilder.append(" MemInfo: ");
1737 logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1738 logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1739 logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1740 logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1741 logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1742 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1743 logBuilder.append(" ZRAM: ");
1744 logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1745 logBuilder.append(" kB RAM, ");
1746 logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1747 logBuilder.append(" kB swap total, ");
1748 logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1749 logBuilder.append(" kB swap free\n");
1751 Slog.i(TAG, logBuilder.toString());
1753 StringBuilder dropBuilder = new StringBuilder(1024);
1755 StringWriter oomSw = new StringWriter();
1756 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1757 StringWriter catSw = new StringWriter();
1758 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1759 String[] emptyArgs = new String[] { };
1760 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
1762 String oomString = oomSw.toString();
1764 dropBuilder.append(stack);
1765 dropBuilder.append('\n');
1766 dropBuilder.append('\n');
1767 dropBuilder.append(logBuilder);
1768 dropBuilder.append('\n');
1770 dropBuilder.append(oomString);
1771 dropBuilder.append('\n');
1773 StringWriter catSw = new StringWriter();
1774 synchronized (ActivityManagerService.this) {
1775 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1776 String[] emptyArgs = new String[] { };
1778 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1780 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1781 false, false, null);
1783 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1786 dropBuilder.append(catSw.toString());
1787 addErrorToDropBox("lowmem", null, "system_server", null,
1788 null, tag.toString(), dropBuilder.toString(), null, null);
1789 //Slog.i(TAG, "Sent to dropbox:");
1790 //Slog.i(TAG, dropBuilder.toString());
1791 synchronized (ActivityManagerService.this) {
1792 long now = SystemClock.uptimeMillis();
1793 if (mLastMemUsageReportTime < now) {
1794 mLastMemUsageReportTime = now;
1802 case START_USER_SWITCH_MSG: {
1803 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1806 case REPORT_USER_SWITCH_MSG: {
1807 dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1810 case CONTINUE_USER_SWITCH_MSG: {
1811 continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1814 case USER_SWITCH_TIMEOUT_MSG: {
1815 timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1818 case IMMERSIVE_MODE_LOCK_MSG: {
1819 final boolean nextState = (msg.arg1 != 0);
1820 if (mUpdateLock.isHeld() != nextState) {
1821 if (DEBUG_IMMERSIVE) {
1822 final ActivityRecord r = (ActivityRecord) msg.obj;
1823 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1826 mUpdateLock.acquire();
1828 mUpdateLock.release();
1833 case PERSIST_URI_GRANTS_MSG: {
1834 writeGrantedUriPermissions();
1837 case REQUEST_ALL_PSS_MSG: {
1838 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1841 case START_PROFILES_MSG: {
1842 synchronized (ActivityManagerService.this) {
1843 startProfilesLocked();
1848 synchronized (ActivityManagerService.this) {
1849 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1850 ProcessRecord r = mLruProcesses.get(i);
1851 if (r.thread != null) {
1853 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1854 } catch (RemoteException ex) {
1855 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1862 case SYSTEM_USER_START_MSG: {
1863 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1864 Integer.toString(msg.arg1), msg.arg1);
1865 mSystemServiceManager.startUser(msg.arg1);
1868 case SYSTEM_USER_CURRENT_MSG: {
1869 mBatteryStatsService.noteEvent(
1870 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1871 Integer.toString(msg.arg2), msg.arg2);
1872 mBatteryStatsService.noteEvent(
1873 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1874 Integer.toString(msg.arg1), msg.arg1);
1875 mSystemServiceManager.switchUser(msg.arg1);
1876 mLockToAppRequest.clearPrompt();
1879 case ENTER_ANIMATION_COMPLETE_MSG: {
1880 synchronized (ActivityManagerService.this) {
1881 ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1882 if (r != null && r.app != null && r.app.thread != null) {
1884 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1885 } catch (RemoteException e) {
1891 case FINISH_BOOTING_MSG: {
1892 if (msg.arg1 != 0) {
1895 if (msg.arg2 != 0) {
1896 enableScreenAfterBoot();
1900 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1902 Locale l = (Locale) msg.obj;
1903 IBinder service = ServiceManager.getService("mount");
1904 IMountService mountService = IMountService.Stub.asInterface(service);
1905 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1906 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1907 } catch (RemoteException e) {
1908 Log.e(TAG, "Error storing locale for decryption UI", e);
1916 static final int COLLECT_PSS_BG_MSG = 1;
1918 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1920 public void handleMessage(Message msg) {
1922 case COLLECT_PSS_BG_MSG: {
1923 long start = SystemClock.uptimeMillis();
1924 MemInfoReader memInfo = null;
1925 synchronized (ActivityManagerService.this) {
1926 if (mFullPssPending) {
1927 mFullPssPending = false;
1928 memInfo = new MemInfoReader();
1931 if (memInfo != null) {
1932 updateCpuStatsNow();
1933 long nativeTotalPss = 0;
1934 synchronized (mProcessCpuTracker) {
1935 final int N = mProcessCpuTracker.countStats();
1936 for (int j=0; j<N; j++) {
1937 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1938 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1939 // This is definitely an application process; skip it.
1942 synchronized (mPidsSelfLocked) {
1943 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1944 // This is one of our own processes; skip it.
1948 nativeTotalPss += Debug.getPss(st.pid, null);
1951 memInfo.readMemInfo();
1952 synchronized (ActivityManagerService.this) {
1953 if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1954 + (SystemClock.uptimeMillis()-start) + "ms");
1955 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1956 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1957 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1958 +memInfo.getSlabSizeKb(),
1964 long[] tmp = new long[1];
1969 synchronized (ActivityManagerService.this) {
1970 if (i >= mPendingPssProcesses.size()) {
1971 if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1972 + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1973 mPendingPssProcesses.clear();
1976 proc = mPendingPssProcesses.get(i);
1977 procState = proc.pssProcState;
1978 if (proc.thread != null && procState == proc.setProcState) {
1987 long pss = Debug.getPss(pid, tmp);
1988 synchronized (ActivityManagerService.this) {
1989 if (proc.thread != null && proc.setProcState == procState
1990 && proc.pid == pid) {
1992 proc.lastPssTime = SystemClock.uptimeMillis();
1993 proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1994 if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1995 + ": " + pss + " lastPss=" + proc.lastPss
1996 + " state=" + ProcessList.makeProcStateString(procState));
1997 if (proc.initialIdlePss == 0) {
1998 proc.initialIdlePss = pss;
2001 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
2002 proc.lastCachedPss = pss;
2014 * Monitor for package changes and update our internal state.
2016 private final PackageMonitor mPackageMonitor = new PackageMonitor() {
2018 public void onPackageRemoved(String packageName, int uid) {
2019 // Remove all tasks with activities in the specified package from the list of recent tasks
2020 final int eventUserId = getChangingUserId();
2021 synchronized (ActivityManagerService.this) {
2022 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2023 TaskRecord tr = mRecentTasks.get(i);
2024 if (tr.userId != eventUserId) continue;
2026 ComponentName cn = tr.intent.getComponent();
2027 if (cn != null && cn.getPackageName().equals(packageName)) {
2028 // If the package name matches, remove the task and kill the process
2029 removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
2036 public boolean onPackageChanged(String packageName, int uid, String[] components) {
2037 onPackageModified(packageName);
2042 public void onPackageModified(String packageName) {
2043 final int eventUserId = getChangingUserId();
2044 final IPackageManager pm = AppGlobals.getPackageManager();
2045 final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
2046 new ArrayList<Pair<Intent, Integer>>();
2047 final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
2048 final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2049 // Copy the list of recent tasks so that we don't hold onto the lock on
2050 // ActivityManagerService for long periods while checking if components exist.
2051 synchronized (ActivityManagerService.this) {
2052 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2053 TaskRecord tr = mRecentTasks.get(i);
2054 if (tr.userId != eventUserId) continue;
2056 recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2059 // Check the recent tasks and filter out all tasks with components that no longer exist.
2060 for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2061 Pair<Intent, Integer> p = recentTaskIntents.get(i);
2062 ComponentName cn = p.first.getComponent();
2063 if (cn != null && cn.getPackageName().equals(packageName)) {
2064 if (componentsKnownToExist.contains(cn)) {
2065 // If we know that the component still exists in the package, then skip
2069 ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
2071 componentsKnownToExist.add(cn);
2073 tasksToRemove.add(p.second);
2075 } catch (RemoteException e) {
2076 Log.e(TAG, "Failed to query activity info for component: " + cn, e);
2080 // Prune all the tasks with removed components from the list of recent tasks
2081 synchronized (ActivityManagerService.this) {
2082 for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2083 // Remove the task but don't kill the process (since other components in that
2084 // package may still be running and in the background)
2085 removeTaskByIdLocked(tasksToRemove.get(i), 0);
2091 public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2092 // Force stop the specified packages
2093 int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
2094 if (packages != null) {
2095 for (String pkg : packages) {
2096 synchronized (ActivityManagerService.this) {
2097 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
2098 userId, "finished booting")) {
2108 public void setSystemProcess() {
2110 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2111 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2112 ServiceManager.addService("meminfo", new MemBinder(this));
2113 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2114 ServiceManager.addService("dbinfo", new DbBinder(this));
2115 if (MONITOR_CPU_USAGE) {
2116 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2118 ServiceManager.addService("permission", new PermissionController(this));
2120 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2121 "android", STOCK_PM_FLAGS);
2122 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2124 synchronized (this) {
2125 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2126 app.persistent = true;
2128 app.maxAdj = ProcessList.SYSTEM_ADJ;
2129 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2130 mProcessNames.put(app.processName, app.uid, app);
2131 synchronized (mPidsSelfLocked) {
2132 mPidsSelfLocked.put(app.pid, app);
2134 updateLruProcessLocked(app, false, null);
2135 updateOomAdjLocked();
2137 } catch (PackageManager.NameNotFoundException e) {
2138 throw new RuntimeException(
2139 "Unable to find android system package", e);
2143 public void setWindowManager(WindowManagerService wm) {
2144 mWindowManager = wm;
2145 mStackSupervisor.setWindowManager(wm);
2148 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2149 mUsageStatsService = usageStatsManager;
2152 public void startObservingNativeCrashes() {
2153 final NativeCrashListener ncl = new NativeCrashListener(this);
2157 public IAppOpsService getAppOpsService() {
2158 return mAppOpsService;
2161 static class MemBinder extends Binder {
2162 ActivityManagerService mActivityManagerService;
2163 MemBinder(ActivityManagerService activityManagerService) {
2164 mActivityManagerService = activityManagerService;
2168 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2169 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2170 != PackageManager.PERMISSION_GRANTED) {
2171 pw.println("Permission Denial: can't dump meminfo from from pid="
2172 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2173 + " without permission " + android.Manifest.permission.DUMP);
2177 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2181 static class GraphicsBinder extends Binder {
2182 ActivityManagerService mActivityManagerService;
2183 GraphicsBinder(ActivityManagerService activityManagerService) {
2184 mActivityManagerService = activityManagerService;
2188 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2189 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2190 != PackageManager.PERMISSION_GRANTED) {
2191 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2192 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2193 + " without permission " + android.Manifest.permission.DUMP);
2197 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2201 static class DbBinder extends Binder {
2202 ActivityManagerService mActivityManagerService;
2203 DbBinder(ActivityManagerService activityManagerService) {
2204 mActivityManagerService = activityManagerService;
2208 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2209 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2210 != PackageManager.PERMISSION_GRANTED) {
2211 pw.println("Permission Denial: can't dump dbinfo from from pid="
2212 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2213 + " without permission " + android.Manifest.permission.DUMP);
2217 mActivityManagerService.dumpDbInfo(fd, pw, args);
2221 static class CpuBinder extends Binder {
2222 ActivityManagerService mActivityManagerService;
2223 CpuBinder(ActivityManagerService activityManagerService) {
2224 mActivityManagerService = activityManagerService;
2228 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2229 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2230 != PackageManager.PERMISSION_GRANTED) {
2231 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2232 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2233 + " without permission " + android.Manifest.permission.DUMP);
2237 synchronized (mActivityManagerService.mProcessCpuTracker) {
2238 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2239 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2240 SystemClock.uptimeMillis()));
2245 public static final class Lifecycle extends SystemService {
2246 private final ActivityManagerService mService;
2248 public Lifecycle(Context context) {
2250 mService = new ActivityManagerService(context);
2254 public void onStart() {
2258 public ActivityManagerService getService() {
2263 // Note: This method is invoked on the main thread but may need to attach various
2264 // handlers to other threads. So take care to be explicit about the looper.
2265 public ActivityManagerService(Context systemContext) {
2266 mContext = systemContext;
2267 mFactoryTest = FactoryTest.getMode();
2268 mSystemThread = ActivityThread.currentActivityThread();
2270 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2272 mHandlerThread = new ServiceThread(TAG,
2273 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2274 mHandlerThread.start();
2275 mHandler = new MainHandler(mHandlerThread.getLooper());
2277 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2278 "foreground", BROADCAST_FG_TIMEOUT, false);
2279 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2280 "background", BROADCAST_BG_TIMEOUT, true);
2281 mBroadcastQueues[0] = mFgBroadcastQueue;
2282 mBroadcastQueues[1] = mBgBroadcastQueue;
2284 mServices = new ActiveServices(this);
2285 mProviderMap = new ProviderMap(this);
2287 // TODO: Move creation of battery stats service outside of activity manager service.
2288 File dataDir = Environment.getDataDirectory();
2289 File systemDir = new File(dataDir, "system");
2291 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2292 mBatteryStatsService.getActiveStatistics().readLocked();
2293 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2294 mOnBattery = DEBUG_POWER ? true
2295 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2296 mBatteryStatsService.getActiveStatistics().setCallback(this);
2298 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2300 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2302 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2304 // User 0 is the first and only user that runs at boot.
2305 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2306 mUserLru.add(Integer.valueOf(0));
2307 updateStartedUserArrayLocked();
2309 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2310 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2312 mConfiguration.setToDefaults();
2313 mConfiguration.setLocale(Locale.getDefault());
2315 mConfigurationSeq = mConfiguration.seq = 1;
2316 mProcessCpuTracker.init();
2318 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2319 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2320 mStackSupervisor = new ActivityStackSupervisor(this);
2321 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2323 mProcessCpuThread = new Thread("CpuTracker") {
2329 synchronized(this) {
2330 final long now = SystemClock.uptimeMillis();
2331 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2332 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2333 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2334 // + ", write delay=" + nextWriteDelay);
2335 if (nextWriteDelay < nextCpuDelay) {
2336 nextCpuDelay = nextWriteDelay;
2338 if (nextCpuDelay > 0) {
2339 mProcessCpuMutexFree.set(true);
2340 this.wait(nextCpuDelay);
2343 } catch (InterruptedException e) {
2345 updateCpuStatsNow();
2346 } catch (Exception e) {
2347 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2353 mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2355 Watchdog.getInstance().addMonitor(this);
2356 Watchdog.getInstance().addThread(mHandler);
2359 public void setSystemServiceManager(SystemServiceManager mgr) {
2360 mSystemServiceManager = mgr;
2363 private void start() {
2364 Process.removeAllProcessGroups();
2365 mProcessCpuThread.start();
2367 mBatteryStatsService.publish(mContext);
2368 mAppOpsService.publish(mContext);
2369 Slog.d("AppOps", "AppOpsService published");
2370 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2373 public void initPowerManagement() {
2374 mStackSupervisor.initPowerManagement();
2375 mBatteryStatsService.initPowerManagement();
2379 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2380 throws RemoteException {
2381 if (code == SYSPROPS_TRANSACTION) {
2382 // We need to tell all apps about the system property change.
2383 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2384 synchronized(this) {
2385 final int NP = mProcessNames.getMap().size();
2386 for (int ip=0; ip<NP; ip++) {
2387 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2388 final int NA = apps.size();
2389 for (int ia=0; ia<NA; ia++) {
2390 ProcessRecord app = apps.valueAt(ia);
2391 if (app.thread != null) {
2392 procs.add(app.thread.asBinder());
2398 int N = procs.size();
2399 for (int i=0; i<N; i++) {
2400 Parcel data2 = Parcel.obtain();
2402 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2403 } catch (RemoteException e) {
2409 return super.onTransact(code, data, reply, flags);
2410 } catch (RuntimeException e) {
2411 // The activity manager only throws security exceptions, so let's
2413 if (!(e instanceof SecurityException)) {
2414 Slog.wtf(TAG, "Activity Manager Crash", e);
2420 void updateCpuStats() {
2421 final long now = SystemClock.uptimeMillis();
2422 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2425 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2426 synchronized (mProcessCpuThread) {
2427 mProcessCpuThread.notify();
2432 void updateCpuStatsNow() {
2433 synchronized (mProcessCpuTracker) {
2434 mProcessCpuMutexFree.set(false);
2435 final long now = SystemClock.uptimeMillis();
2436 boolean haveNewCpuStats = false;
2438 if (MONITOR_CPU_USAGE &&
2439 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2440 mLastCpuTime.set(now);
2441 haveNewCpuStats = true;
2442 mProcessCpuTracker.update();
2443 //Slog.i(TAG, mProcessCpu.printCurrentState());
2444 //Slog.i(TAG, "Total CPU usage: "
2445 // + mProcessCpu.getTotalCpuPercent() + "%");
2447 // Slog the cpu usage if the property is set.
2448 if ("true".equals(SystemProperties.get("events.cpu"))) {
2449 int user = mProcessCpuTracker.getLastUserTime();
2450 int system = mProcessCpuTracker.getLastSystemTime();
2451 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2452 int irq = mProcessCpuTracker.getLastIrqTime();
2453 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2454 int idle = mProcessCpuTracker.getLastIdleTime();
2456 int total = user + system + iowait + irq + softIrq + idle;
2457 if (total == 0) total = 1;
2459 EventLog.writeEvent(EventLogTags.CPU,
2460 ((user+system+iowait+irq+softIrq) * 100) / total,
2461 (user * 100) / total,
2462 (system * 100) / total,
2463 (iowait * 100) / total,
2464 (irq * 100) / total,
2465 (softIrq * 100) / total);
2469 long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2470 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2471 synchronized(bstats) {
2472 synchronized(mPidsSelfLocked) {
2473 if (haveNewCpuStats) {
2475 int perc = bstats.startAddingCpuLocked();
2478 final int N = mProcessCpuTracker.countStats();
2479 for (int i=0; i<N; i++) {
2480 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2484 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2485 int otherUTime = (st.rel_utime*perc)/100;
2486 int otherSTime = (st.rel_stime*perc)/100;
2487 totalUTime += otherUTime;
2488 totalSTime += otherSTime;
2490 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2491 if (ps == null || !ps.isActive()) {
2492 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2493 pr.info.uid, pr.processName);
2495 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2496 st.rel_stime-otherSTime);
2497 ps.addSpeedStepTimes(cpuSpeedTimes);
2498 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2500 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2501 if (ps == null || !ps.isActive()) {
2502 st.batteryStats = ps = bstats.getProcessStatsLocked(
2503 bstats.mapUid(st.uid), st.name);
2505 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2506 st.rel_stime-otherSTime);
2507 ps.addSpeedStepTimes(cpuSpeedTimes);
2510 bstats.finishAddingCpuLocked(perc, totalUTime,
2511 totalSTime, cpuSpeedTimes);
2516 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2517 mLastWriteTime = now;
2518 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2525 public void batteryNeedsCpuUpdate() {
2526 updateCpuStatsNow();
2530 public void batteryPowerChanged(boolean onBattery) {
2531 // When plugging in, update the CPU stats first before changing
2533 updateCpuStatsNow();
2534 synchronized (this) {
2535 synchronized(mPidsSelfLocked) {
2536 mOnBattery = DEBUG_POWER ? true : onBattery;
2542 * Initialize the application bind args. These are passed to each
2543 * process when the bindApplication() IPC is sent to the process. They're
2544 * lazily setup to make sure the services are running when they're asked for.
2546 private HashMap<String, IBinder> getCommonServicesLocked() {
2547 if (mAppBindArgs == null) {
2548 mAppBindArgs = new HashMap<String, IBinder>();
2550 // Setup the application init args
2551 mAppBindArgs.put("package", ServiceManager.getService("package"));
2552 mAppBindArgs.put("window", ServiceManager.getService("window"));
2553 mAppBindArgs.put(Context.ALARM_SERVICE,
2554 ServiceManager.getService(Context.ALARM_SERVICE));
2556 return mAppBindArgs;
2559 final void setFocusedActivityLocked(ActivityRecord r) {
2560 if (mFocusedActivity != r) {
2561 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2562 mFocusedActivity = r;
2563 if (r.task != null && r.task.voiceInteractor != null) {
2564 startRunningVoiceLocked();
2566 finishRunningVoiceLocked();
2568 mStackSupervisor.setFocusedStack(r);
2570 mWindowManager.setFocusedApp(r.appToken, true);
2572 applyUpdateLockStateLocked(r);
2576 final void clearFocusedActivity(ActivityRecord r) {
2577 if (mFocusedActivity == r) {
2578 mFocusedActivity = null;
2583 public void setFocusedStack(int stackId) {
2584 if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2585 synchronized (ActivityManagerService.this) {
2586 ActivityStack stack = mStackSupervisor.getStack(stackId);
2587 if (stack != null) {
2588 ActivityRecord r = stack.topRunningActivityLocked(null);
2590 setFocusedActivityLocked(r);
2597 public void notifyActivityDrawn(IBinder token) {
2598 if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2599 synchronized (this) {
2600 ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2602 r.task.stack.notifyActivityDrawnLocked(r);
2607 final void applyUpdateLockStateLocked(ActivityRecord r) {
2608 // Modifications to the UpdateLock state are done on our handler, outside
2609 // the activity manager's locks. The new state is determined based on the
2610 // state *now* of the relevant activity record. The object is passed to
2611 // the handler solely for logging detail, not to be consulted/modified.
2612 final boolean nextState = r != null && r.immersive;
2613 mHandler.sendMessage(
2614 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2617 final void showAskCompatModeDialogLocked(ActivityRecord r) {
2618 Message msg = Message.obtain();
2619 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2620 msg.obj = r.task.askedCompatMode ? null : r;
2621 mHandler.sendMessage(msg);
2624 private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2625 String what, Object obj, ProcessRecord srcApp) {
2626 app.lastActivityTime = now;
2628 if (app.activities.size() > 0) {
2629 // Don't want to touch dependent processes that are hosting activities.
2633 int lrui = mLruProcesses.lastIndexOf(app);
2635 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2636 + what + " " + obj + " from " + srcApp);
2640 if (lrui >= index) {
2641 // Don't want to cause this to move dependent processes *back* in the
2642 // list as if they were less frequently used.
2646 if (lrui >= mLruProcessActivityStart) {
2647 // Don't want to touch dependent processes that are hosting activities.
2651 mLruProcesses.remove(lrui);
2655 if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2656 + " in LRU list: " + app);
2657 mLruProcesses.add(index, app);
2661 final void removeLruProcessLocked(ProcessRecord app) {
2662 int lrui = mLruProcesses.lastIndexOf(app);
2665 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2666 Process.killProcessQuiet(app.pid);
2667 Process.killProcessGroup(app.info.uid, app.pid);
2669 if (lrui <= mLruProcessActivityStart) {
2670 mLruProcessActivityStart--;
2672 if (lrui <= mLruProcessServiceStart) {
2673 mLruProcessServiceStart--;
2675 mLruProcesses.remove(lrui);
2679 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2680 ProcessRecord client) {
2681 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2682 || app.treatLikeActivity;
2683 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2684 if (!activityChange && hasActivity) {
2685 // The process has activities, so we are only allowing activity-based adjustments
2686 // to move it. It should be kept in the front of the list with other
2687 // processes that have activities, and we don't want those to change their
2688 // order except due to activity operations.
2693 final long now = SystemClock.uptimeMillis();
2694 app.lastActivityTime = now;
2696 // First a quick reject: if the app is already at the position we will
2697 // put it, then there is nothing to do.
2699 final int N = mLruProcesses.size();
2700 if (N > 0 && mLruProcesses.get(N-1) == app) {
2701 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2705 if (mLruProcessServiceStart > 0
2706 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2707 if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2712 int lrui = mLruProcesses.lastIndexOf(app);
2714 if (app.persistent && lrui >= 0) {
2715 // We don't care about the position of persistent processes, as long as
2716 // they are in the list.
2717 if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2721 /* In progress: compute new position first, so we can avoid doing work
2722 if the process is not actually going to move. Not yet working.
2725 boolean inActivity = false, inService = false;
2727 // Process has activities, put it at the very tipsy-top.
2728 addIndex = mLruProcesses.size();
2729 nextIndex = mLruProcessServiceStart;
2731 } else if (hasService) {
2732 // Process has services, put it at the top of the service list.
2733 addIndex = mLruProcessActivityStart;
2734 nextIndex = mLruProcessServiceStart;
2738 // Process not otherwise of interest, it goes to the top of the non-service area.
2739 addIndex = mLruProcessServiceStart;
2740 if (client != null) {
2741 int clientIndex = mLruProcesses.lastIndexOf(client);
2742 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2744 if (clientIndex >= 0 && addIndex > clientIndex) {
2745 addIndex = clientIndex;
2748 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2751 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2752 + mLruProcessActivityStart + "): " + app);
2756 if (lrui < mLruProcessActivityStart) {
2757 mLruProcessActivityStart--;
2759 if (lrui < mLruProcessServiceStart) {
2760 mLruProcessServiceStart--;
2763 if (addIndex > lrui) {
2766 if (nextIndex > lrui) {
2770 mLruProcesses.remove(lrui);
2774 mLruProcesses.add(addIndex, app);
2776 mLruProcessActivityStart++;
2779 mLruProcessActivityStart++;
2785 final int N = mLruProcesses.size();
2786 if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2787 // Process doesn't have activities, but has clients with
2788 // activities... move it up, but one below the top (the top
2789 // should always have a real activity).
2790 if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2791 mLruProcesses.add(N-1, app);
2792 // To keep it from spamming the LRU list (by making a bunch of clients),
2793 // we will push down any other entries owned by the app.
2794 final int uid = app.info.uid;
2795 for (int i=N-2; i>mLruProcessActivityStart; i--) {
2796 ProcessRecord subProc = mLruProcesses.get(i);
2797 if (subProc.info.uid == uid) {
2798 // We want to push this one down the list. If the process after
2799 // it is for the same uid, however, don't do so, because we don't
2800 // want them internally to be re-ordered.
2801 if (mLruProcesses.get(i-1).info.uid != uid) {
2802 if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2803 + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2804 ProcessRecord tmp = mLruProcesses.get(i);
2805 mLruProcesses.set(i, mLruProcesses.get(i-1));
2806 mLruProcesses.set(i-1, tmp);
2810 // A gap, we can stop here.
2815 // Process has activities, put it at the very tipsy-top.
2816 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2817 mLruProcesses.add(app);
2819 nextIndex = mLruProcessServiceStart;
2820 } else if (hasService) {
2821 // Process has services, put it at the top of the service list.
2822 if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2823 mLruProcesses.add(mLruProcessActivityStart, app);
2824 nextIndex = mLruProcessServiceStart;
2825 mLruProcessActivityStart++;
2827 // Process not otherwise of interest, it goes to the top of the non-service area.
2828 int index = mLruProcessServiceStart;
2829 if (client != null) {
2830 // If there is a client, don't allow the process to be moved up higher
2831 // in the list than that client.
2832 int clientIndex = mLruProcesses.lastIndexOf(client);
2833 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2834 + " when updating " + app);
2835 if (clientIndex <= lrui) {
2836 // Don't allow the client index restriction to push it down farther in the
2837 // list than it already is.
2840 if (clientIndex >= 0 && index > clientIndex) {
2841 index = clientIndex;
2844 if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2845 mLruProcesses.add(index, app);
2846 nextIndex = index-1;
2847 mLruProcessActivityStart++;
2848 mLruProcessServiceStart++;
2851 // If the app is currently using a content provider or service,
2852 // bump those processes as well.
2853 for (int j=app.connections.size()-1; j>=0; j--) {
2854 ConnectionRecord cr = app.connections.valueAt(j);
2855 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2856 && cr.binding.service.app != null
2857 && cr.binding.service.app.lruSeq != mLruSeq
2858 && !cr.binding.service.app.persistent) {
2859 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2860 "service connection", cr, app);
2863 for (int j=app.conProviders.size()-1; j>=0; j--) {
2864 ContentProviderRecord cpr = app.conProviders.get(j).provider;
2865 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2866 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2867 "provider reference", cpr, app);
2872 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2873 if (uid == Process.SYSTEM_UID) {
2874 // The system gets to run in any process. If there are multiple
2875 // processes with the same uid, just pick the first (this
2876 // should never happen).
2877 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2878 if (procs == null) return null;
2879 final int procCount = procs.size();
2880 for (int i = 0; i < procCount; i++) {
2881 final int procUid = procs.keyAt(i);
2882 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
2883 // Don't use an app process or different user process for system component.
2886 return procs.valueAt(i);
2889 ProcessRecord proc = mProcessNames.get(processName, uid);
2890 if (false && proc != null && !keepIfLarge
2891 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2892 && proc.lastCachedPss >= 4000) {
2893 // Turn this condition on to cause killing to happen regularly, for testing.
2894 if (proc.baseProcessTracker != null) {
2895 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2897 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2898 } else if (proc != null && !keepIfLarge
2899 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2900 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2901 if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2902 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2903 if (proc.baseProcessTracker != null) {
2904 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2906 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2912 void ensurePackageDexOpt(String packageName) {
2913 IPackageManager pm = AppGlobals.getPackageManager();
2915 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2918 } catch (RemoteException e) {
2922 boolean isNextTransitionForward() {
2923 int transit = mWindowManager.getPendingAppTransition();
2924 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2925 || transit == AppTransition.TRANSIT_TASK_OPEN
2926 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2929 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2930 String processName, String abiOverride, int uid, Runnable crashHandler) {
2931 synchronized(this) {
2932 ApplicationInfo info = new ApplicationInfo();
2933 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2934 // For isolated processes, the former contains the parent's uid and the latter the
2935 // actual uid of the isolated process.
2936 // In the special case introduced by this method (which is, starting an isolated
2937 // process directly from the SystemServer without an actual parent app process) the
2938 // closest thing to a parent's uid is SYSTEM_UID.
2939 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2940 // the |isolated| logic in the ProcessRecord constructor.
2941 info.uid = Process.SYSTEM_UID;
2942 info.processName = processName;
2943 info.className = entryPoint;
2944 info.packageName = "android";
2945 ProcessRecord proc = startProcessLocked(processName, info /* info */,
2946 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
2947 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2948 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2950 return proc != null ? proc.pid : 0;
2954 final ProcessRecord startProcessLocked(String processName,
2955 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2956 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2957 boolean isolated, boolean keepIfLarge) {
2958 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2959 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2960 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2961 null /* crashHandler */);
2964 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2965 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2966 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2967 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2968 long startTime = SystemClock.elapsedRealtime();
2971 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2972 checkTime(startTime, "startProcess: after getProcessRecord");
2974 // If this is an isolated process, it can't re-use an existing process.
2977 // We don't have to do anything more if:
2978 // (1) There is an existing application record; and
2979 // (2) The caller doesn't think it is dead, OR there is no thread
2980 // object attached to it so we know it couldn't have crashed; and
2981 // (3) There is a pid assigned to it, so it is either starting or
2983 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2984 + " app=" + app + " knownToBeDead=" + knownToBeDead
2985 + " thread=" + (app != null ? app.thread : null)
2986 + " pid=" + (app != null ? app.pid : -1));
2987 if (app != null && app.pid > 0) {
2988 if (!knownToBeDead || app.thread == null) {
2989 // We already have the app running, or are waiting for it to
2990 // come up (we have a pid but not yet its thread), so keep it.
2991 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2992 // If this is a new package in the process, add the package to the list
2993 app.addPackage(info.packageName, info.versionCode, mProcessStats);
2994 checkTime(startTime, "startProcess: done, added package to proc");
2998 // An application record is attached to a previous process,
3000 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
3001 checkTime(startTime, "startProcess: bad proc running, killing");
3002 Process.killProcessGroup(app.info.uid, app.pid);
3003 handleAppDiedLocked(app, true, true);
3004 checkTime(startTime, "startProcess: done killing old proc");
3007 String hostingNameStr = hostingName != null
3008 ? hostingName.flattenToShortString() : null;
3011 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
3012 // If we are in the background, then check to see if this process
3013 // is bad. If so, we will just silently fail.
3014 if (mBadProcesses.get(info.processName, info.uid) != null) {
3015 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3016 + "/" + info.processName);
3020 // When the user is explicitly starting a process, then clear its
3021 // crash count so that we won't make it bad until they see at
3022 // least one crash dialog again, and make the process good again
3023 // if it had been bad.
3024 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3025 + "/" + info.processName);
3026 mProcessCrashTimes.remove(info.processName, info.uid);
3027 if (mBadProcesses.get(info.processName, info.uid) != null) {
3028 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3029 UserHandle.getUserId(info.uid), info.uid,
3031 mBadProcesses.remove(info.processName, info.uid);
3040 checkTime(startTime, "startProcess: creating new process record");
3041 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3042 app.crashHandler = crashHandler;
3044 Slog.w(TAG, "Failed making new process record for "
3045 + processName + "/" + info.uid + " isolated=" + isolated);
3048 mProcessNames.put(processName, app.uid, app);
3050 mIsolatedProcesses.put(app.uid, app);
3052 checkTime(startTime, "startProcess: done creating new process record");
3054 // If this is a new package in the process, add the package to the list
3055 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3056 checkTime(startTime, "startProcess: added package to existing proc");
3059 // If the system is not ready yet, then hold off on starting this
3060 // process until it is.
3061 if (!mProcessesReady
3062 && !isAllowedWhileBooting(info)
3063 && !allowWhileBooting) {
3064 if (!mProcessesOnHold.contains(app)) {
3065 mProcessesOnHold.add(app);
3067 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3068 checkTime(startTime, "startProcess: returning with proc on hold");
3072 checkTime(startTime, "startProcess: stepping in to startProcess");
3074 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3075 checkTime(startTime, "startProcess: done starting proc!");
3076 return (app.pid != 0) ? app : null;
3079 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3080 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3083 private final void startProcessLocked(ProcessRecord app,
3084 String hostingType, String hostingNameStr) {
3085 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3086 null /* entryPoint */, null /* entryPointArgs */);
3089 private final void startProcessLocked(ProcessRecord app, String hostingType,
3090 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3091 long startTime = SystemClock.elapsedRealtime();
3092 if (app.pid > 0 && app.pid != MY_PID) {
3093 checkTime(startTime, "startProcess: removing from pids map");
3094 synchronized (mPidsSelfLocked) {
3095 mPidsSelfLocked.remove(app.pid);
3096 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3098 checkTime(startTime, "startProcess: done removing from pids map");
3102 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3103 "startProcessLocked removing on hold: " + app);
3104 mProcessesOnHold.remove(app);
3106 checkTime(startTime, "startProcess: starting to update cpu stats");
3108 checkTime(startTime, "startProcess: done updating cpu stats");
3114 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3115 if (!app.isolated) {
3116 int[] permGids = null;
3118 checkTime(startTime, "startProcess: getting gids from package manager");
3119 final PackageManager pm = mContext.getPackageManager();
3120 permGids = pm.getPackageGids(app.info.packageName);
3122 if (Environment.isExternalStorageEmulated()) {
3123 checkTime(startTime, "startProcess: checking external storage perm");
3124 if (pm.checkPermission(
3125 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3126 app.info.packageName) == PERMISSION_GRANTED) {
3127 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3129 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3132 } catch (PackageManager.NameNotFoundException e) {
3133 Slog.w(TAG, "Unable to retrieve gids", e);
3137 * Add shared application and profile GIDs so applications can share some
3138 * resources like shared libraries and access user-wide resources
3140 if (permGids == null) {
3143 gids = new int[permGids.length + 2];
3144 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3146 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3147 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3149 checkTime(startTime, "startProcess: building args");
3150 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3151 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3152 && mTopComponent != null
3153 && app.processName.equals(mTopComponent.getPackageName())) {
3156 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3157 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3162 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3163 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3164 // Also turn on CheckJNI for debuggable apps. It's quite
3165 // awkward to turn on otherwise.
3166 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3168 // Run the app in safe mode if its manifest requests so or the
3169 // system is booted in safe mode.
3170 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3171 mSafeMode == true) {
3172 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3174 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3175 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3177 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3178 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3180 if ("1".equals(SystemProperties.get("debug.assert"))) {
3181 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3184 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3185 if (requiredAbi == null) {
3186 requiredAbi = Build.SUPPORTED_ABIS[0];
3189 String instructionSet = null;
3190 if (app.info.primaryCpuAbi != null) {
3191 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3194 // Start the process. It will either succeed and return a result containing
3195 // the PID of the new process, or else throw a RuntimeException.
3196 boolean isActivityProcess = (entryPoint == null);
3197 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3198 checkTime(startTime, "startProcess: asking zygote to start proc");
3199 Process.ProcessStartResult startResult = Process.start(entryPoint,
3200 app.processName, uid, uid, gids, debugFlags, mountExternal,
3201 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3202 app.info.dataDir, entryPointArgs);
3203 checkTime(startTime, "startProcess: returned from zygote!");
3206 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3208 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3209 checkTime(startTime, "startProcess: done updating battery stats");
3211 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3212 UserHandle.getUserId(uid), startResult.pid, uid,
3213 app.processName, hostingType,
3214 hostingNameStr != null ? hostingNameStr : "");
3216 if (app.persistent) {
3217 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3220 checkTime(startTime, "startProcess: building log message");
3221 StringBuilder buf = mStringBuilder;
3223 buf.append("Start proc ");
3224 buf.append(app.processName);
3225 if (!isActivityProcess) {
3227 buf.append(entryPoint);
3230 buf.append(" for ");
3231 buf.append(hostingType);
3232 if (hostingNameStr != null) {
3234 buf.append(hostingNameStr);
3236 buf.append(": pid=");
3237 buf.append(startResult.pid);
3238 buf.append(" uid=");
3240 buf.append(" gids={");
3242 for (int gi=0; gi<gids.length; gi++) {
3243 if (gi != 0) buf.append(", ");
3244 buf.append(gids[gi]);
3249 if (requiredAbi != null) {
3250 buf.append(" abi=");
3251 buf.append(requiredAbi);
3253 Slog.i(TAG, buf.toString());
3254 app.setPid(startResult.pid);
3255 app.usingWrapper = startResult.usingWrapper;
3256 app.removed = false;
3258 app.killedByAm = false;
3259 checkTime(startTime, "startProcess: starting to update pids map");
3260 synchronized (mPidsSelfLocked) {
3261 this.mPidsSelfLocked.put(startResult.pid, app);
3262 if (isActivityProcess) {
3263 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3265 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3266 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3269 checkTime(startTime, "startProcess: done updating pids map");
3270 } catch (RuntimeException e) {
3271 // XXX do better error recovery.
3273 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3275 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3277 Slog.e(TAG, "Failure starting process " + app.processName, e);
3281 void updateUsageStats(ActivityRecord component, boolean resumed) {
3282 if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3283 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3285 if (mUsageStatsService != null) {
3286 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3287 UsageEvents.Event.MOVE_TO_FOREGROUND);
3289 synchronized (stats) {
3290 stats.noteActivityResumedLocked(component.app.uid);
3293 if (mUsageStatsService != null) {
3294 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3295 UsageEvents.Event.MOVE_TO_BACKGROUND);
3297 synchronized (stats) {
3298 stats.noteActivityPausedLocked(component.app.uid);
3303 Intent getHomeIntent() {
3304 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3305 intent.setComponent(mTopComponent);
3306 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3307 intent.addCategory(Intent.CATEGORY_HOME);
3312 boolean startHomeActivityLocked(int userId) {
3313 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3314 && mTopAction == null) {
3315 // We are running in factory test mode, but unable to find
3316 // the factory test app, so just sit around displaying the
3317 // error message and don't try to start anything.
3320 Intent intent = getHomeIntent();
3321 ActivityInfo aInfo =
3322 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3323 if (aInfo != null) {
3324 intent.setComponent(new ComponentName(
3325 aInfo.applicationInfo.packageName, aInfo.name));
3326 // Don't do this if the home app is currently being
3328 aInfo = new ActivityInfo(aInfo);
3329 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3330 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3331 aInfo.applicationInfo.uid, true);
3332 if (app == null || app.instrumentationClass == null) {
3333 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3334 mStackSupervisor.startHomeActivity(intent, aInfo);
3341 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3342 ActivityInfo ai = null;
3343 ComponentName comp = intent.getComponent();
3346 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3348 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3350 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3354 ai = info.activityInfo;
3357 } catch (RemoteException e) {
3365 * Starts the "new version setup screen" if appropriate.
3367 void startSetupActivityLocked() {
3368 // Only do this once per boot.
3369 if (mCheckedForSetup) {
3373 // We will show this screen if the current one is a different
3374 // version than the last one shown, and we are not running in
3375 // low-level factory test mode.
3376 final ContentResolver resolver = mContext.getContentResolver();
3377 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3378 Settings.Global.getInt(resolver,
3379 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3380 mCheckedForSetup = true;
3382 // See if we should be showing the platform update setup UI.
3383 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3384 List<ResolveInfo> ris = mContext.getPackageManager()
3385 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3387 // We don't allow third party apps to replace this.
3388 ResolveInfo ri = null;
3389 for (int i=0; ris != null && i<ris.size(); i++) {
3390 if ((ris.get(i).activityInfo.applicationInfo.flags
3391 & ApplicationInfo.FLAG_SYSTEM) != 0) {
3398 String vers = ri.activityInfo.metaData != null
3399 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3401 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3402 vers = ri.activityInfo.applicationInfo.metaData.getString(
3403 Intent.METADATA_SETUP_VERSION);
3405 String lastVers = Settings.Secure.getString(
3406 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3407 if (vers != null && !vers.equals(lastVers)) {
3408 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3409 intent.setComponent(new ComponentName(
3410 ri.activityInfo.packageName, ri.activityInfo.name));
3411 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3412 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, null, null,
3419 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3420 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3423 void enforceNotIsolatedCaller(String caller) {
3424 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3425 throw new SecurityException("Isolated process not allowed to call " + caller);
3429 void enforceShellRestriction(String restriction, int userHandle) {
3430 if (Binder.getCallingUid() == Process.SHELL_UID) {
3432 || mUserManager.hasUserRestriction(restriction, userHandle)) {
3433 throw new SecurityException("Shell does not have permission to access user "
3440 public int getFrontActivityScreenCompatMode() {
3441 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3442 synchronized (this) {
3443 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3448 public void setFrontActivityScreenCompatMode(int mode) {
3449 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3450 "setFrontActivityScreenCompatMode");
3451 synchronized (this) {
3452 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3457 public int getPackageScreenCompatMode(String packageName) {
3458 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3459 synchronized (this) {
3460 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3465 public void setPackageScreenCompatMode(String packageName, int mode) {
3466 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3467 "setPackageScreenCompatMode");
3468 synchronized (this) {
3469 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3474 public boolean getPackageAskScreenCompat(String packageName) {
3475 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3476 synchronized (this) {
3477 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3482 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3483 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3484 "setPackageAskScreenCompat");
3485 synchronized (this) {
3486 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3490 private void dispatchProcessesChanged() {
3492 synchronized (this) {
3493 N = mPendingProcessChanges.size();
3494 if (mActiveProcessChanges.length < N) {
3495 mActiveProcessChanges = new ProcessChangeItem[N];
3497 mPendingProcessChanges.toArray(mActiveProcessChanges);
3498 mAvailProcessChanges.addAll(mPendingProcessChanges);
3499 mPendingProcessChanges.clear();
3500 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3503 int i = mProcessObservers.beginBroadcast();
3506 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3507 if (observer != null) {
3509 for (int j=0; j<N; j++) {
3510 ProcessChangeItem item = mActiveProcessChanges[j];
3511 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3512 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3513 + item.pid + " uid=" + item.uid + ": "
3514 + item.foregroundActivities);
3515 observer.onForegroundActivitiesChanged(item.pid, item.uid,
3516 item.foregroundActivities);
3518 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3519 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3520 + item.pid + " uid=" + item.uid + ": " + item.processState);
3521 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3524 } catch (RemoteException e) {
3528 mProcessObservers.finishBroadcast();
3531 private void dispatchProcessDied(int pid, int uid) {
3532 int i = mProcessObservers.beginBroadcast();
3535 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3536 if (observer != null) {
3538 observer.onProcessDied(pid, uid);
3539 } catch (RemoteException e) {
3543 mProcessObservers.finishBroadcast();
3547 public final int startActivity(IApplicationThread caller, String callingPackage,
3548 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3549 int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3550 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3551 resultWho, requestCode, startFlags, profilerInfo, options,
3552 UserHandle.getCallingUserId());
3556 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3557 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3558 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3559 enforceNotIsolatedCaller("startActivity");
3560 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3561 false, ALLOW_FULL_ONLY, "startActivity", null);
3562 // TODO: Switch to user app stacks here.
3563 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3564 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3565 profilerInfo, null, null, options, userId, null, null);
3569 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3570 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3571 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3573 // This is very dangerous -- it allows you to perform a start activity (including
3574 // permission grants) as any app that may launch one of your own activities. So
3575 // we will only allow this to be done from activities that are part of the core framework,
3576 // and then only when they are running as the system.
3577 final ActivityRecord sourceRecord;
3578 final int targetUid;
3579 final String targetPackage;
3580 synchronized (this) {
3581 if (resultTo == null) {
3582 throw new SecurityException("Must be called from an activity");
3584 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3585 if (sourceRecord == null) {
3586 throw new SecurityException("Called with bad activity token: " + resultTo);
3588 if (!sourceRecord.info.packageName.equals("android")) {
3589 throw new SecurityException(
3590 "Must be called from an activity that is declared in the android package");
3592 if (sourceRecord.app == null) {
3593 throw new SecurityException("Called without a process attached to activity");
3595 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3596 // This is still okay, as long as this activity is running under the
3597 // uid of the original calling activity.
3598 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3599 throw new SecurityException(
3600 "Calling activity in uid " + sourceRecord.app.uid
3601 + " must be system uid or original calling uid "
3602 + sourceRecord.launchedFromUid);
3605 targetUid = sourceRecord.launchedFromUid;
3606 targetPackage = sourceRecord.launchedFromPackage;
3609 if (userId == UserHandle.USER_NULL) {
3610 userId = UserHandle.getUserId(sourceRecord.app.uid);
3613 // TODO: Switch to user app stacks here.
3615 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3616 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3617 null, null, options, userId, null, null);
3619 } catch (SecurityException e) {
3620 // XXX need to figure out how to propagate to original app.
3621 // A SecurityException here is generally actually a fault of the original
3622 // calling activity (such as a fairly granting permissions), so propagate it
3625 StringBuilder msg = new StringBuilder();
3626 msg.append("While launching");
3627 msg.append(intent.toString());
3629 msg.append(e.getMessage());
3636 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3637 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3638 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3639 enforceNotIsolatedCaller("startActivityAndWait");
3640 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3641 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3642 WaitResult res = new WaitResult();
3643 // TODO: Switch to user app stacks here.
3644 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3645 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3646 options, userId, null, null);
3651 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3652 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3653 int startFlags, Configuration config, Bundle options, int userId) {
3654 enforceNotIsolatedCaller("startActivityWithConfig");
3655 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3656 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3657 // TODO: Switch to user app stacks here.
3658 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3659 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3660 null, null, config, options, userId, null, null);
3665 public int startActivityIntentSender(IApplicationThread caller,
3666 IntentSender intent, Intent fillInIntent, String resolvedType,
3667 IBinder resultTo, String resultWho, int requestCode,
3668 int flagsMask, int flagsValues, Bundle options) {
3669 enforceNotIsolatedCaller("startActivityIntentSender");
3670 // Refuse possible leaked file descriptors
3671 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3672 throw new IllegalArgumentException("File descriptors passed in Intent");
3675 IIntentSender sender = intent.getTarget();
3676 if (!(sender instanceof PendingIntentRecord)) {
3677 throw new IllegalArgumentException("Bad PendingIntent object");
3680 PendingIntentRecord pir = (PendingIntentRecord)sender;
3682 synchronized (this) {
3683 // If this is coming from the currently resumed activity, it is
3684 // effectively saying that app switches are allowed at this point.
3685 final ActivityStack stack = getFocusedStack();
3686 if (stack.mResumedActivity != null &&
3687 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3688 mAppSwitchesAllowedTime = 0;
3691 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3692 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3697 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3698 Intent intent, String resolvedType, IVoiceInteractionSession session,
3699 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3700 Bundle options, int userId) {
3701 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3702 != PackageManager.PERMISSION_GRANTED) {
3703 String msg = "Permission Denial: startVoiceActivity() from pid="
3704 + Binder.getCallingPid()
3705 + ", uid=" + Binder.getCallingUid()
3706 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3708 throw new SecurityException(msg);
3710 if (session == null || interactor == null) {
3711 throw new NullPointerException("null session or interactor");
3713 userId = handleIncomingUser(callingPid, callingUid, userId,
3714 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3715 // TODO: Switch to user app stacks here.
3716 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3717 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3718 null, options, userId, null, null);
3722 public boolean startNextMatchingActivity(IBinder callingActivity,
3723 Intent intent, Bundle options) {
3724 // Refuse possible leaked file descriptors
3725 if (intent != null && intent.hasFileDescriptors() == true) {
3726 throw new IllegalArgumentException("File descriptors passed in Intent");
3729 synchronized (this) {
3730 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3732 ActivityOptions.abort(options);
3735 if (r.app == null || r.app.thread == null) {
3736 // The caller is not running... d'oh!
3737 ActivityOptions.abort(options);
3740 intent = new Intent(intent);
3741 // The caller is not allowed to change the data.
3742 intent.setDataAndType(r.intent.getData(), r.intent.getType());
3743 // And we are resetting to find the next component...
3744 intent.setComponent(null);
3746 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3748 ActivityInfo aInfo = null;
3750 List<ResolveInfo> resolves =
3751 AppGlobals.getPackageManager().queryIntentActivities(
3752 intent, r.resolvedType,
3753 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3754 UserHandle.getCallingUserId());
3756 // Look for the original activity in the list...
3757 final int N = resolves != null ? resolves.size() : 0;
3758 for (int i=0; i<N; i++) {
3759 ResolveInfo rInfo = resolves.get(i);
3760 if (rInfo.activityInfo.packageName.equals(r.packageName)
3761 && rInfo.activityInfo.name.equals(r.info.name)) {
3762 // We found the current one... the next matching is
3766 aInfo = resolves.get(i).activityInfo;
3769 Slog.v(TAG, "Next matching activity: found current " + r.packageName
3770 + "/" + r.info.name);
3771 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3772 + "/" + aInfo.name);
3777 } catch (RemoteException e) {
3780 if (aInfo == null) {
3781 // Nobody who is next!
3782 ActivityOptions.abort(options);
3783 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3787 intent.setComponent(new ComponentName(
3788 aInfo.applicationInfo.packageName, aInfo.name));
3789 intent.setFlags(intent.getFlags()&~(
3790 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3791 Intent.FLAG_ACTIVITY_CLEAR_TOP|
3792 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3793 Intent.FLAG_ACTIVITY_NEW_TASK));
3795 // Okay now we need to start the new activity, replacing the
3796 // currently running activity. This is a little tricky because
3797 // we want to start the new one as if the current one is finished,
3798 // but not finish the current one first so that there is no flicker.
3800 final boolean wasFinishing = r.finishing;
3803 // Propagate reply information over to the new activity.
3804 final ActivityRecord resultTo = r.resultTo;
3805 final String resultWho = r.resultWho;
3806 final int requestCode = r.requestCode;
3808 if (resultTo != null) {
3809 resultTo.removeResultsLocked(r, resultWho, requestCode);
3812 final long origId = Binder.clearCallingIdentity();
3813 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3814 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3815 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
3816 -1, r.launchedFromUid, 0, options, false, null, null, null);
3817 Binder.restoreCallingIdentity(origId);
3819 r.finishing = wasFinishing;
3820 if (res != ActivityManager.START_SUCCESS) {
3828 public final int startActivityFromRecents(int taskId, Bundle options) {
3829 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3830 String msg = "Permission Denial: startActivityFromRecents called without " +
3831 START_TASKS_FROM_RECENTS;
3833 throw new SecurityException(msg);
3835 return startActivityFromRecentsInner(taskId, options);
3838 final int startActivityFromRecentsInner(int taskId, Bundle options) {
3839 final TaskRecord task;
3840 final int callingUid;
3841 final String callingPackage;
3842 final Intent intent;
3844 synchronized (this) {
3845 task = recentTaskForIdLocked(taskId);
3847 throw new IllegalArgumentException("Task " + taskId + " not found.");
3849 callingUid = task.mCallingUid;
3850 callingPackage = task.mCallingPackage;
3851 intent = task.intent;
3852 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3853 userId = task.userId;
3855 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3856 options, userId, null, task);
3859 final int startActivityInPackage(int uid, String callingPackage,
3860 Intent intent, String resolvedType, IBinder resultTo,
3861 String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3862 IActivityContainer container, TaskRecord inTask) {
3864 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3865 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3867 // TODO: Switch to user app stacks here.
3868 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3869 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3870 null, null, null, options, userId, container, inTask);
3875 public final int startActivities(IApplicationThread caller, String callingPackage,
3876 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3878 enforceNotIsolatedCaller("startActivities");
3879 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3880 false, ALLOW_FULL_ONLY, "startActivity", null);
3881 // TODO: Switch to user app stacks here.
3882 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3883 resolvedTypes, resultTo, options, userId);
3887 final int startActivitiesInPackage(int uid, String callingPackage,
3888 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3889 Bundle options, int userId) {
3891 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3892 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3893 // TODO: Switch to user app stacks here.
3894 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3895 resultTo, options, userId);
3899 //explicitly remove thd old information in mRecentTasks when removing existing user.
3900 private void removeRecentTasksForUserLocked(int userId) {
3902 Slog.i(TAG, "Can't remove recent task on user " + userId);
3906 for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3907 TaskRecord tr = mRecentTasks.get(i);
3908 if (tr.userId == userId) {
3909 if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3910 + " when finishing user" + userId);
3911 mRecentTasks.remove(i);
3912 tr.removedFromRecents(mTaskPersister);
3916 // Remove tasks from persistent storage.
3917 mTaskPersister.wakeup(null, true);
3921 private Comparator<TaskRecord> mTaskRecordComparator = new Comparator<TaskRecord>() {
3923 public int compare(TaskRecord lhs, TaskRecord rhs) {
3924 return rhs.taskId - lhs.taskId;
3928 // Extract the affiliates of the chain containing mRecentTasks[start].
3929 private int processNextAffiliateChain(int start) {
3930 final TaskRecord startTask = mRecentTasks.get(start);
3931 final int affiliateId = startTask.mAffiliatedTaskId;
3933 // Quick identification of isolated tasks. I.e. those not launched behind.
3934 if (startTask.taskId == affiliateId && startTask.mPrevAffiliate == null &&
3935 startTask.mNextAffiliate == null) {
3936 // There is still a slim chance that there are other tasks that point to this task
3937 // and that the chain is so messed up that this task no longer points to them but
3938 // the gain of this optimization outweighs the risk.
3939 startTask.inRecents = true;
3943 // Remove all tasks that are affiliated to affiliateId and put them in mTmpRecents.
3944 mTmpRecents.clear();
3945 for (int i = mRecentTasks.size() - 1; i >= start; --i) {
3946 final TaskRecord task = mRecentTasks.get(i);
3947 if (task.mAffiliatedTaskId == affiliateId) {
3948 mRecentTasks.remove(i);
3949 mTmpRecents.add(task);
3953 // Sort them all by taskId. That is the order they were create in and that order will
3954 // always be correct.
3955 Collections.sort(mTmpRecents, mTaskRecordComparator);
3957 // Go through and fix up the linked list.
3958 // The first one is the end of the chain and has no next.
3959 final TaskRecord first = mTmpRecents.get(0);
3960 first.inRecents = true;
3961 if (first.mNextAffiliate != null) {
3962 Slog.w(TAG, "Link error 1 first.next=" + first.mNextAffiliate);
3963 first.setNextAffiliate(null);
3964 mTaskPersister.wakeup(first, false);
3966 // Everything in the middle is doubly linked from next to prev.
3967 final int tmpSize = mTmpRecents.size();
3968 for (int i = 0; i < tmpSize - 1; ++i) {
3969 final TaskRecord next = mTmpRecents.get(i);
3970 final TaskRecord prev = mTmpRecents.get(i + 1);
3971 if (next.mPrevAffiliate != prev) {
3972 Slog.w(TAG, "Link error 2 next=" + next + " prev=" + next.mPrevAffiliate +
3973 " setting prev=" + prev);
3974 next.setPrevAffiliate(prev);
3975 mTaskPersister.wakeup(next, false);
3977 if (prev.mNextAffiliate != next) {
3978 Slog.w(TAG, "Link error 3 prev=" + prev + " next=" + prev.mNextAffiliate +
3979 " setting next=" + next);
3980 prev.setNextAffiliate(next);
3981 mTaskPersister.wakeup(prev, false);
3983 prev.inRecents = true;
3985 // The last one is the beginning of the list and has no prev.
3986 final TaskRecord last = mTmpRecents.get(tmpSize - 1);
3987 if (last.mPrevAffiliate != null) {
3988 Slog.w(TAG, "Link error 4 last.prev=" + last.mPrevAffiliate);
3989 last.setPrevAffiliate(null);
3990 mTaskPersister.wakeup(last, false);
3993 // Insert the group back into mRecentTasks at start.
3994 mRecentTasks.addAll(start, mTmpRecents);
3996 // Let the caller know where we left off.
3997 return start + tmpSize;
4001 * Update the recent tasks lists: make sure tasks should still be here (their
4002 * applications / activities still exist), update their availability, fixup ordering
4005 void cleanupRecentTasksLocked(int userId) {
4006 if (mRecentTasks == null) {
4007 // Happens when called from the packagemanager broadcast before boot.
4011 final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
4012 final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
4013 final IPackageManager pm = AppGlobals.getPackageManager();
4014 final ActivityInfo dummyAct = new ActivityInfo();
4015 final ApplicationInfo dummyApp = new ApplicationInfo();
4017 int N = mRecentTasks.size();
4019 int[] users = userId == UserHandle.USER_ALL
4020 ? getUsersLocked() : new int[] { userId };
4021 for (int user : users) {
4022 for (int i = 0; i < N; i++) {
4023 TaskRecord task = mRecentTasks.get(i);
4024 if (task.userId != user) {
4025 // Only look at tasks for the user ID of interest.
4028 if (task.autoRemoveRecents && task.getTopActivity() == null) {
4029 // This situation is broken, and we should just get rid of it now.
4030 mRecentTasks.remove(i);
4031 task.removedFromRecents(mTaskPersister);
4034 Slog.w(TAG, "Removing auto-remove without activity: " + task);
4037 // Check whether this activity is currently available.
4038 if (task.realActivity != null) {
4039 ActivityInfo ai = availActCache.get(task.realActivity);
4042 ai = pm.getActivityInfo(task.realActivity,
4043 PackageManager.GET_UNINSTALLED_PACKAGES
4044 | PackageManager.GET_DISABLED_COMPONENTS, user);
4045 } catch (RemoteException e) {
4046 // Will never happen.
4052 availActCache.put(task.realActivity, ai);
4054 if (ai == dummyAct) {
4055 // This could be either because the activity no longer exists, or the
4056 // app is temporarily gone. For the former we want to remove the recents
4057 // entry; for the latter we want to mark it as unavailable.
4058 ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
4061 app = pm.getApplicationInfo(task.realActivity.getPackageName(),
4062 PackageManager.GET_UNINSTALLED_PACKAGES
4063 | PackageManager.GET_DISABLED_COMPONENTS, user);
4064 } catch (RemoteException e) {
4065 // Will never happen.
4071 availAppCache.put(task.realActivity.getPackageName(), app);
4073 if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4074 // Doesn't exist any more! Good-bye.
4075 mRecentTasks.remove(i);
4076 task.removedFromRecents(mTaskPersister);
4079 Slog.w(TAG, "Removing no longer valid recent: " + task);
4082 // Otherwise just not available for now.
4083 if (task.isAvailable) {
4084 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4087 task.isAvailable = false;
4090 if (!ai.enabled || !ai.applicationInfo.enabled
4091 || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
4092 if (task.isAvailable) {
4093 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
4094 + task + " (enabled=" + ai.enabled + "/"
4095 + ai.applicationInfo.enabled + " flags="
4096 + Integer.toHexString(ai.applicationInfo.flags) + ")");
4098 task.isAvailable = false;
4100 if (!task.isAvailable) {
4101 if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
4104 task.isAvailable = true;
4111 // Verify the affiliate chain for each task.
4112 for (int i = 0; i < N; i = processNextAffiliateChain(i)) {
4115 mTmpRecents.clear();
4116 // mRecentTasks is now in sorted, affiliated order.
4119 private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
4120 int N = mRecentTasks.size();
4121 TaskRecord top = task;
4122 int topIndex = taskIndex;
4123 while (top.mNextAffiliate != null && topIndex > 0) {
4124 top = top.mNextAffiliate;
4127 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4128 + topIndex + " from intial " + taskIndex);
4129 // Find the end of the chain, doing a sanity check along the way.
4130 boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4131 int endIndex = topIndex;
4132 TaskRecord prev = top;
4133 while (endIndex < N) {
4134 TaskRecord cur = mRecentTasks.get(endIndex);
4135 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4136 + endIndex + " " + cur);
4138 // Verify start of the chain.
4139 if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4140 Slog.wtf(TAG, "Bad chain @" + endIndex
4141 + ": first task has next affiliate: " + prev);
4146 // Verify middle of the chain's next points back to the one before.
4147 if (cur.mNextAffiliate != prev
4148 || cur.mNextAffiliateTaskId != prev.taskId) {
4149 Slog.wtf(TAG, "Bad chain @" + endIndex
4150 + ": middle task " + cur + " @" + endIndex
4151 + " has bad next affiliate "
4152 + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4153 + ", expected " + prev);
4158 if (cur.mPrevAffiliateTaskId == -1) {
4160 if (cur.mPrevAffiliate != null) {
4161 Slog.wtf(TAG, "Bad chain @" + endIndex
4162 + ": last task " + cur + " has previous affiliate "
4163 + cur.mPrevAffiliate);
4166 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4169 // Verify middle of the chain's prev points to a valid item.
4170 if (cur.mPrevAffiliate == null) {
4171 Slog.wtf(TAG, "Bad chain @" + endIndex
4172 + ": task " + cur + " has previous affiliate "
4173 + cur.mPrevAffiliate + " but should be id "
4174 + cur.mPrevAffiliate);
4179 if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4180 Slog.wtf(TAG, "Bad chain @" + endIndex
4181 + ": task " + cur + " has affiliated id "
4182 + cur.mAffiliatedTaskId + " but should be "
4183 + task.mAffiliatedTaskId);
4189 if (endIndex >= N) {
4190 Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4191 + ": last task " + prev);
4197 if (endIndex < taskIndex) {
4198 Slog.wtf(TAG, "Bad chain @" + endIndex
4199 + ": did not extend to task " + task + " @" + taskIndex);
4204 // All looks good, we can just move all of the affiliated tasks
4206 for (int i=topIndex; i<=endIndex; i++) {
4207 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4208 + " from " + i + " to " + (i-topIndex));
4209 TaskRecord cur = mRecentTasks.remove(i);
4210 mRecentTasks.add(i-topIndex, cur);
4212 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks " + topIndex
4213 + " to " + endIndex);
4217 // Whoops, couldn't do it.
4221 final void addRecentTaskLocked(TaskRecord task) {
4222 final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4223 || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4225 int N = mRecentTasks.size();
4226 // Quick case: check if the top-most recent task is the same.
4227 if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4228 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4231 // Another quick case: check if this is part of a set of affiliated
4232 // tasks that are at the top.
4233 if (isAffiliated && N > 0 && task.inRecents
4234 && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4235 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4236 + " at top when adding " + task);
4239 // Another quick case: never add voice sessions.
4240 if (task.voiceSession != null) {
4241 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4245 boolean needAffiliationFix = false;
4247 // Slightly less quick case: the task is already in recents, so all we need
4248 // to do is move it.
4249 if (task.inRecents) {
4250 int taskIndex = mRecentTasks.indexOf(task);
4251 if (taskIndex >= 0) {
4252 if (!isAffiliated) {
4253 // Simple case: this is not an affiliated task, so we just move it to the front.
4254 mRecentTasks.remove(taskIndex);
4255 mRecentTasks.add(0, task);
4256 notifyTaskPersisterLocked(task, false);
4257 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4258 + " from " + taskIndex);
4261 // More complicated: need to keep all affiliated tasks together.
4262 if (moveAffiliatedTasksToFront(task, taskIndex)) {
4267 // Uh oh... something bad in the affiliation chain, try to rebuild
4268 // everything and then go through our general path of adding a new task.
4269 needAffiliationFix = true;
4272 Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4273 needAffiliationFix = true;
4277 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4278 trimRecentsForTask(task, true);
4280 N = mRecentTasks.size();
4281 while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4282 final TaskRecord tr = mRecentTasks.remove(N - 1);
4283 tr.removedFromRecents(mTaskPersister);
4286 task.inRecents = true;
4287 if (!isAffiliated || needAffiliationFix) {
4288 // If this is a simple non-affiliated task, or we had some failure trying to
4289 // handle it as part of an affilated task, then just place it at the top.
4290 mRecentTasks.add(0, task);
4291 } else if (isAffiliated) {
4292 // If this is a new affiliated task, then move all of the affiliated tasks
4293 // to the front and insert this new one.
4294 TaskRecord other = task.mNextAffiliate;
4295 if (other == null) {
4296 other = task.mPrevAffiliate;
4298 if (other != null) {
4299 int otherIndex = mRecentTasks.indexOf(other);
4300 if (otherIndex >= 0) {
4301 // Insert new task at appropriate location.
4303 if (other == task.mNextAffiliate) {
4304 // We found the index of our next affiliation, which is who is
4305 // before us in the list, so add after that point.
4306 taskIndex = otherIndex+1;
4308 // We found the index of our previous affiliation, which is who is
4309 // after us in the list, so add at their position.
4310 taskIndex = otherIndex;
4312 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4313 + taskIndex + ": " + task);
4314 mRecentTasks.add(taskIndex, task);
4316 // Now move everything to the front.
4317 if (moveAffiliatedTasksToFront(task, taskIndex)) {
4322 // Uh oh... something bad in the affiliation chain, try to rebuild
4323 // everything and then go through our general path of adding a new task.
4324 needAffiliationFix = true;
4326 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4328 needAffiliationFix = true;
4331 if (DEBUG_RECENTS) Slog.d(TAG,
4332 "addRecent: adding affiliated task without next/prev:" + task);
4333 needAffiliationFix = true;
4336 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4338 if (needAffiliationFix) {
4339 if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4340 cleanupRecentTasksLocked(task.userId);
4345 * If needed, remove oldest existing entries in recents that are for the same kind
4346 * of task as the given one.
4348 int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4349 int N = mRecentTasks.size();
4350 final Intent intent = task.intent;
4351 final boolean document = intent != null && intent.isDocument();
4353 int maxRecents = task.maxRecents - 1;
4354 for (int i=0; i<N; i++) {
4355 final TaskRecord tr = mRecentTasks.get(i);
4357 if (task.userId != tr.userId) {
4360 if (i > MAX_RECENT_BITMAPS) {
4361 tr.freeLastThumbnail();
4363 final Intent trIntent = tr.intent;
4364 if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4365 (intent == null || !intent.filterEquals(trIntent))) {
4368 final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4369 if (document && trIsDocument) {
4370 // These are the same document activity (not necessarily the same doc).
4371 if (maxRecents > 0) {
4375 // Hit the maximum number of documents for this task. Fall through
4376 // and remove this document from recents.
4377 } else if (document || trIsDocument) {
4378 // Only one of these is a document. Not the droid we're looking for.
4384 // If the caller is not actually asking for a trim, just tell them we reached
4385 // a point where the trim would happen.
4389 // Either task and tr are the same or, their affinities match or their intents match
4390 // and neither of them is a document, or they are documents using the same activity
4391 // and their maxRecents has been reached.
4392 tr.disposeThumbnail();
4393 mRecentTasks.remove(i);
4395 tr.removedFromRecents(mTaskPersister);
4399 if (task.intent == null) {
4400 // If the new recent task we are adding is not fully
4401 // specified, then replace it with the existing recent task.
4404 notifyTaskPersisterLocked(tr, false);
4411 public void reportActivityFullyDrawn(IBinder token) {
4412 synchronized (this) {
4413 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4417 r.reportFullyDrawnLocked();
4422 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4423 synchronized (this) {
4424 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4428 final long origId = Binder.clearCallingIdentity();
4429 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4430 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4431 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4432 if (config != null) {
4433 r.frozenBeforeDestroy = true;
4434 if (!updateConfigurationLocked(config, r, false, false)) {
4435 mStackSupervisor.resumeTopActivitiesLocked();
4438 Binder.restoreCallingIdentity(origId);
4443 public int getRequestedOrientation(IBinder token) {
4444 synchronized (this) {
4445 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4447 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4449 return mWindowManager.getAppOrientation(r.appToken);
4454 * This is the internal entry point for handling Activity.finish().
4456 * @param token The Binder token referencing the Activity we want to finish.
4457 * @param resultCode Result code, if any, from this Activity.
4458 * @param resultData Result data (Intent), if any, from this Activity.
4459 * @param finishTask Whether to finish the task associated with this Activity. Only applies to
4460 * the root Activity in the task.
4462 * @return Returns true if the activity successfully finished, or false if it is still running.
4465 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4466 boolean finishTask) {
4467 // Refuse possible leaked file descriptors
4468 if (resultData != null && resultData.hasFileDescriptors() == true) {
4469 throw new IllegalArgumentException("File descriptors passed in Intent");
4472 synchronized(this) {
4473 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4477 // Keep track of the root activity of the task before we finish it
4478 TaskRecord tr = r.task;
4479 ActivityRecord rootR = tr.getRootActivity();
4480 // Do not allow task to finish in Lock Task mode.
4481 if (tr == mStackSupervisor.mLockTaskModeTask) {
4483 mStackSupervisor.showLockTaskToast();
4487 if (mController != null) {
4488 // Find the first activity that is not finishing.
4489 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4491 // ask watcher if this is allowed
4492 boolean resumeOK = true;
4494 resumeOK = mController.activityResuming(next.packageName);
4495 } catch (RemoteException e) {
4497 Watchdog.getInstance().setActivityController(null);
4505 final long origId = Binder.clearCallingIdentity();
4508 if (finishTask && r == rootR) {
4509 // If requested, remove the task that is associated to this activity only if it
4510 // was the root activity in the task. The result code and data is ignored because
4511 // we don't support returning them across task boundaries.
4512 res = removeTaskByIdLocked(tr.taskId, 0);
4514 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4515 resultData, "app-request", true);
4519 Binder.restoreCallingIdentity(origId);
4525 public final void finishHeavyWeightApp() {
4526 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4527 != PackageManager.PERMISSION_GRANTED) {
4528 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4529 + Binder.getCallingPid()
4530 + ", uid=" + Binder.getCallingUid()
4531 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4533 throw new SecurityException(msg);
4536 synchronized(this) {
4537 if (mHeavyWeightProcess == null) {
4541 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4542 mHeavyWeightProcess.activities);
4543 for (int i=0; i<activities.size(); i++) {
4544 ActivityRecord r = activities.get(i);
4546 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4547 null, "finish-heavy", true);
4551 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4552 mHeavyWeightProcess.userId, 0));
4553 mHeavyWeightProcess = null;
4558 public void crashApplication(int uid, int initialPid, String packageName,
4560 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4561 != PackageManager.PERMISSION_GRANTED) {
4562 String msg = "Permission Denial: crashApplication() from pid="
4563 + Binder.getCallingPid()
4564 + ", uid=" + Binder.getCallingUid()
4565 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4567 throw new SecurityException(msg);
4570 synchronized(this) {
4571 ProcessRecord proc = null;
4573 // Figure out which process to kill. We don't trust that initialPid
4574 // still has any relation to current pids, so must scan through the
4576 synchronized (mPidsSelfLocked) {
4577 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4578 ProcessRecord p = mPidsSelfLocked.valueAt(i);
4582 if (p.pid == initialPid) {
4586 if (p.pkgList.containsKey(packageName)) {
4593 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4594 + " initialPid=" + initialPid
4595 + " packageName=" + packageName);
4599 if (proc.thread != null) {
4600 if (proc.pid == Process.myPid()) {
4601 Log.w(TAG, "crashApplication: trying to crash self!");
4604 long ident = Binder.clearCallingIdentity();
4606 proc.thread.scheduleCrash(message);
4607 } catch (RemoteException e) {
4609 Binder.restoreCallingIdentity(ident);
4615 public final void finishSubActivity(IBinder token, String resultWho,
4617 synchronized(this) {
4618 final long origId = Binder.clearCallingIdentity();
4619 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4621 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4623 Binder.restoreCallingIdentity(origId);
4628 public boolean finishActivityAffinity(IBinder token) {
4629 synchronized(this) {
4630 final long origId = Binder.clearCallingIdentity();
4632 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4634 ActivityRecord rootR = r.task.getRootActivity();
4635 // Do not allow task to finish in Lock Task mode.
4636 if (r.task == mStackSupervisor.mLockTaskModeTask) {
4638 mStackSupervisor.showLockTaskToast();
4642 boolean res = false;
4644 res = r.task.stack.finishActivityAffinityLocked(r);
4648 Binder.restoreCallingIdentity(origId);
4654 public void finishVoiceTask(IVoiceInteractionSession session) {
4655 synchronized(this) {
4656 final long origId = Binder.clearCallingIdentity();
4658 mStackSupervisor.finishVoiceTask(session);
4660 Binder.restoreCallingIdentity(origId);
4667 public boolean releaseActivityInstance(IBinder token) {
4668 synchronized(this) {
4669 final long origId = Binder.clearCallingIdentity();
4671 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4672 if (r.task == null || r.task.stack == null) {
4675 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4677 Binder.restoreCallingIdentity(origId);
4683 public void releaseSomeActivities(IApplicationThread appInt) {
4684 synchronized(this) {
4685 final long origId = Binder.clearCallingIdentity();
4687 ProcessRecord app = getRecordForAppLocked(appInt);
4688 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4690 Binder.restoreCallingIdentity(origId);
4696 public boolean willActivityBeVisible(IBinder token) {
4697 synchronized(this) {
4698 ActivityStack stack = ActivityRecord.getStackLocked(token);
4699 if (stack != null) {
4700 return stack.willActivityBeVisibleLocked(token);
4707 public void overridePendingTransition(IBinder token, String packageName,
4708 int enterAnim, int exitAnim) {
4709 synchronized(this) {
4710 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4715 final long origId = Binder.clearCallingIdentity();
4717 if (self.state == ActivityState.RESUMED
4718 || self.state == ActivityState.PAUSING) {
4719 mWindowManager.overridePendingAppTransition(packageName,
4720 enterAnim, exitAnim, null);
4723 Binder.restoreCallingIdentity(origId);
4728 * Main function for removing an existing process from the activity manager
4729 * as a result of that process going away. Clears out all connections
4732 private final void handleAppDiedLocked(ProcessRecord app,
4733 boolean restarting, boolean allowRestart) {
4735 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4736 if (!kept && !restarting) {
4737 removeLruProcessLocked(app);
4739 ProcessList.remove(pid);
4743 if (mProfileProc == app) {
4744 clearProfilerLocked();
4747 // Remove this application's activities from active lists.
4748 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4750 app.activities.clear();
4752 if (app.instrumentationClass != null) {
4753 Slog.w(TAG, "Crash of app " + app.processName
4754 + " running instrumentation " + app.instrumentationClass);
4755 Bundle info = new Bundle();
4756 info.putString("shortMsg", "Process crashed.");
4757 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4761 if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4762 // If there was nothing to resume, and we are not already
4763 // restarting this process, but there is a visible activity that
4764 // is hosted by the process... then make sure all visible
4765 // activities are running, taking care of restarting this
4767 if (hasVisibleActivities) {
4768 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4774 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4775 IBinder threadBinder = thread.asBinder();
4776 // Find the application record.
4777 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4778 ProcessRecord rec = mLruProcesses.get(i);
4779 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4786 final ProcessRecord getRecordForAppLocked(
4787 IApplicationThread thread) {
4788 if (thread == null) {
4792 int appIndex = getLRURecordIndexForAppLocked(thread);
4793 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4796 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4797 // If there are no longer any background processes running,
4798 // and the app that died was not running instrumentation,
4799 // then tell everyone we are now low on memory.
4800 boolean haveBg = false;
4801 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4802 ProcessRecord rec = mLruProcesses.get(i);
4803 if (rec.thread != null
4804 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4811 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4813 long now = SystemClock.uptimeMillis();
4814 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4817 mLastMemUsageReportTime = now;
4820 final ArrayList<ProcessMemInfo> memInfos
4821 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4822 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4823 long now = SystemClock.uptimeMillis();
4824 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4825 ProcessRecord rec = mLruProcesses.get(i);
4826 if (rec == dyingProc || rec.thread == null) {
4830 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4831 rec.setProcState, rec.adjType, rec.makeAdjReason()));
4833 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4834 // The low memory report is overriding any current
4835 // state for a GC request. Make sure to do
4836 // heavy/important/visible/foreground processes first.
4837 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4838 rec.lastRequestedGc = 0;
4840 rec.lastRequestedGc = rec.lastLowMemory;
4842 rec.reportLowMemory = true;
4843 rec.lastLowMemory = now;
4844 mProcessesToGc.remove(rec);
4845 addProcessToGcListLocked(rec);
4849 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4850 mHandler.sendMessage(msg);
4852 scheduleAppGcsLocked();
4856 final void appDiedLocked(ProcessRecord app) {
4857 appDiedLocked(app, app.pid, app.thread);
4860 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) {
4861 // First check if this ProcessRecord is actually active for the pid.
4862 synchronized (mPidsSelfLocked) {
4863 ProcessRecord curProc = mPidsSelfLocked.get(pid);
4864 if (curProc != app) {
4865 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4870 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4871 synchronized (stats) {
4872 stats.noteProcessDiedLocked(app.info.uid, pid);
4875 Process.killProcessQuiet(pid);
4876 Process.killProcessGroup(app.info.uid, pid);
4879 // Clean up already done if the process has been re-started.
4880 if (app.pid == pid && app.thread != null &&
4881 app.thread.asBinder() == thread.asBinder()) {
4882 boolean doLowMem = app.instrumentationClass == null;
4883 boolean doOomAdj = doLowMem;
4884 if (!app.killedByAm) {
4885 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4887 mAllowLowerMemLevel = true;
4889 // Note that we always want to do oom adj to update our state with the
4890 // new number of procs.
4891 mAllowLowerMemLevel = false;
4894 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4895 if (DEBUG_CLEANUP) Slog.v(
4896 TAG, "Dying app: " + app + ", pid: " + pid
4897 + ", thread: " + thread.asBinder());
4898 handleAppDiedLocked(app, false, true);
4901 updateOomAdjLocked();
4904 doLowMemReportIfNeededLocked(app);
4906 } else if (app.pid != pid) {
4907 // A new process has already been started.
4908 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4909 + ") has died and restarted (pid " + app.pid + ").");
4910 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4911 } else if (DEBUG_PROCESSES) {
4912 Slog.d(TAG, "Received spurious death notification for thread "
4913 + thread.asBinder());
4918 * If a stack trace dump file is configured, dump process stack traces.
4919 * @param clearTraces causes the dump file to be erased prior to the new
4920 * traces being written, if true; when false, the new traces will be
4921 * appended to any existing file content.
4922 * @param firstPids of dalvik VM processes to dump stack traces for first
4923 * @param lastPids of dalvik VM processes to dump stack traces for last
4924 * @param nativeProcs optional list of native process names to dump stack crawls
4925 * @return file containing stack traces, or null if no dump file is configured
4927 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4928 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4929 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4930 if (tracesPath == null || tracesPath.length() == 0) {
4934 File tracesFile = new File(tracesPath);
4936 File tracesDir = tracesFile.getParentFile();
4937 if (!tracesDir.exists()) {
4939 if (!SELinux.restorecon(tracesDir)) {
4943 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4945 if (clearTraces && tracesFile.exists()) tracesFile.delete();
4946 tracesFile.createNewFile();
4947 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4948 } catch (IOException e) {
4949 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4953 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4957 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4958 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4959 // Use a FileObserver to detect when traces finish writing.
4960 // The order of traces is considered important to maintain for legibility.
4961 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4963 public synchronized void onEvent(int event, String path) { notify(); }
4967 observer.startWatching();
4969 // First collect all of the stacks of the most important pids.
4970 if (firstPids != null) {
4972 int num = firstPids.size();
4973 for (int i = 0; i < num; i++) {
4974 synchronized (observer) {
4975 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4976 observer.wait(200); // Wait for write-close, give up after 200msec
4979 } catch (InterruptedException e) {
4984 // Next collect the stacks of the native pids
4985 if (nativeProcs != null) {
4986 int[] pids = Process.getPidsForCommands(nativeProcs);
4988 for (int pid : pids) {
4989 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4994 // Lastly, measure CPU usage.
4995 if (processCpuTracker != null) {
4996 processCpuTracker.init();
4998 processCpuTracker.update();
5000 synchronized (processCpuTracker) {
5001 processCpuTracker.wait(500); // measure over 1/2 second.
5003 } catch (InterruptedException e) {
5005 processCpuTracker.update();
5007 // We'll take the stack crawls of just the top apps using CPU.
5008 final int N = processCpuTracker.countWorkingStats();
5010 for (int i=0; i<N && numProcs<5; i++) {
5011 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5012 if (lastPids.indexOfKey(stats.pid) >= 0) {
5015 synchronized (observer) {
5016 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5017 observer.wait(200); // Wait for write-close, give up after 200msec
5019 } catch (InterruptedException e) {
5027 observer.stopWatching();
5031 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5032 if (true || IS_USER_BUILD) {
5035 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5036 if (tracesPath == null || tracesPath.length() == 0) {
5040 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5041 StrictMode.allowThreadDiskWrites();
5043 final File tracesFile = new File(tracesPath);
5044 final File tracesDir = tracesFile.getParentFile();
5045 final File tracesTmp = new File(tracesDir, "__tmp__");
5047 if (!tracesDir.exists()) {
5049 if (!SELinux.restorecon(tracesDir.getPath())) {
5053 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
5055 if (tracesFile.exists()) {
5057 tracesFile.renameTo(tracesTmp);
5059 StringBuilder sb = new StringBuilder();
5060 Time tobj = new Time();
5061 tobj.set(System.currentTimeMillis());
5062 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5064 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5065 sb.append(" since ");
5067 FileOutputStream fos = new FileOutputStream(tracesFile);
5068 fos.write(sb.toString().getBytes());
5070 fos.write("\n*** No application process!".getBytes());
5073 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5074 } catch (IOException e) {
5075 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5080 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5081 firstPids.add(app.pid);
5082 dumpStackTraces(tracesPath, firstPids, null, null, null);
5085 File lastTracesFile = null;
5086 File curTracesFile = null;
5087 for (int i=9; i>=0; i--) {
5088 String name = String.format(Locale.US, "slow%02d.txt", i);
5089 curTracesFile = new File(tracesDir, name);
5090 if (curTracesFile.exists()) {
5091 if (lastTracesFile != null) {
5092 curTracesFile.renameTo(lastTracesFile);
5094 curTracesFile.delete();
5097 lastTracesFile = curTracesFile;
5099 tracesFile.renameTo(curTracesFile);
5100 if (tracesTmp.exists()) {
5101 tracesTmp.renameTo(tracesFile);
5104 StrictMode.setThreadPolicy(oldPolicy);
5108 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
5109 ActivityRecord parent, boolean aboveSystem, final String annotation) {
5110 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
5111 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
5113 if (mController != null) {
5115 // 0 == continue, -1 = kill process immediately
5116 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
5117 if (res < 0 && app.pid != MY_PID) {
5118 app.kill("anr", true);
5120 } catch (RemoteException e) {
5122 Watchdog.getInstance().setActivityController(null);
5126 long anrTime = SystemClock.uptimeMillis();
5127 if (MONITOR_CPU_USAGE) {
5128 updateCpuStatsNow();
5131 synchronized (this) {
5132 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
5133 if (mShuttingDown) {
5134 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5136 } else if (app.notResponding) {
5137 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5139 } else if (app.crashing) {
5140 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5144 // In case we come through here for the same app before completing
5145 // this one, mark as anring now so we will bail out.
5146 app.notResponding = true;
5148 // Log the ANR to the event log.
5149 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5150 app.processName, app.info.flags, annotation);
5152 // Dump thread traces as quickly as we can, starting with "interesting" processes.
5153 firstPids.add(app.pid);
5155 int parentPid = app.pid;
5156 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5157 if (parentPid != app.pid) firstPids.add(parentPid);
5159 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5161 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5162 ProcessRecord r = mLruProcesses.get(i);
5163 if (r != null && r.thread != null) {
5165 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5169 lastPids.put(pid, Boolean.TRUE);
5176 // Log the ANR to the main log.
5177 StringBuilder info = new StringBuilder();
5179 info.append("ANR in ").append(app.processName);
5180 if (activity != null && activity.shortComponentName != null) {
5181 info.append(" (").append(activity.shortComponentName).append(")");
5184 info.append("PID: ").append(app.pid).append("\n");
5185 if (annotation != null) {
5186 info.append("Reason: ").append(annotation).append("\n");
5188 if (parent != null && parent != activity) {
5189 info.append("Parent: ").append(parent.shortComponentName).append("\n");
5192 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5194 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5195 NATIVE_STACKS_OF_INTEREST);
5197 String cpuInfo = null;
5198 if (MONITOR_CPU_USAGE) {
5199 updateCpuStatsNow();
5200 synchronized (mProcessCpuTracker) {
5201 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5203 info.append(processCpuTracker.printCurrentLoad());
5204 info.append(cpuInfo);
5207 info.append(processCpuTracker.printCurrentState(anrTime));
5209 Slog.e(TAG, info.toString());
5210 if (tracesFile == null) {
5211 // There is no trace file, so dump (only) the alleged culprit's threads to the log
5212 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5215 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5216 cpuInfo, tracesFile, null);
5218 if (mController != null) {
5220 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5221 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5223 if (res < 0 && app.pid != MY_PID) {
5224 app.kill("anr", true);
5226 synchronized (this) {
5227 mServices.scheduleServiceTimeoutLocked(app);
5232 } catch (RemoteException e) {
5234 Watchdog.getInstance().setActivityController(null);
5238 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5239 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5240 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5242 synchronized (this) {
5243 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5244 app.kill("bg anr", true);
5248 // Set the app's notResponding state, and look up the errorReportReceiver
5249 makeAppNotRespondingLocked(app,
5250 activity != null ? activity.shortComponentName : null,
5251 annotation != null ? "ANR " + annotation : "ANR",
5254 // Bring up the infamous App Not Responding dialog
5255 Message msg = Message.obtain();
5256 HashMap<String, Object> map = new HashMap<String, Object>();
5257 msg.what = SHOW_NOT_RESPONDING_MSG;
5259 msg.arg1 = aboveSystem ? 1 : 0;
5260 map.put("app", app);
5261 if (activity != null) {
5262 map.put("activity", activity);
5265 mHandler.sendMessage(msg);
5269 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5270 if (!mLaunchWarningShown) {
5271 mLaunchWarningShown = true;
5272 mHandler.post(new Runnable() {
5275 synchronized (ActivityManagerService.this) {
5276 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5278 mHandler.postDelayed(new Runnable() {
5281 synchronized (ActivityManagerService.this) {
5283 mLaunchWarningShown = false;
5294 public boolean clearApplicationUserData(final String packageName,
5295 final IPackageDataObserver observer, int userId) {
5296 enforceNotIsolatedCaller("clearApplicationUserData");
5297 int uid = Binder.getCallingUid();
5298 int pid = Binder.getCallingPid();
5299 userId = handleIncomingUser(pid, uid,
5300 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5301 long callingId = Binder.clearCallingIdentity();
5303 IPackageManager pm = AppGlobals.getPackageManager();
5305 synchronized(this) {
5307 pkgUid = pm.getPackageUid(packageName, userId);
5308 } catch (RemoteException e) {
5311 Slog.w(TAG, "Invalid packageName: " + packageName);
5312 if (observer != null) {
5314 observer.onRemoveCompleted(packageName, false);
5315 } catch (RemoteException e) {
5316 Slog.i(TAG, "Observer no longer exists.");
5321 if (uid == pkgUid || checkComponentPermission(
5322 android.Manifest.permission.CLEAR_APP_USER_DATA,
5324 == PackageManager.PERMISSION_GRANTED) {
5325 forceStopPackageLocked(packageName, pkgUid, "clear data");
5327 throw new SecurityException("PID " + pid + " does not have permission "
5328 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5329 + " of package " + packageName);
5332 // Remove all tasks match the cleared application package and user
5333 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5334 final TaskRecord tr = mRecentTasks.get(i);
5335 final String taskPackageName =
5336 tr.getBaseIntent().getComponent().getPackageName();
5337 if (tr.userId != userId) continue;
5338 if (!taskPackageName.equals(packageName)) continue;
5339 removeTaskByIdLocked(tr.taskId, 0);
5344 // Clear application user data
5345 pm.clearApplicationUserData(packageName, observer, userId);
5347 synchronized(this) {
5348 // Remove all permissions granted from/to this package
5349 removeUriPermissionsForPackageLocked(packageName, userId, true);
5352 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5353 Uri.fromParts("package", packageName, null));
5354 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5355 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5356 null, null, 0, null, null, null, false, false, userId);
5357 } catch (RemoteException e) {
5360 Binder.restoreCallingIdentity(callingId);
5366 public void killBackgroundProcesses(final String packageName, int userId) {
5367 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5368 != PackageManager.PERMISSION_GRANTED &&
5369 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5370 != PackageManager.PERMISSION_GRANTED) {
5371 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5372 + Binder.getCallingPid()
5373 + ", uid=" + Binder.getCallingUid()
5374 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5376 throw new SecurityException(msg);
5379 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5380 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5381 long callingId = Binder.clearCallingIdentity();
5383 IPackageManager pm = AppGlobals.getPackageManager();
5384 synchronized(this) {
5387 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5388 } catch (RemoteException e) {
5391 Slog.w(TAG, "Invalid packageName: " + packageName);
5394 killPackageProcessesLocked(packageName, appId, userId,
5395 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5398 Binder.restoreCallingIdentity(callingId);
5403 public void killAllBackgroundProcesses() {
5404 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5405 != PackageManager.PERMISSION_GRANTED) {
5406 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5407 + Binder.getCallingPid()
5408 + ", uid=" + Binder.getCallingUid()
5409 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5411 throw new SecurityException(msg);
5414 long callingId = Binder.clearCallingIdentity();
5416 synchronized(this) {
5417 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5418 final int NP = mProcessNames.getMap().size();
5419 for (int ip=0; ip<NP; ip++) {
5420 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5421 final int NA = apps.size();
5422 for (int ia=0; ia<NA; ia++) {
5423 ProcessRecord app = apps.valueAt(ia);
5424 if (app.persistent) {
5425 // we don't kill persistent processes
5430 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5437 int N = procs.size();
5438 for (int i=0; i<N; i++) {
5439 removeProcessLocked(procs.get(i), false, true, "kill all background");
5441 mAllowLowerMemLevel = true;
5442 updateOomAdjLocked();
5443 doLowMemReportIfNeededLocked(null);
5446 Binder.restoreCallingIdentity(callingId);
5451 public void forceStopPackage(final String packageName, int userId) {
5452 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5453 != PackageManager.PERMISSION_GRANTED) {
5454 String msg = "Permission Denial: forceStopPackage() from pid="
5455 + Binder.getCallingPid()
5456 + ", uid=" + Binder.getCallingUid()
5457 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5459 throw new SecurityException(msg);
5461 final int callingPid = Binder.getCallingPid();
5462 userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5463 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5464 long callingId = Binder.clearCallingIdentity();
5466 IPackageManager pm = AppGlobals.getPackageManager();
5467 synchronized(this) {
5468 int[] users = userId == UserHandle.USER_ALL
5469 ? getUsersLocked() : new int[] { userId };
5470 for (int user : users) {
5473 pkgUid = pm.getPackageUid(packageName, user);
5474 } catch (RemoteException e) {
5477 Slog.w(TAG, "Invalid packageName: " + packageName);
5481 pm.setPackageStoppedState(packageName, true, user);
5482 } catch (RemoteException e) {
5483 } catch (IllegalArgumentException e) {
5484 Slog.w(TAG, "Failed trying to unstop package "
5485 + packageName + ": " + e);
5487 if (isUserRunningLocked(user, false)) {
5488 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5493 Binder.restoreCallingIdentity(callingId);
5498 public void addPackageDependency(String packageName) {
5499 synchronized (this) {
5500 int callingPid = Binder.getCallingPid();
5501 if (callingPid == Process.myPid()) {
5503 Slog.w(TAG, "Can't addPackageDependency on system process");
5507 synchronized (mPidsSelfLocked) {
5508 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5511 if (proc.pkgDeps == null) {
5512 proc.pkgDeps = new ArraySet<String>(1);
5514 proc.pkgDeps.add(packageName);
5520 * The pkg name and app id have to be specified.
5523 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5527 // Make sure the uid is valid.
5529 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5532 int callerUid = Binder.getCallingUid();
5533 // Only the system server can kill an application
5534 if (callerUid == Process.SYSTEM_UID) {
5535 // Post an aysnc message to kill the application
5536 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5539 Bundle bundle = new Bundle();
5540 bundle.putString("pkg", pkg);
5541 bundle.putString("reason", reason);
5543 mHandler.sendMessage(msg);
5545 throw new SecurityException(callerUid + " cannot kill pkg: " +
5551 public void closeSystemDialogs(String reason) {
5552 enforceNotIsolatedCaller("closeSystemDialogs");
5554 final int pid = Binder.getCallingPid();
5555 final int uid = Binder.getCallingUid();
5556 final long origId = Binder.clearCallingIdentity();
5558 synchronized (this) {
5559 // Only allow this from foreground processes, so that background
5560 // applications can't abuse it to prevent system UI from being shown.
5561 if (uid >= Process.FIRST_APPLICATION_UID) {
5563 synchronized (mPidsSelfLocked) {
5564 proc = mPidsSelfLocked.get(pid);
5566 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5567 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5568 + " from background process " + proc);
5572 closeSystemDialogsLocked(reason);
5575 Binder.restoreCallingIdentity(origId);
5579 void closeSystemDialogsLocked(String reason) {
5580 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5581 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5582 | Intent.FLAG_RECEIVER_FOREGROUND);
5583 if (reason != null) {
5584 intent.putExtra("reason", reason);
5586 mWindowManager.closeSystemDialogs(reason);
5588 mStackSupervisor.closeSystemDialogsLocked();
5590 broadcastIntentLocked(null, null, intent, null,
5591 null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5592 Process.SYSTEM_UID, UserHandle.USER_ALL);
5596 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5597 enforceNotIsolatedCaller("getProcessMemoryInfo");
5598 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5599 for (int i=pids.length-1; i>=0; i--) {
5602 synchronized (this) {
5603 synchronized (mPidsSelfLocked) {
5604 proc = mPidsSelfLocked.get(pids[i]);
5605 oomAdj = proc != null ? proc.setAdj : 0;
5608 infos[i] = new Debug.MemoryInfo();
5609 Debug.getMemoryInfo(pids[i], infos[i]);
5611 synchronized (this) {
5612 if (proc.thread != null && proc.setAdj == oomAdj) {
5613 // Record this for posterity if the process has been stable.
5614 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5615 infos[i].getTotalUss(), false, proc.pkgList);
5624 public long[] getProcessPss(int[] pids) {
5625 enforceNotIsolatedCaller("getProcessPss");
5626 long[] pss = new long[pids.length];
5627 for (int i=pids.length-1; i>=0; i--) {
5630 synchronized (this) {
5631 synchronized (mPidsSelfLocked) {
5632 proc = mPidsSelfLocked.get(pids[i]);
5633 oomAdj = proc != null ? proc.setAdj : 0;
5636 long[] tmpUss = new long[1];
5637 pss[i] = Debug.getPss(pids[i], tmpUss);
5639 synchronized (this) {
5640 if (proc.thread != null && proc.setAdj == oomAdj) {
5641 // Record this for posterity if the process has been stable.
5642 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5651 public void killApplicationProcess(String processName, int uid) {
5652 if (processName == null) {
5656 int callerUid = Binder.getCallingUid();
5657 // Only the system server can kill an application
5658 if (callerUid == Process.SYSTEM_UID) {
5659 synchronized (this) {
5660 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5661 if (app != null && app.thread != null) {
5663 app.thread.scheduleSuicide();
5664 } catch (RemoteException e) {
5665 // If the other end already died, then our work here is done.
5668 Slog.w(TAG, "Process/uid not found attempting kill of "
5669 + processName + " / " + uid);
5673 throw new SecurityException(callerUid + " cannot kill app process: " +
5678 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5679 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5680 false, true, false, false, UserHandle.getUserId(uid), reason);
5681 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5682 Uri.fromParts("package", packageName, null));
5683 if (!mProcessesReady) {
5684 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5685 | Intent.FLAG_RECEIVER_FOREGROUND);
5687 intent.putExtra(Intent.EXTRA_UID, uid);
5688 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5689 broadcastIntentLocked(null, null, intent,
5690 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5692 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5695 private void forceStopUserLocked(int userId, String reason) {
5696 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5697 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5698 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5699 | Intent.FLAG_RECEIVER_FOREGROUND);
5700 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5701 broadcastIntentLocked(null, null, intent,
5702 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5704 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5707 private final boolean killPackageProcessesLocked(String packageName, int appId,
5708 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5709 boolean doit, boolean evenPersistent, String reason) {
5710 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5712 // Remove all processes this package may have touched: all with the
5713 // same UID (except for the system or root user), and all whose name
5714 // matches the package name.
5715 final int NP = mProcessNames.getMap().size();
5716 for (int ip=0; ip<NP; ip++) {
5717 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5718 final int NA = apps.size();
5719 for (int ia=0; ia<NA; ia++) {
5720 ProcessRecord app = apps.valueAt(ia);
5721 if (app.persistent && !evenPersistent) {
5722 // we don't kill persistent processes
5732 // Skip process if it doesn't meet our oom adj requirement.
5733 if (app.setAdj < minOomAdj) {
5737 // If no package is specified, we call all processes under the
5739 if (packageName == null) {
5740 if (app.userId != userId) {
5743 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5746 // Package has been specified, we want to hit all processes
5747 // that match it. We need to qualify this by the processes
5748 // that are running under the specified app and user ID.
5750 final boolean isDep = app.pkgDeps != null
5751 && app.pkgDeps.contains(packageName);
5752 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5755 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5758 if (!app.pkgList.containsKey(packageName) && !isDep) {
5763 // Process has passed all conditions, kill it!
5772 int N = procs.size();
5773 for (int i=0; i<N; i++) {
5774 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5776 updateOomAdjLocked();
5780 private final boolean forceStopPackageLocked(String name, int appId,
5781 boolean callerWillRestart, boolean purgeCache, boolean doit,
5782 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5786 if (userId == UserHandle.USER_ALL && name == null) {
5787 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5790 if (appId < 0 && name != null) {
5792 appId = UserHandle.getAppId(
5793 AppGlobals.getPackageManager().getPackageUid(name, 0));
5794 } catch (RemoteException e) {
5800 Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5801 + " user=" + userId + ": " + reason);
5803 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5806 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5807 for (int ip=pmap.size()-1; ip>=0; ip--) {
5808 SparseArray<Long> ba = pmap.valueAt(ip);
5809 for (i=ba.size()-1; i>=0; i--) {
5810 boolean remove = false;
5811 final int entUid = ba.keyAt(i);
5813 if (userId == UserHandle.USER_ALL) {
5814 if (UserHandle.getAppId(entUid) == appId) {
5818 if (entUid == UserHandle.getUid(userId, appId)) {
5822 } else if (UserHandle.getUserId(entUid) == userId) {
5829 if (ba.size() == 0) {
5835 boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5836 -100, callerWillRestart, true, doit, evenPersistent,
5837 name == null ? ("stop user " + userId) : ("stop " + name));
5839 if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5843 didSomething = true;
5846 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5850 didSomething = true;
5854 // Remove all sticky broadcasts from this user.
5855 mStickyBroadcasts.remove(userId);
5858 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5859 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5860 userId, providers)) {
5864 didSomething = true;
5866 N = providers.size();
5867 for (i=0; i<N; i++) {
5868 removeDyingProviderLocked(null, providers.get(i), true);
5871 // Remove transient permissions granted from/to this package/user
5872 removeUriPermissionsForPackageLocked(name, userId, false);
5874 if (name == null || uninstalling) {
5875 // Remove pending intents. For now we only do this when force
5876 // stopping users, because we have some problems when doing this
5877 // for packages -- app widgets are not currently cleaned up for
5878 // such packages, so they can be left with bad pending intents.
5879 if (mIntentSenderRecords.size() > 0) {
5880 Iterator<WeakReference<PendingIntentRecord>> it
5881 = mIntentSenderRecords.values().iterator();
5882 while (it.hasNext()) {
5883 WeakReference<PendingIntentRecord> wpir = it.next();
5888 PendingIntentRecord pir = wpir.get();
5894 // Stopping user, remove all objects for the user.
5895 if (pir.key.userId != userId) {
5896 // Not the same user, skip it.
5900 if (UserHandle.getAppId(pir.uid) != appId) {
5901 // Different app id, skip it.
5904 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5905 // Different user, skip it.
5908 if (!pir.key.packageName.equals(name)) {
5909 // Different package, skip it.
5916 didSomething = true;
5918 pir.canceled = true;
5919 if (pir.key.activity != null) {
5920 pir.key.activity.pendingResults.remove(pir.ref);
5927 if (purgeCache && name != null) {
5928 AttributeCache ac = AttributeCache.instance();
5930 ac.removePackage(name);
5934 mStackSupervisor.resumeTopActivitiesLocked();
5935 mStackSupervisor.scheduleIdleLocked();
5939 return didSomething;
5942 private final boolean removeProcessLocked(ProcessRecord app,
5943 boolean callerWillRestart, boolean allowRestart, String reason) {
5944 final String name = app.processName;
5945 final int uid = app.uid;
5946 if (DEBUG_PROCESSES) Slog.d(
5947 TAG, "Force removing proc " + app.toShortString() + " (" + name
5950 mProcessNames.remove(name, uid);
5951 mIsolatedProcesses.remove(app.uid);
5952 if (mHeavyWeightProcess == app) {
5953 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5954 mHeavyWeightProcess.userId, 0));
5955 mHeavyWeightProcess = null;
5957 boolean needRestart = false;
5958 if (app.pid > 0 && app.pid != MY_PID) {
5960 synchronized (mPidsSelfLocked) {
5961 mPidsSelfLocked.remove(pid);
5962 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5964 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5966 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5968 app.kill(reason, true);
5969 handleAppDiedLocked(app, true, allowRestart);
5970 removeLruProcessLocked(app);
5972 if (app.persistent && !app.isolated) {
5973 if (!callerWillRestart) {
5974 addAppLocked(app.info, false, null /* ABI override */);
5980 mRemovedProcesses.add(app);
5986 private final void processStartTimedOutLocked(ProcessRecord app) {
5987 final int pid = app.pid;
5988 boolean gone = false;
5989 synchronized (mPidsSelfLocked) {
5990 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5991 if (knownApp != null && knownApp.thread == null) {
5992 mPidsSelfLocked.remove(pid);
5998 Slog.w(TAG, "Process " + app + " failed to attach");
5999 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6000 pid, app.uid, app.processName);
6001 mProcessNames.remove(app.processName, app.uid);
6002 mIsolatedProcesses.remove(app.uid);
6003 if (mHeavyWeightProcess == app) {
6004 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6005 mHeavyWeightProcess.userId, 0));
6006 mHeavyWeightProcess = null;
6008 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6010 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6012 // Take care of any launching providers waiting for this process.
6013 checkAppInLaunchingProvidersLocked(app, true);
6014 // Take care of any services that are waiting for the process.
6015 mServices.processStartTimedOutLocked(app);
6016 app.kill("start timeout", true);
6017 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6018 Slog.w(TAG, "Unattached app died before backup, skipping");
6020 IBackupManager bm = IBackupManager.Stub.asInterface(
6021 ServiceManager.getService(Context.BACKUP_SERVICE));
6022 bm.agentDisconnected(app.info.packageName);
6023 } catch (RemoteException e) {
6024 // Can't happen; the backup manager is local
6027 if (isPendingBroadcastProcessLocked(pid)) {
6028 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6029 skipPendingBroadcastLocked(pid);
6032 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6036 private final boolean attachApplicationLocked(IApplicationThread thread,
6039 // Find the application record that is being attached... either via
6040 // the pid if we are running in multiple processes, or just pull the
6041 // next app record if we are emulating process with anonymous threads.
6043 if (pid != MY_PID && pid >= 0) {
6044 synchronized (mPidsSelfLocked) {
6045 app = mPidsSelfLocked.get(pid);
6052 Slog.w(TAG, "No pending application record for pid " + pid
6053 + " (IApplicationThread " + thread + "); dropping process");
6054 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6055 if (pid > 0 && pid != MY_PID) {
6056 Process.killProcessQuiet(pid);
6057 //TODO: Process.killProcessGroup(app.info.uid, pid);
6060 thread.scheduleExit();
6061 } catch (Exception e) {
6062 // Ignore exceptions.
6068 // If this application record is still attached to a previous
6069 // process, clean it up now.
6070 if (app.thread != null) {
6071 handleAppDiedLocked(app, true, true);
6074 // Tell the process all about itself.
6076 if (localLOGV) Slog.v(
6077 TAG, "Binding process pid " + pid + " to record " + app);
6079 final String processName = app.processName;
6081 AppDeathRecipient adr = new AppDeathRecipient(
6083 thread.asBinder().linkToDeath(adr, 0);
6084 app.deathRecipient = adr;
6085 } catch (RemoteException e) {
6086 app.resetPackageList(mProcessStats);
6087 startProcessLocked(app, "link fail", processName);
6091 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6093 app.makeActive(thread, mProcessStats);
6094 app.curAdj = app.setAdj = -100;
6095 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6096 app.forcingToForeground = null;
6097 updateProcessForegroundLocked(app, false, false);
6098 app.hasShownUi = false;
6099 app.debugging = false;
6102 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6104 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6105 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6108 Slog.i(TAG, "Launching preboot mode app: " + app);
6111 if (localLOGV) Slog.v(
6112 TAG, "New app record " + app
6113 + " thread=" + thread.asBinder() + " pid=" + pid);
6115 int testMode = IApplicationThread.DEBUG_OFF;
6116 if (mDebugApp != null && mDebugApp.equals(processName)) {
6117 testMode = mWaitForDebugger
6118 ? IApplicationThread.DEBUG_WAIT
6119 : IApplicationThread.DEBUG_ON;
6120 app.debugging = true;
6121 if (mDebugTransient) {
6122 mDebugApp = mOrigDebugApp;
6123 mWaitForDebugger = mOrigWaitForDebugger;
6126 String profileFile = app.instrumentationProfileFile;
6127 ParcelFileDescriptor profileFd = null;
6128 int samplingInterval = 0;
6129 boolean profileAutoStop = false;
6130 if (mProfileApp != null && mProfileApp.equals(processName)) {
6132 profileFile = mProfileFile;
6133 profileFd = mProfileFd;
6134 samplingInterval = mSamplingInterval;
6135 profileAutoStop = mAutoStopProfiler;
6137 boolean enableOpenGlTrace = false;
6138 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6139 enableOpenGlTrace = true;
6140 mOpenGlTraceApp = null;
6143 // If the app is being launched for restore or full backup, set it up specially
6144 boolean isRestrictedBackupMode = false;
6145 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6146 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6147 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6148 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6151 ensurePackageDexOpt(app.instrumentationInfo != null
6152 ? app.instrumentationInfo.packageName
6153 : app.info.packageName);
6154 if (app.instrumentationClass != null) {
6155 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6157 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6158 + processName + " with config " + mConfiguration);
6159 ApplicationInfo appInfo = app.instrumentationInfo != null
6160 ? app.instrumentationInfo : app.info;
6161 app.compat = compatibilityInfoForPackageLocked(appInfo);
6162 if (profileFd != null) {
6163 profileFd = profileFd.dup();
6165 ProfilerInfo profilerInfo = profileFile == null ? null
6166 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6167 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6168 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6169 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6170 isRestrictedBackupMode || !normalMode, app.persistent,
6171 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6172 mCoreSettingsObserver.getCoreSettingsLocked());
6173 updateLruProcessLocked(app, false, null);
6174 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6175 } catch (Exception e) {
6176 // todo: Yikes! What should we do? For now we will try to
6177 // start another process, but that could easily get us in
6178 // an infinite loop of restarting processes...
6179 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6181 app.resetPackageList(mProcessStats);
6182 app.unlinkDeathRecipient();
6183 startProcessLocked(app, "bind fail", processName);
6187 // Remove this record from the list of starting applications.
6188 mPersistentStartingProcesses.remove(app);
6189 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6190 "Attach application locked removing on hold: " + app);
6191 mProcessesOnHold.remove(app);
6193 boolean badApp = false;
6194 boolean didSomething = false;
6196 // See if the top visible activity is waiting to run in this process...
6199 if (mStackSupervisor.attachApplicationLocked(app)) {
6200 didSomething = true;
6202 } catch (Exception e) {
6203 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6208 // Find any services that should be running in this process...
6211 didSomething |= mServices.attachApplicationLocked(app, processName);
6212 } catch (Exception e) {
6213 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6218 // Check if a next-broadcast receiver is in this process...
6219 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6221 didSomething |= sendPendingBroadcastsLocked(app);
6222 } catch (Exception e) {
6223 // If the app died trying to launch the receiver we declare it 'bad'
6224 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6229 // Check whether the next backup agent is in this process...
6230 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6231 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6232 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6234 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6235 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6236 mBackupTarget.backupMode);
6237 } catch (Exception e) {
6238 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6244 app.kill("error during init", true);
6245 handleAppDiedLocked(app, false, true);
6249 if (!didSomething) {
6250 updateOomAdjLocked();
6257 public final void attachApplication(IApplicationThread thread) {
6258 synchronized (this) {
6259 int callingPid = Binder.getCallingPid();
6260 final long origId = Binder.clearCallingIdentity();
6261 attachApplicationLocked(thread, callingPid);
6262 Binder.restoreCallingIdentity(origId);
6267 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6268 final long origId = Binder.clearCallingIdentity();
6269 synchronized (this) {
6270 ActivityStack stack = ActivityRecord.getStackLocked(token);
6271 if (stack != null) {
6273 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6274 if (stopProfiling) {
6275 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6278 } catch (IOException e) {
6280 clearProfilerLocked();
6285 Binder.restoreCallingIdentity(origId);
6288 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6289 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6290 finishBooting? 1 : 0, enableScreen ? 1 : 0));
6293 void enableScreenAfterBoot() {
6294 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6295 SystemClock.uptimeMillis());
6296 mWindowManager.enableScreenAfterBoot();
6298 synchronized (this) {
6299 updateEventDispatchingLocked();
6304 public void showBootMessage(final CharSequence msg, final boolean always) {
6305 enforceNotIsolatedCaller("showBootMessage");
6306 mWindowManager.showBootMessage(msg, always);
6310 public void keyguardWaitingForActivityDrawn() {
6311 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6312 final long token = Binder.clearCallingIdentity();
6314 synchronized (this) {
6315 if (DEBUG_LOCKSCREEN) logLockScreen("");
6316 mWindowManager.keyguardWaitingForActivityDrawn();
6317 if (mLockScreenShown) {
6318 mLockScreenShown = false;
6319 updateSleepIfNeededLocked();
6323 Binder.restoreCallingIdentity(token);
6327 final void finishBooting() {
6328 synchronized (this) {
6329 if (!mBootAnimationComplete) {
6330 mCallFinishBooting = true;
6333 mCallFinishBooting = false;
6336 // Register receivers to handle package update events
6337 mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
6339 // Let system services know.
6340 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6342 synchronized (this) {
6343 // Ensure that any processes we had put on hold are now started
6345 final int NP = mProcessesOnHold.size();
6347 ArrayList<ProcessRecord> procs =
6348 new ArrayList<ProcessRecord>(mProcessesOnHold);
6349 for (int ip=0; ip<NP; ip++) {
6350 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6352 startProcessLocked(procs.get(ip), "on-hold", null);
6356 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6357 // Start looking for apps that are abusing wake locks.
6358 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6359 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6360 // Tell anyone interested that we are done booting!
6361 SystemProperties.set("sys.boot_completed", "1");
6363 // And trigger dev.bootcomplete if we are not showing encryption progress
6364 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6365 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6366 SystemProperties.set("dev.bootcomplete", "1");
6368 for (int i=0; i<mStartedUsers.size(); i++) {
6369 UserStartedState uss = mStartedUsers.valueAt(i);
6370 if (uss.mState == UserStartedState.STATE_BOOTING) {
6371 uss.mState = UserStartedState.STATE_RUNNING;
6372 final int userId = mStartedUsers.keyAt(i);
6373 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6374 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6375 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6376 broadcastIntentLocked(null, null, intent, null,
6377 new IIntentReceiver.Stub() {
6379 public void performReceive(Intent intent, int resultCode,
6380 String data, Bundle extras, boolean ordered,
6381 boolean sticky, int sendingUser) {
6382 synchronized (ActivityManagerService.this) {
6383 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6389 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6390 AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6394 scheduleStartProfilesLocked();
6400 public void bootAnimationComplete() {
6401 final boolean callFinishBooting;
6402 synchronized (this) {
6403 callFinishBooting = mCallFinishBooting;
6404 mBootAnimationComplete = true;
6406 if (callFinishBooting) {
6411 final void ensureBootCompleted() {
6413 boolean enableScreen;
6414 synchronized (this) {
6417 enableScreen = !mBooted;
6426 enableScreenAfterBoot();
6431 public final void activityResumed(IBinder token) {
6432 final long origId = Binder.clearCallingIdentity();
6433 synchronized(this) {
6434 ActivityStack stack = ActivityRecord.getStackLocked(token);
6435 if (stack != null) {
6436 ActivityRecord.activityResumedLocked(token);
6439 Binder.restoreCallingIdentity(origId);
6443 public final void activityPaused(IBinder token) {
6444 final long origId = Binder.clearCallingIdentity();
6445 synchronized(this) {
6446 ActivityStack stack = ActivityRecord.getStackLocked(token);
6447 if (stack != null) {
6448 stack.activityPausedLocked(token, false);
6451 Binder.restoreCallingIdentity(origId);
6455 public final void activityStopped(IBinder token, Bundle icicle,
6456 PersistableBundle persistentState, CharSequence description) {
6457 if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6459 // Refuse possible leaked file descriptors
6460 if (icicle != null && icicle.hasFileDescriptors()) {
6461 throw new IllegalArgumentException("File descriptors passed in Bundle");
6464 final long origId = Binder.clearCallingIdentity();
6466 synchronized (this) {
6467 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6469 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6475 Binder.restoreCallingIdentity(origId);
6479 public final void activityDestroyed(IBinder token) {
6480 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6481 synchronized (this) {
6482 ActivityStack stack = ActivityRecord.getStackLocked(token);
6483 if (stack != null) {
6484 stack.activityDestroyedLocked(token);
6490 public final void backgroundResourcesReleased(IBinder token) {
6491 final long origId = Binder.clearCallingIdentity();
6493 synchronized (this) {
6494 ActivityStack stack = ActivityRecord.getStackLocked(token);
6495 if (stack != null) {
6496 stack.backgroundResourcesReleased(token);
6500 Binder.restoreCallingIdentity(origId);
6505 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6506 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6510 public final void notifyEnterAnimationComplete(IBinder token) {
6511 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6515 public String getCallingPackage(IBinder token) {
6516 synchronized (this) {
6517 ActivityRecord r = getCallingRecordLocked(token);
6518 return r != null ? r.info.packageName : null;
6523 public ComponentName getCallingActivity(IBinder token) {
6524 synchronized (this) {
6525 ActivityRecord r = getCallingRecordLocked(token);
6526 return r != null ? r.intent.getComponent() : null;
6530 private ActivityRecord getCallingRecordLocked(IBinder token) {
6531 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6539 public ComponentName getActivityClassForToken(IBinder token) {
6540 synchronized(this) {
6541 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6545 return r.intent.getComponent();
6550 public String getPackageForToken(IBinder token) {
6551 synchronized(this) {
6552 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6556 return r.packageName;
6561 public IIntentSender getIntentSender(int type,
6562 String packageName, IBinder token, String resultWho,
6563 int requestCode, Intent[] intents, String[] resolvedTypes,
6564 int flags, Bundle options, int userId) {
6565 enforceNotIsolatedCaller("getIntentSender");
6566 // Refuse possible leaked file descriptors
6567 if (intents != null) {
6568 if (intents.length < 1) {
6569 throw new IllegalArgumentException("Intents array length must be >= 1");
6571 for (int i=0; i<intents.length; i++) {
6572 Intent intent = intents[i];
6573 if (intent != null) {
6574 if (intent.hasFileDescriptors()) {
6575 throw new IllegalArgumentException("File descriptors passed in Intent");
6577 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6578 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6579 throw new IllegalArgumentException(
6580 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6582 intents[i] = new Intent(intent);
6585 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6586 throw new IllegalArgumentException(
6587 "Intent array length does not match resolvedTypes length");
6590 if (options != null) {
6591 if (options.hasFileDescriptors()) {
6592 throw new IllegalArgumentException("File descriptors passed in options");
6596 synchronized(this) {
6597 int callingUid = Binder.getCallingUid();
6598 int origUserId = userId;
6599 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6600 type == ActivityManager.INTENT_SENDER_BROADCAST,
6601 ALLOW_NON_FULL, "getIntentSender", null);
6602 if (origUserId == UserHandle.USER_CURRENT) {
6603 // We don't want to evaluate this until the pending intent is
6604 // actually executed. However, we do want to always do the
6605 // security checking for it above.
6606 userId = UserHandle.USER_CURRENT;
6609 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6610 int uid = AppGlobals.getPackageManager()
6611 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6612 if (!UserHandle.isSameApp(callingUid, uid)) {
6613 String msg = "Permission Denial: getIntentSender() from pid="
6614 + Binder.getCallingPid()
6615 + ", uid=" + Binder.getCallingUid()
6616 + ", (need uid=" + uid + ")"
6617 + " is not allowed to send as package " + packageName;
6619 throw new SecurityException(msg);
6623 return getIntentSenderLocked(type, packageName, callingUid, userId,
6624 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6626 } catch (RemoteException e) {
6627 throw new SecurityException(e);
6632 IIntentSender getIntentSenderLocked(int type, String packageName,
6633 int callingUid, int userId, IBinder token, String resultWho,
6634 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6637 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6638 ActivityRecord activity = null;
6639 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6640 activity = ActivityRecord.isInStackLocked(token);
6641 if (activity == null) {
6644 if (activity.finishing) {
6649 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6650 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6651 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6652 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6653 |PendingIntent.FLAG_UPDATE_CURRENT);
6655 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6656 type, packageName, activity, resultWho,
6657 requestCode, intents, resolvedTypes, flags, options, userId);
6658 WeakReference<PendingIntentRecord> ref;
6659 ref = mIntentSenderRecords.get(key);
6660 PendingIntentRecord rec = ref != null ? ref.get() : null;
6662 if (!cancelCurrent) {
6663 if (updateCurrent) {
6664 if (rec.key.requestIntent != null) {
6665 rec.key.requestIntent.replaceExtras(intents != null ?
6666 intents[intents.length - 1] : null);
6668 if (intents != null) {
6669 intents[intents.length-1] = rec.key.requestIntent;
6670 rec.key.allIntents = intents;
6671 rec.key.allResolvedTypes = resolvedTypes;
6673 rec.key.allIntents = null;
6674 rec.key.allResolvedTypes = null;
6679 rec.canceled = true;
6680 mIntentSenderRecords.remove(key);
6685 rec = new PendingIntentRecord(this, key, callingUid);
6686 mIntentSenderRecords.put(key, rec.ref);
6687 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6688 if (activity.pendingResults == null) {
6689 activity.pendingResults
6690 = new HashSet<WeakReference<PendingIntentRecord>>();
6692 activity.pendingResults.add(rec.ref);
6698 public void cancelIntentSender(IIntentSender sender) {
6699 if (!(sender instanceof PendingIntentRecord)) {
6702 synchronized(this) {
6703 PendingIntentRecord rec = (PendingIntentRecord)sender;
6705 int uid = AppGlobals.getPackageManager()
6706 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6707 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6708 String msg = "Permission Denial: cancelIntentSender() from pid="
6709 + Binder.getCallingPid()
6710 + ", uid=" + Binder.getCallingUid()
6711 + " is not allowed to cancel packges "
6712 + rec.key.packageName;
6714 throw new SecurityException(msg);
6716 } catch (RemoteException e) {
6717 throw new SecurityException(e);
6719 cancelIntentSenderLocked(rec, true);
6723 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6724 rec.canceled = true;
6725 mIntentSenderRecords.remove(rec.key);
6726 if (cleanActivity && rec.key.activity != null) {
6727 rec.key.activity.pendingResults.remove(rec.ref);
6732 public String getPackageForIntentSender(IIntentSender pendingResult) {
6733 if (!(pendingResult instanceof PendingIntentRecord)) {
6737 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6738 return res.key.packageName;
6739 } catch (ClassCastException e) {
6745 public int getUidForIntentSender(IIntentSender sender) {
6746 if (sender instanceof PendingIntentRecord) {
6748 PendingIntentRecord res = (PendingIntentRecord)sender;
6750 } catch (ClassCastException e) {
6757 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6758 if (!(pendingResult instanceof PendingIntentRecord)) {
6762 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6763 if (res.key.allIntents == null) {
6766 for (int i=0; i<res.key.allIntents.length; i++) {
6767 Intent intent = res.key.allIntents[i];
6768 if (intent.getPackage() != null && intent.getComponent() != null) {
6773 } catch (ClassCastException e) {
6779 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6780 if (!(pendingResult instanceof PendingIntentRecord)) {
6784 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6785 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6789 } catch (ClassCastException e) {
6795 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6796 if (!(pendingResult instanceof PendingIntentRecord)) {
6800 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6801 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6802 } catch (ClassCastException e) {
6808 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6809 if (!(pendingResult instanceof PendingIntentRecord)) {
6813 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6814 Intent intent = res.key.requestIntent;
6815 if (intent != null) {
6816 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6817 || res.lastTagPrefix.equals(prefix))) {
6820 res.lastTagPrefix = prefix;
6821 StringBuilder sb = new StringBuilder(128);
6822 if (prefix != null) {
6825 if (intent.getAction() != null) {
6826 sb.append(intent.getAction());
6827 } else if (intent.getComponent() != null) {
6828 intent.getComponent().appendShortString(sb);
6832 return res.lastTag = sb.toString();
6834 } catch (ClassCastException e) {
6840 public void setProcessLimit(int max) {
6841 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6842 "setProcessLimit()");
6843 synchronized (this) {
6844 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6845 mProcessLimitOverride = max;
6851 public int getProcessLimit() {
6852 synchronized (this) {
6853 return mProcessLimitOverride;
6857 void foregroundTokenDied(ForegroundToken token) {
6858 synchronized (ActivityManagerService.this) {
6859 synchronized (mPidsSelfLocked) {
6861 = mForegroundProcesses.get(token.pid);
6865 mForegroundProcesses.remove(token.pid);
6866 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6870 pr.forcingToForeground = null;
6871 updateProcessForegroundLocked(pr, false, false);
6873 updateOomAdjLocked();
6878 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6879 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6880 "setProcessForeground()");
6881 synchronized(this) {
6882 boolean changed = false;
6884 synchronized (mPidsSelfLocked) {
6885 ProcessRecord pr = mPidsSelfLocked.get(pid);
6886 if (pr == null && isForeground) {
6887 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6890 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6891 if (oldToken != null) {
6892 oldToken.token.unlinkToDeath(oldToken, 0);
6893 mForegroundProcesses.remove(pid);
6895 pr.forcingToForeground = null;
6899 if (isForeground && token != null) {
6900 ForegroundToken newToken = new ForegroundToken() {
6902 public void binderDied() {
6903 foregroundTokenDied(this);
6907 newToken.token = token;
6909 token.linkToDeath(newToken, 0);
6910 mForegroundProcesses.put(pid, newToken);
6911 pr.forcingToForeground = token;
6913 } catch (RemoteException e) {
6914 // If the process died while doing this, we will later
6915 // do the cleanup with the process death link.
6921 updateOomAdjLocked();
6926 // =========================================================
6928 // =========================================================
6930 static class PermissionController extends IPermissionController.Stub {
6931 ActivityManagerService mActivityManagerService;
6932 PermissionController(ActivityManagerService activityManagerService) {
6933 mActivityManagerService = activityManagerService;
6937 public boolean checkPermission(String permission, int pid, int uid) {
6938 return mActivityManagerService.checkPermission(permission, pid,
6939 uid) == PackageManager.PERMISSION_GRANTED;
6943 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6945 public int checkComponentPermission(String permission, int pid, int uid,
6946 int owningUid, boolean exported) {
6947 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6948 owningUid, exported);
6952 public Object getAMSLock() {
6953 return ActivityManagerService.this;
6958 * This can be called with or without the global lock held.
6960 int checkComponentPermission(String permission, int pid, int uid,
6961 int owningUid, boolean exported) {
6962 // We might be performing an operation on behalf of an indirect binder
6963 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
6964 // client identity accordingly before proceeding.
6965 Identity tlsIdentity = sCallerIdentity.get();
6966 if (tlsIdentity != null) {
6967 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6968 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6969 uid = tlsIdentity.uid;
6970 pid = tlsIdentity.pid;
6973 if (pid == MY_PID) {
6974 return PackageManager.PERMISSION_GRANTED;
6977 return ActivityManager.checkComponentPermission(permission, uid,
6978 owningUid, exported);
6982 * As the only public entry point for permissions checking, this method
6983 * can enforce the semantic that requesting a check on a null global
6984 * permission is automatically denied. (Internally a null permission
6985 * string is used when calling {@link #checkComponentPermission} in cases
6986 * when only uid-based security is needed.)
6988 * This can be called with or without the global lock held.
6991 public int checkPermission(String permission, int pid, int uid) {
6992 if (permission == null) {
6993 return PackageManager.PERMISSION_DENIED;
6995 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6999 * Binder IPC calls go through the public entry point.
7000 * This can be called with or without the global lock held.
7002 int checkCallingPermission(String permission) {
7003 return checkPermission(permission,
7004 Binder.getCallingPid(),
7005 UserHandle.getAppId(Binder.getCallingUid()));
7009 * This can be called with or without the global lock held.
7011 void enforceCallingPermission(String permission, String func) {
7012 if (checkCallingPermission(permission)
7013 == PackageManager.PERMISSION_GRANTED) {
7017 String msg = "Permission Denial: " + func + " from pid="
7018 + Binder.getCallingPid()
7019 + ", uid=" + Binder.getCallingUid()
7020 + " requires " + permission;
7022 throw new SecurityException(msg);
7026 * Determine if UID is holding permissions required to access {@link Uri} in
7027 * the given {@link ProviderInfo}. Final permission checking is always done
7028 * in {@link ContentProvider}.
7030 private final boolean checkHoldingPermissionsLocked(
7031 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7032 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7033 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7034 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7035 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7036 != PERMISSION_GRANTED) {
7040 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7043 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7044 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7045 if (pi.applicationInfo.uid == uid) {
7047 } else if (!pi.exported) {
7051 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7052 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7054 // check if target holds top-level <provider> permissions
7055 if (!readMet && pi.readPermission != null && considerUidPermissions
7056 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7059 if (!writeMet && pi.writePermission != null && considerUidPermissions
7060 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7064 // track if unprotected read/write is allowed; any denied
7065 // <path-permission> below removes this ability
7066 boolean allowDefaultRead = pi.readPermission == null;
7067 boolean allowDefaultWrite = pi.writePermission == null;
7069 // check if target holds any <path-permission> that match uri
7070 final PathPermission[] pps = pi.pathPermissions;
7072 final String path = grantUri.uri.getPath();
7074 while (i > 0 && (!readMet || !writeMet)) {
7076 PathPermission pp = pps[i];
7077 if (pp.match(path)) {
7079 final String pprperm = pp.getReadPermission();
7080 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
7081 + pprperm + " for " + pp.getPath()
7082 + ": match=" + pp.match(path)
7083 + " check=" + pm.checkUidPermission(pprperm, uid));
7084 if (pprperm != null) {
7085 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7086 == PERMISSION_GRANTED) {
7089 allowDefaultRead = false;
7094 final String ppwperm = pp.getWritePermission();
7095 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
7096 + ppwperm + " for " + pp.getPath()
7097 + ": match=" + pp.match(path)
7098 + " check=" + pm.checkUidPermission(ppwperm, uid));
7099 if (ppwperm != null) {
7100 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7101 == PERMISSION_GRANTED) {
7104 allowDefaultWrite = false;
7112 // grant unprotected <provider> read/write, if not blocked by
7113 // <path-permission> above
7114 if (allowDefaultRead) readMet = true;
7115 if (allowDefaultWrite) writeMet = true;
7117 } catch (RemoteException e) {
7121 return readMet && writeMet;
7124 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7125 ProviderInfo pi = null;
7126 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7131 pi = AppGlobals.getPackageManager().resolveContentProvider(
7132 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7133 } catch (RemoteException ex) {
7139 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7140 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7141 if (targetUris != null) {
7142 return targetUris.get(grantUri);
7147 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7148 String targetPkg, int targetUid, GrantUri grantUri) {
7149 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7150 if (targetUris == null) {
7151 targetUris = Maps.newArrayMap();
7152 mGrantedUriPermissions.put(targetUid, targetUris);
7155 UriPermission perm = targetUris.get(grantUri);
7157 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7158 targetUris.put(grantUri, perm);
7164 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7165 final int modeFlags) {
7166 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7167 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7168 : UriPermission.STRENGTH_OWNED;
7170 // Root gets to do everything.
7175 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7176 if (perms == null) return false;
7178 // First look for exact match
7179 final UriPermission exactPerm = perms.get(grantUri);
7180 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7184 // No exact match, look for prefixes
7185 final int N = perms.size();
7186 for (int i = 0; i < N; i++) {
7187 final UriPermission perm = perms.valueAt(i);
7188 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7189 && perm.getStrength(modeFlags) >= minStrength) {
7198 * @param uri This uri must NOT contain an embedded userId.
7199 * @param userId The userId in which the uri is to be resolved.
7202 public int checkUriPermission(Uri uri, int pid, int uid,
7203 final int modeFlags, int userId) {
7204 enforceNotIsolatedCaller("checkUriPermission");
7206 // Another redirected-binder-call permissions check as in
7207 // {@link checkComponentPermission}.
7208 Identity tlsIdentity = sCallerIdentity.get();
7209 if (tlsIdentity != null) {
7210 uid = tlsIdentity.uid;
7211 pid = tlsIdentity.pid;
7214 // Our own process gets to do everything.
7215 if (pid == MY_PID) {
7216 return PackageManager.PERMISSION_GRANTED;
7218 synchronized (this) {
7219 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7220 ? PackageManager.PERMISSION_GRANTED
7221 : PackageManager.PERMISSION_DENIED;
7226 * Check if the targetPkg can be granted permission to access uri by
7227 * the callingUid using the given modeFlags. Throws a security exception
7228 * if callingUid is not allowed to do this. Returns the uid of the target
7229 * if the URI permission grant should be performed; returns -1 if it is not
7230 * needed (for example targetPkg already has permission to access the URI).
7231 * If you already know the uid of the target, you can supply it in
7232 * lastTargetUid else set that to -1.
7234 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7235 final int modeFlags, int lastTargetUid) {
7236 if (!Intent.isAccessUriMode(modeFlags)) {
7240 if (targetPkg != null) {
7241 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7242 "Checking grant " + targetPkg + " permission to " + grantUri);
7245 final IPackageManager pm = AppGlobals.getPackageManager();
7247 // If this is not a content: uri, we can't do anything with it.
7248 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7249 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7250 "Can't grant URI permission for non-content URI: " + grantUri);
7254 final String authority = grantUri.uri.getAuthority();
7255 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7257 Slog.w(TAG, "No content provider found for permission check: " +
7258 grantUri.uri.toSafeString());
7262 int targetUid = lastTargetUid;
7263 if (targetUid < 0 && targetPkg != null) {
7265 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7266 if (targetUid < 0) {
7267 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7268 "Can't grant URI permission no uid for: " + targetPkg);
7271 } catch (RemoteException ex) {
7276 if (targetUid >= 0) {
7277 // First... does the target actually need this permission?
7278 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7279 // No need to grant the target this permission.
7280 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7281 "Target " + targetPkg + " already has full permission to " + grantUri);
7285 // First... there is no target package, so can anyone access it?
7286 boolean allowed = pi.exported;
7287 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7288 if (pi.readPermission != null) {
7292 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7293 if (pi.writePermission != null) {
7302 /* There is a special cross user grant if:
7303 * - The target is on another user.
7304 * - Apps on the current user can access the uri without any uid permissions.
7305 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7306 * grant uri permissions.
7308 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7309 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7310 modeFlags, false /*without considering the uid permissions*/);
7312 // Second... is the provider allowing granting of URI permissions?
7313 if (!specialCrossUserGrant) {
7314 if (!pi.grantUriPermissions) {
7315 throw new SecurityException("Provider " + pi.packageName
7317 + " does not allow granting of Uri permissions (uri "
7320 if (pi.uriPermissionPatterns != null) {
7321 final int N = pi.uriPermissionPatterns.length;
7322 boolean allowed = false;
7323 for (int i=0; i<N; i++) {
7324 if (pi.uriPermissionPatterns[i] != null
7325 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7331 throw new SecurityException("Provider " + pi.packageName
7333 + " does not allow granting of permission to path of Uri "
7339 // Third... does the caller itself have permission to access
7341 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7342 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7343 // Require they hold a strong enough Uri permission
7344 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7345 throw new SecurityException("Uid " + callingUid
7346 + " does not have permission to uri " + grantUri);
7354 * @param uri This uri must NOT contain an embedded userId.
7355 * @param userId The userId in which the uri is to be resolved.
7358 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7359 final int modeFlags, int userId) {
7360 enforceNotIsolatedCaller("checkGrantUriPermission");
7361 synchronized(this) {
7362 return checkGrantUriPermissionLocked(callingUid, targetPkg,
7363 new GrantUri(userId, uri, false), modeFlags, -1);
7367 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7368 final int modeFlags, UriPermissionOwner owner) {
7369 if (!Intent.isAccessUriMode(modeFlags)) {
7373 // So here we are: the caller has the assumed permission
7374 // to the uri, and the target doesn't. Let's now give this to
7377 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7378 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7380 final String authority = grantUri.uri.getAuthority();
7381 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7383 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7387 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7388 grantUri.prefix = true;
7390 final UriPermission perm = findOrCreateUriPermissionLocked(
7391 pi.packageName, targetPkg, targetUid, grantUri);
7392 perm.grantModes(modeFlags, owner);
7395 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7396 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7397 if (targetPkg == null) {
7398 throw new NullPointerException("targetPkg");
7401 final IPackageManager pm = AppGlobals.getPackageManager();
7403 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7404 } catch (RemoteException ex) {
7408 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7410 if (targetUid < 0) {
7414 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7418 static class NeededUriGrants extends ArrayList<GrantUri> {
7419 final String targetPkg;
7420 final int targetUid;
7423 NeededUriGrants(String targetPkg, int targetUid, int flags) {
7424 this.targetPkg = targetPkg;
7425 this.targetUid = targetUid;
7431 * Like checkGrantUriPermissionLocked, but takes an Intent.
7433 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7434 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7435 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7436 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7437 + " clip=" + (intent != null ? intent.getClipData() : null)
7438 + " from " + intent + "; flags=0x"
7439 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7441 if (targetPkg == null) {
7442 throw new NullPointerException("targetPkg");
7445 if (intent == null) {
7448 Uri data = intent.getData();
7449 ClipData clip = intent.getClipData();
7450 if (data == null && clip == null) {
7453 // Default userId for uris in the intent (if they don't specify it themselves)
7454 int contentUserHint = intent.getContentUserHint();
7455 if (contentUserHint == UserHandle.USER_CURRENT) {
7456 contentUserHint = UserHandle.getUserId(callingUid);
7458 final IPackageManager pm = AppGlobals.getPackageManager();
7460 if (needed != null) {
7461 targetUid = needed.targetUid;
7464 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7465 } catch (RemoteException ex) {
7468 if (targetUid < 0) {
7469 if (DEBUG_URI_PERMISSION) {
7470 Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7471 + " on user " + targetUserId);
7477 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7478 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7480 if (targetUid > 0) {
7481 if (needed == null) {
7482 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7484 needed.add(grantUri);
7488 for (int i=0; i<clip.getItemCount(); i++) {
7489 Uri uri = clip.getItemAt(i).getUri();
7491 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7492 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7494 if (targetUid > 0) {
7495 if (needed == null) {
7496 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7498 needed.add(grantUri);
7501 Intent clipIntent = clip.getItemAt(i).getIntent();
7502 if (clipIntent != null) {
7503 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7504 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7505 if (newNeeded != null) {
7517 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7519 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7520 UriPermissionOwner owner) {
7521 if (needed != null) {
7522 for (int i=0; i<needed.size(); i++) {
7523 GrantUri grantUri = needed.get(i);
7524 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7525 grantUri, needed.flags, owner);
7530 void grantUriPermissionFromIntentLocked(int callingUid,
7531 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7532 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7533 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7534 if (needed == null) {
7538 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7542 * @param uri This uri must NOT contain an embedded userId.
7543 * @param userId The userId in which the uri is to be resolved.
7546 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7547 final int modeFlags, int userId) {
7548 enforceNotIsolatedCaller("grantUriPermission");
7549 GrantUri grantUri = new GrantUri(userId, uri, false);
7550 synchronized(this) {
7551 final ProcessRecord r = getRecordForAppLocked(caller);
7553 throw new SecurityException("Unable to find app for caller "
7555 + " when granting permission to uri " + grantUri);
7557 if (targetPkg == null) {
7558 throw new IllegalArgumentException("null target");
7560 if (grantUri == null) {
7561 throw new IllegalArgumentException("null uri");
7564 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7565 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7566 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7567 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7569 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7570 UserHandle.getUserId(r.uid));
7574 void removeUriPermissionIfNeededLocked(UriPermission perm) {
7575 if (perm.modeFlags == 0) {
7576 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7578 if (perms != null) {
7579 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7580 "Removing " + perm.targetUid + " permission to " + perm.uri);
7582 perms.remove(perm.uri);
7583 if (perms.isEmpty()) {
7584 mGrantedUriPermissions.remove(perm.targetUid);
7590 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7591 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7593 final IPackageManager pm = AppGlobals.getPackageManager();
7594 final String authority = grantUri.uri.getAuthority();
7595 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7597 Slog.w(TAG, "No content provider found for permission revoke: "
7598 + grantUri.toSafeString());
7602 // Does the caller have this permission on the URI?
7603 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7604 // If they don't have direct access to the URI, then revoke any
7605 // ownerless URI permissions that have been granted to them.
7606 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7607 if (perms != null) {
7608 boolean persistChanged = false;
7609 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7610 final UriPermission perm = it.next();
7611 if (perm.uri.sourceUserId == grantUri.sourceUserId
7612 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7613 if (DEBUG_URI_PERMISSION)
7614 Slog.v(TAG, "Revoking non-owned " + perm.targetUid +
7615 " permission to " + perm.uri);
7616 persistChanged |= perm.revokeModes(
7617 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7618 if (perm.modeFlags == 0) {
7623 if (perms.isEmpty()) {
7624 mGrantedUriPermissions.remove(callingUid);
7626 if (persistChanged) {
7627 schedulePersistUriGrants();
7633 boolean persistChanged = false;
7635 // Go through all of the permissions and remove any that match.
7636 int N = mGrantedUriPermissions.size();
7637 for (int i = 0; i < N; i++) {
7638 final int targetUid = mGrantedUriPermissions.keyAt(i);
7639 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7641 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7642 final UriPermission perm = it.next();
7643 if (perm.uri.sourceUserId == grantUri.sourceUserId
7644 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7645 if (DEBUG_URI_PERMISSION)
7647 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7648 persistChanged |= perm.revokeModes(
7649 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7650 if (perm.modeFlags == 0) {
7656 if (perms.isEmpty()) {
7657 mGrantedUriPermissions.remove(targetUid);
7663 if (persistChanged) {
7664 schedulePersistUriGrants();
7669 * @param uri This uri must NOT contain an embedded userId.
7670 * @param userId The userId in which the uri is to be resolved.
7673 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7675 enforceNotIsolatedCaller("revokeUriPermission");
7676 synchronized(this) {
7677 final ProcessRecord r = getRecordForAppLocked(caller);
7679 throw new SecurityException("Unable to find app for caller "
7681 + " when revoking permission to uri " + uri);
7684 Slog.w(TAG, "revokeUriPermission: null uri");
7688 if (!Intent.isAccessUriMode(modeFlags)) {
7692 final IPackageManager pm = AppGlobals.getPackageManager();
7693 final String authority = uri.getAuthority();
7694 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7696 Slog.w(TAG, "No content provider found for permission revoke: "
7697 + uri.toSafeString());
7701 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7706 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7709 * @param packageName Package name to match, or {@code null} to apply to all
7711 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7713 * @param persistable If persistable grants should be removed.
7715 private void removeUriPermissionsForPackageLocked(
7716 String packageName, int userHandle, boolean persistable) {
7717 if (userHandle == UserHandle.USER_ALL && packageName == null) {
7718 throw new IllegalArgumentException("Must narrow by either package or user");
7721 boolean persistChanged = false;
7723 int N = mGrantedUriPermissions.size();
7724 for (int i = 0; i < N; i++) {
7725 final int targetUid = mGrantedUriPermissions.keyAt(i);
7726 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7728 // Only inspect grants matching user
7729 if (userHandle == UserHandle.USER_ALL
7730 || userHandle == UserHandle.getUserId(targetUid)) {
7731 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7732 final UriPermission perm = it.next();
7734 // Only inspect grants matching package
7735 if (packageName == null || perm.sourcePkg.equals(packageName)
7736 || perm.targetPkg.equals(packageName)) {
7737 persistChanged |= perm.revokeModes(persistable
7738 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7740 // Only remove when no modes remain; any persisted grants
7741 // will keep this alive.
7742 if (perm.modeFlags == 0) {
7748 if (perms.isEmpty()) {
7749 mGrantedUriPermissions.remove(targetUid);
7756 if (persistChanged) {
7757 schedulePersistUriGrants();
7762 public IBinder newUriPermissionOwner(String name) {
7763 enforceNotIsolatedCaller("newUriPermissionOwner");
7764 synchronized(this) {
7765 UriPermissionOwner owner = new UriPermissionOwner(this, name);
7766 return owner.getExternalTokenLocked();
7771 * @param uri This uri must NOT contain an embedded userId.
7772 * @param sourceUserId The userId in which the uri is to be resolved.
7773 * @param targetUserId The userId of the app that receives the grant.
7776 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7777 final int modeFlags, int sourceUserId, int targetUserId) {
7778 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7779 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7780 synchronized(this) {
7781 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7782 if (owner == null) {
7783 throw new IllegalArgumentException("Unknown owner: " + token);
7785 if (fromUid != Binder.getCallingUid()) {
7786 if (Binder.getCallingUid() != Process.myUid()) {
7787 // Only system code can grant URI permissions on behalf
7789 throw new SecurityException("nice try");
7792 if (targetPkg == null) {
7793 throw new IllegalArgumentException("null target");
7796 throw new IllegalArgumentException("null uri");
7799 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7800 modeFlags, owner, targetUserId);
7805 * @param uri This uri must NOT contain an embedded userId.
7806 * @param userId The userId in which the uri is to be resolved.
7809 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7810 synchronized(this) {
7811 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7812 if (owner == null) {
7813 throw new IllegalArgumentException("Unknown owner: " + token);
7817 owner.removeUriPermissionsLocked(mode);
7819 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7824 private void schedulePersistUriGrants() {
7825 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7826 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7827 10 * DateUtils.SECOND_IN_MILLIS);
7831 private void writeGrantedUriPermissions() {
7832 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7834 // Snapshot permissions so we can persist without lock
7835 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7836 synchronized (this) {
7837 final int size = mGrantedUriPermissions.size();
7838 for (int i = 0; i < size; i++) {
7839 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7840 for (UriPermission perm : perms.values()) {
7841 if (perm.persistedModeFlags != 0) {
7842 persist.add(perm.snapshot());
7848 FileOutputStream fos = null;
7850 fos = mGrantFile.startWrite();
7852 XmlSerializer out = new FastXmlSerializer();
7853 out.setOutput(fos, "utf-8");
7854 out.startDocument(null, true);
7855 out.startTag(null, TAG_URI_GRANTS);
7856 for (UriPermission.Snapshot perm : persist) {
7857 out.startTag(null, TAG_URI_GRANT);
7858 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7859 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7860 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7861 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7862 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7863 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7864 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7865 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7866 out.endTag(null, TAG_URI_GRANT);
7868 out.endTag(null, TAG_URI_GRANTS);
7871 mGrantFile.finishWrite(fos);
7872 } catch (IOException e) {
7874 mGrantFile.failWrite(fos);
7879 private void readGrantedUriPermissionsLocked() {
7880 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7882 final long now = System.currentTimeMillis();
7884 FileInputStream fis = null;
7886 fis = mGrantFile.openRead();
7887 final XmlPullParser in = Xml.newPullParser();
7888 in.setInput(fis, null);
7891 while ((type = in.next()) != END_DOCUMENT) {
7892 final String tag = in.getName();
7893 if (type == START_TAG) {
7894 if (TAG_URI_GRANT.equals(tag)) {
7895 final int sourceUserId;
7896 final int targetUserId;
7897 final int userHandle = readIntAttribute(in,
7898 ATTR_USER_HANDLE, UserHandle.USER_NULL);
7899 if (userHandle != UserHandle.USER_NULL) {
7900 // For backwards compatibility.
7901 sourceUserId = userHandle;
7902 targetUserId = userHandle;
7904 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7905 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7907 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7908 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7909 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7910 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7911 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7912 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7914 // Sanity check that provider still belongs to source package
7915 final ProviderInfo pi = getProviderInfoLocked(
7916 uri.getAuthority(), sourceUserId);
7917 if (pi != null && sourcePkg.equals(pi.packageName)) {
7920 targetUid = AppGlobals.getPackageManager()
7921 .getPackageUid(targetPkg, targetUserId);
7922 } catch (RemoteException e) {
7924 if (targetUid != -1) {
7925 final UriPermission perm = findOrCreateUriPermissionLocked(
7926 sourcePkg, targetPkg, targetUid,
7927 new GrantUri(sourceUserId, uri, prefix));
7928 perm.initPersistedModes(modeFlags, createdTime);
7931 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7932 + " but instead found " + pi);
7937 } catch (FileNotFoundException e) {
7938 // Missing grants is okay
7939 } catch (IOException e) {
7940 Slog.wtf(TAG, "Failed reading Uri grants", e);
7941 } catch (XmlPullParserException e) {
7942 Slog.wtf(TAG, "Failed reading Uri grants", e);
7944 IoUtils.closeQuietly(fis);
7949 * @param uri This uri must NOT contain an embedded userId.
7950 * @param userId The userId in which the uri is to be resolved.
7953 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7954 enforceNotIsolatedCaller("takePersistableUriPermission");
7956 Preconditions.checkFlagsArgument(modeFlags,
7957 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7959 synchronized (this) {
7960 final int callingUid = Binder.getCallingUid();
7961 boolean persistChanged = false;
7962 GrantUri grantUri = new GrantUri(userId, uri, false);
7964 UriPermission exactPerm = findUriPermissionLocked(callingUid,
7965 new GrantUri(userId, uri, false));
7966 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7967 new GrantUri(userId, uri, true));
7969 final boolean exactValid = (exactPerm != null)
7970 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7971 final boolean prefixValid = (prefixPerm != null)
7972 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7974 if (!(exactValid || prefixValid)) {
7975 throw new SecurityException("No persistable permission grants found for UID "
7976 + callingUid + " and Uri " + grantUri.toSafeString());
7980 persistChanged |= exactPerm.takePersistableModes(modeFlags);
7983 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7986 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7988 if (persistChanged) {
7989 schedulePersistUriGrants();
7995 * @param uri This uri must NOT contain an embedded userId.
7996 * @param userId The userId in which the uri is to be resolved.
7999 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8000 enforceNotIsolatedCaller("releasePersistableUriPermission");
8002 Preconditions.checkFlagsArgument(modeFlags,
8003 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8005 synchronized (this) {
8006 final int callingUid = Binder.getCallingUid();
8007 boolean persistChanged = false;
8009 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8010 new GrantUri(userId, uri, false));
8011 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8012 new GrantUri(userId, uri, true));
8013 if (exactPerm == null && prefixPerm == null) {
8014 throw new SecurityException("No permission grants found for UID " + callingUid
8015 + " and Uri " + uri.toSafeString());
8018 if (exactPerm != null) {
8019 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8020 removeUriPermissionIfNeededLocked(exactPerm);
8022 if (prefixPerm != null) {
8023 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8024 removeUriPermissionIfNeededLocked(prefixPerm);
8027 if (persistChanged) {
8028 schedulePersistUriGrants();
8034 * Prune any older {@link UriPermission} for the given UID until outstanding
8035 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8037 * @return if any mutations occured that require persisting.
8039 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8040 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8041 if (perms == null) return false;
8042 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8044 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8045 for (UriPermission perm : perms.values()) {
8046 if (perm.persistedModeFlags != 0) {
8047 persisted.add(perm);
8051 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8052 if (trimCount <= 0) return false;
8054 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8055 for (int i = 0; i < trimCount; i++) {
8056 final UriPermission perm = persisted.get(i);
8058 if (DEBUG_URI_PERMISSION) {
8059 Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
8062 perm.releasePersistableModes(~0);
8063 removeUriPermissionIfNeededLocked(perm);
8070 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8071 String packageName, boolean incoming) {
8072 enforceNotIsolatedCaller("getPersistedUriPermissions");
8073 Preconditions.checkNotNull(packageName, "packageName");
8075 final int callingUid = Binder.getCallingUid();
8076 final IPackageManager pm = AppGlobals.getPackageManager();
8078 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8079 if (packageUid != callingUid) {
8080 throw new SecurityException(
8081 "Package " + packageName + " does not belong to calling UID " + callingUid);
8083 } catch (RemoteException e) {
8084 throw new SecurityException("Failed to verify package name ownership");
8087 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8088 synchronized (this) {
8090 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8092 if (perms == null) {
8093 Slog.w(TAG, "No permission grants found for " + packageName);
8095 for (UriPermission perm : perms.values()) {
8096 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8097 result.add(perm.buildPersistedPublicApiObject());
8102 final int size = mGrantedUriPermissions.size();
8103 for (int i = 0; i < size; i++) {
8104 final ArrayMap<GrantUri, UriPermission> perms =
8105 mGrantedUriPermissions.valueAt(i);
8106 for (UriPermission perm : perms.values()) {
8107 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8108 result.add(perm.buildPersistedPublicApiObject());
8114 return new ParceledListSlice<android.content.UriPermission>(result);
8118 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8119 synchronized (this) {
8121 who != null ? getRecordForAppLocked(who) : null;
8122 if (app == null) return;
8124 Message msg = Message.obtain();
8125 msg.what = WAIT_FOR_DEBUGGER_MSG;
8127 msg.arg1 = waiting ? 1 : 0;
8128 mHandler.sendMessage(msg);
8133 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8134 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8135 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8136 outInfo.availMem = Process.getFreeMemory();
8137 outInfo.totalMem = Process.getTotalMemory();
8138 outInfo.threshold = homeAppMem;
8139 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8140 outInfo.hiddenAppThreshold = cachedAppMem;
8141 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8142 ProcessList.SERVICE_ADJ);
8143 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8144 ProcessList.VISIBLE_APP_ADJ);
8145 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8146 ProcessList.FOREGROUND_APP_ADJ);
8149 // =========================================================
8151 // =========================================================
8154 public List<IAppTask> getAppTasks(String callingPackage) {
8155 int callingUid = Binder.getCallingUid();
8156 long ident = Binder.clearCallingIdentity();
8158 synchronized(this) {
8159 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8161 if (localLOGV) Slog.v(TAG, "getAppTasks");
8163 final int N = mRecentTasks.size();
8164 for (int i = 0; i < N; i++) {
8165 TaskRecord tr = mRecentTasks.get(i);
8166 // Skip tasks that do not match the caller. We don't need to verify
8167 // callingPackage, because we are also limiting to callingUid and know
8168 // that will limit to the correct security sandbox.
8169 if (tr.effectiveUid != callingUid) {
8172 Intent intent = tr.getBaseIntent();
8173 if (intent == null ||
8174 !callingPackage.equals(intent.getComponent().getPackageName())) {
8177 ActivityManager.RecentTaskInfo taskInfo =
8178 createRecentTaskInfoFromTaskRecord(tr);
8179 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8183 Binder.restoreCallingIdentity(ident);
8190 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8191 final int callingUid = Binder.getCallingUid();
8192 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8194 synchronized(this) {
8195 if (localLOGV) Slog.v(
8196 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8198 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8201 // TODO: Improve with MRU list from all ActivityStacks.
8202 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8208 TaskRecord getMostRecentTask() {
8209 return mRecentTasks.get(0);
8213 * Creates a new RecentTaskInfo from a TaskRecord.
8215 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8216 // Update the task description to reflect any changes in the task stack
8217 tr.updateTaskDescription();
8219 // Compose the recent task info
8220 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8221 rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8222 rti.persistentId = tr.taskId;
8223 rti.baseIntent = new Intent(tr.getBaseIntent());
8224 rti.origActivity = tr.origActivity;
8225 rti.description = tr.lastDescription;
8226 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8227 rti.userId = tr.userId;
8228 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8229 rti.firstActiveTime = tr.firstActiveTime;
8230 rti.lastActiveTime = tr.lastActiveTime;
8231 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8232 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8236 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8237 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8238 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8240 if (checkPermission(android.Manifest.permission.GET_TASKS,
8241 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8242 // Temporary compatibility: some existing apps on the system image may
8243 // still be requesting the old permission and not switched to the new
8244 // one; if so, we'll still allow them full access. This means we need
8245 // to see if they are holding the old permission and are a system app.
8247 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8249 Slog.w(TAG, caller + ": caller " + callingUid
8250 + " is using old GET_TASKS but privileged; allowing");
8252 } catch (RemoteException e) {
8257 Slog.w(TAG, caller + ": caller " + callingUid
8258 + " does not hold REAL_GET_TASKS; limiting output");
8264 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8265 final int callingUid = Binder.getCallingUid();
8266 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8267 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8269 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8270 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8271 synchronized (this) {
8272 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8274 final boolean detailed = checkCallingPermission(
8275 android.Manifest.permission.GET_DETAILED_TASKS)
8276 == PackageManager.PERMISSION_GRANTED;
8278 final int N = mRecentTasks.size();
8279 ArrayList<ActivityManager.RecentTaskInfo> res
8280 = new ArrayList<ActivityManager.RecentTaskInfo>(
8281 maxNum < N ? maxNum : N);
8283 final Set<Integer> includedUsers;
8284 if (includeProfiles) {
8285 includedUsers = getProfileIdsLocked(userId);
8287 includedUsers = new HashSet<Integer>();
8289 includedUsers.add(Integer.valueOf(userId));
8291 for (int i=0; i<N && maxNum > 0; i++) {
8292 TaskRecord tr = mRecentTasks.get(i);
8293 // Only add calling user or related users recent tasks
8294 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8295 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8299 // Return the entry if desired by the caller. We always return
8300 // the first entry, because callers always expect this to be the
8301 // foreground app. We may filter others if the caller has
8302 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8303 // we should exclude the entry.
8307 || (tr.intent == null)
8308 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8311 // If the caller doesn't have the GET_TASKS permission, then only
8312 // allow them to see a small subset of tasks -- their own and home.
8313 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8314 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8318 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8319 if (tr.stack != null && tr.stack.isHomeStack()) {
8320 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8324 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8325 // Don't include auto remove tasks that are finished or finishing.
8326 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8330 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8331 && !tr.isAvailable) {
8332 if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8336 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8338 rti.baseIntent.replaceExtras((Bundle)null);
8349 private TaskRecord recentTaskForIdLocked(int id) {
8350 final int N = mRecentTasks.size();
8351 for (int i=0; i<N; i++) {
8352 TaskRecord tr = mRecentTasks.get(i);
8353 if (tr.taskId == id) {
8361 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8362 synchronized (this) {
8363 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8364 "getTaskThumbnail()");
8365 TaskRecord tr = recentTaskForIdLocked(id);
8367 return tr.getTaskThumbnailLocked();
8374 public int addAppTask(IBinder activityToken, Intent intent,
8375 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8376 final int callingUid = Binder.getCallingUid();
8377 final long callingIdent = Binder.clearCallingIdentity();
8380 synchronized (this) {
8381 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8383 throw new IllegalArgumentException("Activity does not exist; token="
8386 ComponentName comp = intent.getComponent();
8388 throw new IllegalArgumentException("Intent " + intent
8389 + " must specify explicit component");
8391 if (thumbnail.getWidth() != mThumbnailWidth
8392 || thumbnail.getHeight() != mThumbnailHeight) {
8393 throw new IllegalArgumentException("Bad thumbnail size: got "
8394 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8395 + mThumbnailWidth + "x" + mThumbnailHeight);
8397 if (intent.getSelector() != null) {
8398 intent.setSelector(null);
8400 if (intent.getSourceBounds() != null) {
8401 intent.setSourceBounds(null);
8403 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8404 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8405 // The caller has added this as an auto-remove task... that makes no
8406 // sense, so turn off auto-remove.
8407 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8409 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8410 // Must be a new task.
8411 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8413 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8414 mLastAddedTaskActivity = null;
8416 ActivityInfo ainfo = mLastAddedTaskActivity;
8417 if (ainfo == null) {
8418 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8419 comp, 0, UserHandle.getUserId(callingUid));
8420 if (ainfo.applicationInfo.uid != callingUid) {
8421 throw new SecurityException(
8422 "Can't add task for another application: target uid="
8423 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8427 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8428 intent, description);
8430 int trimIdx = trimRecentsForTask(task, false);
8432 // If this would have caused a trim, then we'll abort because that
8433 // means it would be added at the end of the list but then just removed.
8437 final int N = mRecentTasks.size();
8438 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8439 final TaskRecord tr = mRecentTasks.remove(N - 1);
8440 tr.removedFromRecents(mTaskPersister);
8443 task.inRecents = true;
8444 mRecentTasks.add(task);
8445 r.task.stack.addTask(task, false, false);
8447 task.setLastThumbnail(thumbnail);
8448 task.freeLastThumbnail();
8453 Binder.restoreCallingIdentity(callingIdent);
8458 public Point getAppTaskThumbnailSize() {
8459 synchronized (this) {
8460 return new Point(mThumbnailWidth, mThumbnailHeight);
8465 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8466 synchronized (this) {
8467 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8469 r.setTaskDescription(td);
8470 r.task.updateTaskDescription();
8476 public Bitmap getTaskDescriptionIcon(String filename) {
8477 if (!FileUtils.isValidExtFilename(filename)
8478 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8479 throw new IllegalArgumentException("Bad filename: " + filename);
8481 return mTaskPersister.getTaskDescriptionIcon(filename);
8484 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8485 mRecentTasks.remove(tr);
8486 tr.removedFromRecents(mTaskPersister);
8487 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8488 Intent baseIntent = new Intent(
8489 tr.intent != null ? tr.intent : tr.affinityIntent);
8490 ComponentName component = baseIntent.getComponent();
8491 if (component == null) {
8492 Slog.w(TAG, "Now component for base intent of task: " + tr);
8496 // Find any running services associated with this app.
8497 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8499 if (killProcesses) {
8500 // Find any running processes associated with this app.
8501 final String pkg = component.getPackageName();
8502 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8503 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8504 for (int i=0; i<pmap.size(); i++) {
8505 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8506 for (int j=0; j<uids.size(); j++) {
8507 ProcessRecord proc = uids.valueAt(j);
8508 if (proc.userId != tr.userId) {
8511 if (!proc.pkgList.containsKey(pkg)) {
8518 // Kill the running processes.
8519 for (int i=0; i<procs.size(); i++) {
8520 ProcessRecord pr = procs.get(i);
8521 if (pr == mHomeProcess) {
8522 // Don't kill the home process along with tasks from the same package.
8525 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8526 pr.kill("remove task", true);
8528 pr.waitingToKill = "remove task";
8535 * Removes the task with the specified task id.
8537 * @param taskId Identifier of the task to be removed.
8538 * @param flags Additional operational flags. May be 0 or
8539 * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8540 * @return Returns true if the given task was found and removed.
8542 private boolean removeTaskByIdLocked(int taskId, int flags) {
8543 TaskRecord tr = recentTaskForIdLocked(taskId);
8545 tr.removeTaskActivitiesLocked();
8546 cleanUpRemovedTaskLocked(tr, flags);
8547 if (tr.isPersistable) {
8548 notifyTaskPersisterLocked(null, true);
8556 public boolean removeTask(int taskId, int flags) {
8557 synchronized (this) {
8558 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8560 long ident = Binder.clearCallingIdentity();
8562 return removeTaskByIdLocked(taskId, flags);
8564 Binder.restoreCallingIdentity(ident);
8570 * TODO: Add mController hook
8573 public void moveTaskToFront(int taskId, int flags, Bundle options) {
8574 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8575 "moveTaskToFront()");
8577 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8578 synchronized(this) {
8579 moveTaskToFrontLocked(taskId, flags, options);
8583 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8584 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8585 Binder.getCallingUid(), -1, -1, "Task to front")) {
8586 ActivityOptions.abort(options);
8589 final long origId = Binder.clearCallingIdentity();
8591 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8595 if (mStackSupervisor.isLockTaskModeViolation(task)) {
8596 mStackSupervisor.showLockTaskToast();
8597 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8600 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8601 if (prev != null && prev.isRecentsActivity()) {
8602 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8604 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8606 Binder.restoreCallingIdentity(origId);
8608 ActivityOptions.abort(options);
8612 public void moveTaskToBack(int taskId) {
8613 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8614 "moveTaskToBack()");
8616 synchronized(this) {
8617 TaskRecord tr = recentTaskForIdLocked(taskId);
8619 if (tr == mStackSupervisor.mLockTaskModeTask) {
8620 mStackSupervisor.showLockTaskToast();
8623 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8624 ActivityStack stack = tr.stack;
8625 if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8626 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8627 Binder.getCallingUid(), -1, -1, "Task to back")) {
8631 final long origId = Binder.clearCallingIdentity();
8633 stack.moveTaskToBackLocked(taskId, null);
8635 Binder.restoreCallingIdentity(origId);
8642 * Moves an activity, and all of the other activities within the same task, to the bottom
8643 * of the history stack. The activity's order within the task is unchanged.
8645 * @param token A reference to the activity we wish to move
8646 * @param nonRoot If false then this only works if the activity is the root
8647 * of a task; if true it will work for any activity in a task.
8648 * @return Returns true if the move completed, false if not.
8651 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8652 enforceNotIsolatedCaller("moveActivityTaskToBack");
8653 synchronized(this) {
8654 final long origId = Binder.clearCallingIdentity();
8656 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8658 if ((mStackSupervisor.mLockTaskModeTask != null)
8659 && (mStackSupervisor.mLockTaskModeTask.taskId == taskId)) {
8660 mStackSupervisor.showLockTaskToast();
8663 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8666 Binder.restoreCallingIdentity(origId);
8673 public void moveTaskBackwards(int task) {
8674 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8675 "moveTaskBackwards()");
8677 synchronized(this) {
8678 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8679 Binder.getCallingUid(), -1, -1, "Task backwards")) {
8682 final long origId = Binder.clearCallingIdentity();
8683 moveTaskBackwardsLocked(task);
8684 Binder.restoreCallingIdentity(origId);
8688 private final void moveTaskBackwardsLocked(int task) {
8689 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8693 public IBinder getHomeActivityToken() throws RemoteException {
8694 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8695 "getHomeActivityToken()");
8696 synchronized (this) {
8697 return mStackSupervisor.getHomeActivityToken();
8702 public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8703 IActivityContainerCallback callback) throws RemoteException {
8704 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8705 "createActivityContainer()");
8706 synchronized (this) {
8707 if (parentActivityToken == null) {
8708 throw new IllegalArgumentException("parent token must not be null");
8710 ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8714 if (callback == null) {
8715 throw new IllegalArgumentException("callback must not be null");
8717 return mStackSupervisor.createActivityContainer(r, callback);
8722 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8723 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8724 "deleteActivityContainer()");
8725 synchronized (this) {
8726 mStackSupervisor.deleteActivityContainer(container);
8731 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8732 synchronized (this) {
8733 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8734 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8735 return stack.mActivityContainer.getDisplayId();
8737 return Display.DEFAULT_DISPLAY;
8742 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8743 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8744 "moveTaskToStack()");
8745 if (stackId == HOME_STACK_ID) {
8746 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8747 new RuntimeException("here").fillInStackTrace());
8749 synchronized (this) {
8750 long ident = Binder.clearCallingIdentity();
8752 if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8753 + stackId + " toTop=" + toTop);
8754 mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8756 Binder.restoreCallingIdentity(ident);
8762 public void resizeStack(int stackBoxId, Rect bounds) {
8763 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8764 "resizeStackBox()");
8765 long ident = Binder.clearCallingIdentity();
8767 mWindowManager.resizeStack(stackBoxId, bounds);
8769 Binder.restoreCallingIdentity(ident);
8774 public List<StackInfo> getAllStackInfos() {
8775 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8776 "getAllStackInfos()");
8777 long ident = Binder.clearCallingIdentity();
8779 synchronized (this) {
8780 return mStackSupervisor.getAllStackInfosLocked();
8783 Binder.restoreCallingIdentity(ident);
8788 public StackInfo getStackInfo(int stackId) {
8789 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8791 long ident = Binder.clearCallingIdentity();
8793 synchronized (this) {
8794 return mStackSupervisor.getStackInfoLocked(stackId);
8797 Binder.restoreCallingIdentity(ident);
8802 public boolean isInHomeStack(int taskId) {
8803 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8805 long ident = Binder.clearCallingIdentity();
8807 synchronized (this) {
8808 TaskRecord tr = recentTaskForIdLocked(taskId);
8809 return tr != null && tr.stack != null && tr.stack.isHomeStack();
8812 Binder.restoreCallingIdentity(ident);
8817 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8818 synchronized(this) {
8819 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8823 private boolean isLockTaskAuthorized(String pkg) {
8824 final DevicePolicyManager dpm = (DevicePolicyManager)
8825 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8827 int uid = mContext.getPackageManager().getPackageUid(pkg,
8828 Binder.getCallingUserHandle().getIdentifier());
8829 return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8830 } catch (NameNotFoundException e) {
8835 void startLockTaskMode(TaskRecord task) {
8837 synchronized (this) {
8838 pkg = task.intent.getComponent().getPackageName();
8840 boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8841 if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8842 final TaskRecord taskRecord = task;
8843 mHandler.post(new Runnable() {
8846 mLockToAppRequest.showLockTaskPrompt(taskRecord);
8851 long ident = Binder.clearCallingIdentity();
8853 synchronized (this) {
8854 // Since we lost lock on task, make sure it is still there.
8855 task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8857 if (!isSystemInitiated
8858 && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8859 throw new IllegalArgumentException("Invalid task, not in foreground");
8861 mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8865 Binder.restoreCallingIdentity(ident);
8870 public void startLockTaskMode(int taskId) {
8871 final TaskRecord task;
8872 long ident = Binder.clearCallingIdentity();
8874 synchronized (this) {
8875 task = mStackSupervisor.anyTaskForIdLocked(taskId);
8878 Binder.restoreCallingIdentity(ident);
8881 startLockTaskMode(task);
8886 public void startLockTaskMode(IBinder token) {
8887 final TaskRecord task;
8888 long ident = Binder.clearCallingIdentity();
8890 synchronized (this) {
8891 final ActivityRecord r = ActivityRecord.forToken(token);
8898 Binder.restoreCallingIdentity(ident);
8901 startLockTaskMode(task);
8906 public void startLockTaskModeOnCurrent() throws RemoteException {
8907 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8908 "startLockTaskModeOnCurrent");
8909 ActivityRecord r = null;
8910 synchronized (this) {
8911 r = mStackSupervisor.topRunningActivityLocked();
8913 startLockTaskMode(r.task);
8917 public void stopLockTaskMode() {
8918 // Verify that the user matches the package of the intent for the TaskRecord
8919 // we are locked to or systtem. This will ensure the same caller for startLockTaskMode
8920 // and stopLockTaskMode.
8921 final int callingUid = Binder.getCallingUid();
8922 if (callingUid != Process.SYSTEM_UID) {
8925 mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8926 int uid = mContext.getPackageManager().getPackageUid(pkg,
8927 Binder.getCallingUserHandle().getIdentifier());
8928 if (uid != callingUid) {
8929 throw new SecurityException("Invalid uid, expected " + uid);
8931 } catch (NameNotFoundException e) {
8932 Log.d(TAG, "stopLockTaskMode " + e);
8936 long ident = Binder.clearCallingIdentity();
8938 Log.d(TAG, "stopLockTaskMode");
8940 synchronized (this) {
8941 mStackSupervisor.setLockTaskModeLocked(null, false);
8944 Binder.restoreCallingIdentity(ident);
8949 public void stopLockTaskModeOnCurrent() throws RemoteException {
8950 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8951 "stopLockTaskModeOnCurrent");
8952 long ident = Binder.clearCallingIdentity();
8956 Binder.restoreCallingIdentity(ident);
8961 public boolean isInLockTaskMode() {
8962 synchronized (this) {
8963 return mStackSupervisor.isInLockTaskMode();
8967 // =========================================================
8968 // CONTENT PROVIDERS
8969 // =========================================================
8971 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8972 List<ProviderInfo> providers = null;
8974 providers = AppGlobals.getPackageManager().
8975 queryContentProviders(app.processName, app.uid,
8976 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8977 } catch (RemoteException ex) {
8980 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8981 int userId = app.userId;
8982 if (providers != null) {
8983 int N = providers.size();
8984 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8985 for (int i=0; i<N; i++) {
8987 (ProviderInfo)providers.get(i);
8988 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8989 cpi.name, cpi.flags);
8990 if (singleton && UserHandle.getUserId(app.uid) != 0) {
8991 // This is a singleton provider, but a user besides the
8992 // default user is asking to initialize a process it runs
8993 // in... well, no, it doesn't actually run in this process,
8994 // it runs in the process of the default user. Get rid of it.
8995 providers.remove(i);
9001 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9002 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9004 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9005 mProviderMap.putProviderByClass(comp, cpr);
9008 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9009 app.pubProviders.put(cpi.name, cpr);
9010 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9011 // Don't add this if it is a platform component that is marked
9012 // to run in multiple processes, because this is actually
9013 // part of the framework so doesn't make sense to track as a
9014 // separate apk in the process.
9015 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9018 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9025 * Check if {@link ProcessRecord} has a possible chance at accessing the
9026 * given {@link ProviderInfo}. Final permission checking is always done
9027 * in {@link ContentProvider}.
9029 private final String checkContentProviderPermissionLocked(
9030 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9031 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9032 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9033 boolean checkedGrants = false;
9035 // Looking for cross-user grants before enforcing the typical cross-users permissions
9036 int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9037 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9038 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9041 checkedGrants = true;
9043 userId = handleIncomingUser(callingPid, callingUid, userId,
9044 false, ALLOW_NON_FULL,
9045 "checkContentProviderPermissionLocked " + cpi.authority, null);
9046 if (userId != tmpTargetUserId) {
9047 // When we actually went to determine the final targer user ID, this ended
9048 // up different than our initial check for the authority. This is because
9049 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9050 // SELF. So we need to re-check the grants again.
9051 checkedGrants = false;
9054 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9055 cpi.applicationInfo.uid, cpi.exported)
9056 == PackageManager.PERMISSION_GRANTED) {
9059 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9060 cpi.applicationInfo.uid, cpi.exported)
9061 == PackageManager.PERMISSION_GRANTED) {
9065 PathPermission[] pps = cpi.pathPermissions;
9070 PathPermission pp = pps[i];
9071 String pprperm = pp.getReadPermission();
9072 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9073 cpi.applicationInfo.uid, cpi.exported)
9074 == PackageManager.PERMISSION_GRANTED) {
9077 String ppwperm = pp.getWritePermission();
9078 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9079 cpi.applicationInfo.uid, cpi.exported)
9080 == PackageManager.PERMISSION_GRANTED) {
9085 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9090 if (!cpi.exported) {
9091 msg = "Permission Denial: opening provider " + cpi.name
9092 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9093 + ", uid=" + callingUid + ") that is not exported from uid "
9094 + cpi.applicationInfo.uid;
9096 msg = "Permission Denial: opening provider " + cpi.name
9097 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9098 + ", uid=" + callingUid + ") requires "
9099 + cpi.readPermission + " or " + cpi.writePermission;
9106 * Returns if the ContentProvider has granted a uri to callingUid
9108 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9109 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9110 if (perms != null) {
9111 for (int i=perms.size()-1; i>=0; i--) {
9112 GrantUri grantUri = perms.keyAt(i);
9113 if (grantUri.sourceUserId == userId || !checkUser) {
9114 if (matchesProvider(grantUri.uri, cpi)) {
9124 * Returns true if the uri authority is one of the authorities specified in the provider.
9126 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9127 String uriAuth = uri.getAuthority();
9128 String cpiAuth = cpi.authority;
9129 if (cpiAuth.indexOf(';') == -1) {
9130 return cpiAuth.equals(uriAuth);
9132 String[] cpiAuths = cpiAuth.split(";");
9133 int length = cpiAuths.length;
9134 for (int i = 0; i < length; i++) {
9135 if (cpiAuths[i].equals(uriAuth)) return true;
9140 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9141 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9143 for (int i=0; i<r.conProviders.size(); i++) {
9144 ContentProviderConnection conn = r.conProviders.get(i);
9145 if (conn.provider == cpr) {
9146 if (DEBUG_PROVIDER) Slog.v(TAG,
9147 "Adding provider requested by "
9148 + r.processName + " from process "
9149 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9150 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9153 conn.numStableIncs++;
9155 conn.unstableCount++;
9156 conn.numUnstableIncs++;
9161 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9163 conn.stableCount = 1;
9164 conn.numStableIncs = 1;
9166 conn.unstableCount = 1;
9167 conn.numUnstableIncs = 1;
9169 cpr.connections.add(conn);
9170 r.conProviders.add(conn);
9173 cpr.addExternalProcessHandleLocked(externalProcessToken);
9177 boolean decProviderCountLocked(ContentProviderConnection conn,
9178 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9180 cpr = conn.provider;
9181 if (DEBUG_PROVIDER) Slog.v(TAG,
9182 "Removing provider requested by "
9183 + conn.client.processName + " from process "
9184 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9185 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9189 conn.unstableCount--;
9191 if (conn.stableCount == 0 && conn.unstableCount == 0) {
9192 cpr.connections.remove(conn);
9193 conn.client.conProviders.remove(conn);
9198 cpr.removeExternalProcessHandleLocked(externalProcessToken);
9202 private void checkTime(long startTime, String where) {
9203 long now = SystemClock.elapsedRealtime();
9204 if ((now-startTime) > 1000) {
9205 // If we are taking more than a second, log about it.
9206 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9210 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9211 String name, IBinder token, boolean stable, int userId) {
9212 ContentProviderRecord cpr;
9213 ContentProviderConnection conn = null;
9214 ProviderInfo cpi = null;
9216 synchronized(this) {
9217 long startTime = SystemClock.elapsedRealtime();
9219 ProcessRecord r = null;
9220 if (caller != null) {
9221 r = getRecordForAppLocked(caller);
9223 throw new SecurityException(
9224 "Unable to find app for caller " + caller
9225 + " (pid=" + Binder.getCallingPid()
9226 + ") when getting content provider " + name);
9230 boolean checkCrossUser = true;
9232 checkTime(startTime, "getContentProviderImpl: getProviderByName");
9234 // First check if this content provider has been published...
9235 cpr = mProviderMap.getProviderByName(name, userId);
9236 // If that didn't work, check if it exists for user 0 and then
9237 // verify that it's a singleton provider before using it.
9238 if (cpr == null && userId != UserHandle.USER_OWNER) {
9239 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9242 if (isSingleton(cpi.processName, cpi.applicationInfo,
9243 cpi.name, cpi.flags)
9244 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9245 userId = UserHandle.USER_OWNER;
9246 checkCrossUser = false;
9254 boolean providerRunning = cpr != null;
9255 if (providerRunning) {
9258 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9259 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9261 throw new SecurityException(msg);
9263 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9265 if (r != null && cpr.canRunHere(r)) {
9266 // This provider has been published or is in the process
9267 // of being published... but it is also allowed to run
9268 // in the caller's process, so don't make a connection
9269 // and just let the caller instantiate its own instance.
9270 ContentProviderHolder holder = cpr.newHolder(null);
9271 // don't give caller the provider object, it needs
9273 holder.provider = null;
9277 final long origId = Binder.clearCallingIdentity();
9279 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9281 // In this case the provider instance already exists, so we can
9282 // return it right away.
9283 conn = incProviderCountLocked(r, cpr, token, stable);
9284 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9285 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9286 // If this is a perceptible app accessing the provider,
9287 // make sure to count it as being accessed and thus
9288 // back up on the LRU list. This is good because
9289 // content providers are often expensive to start.
9290 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9291 updateLruProcessLocked(cpr.proc, false, null);
9292 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9296 if (cpr.proc != null) {
9298 if (cpr.name.flattenToShortString().equals(
9299 "com.android.providers.calendar/.CalendarProvider2")) {
9300 Slog.v(TAG, "****************** KILLING "
9301 + cpr.name.flattenToShortString());
9302 Process.killProcess(cpr.proc.pid);
9305 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9306 boolean success = updateOomAdjLocked(cpr.proc);
9307 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9308 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9309 // NOTE: there is still a race here where a signal could be
9310 // pending on the process even though we managed to update its
9311 // adj level. Not sure what to do about this, but at least
9312 // the race is now smaller.
9314 // Uh oh... it looks like the provider's process
9315 // has been killed on us. We need to wait for a new
9316 // process to be started, and make sure its death
9317 // doesn't kill our process.
9319 "Existing provider " + cpr.name.flattenToShortString()
9320 + " is crashing; detaching " + r);
9321 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9322 checkTime(startTime, "getContentProviderImpl: before appDied");
9323 appDiedLocked(cpr.proc);
9324 checkTime(startTime, "getContentProviderImpl: after appDied");
9326 // This wasn't the last ref our process had on
9327 // the provider... we have now been killed, bail.
9330 providerRunning = false;
9335 Binder.restoreCallingIdentity(origId);
9339 if (!providerRunning) {
9341 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9342 cpi = AppGlobals.getPackageManager().
9343 resolveContentProvider(name,
9344 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9345 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9346 } catch (RemoteException ex) {
9351 // If the provider is a singleton AND
9352 // (it's a call within the same user || the provider is a
9354 // Then allow connecting to the singleton provider
9355 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9356 cpi.name, cpi.flags)
9357 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9359 userId = UserHandle.USER_OWNER;
9361 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9362 checkTime(startTime, "getContentProviderImpl: got app info for user");
9365 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9366 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9368 throw new SecurityException(msg);
9370 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9372 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9373 && !cpi.processName.equals("system")) {
9374 // If this content provider does not run in the system
9375 // process, and the system is not yet ready to run other
9376 // processes, then fail fast instead of hanging.
9377 throw new IllegalArgumentException(
9378 "Attempt to launch content provider before system ready");
9381 // Make sure that the user who owns this provider is started. If not,
9382 // we don't want to allow it to run.
9383 if (mStartedUsers.get(userId) == null) {
9384 Slog.w(TAG, "Unable to launch app "
9385 + cpi.applicationInfo.packageName + "/"
9386 + cpi.applicationInfo.uid + " for provider "
9387 + name + ": user " + userId + " is stopped");
9391 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9392 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9393 cpr = mProviderMap.getProviderByClass(comp, userId);
9394 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9395 final boolean firstClass = cpr == null;
9397 final long ident = Binder.clearCallingIdentity();
9399 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9400 ApplicationInfo ai =
9401 AppGlobals.getPackageManager().
9403 cpi.applicationInfo.packageName,
9404 STOCK_PM_FLAGS, userId);
9405 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9407 Slog.w(TAG, "No package info for content provider "
9411 ai = getAppInfoForUser(ai, userId);
9412 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9413 } catch (RemoteException ex) {
9414 // pm is in same process, this will never happen.
9416 Binder.restoreCallingIdentity(ident);
9420 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9422 if (r != null && cpr.canRunHere(r)) {
9423 // If this is a multiprocess provider, then just return its
9424 // info and allow the caller to instantiate it. Only do
9425 // this if the provider is the same user as the caller's
9426 // process, or can run as root (so can be in any process).
9427 return cpr.newHolder(null);
9430 if (DEBUG_PROVIDER) {
9431 RuntimeException e = new RuntimeException("here");
9432 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9433 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9436 // This is single process, and our app is now connecting to it.
9437 // See if we are already in the process of launching this
9439 final int N = mLaunchingProviders.size();
9441 for (i=0; i<N; i++) {
9442 if (mLaunchingProviders.get(i) == cpr) {
9447 // If the provider is not already being launched, then get it
9450 final long origId = Binder.clearCallingIdentity();
9453 // Content provider is now in use, its package can't be stopped.
9455 checkTime(startTime, "getContentProviderImpl: before set stopped state");
9456 AppGlobals.getPackageManager().setPackageStoppedState(
9457 cpr.appInfo.packageName, false, userId);
9458 checkTime(startTime, "getContentProviderImpl: after set stopped state");
9459 } catch (RemoteException e) {
9460 } catch (IllegalArgumentException e) {
9461 Slog.w(TAG, "Failed trying to unstop package "
9462 + cpr.appInfo.packageName + ": " + e);
9465 // Use existing process if already started
9466 checkTime(startTime, "getContentProviderImpl: looking for process record");
9467 ProcessRecord proc = getProcessRecordLocked(
9468 cpi.processName, cpr.appInfo.uid, false);
9469 if (proc != null && proc.thread != null) {
9470 if (DEBUG_PROVIDER) {
9471 Slog.d(TAG, "Installing in existing process " + proc);
9473 checkTime(startTime, "getContentProviderImpl: scheduling install");
9474 proc.pubProviders.put(cpi.name, cpr);
9476 proc.thread.scheduleInstallProvider(cpi);
9477 } catch (RemoteException e) {
9480 checkTime(startTime, "getContentProviderImpl: before start process");
9481 proc = startProcessLocked(cpi.processName,
9482 cpr.appInfo, false, 0, "content provider",
9483 new ComponentName(cpi.applicationInfo.packageName,
9484 cpi.name), false, false, false);
9485 checkTime(startTime, "getContentProviderImpl: after start process");
9487 Slog.w(TAG, "Unable to launch app "
9488 + cpi.applicationInfo.packageName + "/"
9489 + cpi.applicationInfo.uid + " for provider "
9490 + name + ": process is bad");
9494 cpr.launchingApp = proc;
9495 mLaunchingProviders.add(cpr);
9497 Binder.restoreCallingIdentity(origId);
9501 checkTime(startTime, "getContentProviderImpl: updating data structures");
9503 // Make sure the provider is published (the same provider class
9504 // may be published under multiple names).
9506 mProviderMap.putProviderByClass(comp, cpr);
9509 mProviderMap.putProviderByName(name, cpr);
9510 conn = incProviderCountLocked(r, cpr, token, stable);
9512 conn.waiting = true;
9515 checkTime(startTime, "getContentProviderImpl: done!");
9518 // Wait for the provider to be published...
9519 synchronized (cpr) {
9520 while (cpr.provider == null) {
9521 if (cpr.launchingApp == null) {
9522 Slog.w(TAG, "Unable to launch app "
9523 + cpi.applicationInfo.packageName + "/"
9524 + cpi.applicationInfo.uid + " for provider "
9525 + name + ": launching app became null");
9526 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9527 UserHandle.getUserId(cpi.applicationInfo.uid),
9528 cpi.applicationInfo.packageName,
9529 cpi.applicationInfo.uid, name);
9534 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9535 + cpr.launchingApp);
9538 conn.waiting = true;
9541 } catch (InterruptedException ex) {
9544 conn.waiting = false;
9549 return cpr != null ? cpr.newHolder(conn) : null;
9553 public final ContentProviderHolder getContentProvider(
9554 IApplicationThread caller, String name, int userId, boolean stable) {
9555 enforceNotIsolatedCaller("getContentProvider");
9556 if (caller == null) {
9557 String msg = "null IApplicationThread when getting content provider "
9560 throw new SecurityException(msg);
9562 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9563 // with cross-user grant.
9564 return getContentProviderImpl(caller, name, null, stable, userId);
9567 public ContentProviderHolder getContentProviderExternal(
9568 String name, int userId, IBinder token) {
9569 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9570 "Do not have permission in call getContentProviderExternal()");
9571 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9572 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9573 return getContentProviderExternalUnchecked(name, token, userId);
9576 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9577 IBinder token, int userId) {
9578 return getContentProviderImpl(null, name, token, true, userId);
9582 * Drop a content provider from a ProcessRecord's bookkeeping
9584 public void removeContentProvider(IBinder connection, boolean stable) {
9585 enforceNotIsolatedCaller("removeContentProvider");
9586 long ident = Binder.clearCallingIdentity();
9588 synchronized (this) {
9589 ContentProviderConnection conn;
9591 conn = (ContentProviderConnection)connection;
9592 } catch (ClassCastException e) {
9593 String msg ="removeContentProvider: " + connection
9594 + " not a ContentProviderConnection";
9596 throw new IllegalArgumentException(msg);
9599 throw new NullPointerException("connection is null");
9601 if (decProviderCountLocked(conn, null, null, stable)) {
9602 updateOomAdjLocked();
9606 Binder.restoreCallingIdentity(ident);
9610 public void removeContentProviderExternal(String name, IBinder token) {
9611 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9612 "Do not have permission in call removeContentProviderExternal()");
9613 int userId = UserHandle.getCallingUserId();
9614 long ident = Binder.clearCallingIdentity();
9616 removeContentProviderExternalUnchecked(name, token, userId);
9618 Binder.restoreCallingIdentity(ident);
9622 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9623 synchronized (this) {
9624 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9626 //remove from mProvidersByClass
9627 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9631 //update content provider record entry info
9632 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9633 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9634 if (localCpr.hasExternalProcessHandles()) {
9635 if (localCpr.removeExternalProcessHandleLocked(token)) {
9636 updateOomAdjLocked();
9638 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9639 + " with no external reference for token: "
9643 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9644 + " with no external references.");
9649 public final void publishContentProviders(IApplicationThread caller,
9650 List<ContentProviderHolder> providers) {
9651 if (providers == null) {
9655 enforceNotIsolatedCaller("publishContentProviders");
9656 synchronized (this) {
9657 final ProcessRecord r = getRecordForAppLocked(caller);
9659 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9661 throw new SecurityException(
9662 "Unable to find app for caller " + caller
9663 + " (pid=" + Binder.getCallingPid()
9664 + ") when publishing content providers");
9667 final long origId = Binder.clearCallingIdentity();
9669 final int N = providers.size();
9670 for (int i=0; i<N; i++) {
9671 ContentProviderHolder src = providers.get(i);
9672 if (src == null || src.info == null || src.provider == null) {
9675 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9677 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9679 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9680 mProviderMap.putProviderByClass(comp, dst);
9681 String names[] = dst.info.authority.split(";");
9682 for (int j = 0; j < names.length; j++) {
9683 mProviderMap.putProviderByName(names[j], dst);
9686 int NL = mLaunchingProviders.size();
9688 for (j=0; j<NL; j++) {
9689 if (mLaunchingProviders.get(j) == dst) {
9690 mLaunchingProviders.remove(j);
9695 synchronized (dst) {
9696 dst.provider = src.provider;
9700 updateOomAdjLocked(r);
9704 Binder.restoreCallingIdentity(origId);
9708 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9709 ContentProviderConnection conn;
9711 conn = (ContentProviderConnection)connection;
9712 } catch (ClassCastException e) {
9713 String msg ="refContentProvider: " + connection
9714 + " not a ContentProviderConnection";
9716 throw new IllegalArgumentException(msg);
9719 throw new NullPointerException("connection is null");
9722 synchronized (this) {
9724 conn.numStableIncs += stable;
9726 stable = conn.stableCount + stable;
9728 throw new IllegalStateException("stableCount < 0: " + stable);
9732 conn.numUnstableIncs += unstable;
9734 unstable = conn.unstableCount + unstable;
9736 throw new IllegalStateException("unstableCount < 0: " + unstable);
9739 if ((stable+unstable) <= 0) {
9740 throw new IllegalStateException("ref counts can't go to zero here: stable="
9741 + stable + " unstable=" + unstable);
9743 conn.stableCount = stable;
9744 conn.unstableCount = unstable;
9749 public void unstableProviderDied(IBinder connection) {
9750 ContentProviderConnection conn;
9752 conn = (ContentProviderConnection)connection;
9753 } catch (ClassCastException e) {
9754 String msg ="refContentProvider: " + connection
9755 + " not a ContentProviderConnection";
9757 throw new IllegalArgumentException(msg);
9760 throw new NullPointerException("connection is null");
9763 // Safely retrieve the content provider associated with the connection.
9764 IContentProvider provider;
9765 synchronized (this) {
9766 provider = conn.provider.provider;
9769 if (provider == null) {
9770 // Um, yeah, we're way ahead of you.
9774 // Make sure the caller is being honest with us.
9775 if (provider.asBinder().pingBinder()) {
9776 // Er, no, still looks good to us.
9777 synchronized (this) {
9778 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9779 + " says " + conn + " died, but we don't agree");
9784 // Well look at that! It's dead!
9785 synchronized (this) {
9786 if (conn.provider.provider != provider) {
9787 // But something changed... good enough.
9791 ProcessRecord proc = conn.provider.proc;
9792 if (proc == null || proc.thread == null) {
9793 // Seems like the process is already cleaned up.
9797 // As far as we're concerned, this is just like receiving a
9798 // death notification... just a bit prematurely.
9799 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9800 + ") early provider death");
9801 final long ident = Binder.clearCallingIdentity();
9803 appDiedLocked(proc);
9805 Binder.restoreCallingIdentity(ident);
9811 public void appNotRespondingViaProvider(IBinder connection) {
9812 enforceCallingPermission(
9813 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9815 final ContentProviderConnection conn = (ContentProviderConnection) connection;
9817 Slog.w(TAG, "ContentProviderConnection is null");
9821 final ProcessRecord host = conn.provider.proc;
9823 Slog.w(TAG, "Failed to find hosting ProcessRecord");
9827 final long token = Binder.clearCallingIdentity();
9829 appNotResponding(host, null, null, false, "ContentProvider not responding");
9831 Binder.restoreCallingIdentity(token);
9835 public final void installSystemProviders() {
9836 List<ProviderInfo> providers;
9837 synchronized (this) {
9838 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9839 providers = generateApplicationProvidersLocked(app);
9840 if (providers != null) {
9841 for (int i=providers.size()-1; i>=0; i--) {
9842 ProviderInfo pi = (ProviderInfo)providers.get(i);
9843 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9844 Slog.w(TAG, "Not installing system proc provider " + pi.name
9845 + ": not system .apk");
9846 providers.remove(i);
9851 if (providers != null) {
9852 mSystemThread.installSystemProviders(providers);
9855 mCoreSettingsObserver = new CoreSettingsObserver(this);
9857 //mUsageStatsService.monitorPackages();
9861 * Allows apps to retrieve the MIME type of a URI.
9862 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9863 * users, then it does not need permission to access the ContentProvider.
9864 * Either, it needs cross-user uri grants.
9866 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9868 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9869 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9871 public String getProviderMimeType(Uri uri, int userId) {
9872 enforceNotIsolatedCaller("getProviderMimeType");
9873 final String name = uri.getAuthority();
9874 int callingUid = Binder.getCallingUid();
9875 int callingPid = Binder.getCallingPid();
9877 boolean clearedIdentity = false;
9878 userId = unsafeConvertIncomingUser(userId);
9879 if (canClearIdentity(callingPid, callingUid, userId)) {
9880 clearedIdentity = true;
9881 ident = Binder.clearCallingIdentity();
9883 ContentProviderHolder holder = null;
9885 holder = getContentProviderExternalUnchecked(name, null, userId);
9886 if (holder != null) {
9887 return holder.provider.getType(uri);
9889 } catch (RemoteException e) {
9890 Log.w(TAG, "Content provider dead retrieving " + uri, e);
9893 // We need to clear the identity to call removeContentProviderExternalUnchecked
9894 if (!clearedIdentity) {
9895 ident = Binder.clearCallingIdentity();
9898 if (holder != null) {
9899 removeContentProviderExternalUnchecked(name, null, userId);
9902 Binder.restoreCallingIdentity(ident);
9909 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
9910 if (UserHandle.getUserId(callingUid) == userId) {
9913 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9914 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9915 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9916 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9922 // =========================================================
9923 // GLOBAL MANAGEMENT
9924 // =========================================================
9926 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9927 boolean isolated, int isolatedUid) {
9928 String proc = customProcess != null ? customProcess : info.processName;
9929 BatteryStatsImpl.Uid.Proc ps = null;
9930 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9933 if (isolatedUid == 0) {
9934 int userId = UserHandle.getUserId(uid);
9935 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9937 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9938 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9939 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9941 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9942 mNextIsolatedProcessUid++;
9943 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9944 // No process for this uid, use it.
9948 if (stepsLeft <= 0) {
9953 // Special case for startIsolatedProcess (internal only), where
9954 // the uid of the isolated process is specified by the caller.
9958 return new ProcessRecord(stats, info, proc, uid);
9961 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9962 String abiOverride) {
9965 app = getProcessRecordLocked(info.processName, info.uid, true);
9971 app = newProcessRecordLocked(info, null, isolated, 0);
9972 mProcessNames.put(info.processName, app.uid, app);
9974 mIsolatedProcesses.put(app.uid, app);
9976 updateLruProcessLocked(app, false, null);
9977 updateOomAdjLocked();
9980 // This package really, really can not be stopped.
9982 AppGlobals.getPackageManager().setPackageStoppedState(
9983 info.packageName, false, UserHandle.getUserId(app.uid));
9984 } catch (RemoteException e) {
9985 } catch (IllegalArgumentException e) {
9986 Slog.w(TAG, "Failed trying to unstop package "
9987 + info.packageName + ": " + e);
9990 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9991 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9992 app.persistent = true;
9993 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9995 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9996 mPersistentStartingProcesses.add(app);
9997 startProcessLocked(app, "added application", app.processName, abiOverride,
9998 null /* entryPoint */, null /* entryPointArgs */);
10004 public void unhandledBack() {
10005 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10006 "unhandledBack()");
10008 synchronized(this) {
10009 final long origId = Binder.clearCallingIdentity();
10011 getFocusedStack().unhandledBackLocked();
10013 Binder.restoreCallingIdentity(origId);
10018 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10019 enforceNotIsolatedCaller("openContentUri");
10020 final int userId = UserHandle.getCallingUserId();
10021 String name = uri.getAuthority();
10022 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10023 ParcelFileDescriptor pfd = null;
10025 // We record the binder invoker's uid in thread-local storage before
10026 // going to the content provider to open the file. Later, in the code
10027 // that handles all permissions checks, we look for this uid and use
10028 // that rather than the Activity Manager's own uid. The effect is that
10029 // we do the check against the caller's permissions even though it looks
10030 // to the content provider like the Activity Manager itself is making
10032 sCallerIdentity.set(new Identity(
10033 Binder.getCallingPid(), Binder.getCallingUid()));
10035 pfd = cph.provider.openFile(null, uri, "r", null);
10036 } catch (FileNotFoundException e) {
10037 // do nothing; pfd will be returned null
10039 // Ensure that whatever happens, we clean up the identity state
10040 sCallerIdentity.remove();
10043 // We've got the fd now, so we're done with the provider.
10044 removeContentProviderExternalUnchecked(name, null, userId);
10046 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10051 // Actually is sleeping or shutting down or whatever else in the future
10052 // is an inactive state.
10053 public boolean isSleepingOrShuttingDown() {
10054 return isSleeping() || mShuttingDown;
10057 public boolean isSleeping() {
10061 void onWakefulnessChanged(int wakefulness) {
10062 synchronized(this) {
10063 mWakefulness = wakefulness;
10064 updateSleepIfNeededLocked();
10068 void finishRunningVoiceLocked() {
10069 if (mRunningVoice) {
10070 mRunningVoice = false;
10071 updateSleepIfNeededLocked();
10075 void updateSleepIfNeededLocked() {
10076 if (mSleeping && !shouldSleepLocked()) {
10078 mStackSupervisor.comeOutOfSleepIfNeededLocked();
10079 } else if (!mSleeping && shouldSleepLocked()) {
10081 mStackSupervisor.goingToSleepLocked();
10083 // Initialize the wake times of all processes.
10084 checkExcessivePowerUsageLocked(false);
10085 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10086 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10087 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10091 private boolean shouldSleepLocked() {
10092 // Resume applications while running a voice interactor.
10093 if (mRunningVoice) {
10097 switch (mWakefulness) {
10098 case PowerManagerInternal.WAKEFULNESS_AWAKE:
10099 case PowerManagerInternal.WAKEFULNESS_DREAMING:
10100 // If we're interactive but applications are already paused then defer
10101 // resuming them until the lock screen is hidden.
10102 return mSleeping && mLockScreenShown;
10103 case PowerManagerInternal.WAKEFULNESS_DOZING:
10104 // If we're dozing then pause applications whenever the lock screen is shown.
10105 return mLockScreenShown;
10106 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10108 // If we're asleep then pause applications unconditionally.
10113 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10114 if (task != null && task.stack != null && task.stack.isHomeStack()) {
10115 // Never persist the home stack.
10118 mTaskPersister.wakeup(task, flush);
10122 public boolean shutdown(int timeout) {
10123 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10124 != PackageManager.PERMISSION_GRANTED) {
10125 throw new SecurityException("Requires permission "
10126 + android.Manifest.permission.SHUTDOWN);
10129 boolean timedout = false;
10131 synchronized(this) {
10132 mShuttingDown = true;
10133 updateEventDispatchingLocked();
10134 timedout = mStackSupervisor.shutdownLocked(timeout);
10137 mAppOpsService.shutdown();
10138 if (mUsageStatsService != null) {
10139 mUsageStatsService.prepareShutdown();
10141 mBatteryStatsService.shutdown();
10142 synchronized (this) {
10143 mProcessStats.shutdownLocked();
10145 notifyTaskPersisterLocked(null, true);
10150 public final void activitySlept(IBinder token) {
10151 if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
10153 final long origId = Binder.clearCallingIdentity();
10155 synchronized (this) {
10156 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10158 mStackSupervisor.activitySleptLocked(r);
10162 Binder.restoreCallingIdentity(origId);
10165 void logLockScreen(String msg) {
10166 if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg
10167 + " mLockScreenShown=" + mLockScreenShown + " mWakefulness="
10168 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10169 + " mSleeping=" + mSleeping);
10172 void startRunningVoiceLocked() {
10173 if (!mRunningVoice) {
10174 mRunningVoice = true;
10175 updateSleepIfNeededLocked();
10179 private void updateEventDispatchingLocked() {
10180 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10183 public void setLockScreenShown(boolean shown) {
10184 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10185 != PackageManager.PERMISSION_GRANTED) {
10186 throw new SecurityException("Requires permission "
10187 + android.Manifest.permission.DEVICE_POWER);
10190 synchronized(this) {
10191 long ident = Binder.clearCallingIdentity();
10193 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10194 mLockScreenShown = shown;
10195 updateSleepIfNeededLocked();
10197 Binder.restoreCallingIdentity(ident);
10203 public void stopAppSwitches() {
10204 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10205 != PackageManager.PERMISSION_GRANTED) {
10206 throw new SecurityException("Requires permission "
10207 + android.Manifest.permission.STOP_APP_SWITCHES);
10210 synchronized(this) {
10211 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10212 + APP_SWITCH_DELAY_TIME;
10213 mDidAppSwitch = false;
10214 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10215 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10216 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10220 public void resumeAppSwitches() {
10221 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10222 != PackageManager.PERMISSION_GRANTED) {
10223 throw new SecurityException("Requires permission "
10224 + android.Manifest.permission.STOP_APP_SWITCHES);
10227 synchronized(this) {
10228 // Note that we don't execute any pending app switches... we will
10229 // let those wait until either the timeout, or the next start
10230 // activity request.
10231 mAppSwitchesAllowedTime = 0;
10235 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10236 int callingPid, int callingUid, String name) {
10237 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10241 int perm = checkComponentPermission(
10242 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10243 sourceUid, -1, true);
10244 if (perm == PackageManager.PERMISSION_GRANTED) {
10248 // If the actual IPC caller is different from the logical source, then
10249 // also see if they are allowed to control app switches.
10250 if (callingUid != -1 && callingUid != sourceUid) {
10251 perm = checkComponentPermission(
10252 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10253 callingUid, -1, true);
10254 if (perm == PackageManager.PERMISSION_GRANTED) {
10259 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10263 public void setDebugApp(String packageName, boolean waitForDebugger,
10264 boolean persistent) {
10265 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10268 long ident = Binder.clearCallingIdentity();
10270 // Note that this is not really thread safe if there are multiple
10271 // callers into it at the same time, but that's not a situation we
10274 final ContentResolver resolver = mContext.getContentResolver();
10275 Settings.Global.putString(
10276 resolver, Settings.Global.DEBUG_APP,
10278 Settings.Global.putInt(
10279 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10280 waitForDebugger ? 1 : 0);
10283 synchronized (this) {
10285 mOrigDebugApp = mDebugApp;
10286 mOrigWaitForDebugger = mWaitForDebugger;
10288 mDebugApp = packageName;
10289 mWaitForDebugger = waitForDebugger;
10290 mDebugTransient = !persistent;
10291 if (packageName != null) {
10292 forceStopPackageLocked(packageName, -1, false, false, true, true,
10293 false, UserHandle.USER_ALL, "set debug app");
10297 Binder.restoreCallingIdentity(ident);
10301 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10302 synchronized (this) {
10303 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10304 if (!isDebuggable) {
10305 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10306 throw new SecurityException("Process not debuggable: " + app.packageName);
10310 mOpenGlTraceApp = processName;
10314 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10315 synchronized (this) {
10316 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10317 if (!isDebuggable) {
10318 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10319 throw new SecurityException("Process not debuggable: " + app.packageName);
10322 mProfileApp = processName;
10323 mProfileFile = profilerInfo.profileFile;
10324 if (mProfileFd != null) {
10326 mProfileFd.close();
10327 } catch (IOException e) {
10331 mProfileFd = profilerInfo.profileFd;
10332 mSamplingInterval = profilerInfo.samplingInterval;
10333 mAutoStopProfiler = profilerInfo.autoStopProfiler;
10339 public void setAlwaysFinish(boolean enabled) {
10340 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10341 "setAlwaysFinish()");
10343 Settings.Global.putInt(
10344 mContext.getContentResolver(),
10345 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10347 synchronized (this) {
10348 mAlwaysFinishActivities = enabled;
10353 public void setActivityController(IActivityController controller) {
10354 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10355 "setActivityController()");
10356 synchronized (this) {
10357 mController = controller;
10358 Watchdog.getInstance().setActivityController(controller);
10363 public void setUserIsMonkey(boolean userIsMonkey) {
10364 synchronized (this) {
10365 synchronized (mPidsSelfLocked) {
10366 final int callingPid = Binder.getCallingPid();
10367 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10368 if (precessRecord == null) {
10369 throw new SecurityException("Unknown process: " + callingPid);
10371 if (precessRecord.instrumentationUiAutomationConnection == null) {
10372 throw new SecurityException("Only an instrumentation process "
10373 + "with a UiAutomation can call setUserIsMonkey");
10376 mUserIsMonkey = userIsMonkey;
10381 public boolean isUserAMonkey() {
10382 synchronized (this) {
10383 // If there is a controller also implies the user is a monkey.
10384 return (mUserIsMonkey || mController != null);
10388 public void requestBugReport() {
10389 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10390 SystemProperties.set("ctl.start", "bugreport");
10393 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10394 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10397 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10398 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10399 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10401 return KEY_DISPATCHING_TIMEOUT;
10405 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10406 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10407 != PackageManager.PERMISSION_GRANTED) {
10408 throw new SecurityException("Requires permission "
10409 + android.Manifest.permission.FILTER_EVENTS);
10411 ProcessRecord proc;
10413 synchronized (this) {
10414 synchronized (mPidsSelfLocked) {
10415 proc = mPidsSelfLocked.get(pid);
10417 timeout = getInputDispatchingTimeoutLocked(proc);
10420 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10428 * Handle input dispatching timeouts.
10429 * Returns whether input dispatching should be aborted or not.
10431 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10432 final ActivityRecord activity, final ActivityRecord parent,
10433 final boolean aboveSystem, String reason) {
10434 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10435 != PackageManager.PERMISSION_GRANTED) {
10436 throw new SecurityException("Requires permission "
10437 + android.Manifest.permission.FILTER_EVENTS);
10440 final String annotation;
10441 if (reason == null) {
10442 annotation = "Input dispatching timed out";
10444 annotation = "Input dispatching timed out (" + reason + ")";
10447 if (proc != null) {
10448 synchronized (this) {
10449 if (proc.debugging) {
10454 // Give more time since we were dexopting.
10455 mDidDexOpt = false;
10459 if (proc.instrumentationClass != null) {
10460 Bundle info = new Bundle();
10461 info.putString("shortMsg", "keyDispatchingTimedOut");
10462 info.putString("longMsg", annotation);
10463 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10467 mHandler.post(new Runnable() {
10469 public void run() {
10470 appNotResponding(proc, activity, parent, aboveSystem, annotation);
10478 public Bundle getAssistContextExtras(int requestType) {
10479 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
10480 UserHandle.getCallingUserId());
10484 synchronized (pae) {
10485 while (!pae.haveResult) {
10488 } catch (InterruptedException e) {
10491 if (pae.result != null) {
10492 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10495 synchronized (this) {
10496 mPendingAssistExtras.remove(pae);
10497 mHandler.removeCallbacks(pae);
10502 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10504 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10505 "getAssistContextExtras()");
10506 PendingAssistExtras pae;
10507 Bundle extras = new Bundle();
10508 synchronized (this) {
10509 ActivityRecord activity = getFocusedStack().mResumedActivity;
10510 if (activity == null) {
10511 Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10514 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10515 if (activity.app == null || activity.app.thread == null) {
10516 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10519 if (activity.app.pid == Binder.getCallingPid()) {
10520 Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10523 pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
10525 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10527 mPendingAssistExtras.add(pae);
10528 mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10529 } catch (RemoteException e) {
10530 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10537 public void reportAssistContextExtras(IBinder token, Bundle extras) {
10538 PendingAssistExtras pae = (PendingAssistExtras)token;
10539 synchronized (pae) {
10540 pae.result = extras;
10541 pae.haveResult = true;
10543 if (pae.intent == null) {
10544 // Caller is just waiting for the result.
10549 // We are now ready to launch the assist activity.
10550 synchronized (this) {
10551 boolean exists = mPendingAssistExtras.remove(pae);
10552 mHandler.removeCallbacks(pae);
10558 pae.intent.replaceExtras(extras);
10559 if (pae.hint != null) {
10560 pae.intent.putExtra(pae.hint, true);
10562 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10563 | Intent.FLAG_ACTIVITY_SINGLE_TOP
10564 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10565 closeSystemDialogs("assist");
10567 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10568 } catch (ActivityNotFoundException e) {
10569 Slog.w(TAG, "No activity to handle assist action.", e);
10573 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
10574 return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
10577 public void registerProcessObserver(IProcessObserver observer) {
10578 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10579 "registerProcessObserver()");
10580 synchronized (this) {
10581 mProcessObservers.register(observer);
10586 public void unregisterProcessObserver(IProcessObserver observer) {
10587 synchronized (this) {
10588 mProcessObservers.unregister(observer);
10593 public boolean convertFromTranslucent(IBinder token) {
10594 final long origId = Binder.clearCallingIdentity();
10596 synchronized (this) {
10597 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10601 final boolean translucentChanged = r.changeWindowTranslucency(true);
10602 if (translucentChanged) {
10603 r.task.stack.releaseBackgroundResources();
10604 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10606 mWindowManager.setAppFullscreen(token, true);
10607 return translucentChanged;
10610 Binder.restoreCallingIdentity(origId);
10615 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10616 final long origId = Binder.clearCallingIdentity();
10618 synchronized (this) {
10619 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10623 int index = r.task.mActivities.lastIndexOf(r);
10625 ActivityRecord under = r.task.mActivities.get(index - 1);
10626 under.returningOptions = options;
10628 final boolean translucentChanged = r.changeWindowTranslucency(false);
10629 if (translucentChanged) {
10630 r.task.stack.convertToTranslucent(r);
10632 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10633 mWindowManager.setAppFullscreen(token, false);
10634 return translucentChanged;
10637 Binder.restoreCallingIdentity(origId);
10642 public boolean requestVisibleBehind(IBinder token, boolean visible) {
10643 final long origId = Binder.clearCallingIdentity();
10645 synchronized (this) {
10646 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10648 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10653 Binder.restoreCallingIdentity(origId);
10658 public boolean isBackgroundVisibleBehind(IBinder token) {
10659 final long origId = Binder.clearCallingIdentity();
10661 synchronized (this) {
10662 final ActivityStack stack = ActivityRecord.getStackLocked(token);
10663 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10664 if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10665 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10669 Binder.restoreCallingIdentity(origId);
10674 public ActivityOptions getActivityOptions(IBinder token) {
10675 final long origId = Binder.clearCallingIdentity();
10677 synchronized (this) {
10678 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10680 final ActivityOptions activityOptions = r.pendingOptions;
10681 r.pendingOptions = null;
10682 return activityOptions;
10687 Binder.restoreCallingIdentity(origId);
10692 public void setImmersive(IBinder token, boolean immersive) {
10693 synchronized(this) {
10694 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10696 throw new IllegalArgumentException();
10698 r.immersive = immersive;
10700 // update associated state if we're frontmost
10701 if (r == mFocusedActivity) {
10702 if (DEBUG_IMMERSIVE) {
10703 Slog.d(TAG, "Frontmost changed immersion: "+ r);
10705 applyUpdateLockStateLocked(r);
10711 public boolean isImmersive(IBinder token) {
10712 synchronized (this) {
10713 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10715 throw new IllegalArgumentException();
10717 return r.immersive;
10721 public boolean isTopActivityImmersive() {
10722 enforceNotIsolatedCaller("startActivity");
10723 synchronized (this) {
10724 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10725 return (r != null) ? r.immersive : false;
10730 public boolean isTopOfTask(IBinder token) {
10731 synchronized (this) {
10732 ActivityRecord r = ActivityRecord.isInStackLocked(token);
10734 throw new IllegalArgumentException();
10736 return r.task.getTopActivity() == r;
10740 public final void enterSafeMode() {
10741 synchronized(this) {
10742 // It only makes sense to do this before the system is ready
10743 // and started launching other packages.
10744 if (!mSystemReady) {
10746 AppGlobals.getPackageManager().enterSafeMode();
10747 } catch (RemoteException e) {
10755 public final void showSafeModeOverlay() {
10756 View v = LayoutInflater.from(mContext).inflate(
10757 com.android.internal.R.layout.safe_mode, null);
10758 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10759 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10760 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10761 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10762 lp.gravity = Gravity.BOTTOM | Gravity.START;
10763 lp.format = v.getBackground().getOpacity();
10764 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10765 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10766 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10767 ((WindowManager)mContext.getSystemService(
10768 Context.WINDOW_SERVICE)).addView(v, lp);
10771 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10772 if (!(sender instanceof PendingIntentRecord)) {
10775 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10776 synchronized (stats) {
10777 if (mBatteryStatsService.isOnBattery()) {
10778 mBatteryStatsService.enforceCallingPermission();
10779 PendingIntentRecord rec = (PendingIntentRecord)sender;
10780 int MY_UID = Binder.getCallingUid();
10781 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10782 BatteryStatsImpl.Uid.Pkg pkg =
10783 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10784 sourcePkg != null ? sourcePkg : rec.key.packageName);
10785 pkg.incWakeupsLocked();
10790 public boolean killPids(int[] pids, String pReason, boolean secure) {
10791 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10792 throw new SecurityException("killPids only available to the system");
10794 String reason = (pReason == null) ? "Unknown" : pReason;
10795 // XXX Note: don't acquire main activity lock here, because the window
10796 // manager calls in with its locks held.
10798 boolean killed = false;
10799 synchronized (mPidsSelfLocked) {
10800 int[] types = new int[pids.length];
10802 for (int i=0; i<pids.length; i++) {
10803 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10804 if (proc != null) {
10805 int type = proc.setAdj;
10807 if (type > worstType) {
10813 // If the worst oom_adj is somewhere in the cached proc LRU range,
10814 // then constrain it so we will kill all cached procs.
10815 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10816 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10817 worstType = ProcessList.CACHED_APP_MIN_ADJ;
10820 // If this is not a secure call, don't let it kill processes that
10822 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10823 worstType = ProcessList.SERVICE_ADJ;
10826 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10827 for (int i=0; i<pids.length; i++) {
10828 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10829 if (proc == null) {
10832 int adj = proc.setAdj;
10833 if (adj >= worstType && !proc.killedByAm) {
10834 proc.kill(reason, true);
10843 public void killUid(int uid, String reason) {
10844 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10845 throw new SecurityException("killUid only available to the system");
10847 synchronized (this) {
10848 killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10849 ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10850 reason != null ? reason : "kill uid");
10855 public boolean killProcessesBelowForeground(String reason) {
10856 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10857 throw new SecurityException("killProcessesBelowForeground() only available to system");
10860 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10863 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10864 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10865 throw new SecurityException("killProcessesBelowAdj() only available to system");
10868 boolean killed = false;
10869 synchronized (mPidsSelfLocked) {
10870 final int size = mPidsSelfLocked.size();
10871 for (int i = 0; i < size; i++) {
10872 final int pid = mPidsSelfLocked.keyAt(i);
10873 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10874 if (proc == null) continue;
10876 final int adj = proc.setAdj;
10877 if (adj > belowAdj && !proc.killedByAm) {
10878 proc.kill(reason, true);
10887 public void hang(final IBinder who, boolean allowRestart) {
10888 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10889 != PackageManager.PERMISSION_GRANTED) {
10890 throw new SecurityException("Requires permission "
10891 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10894 final IBinder.DeathRecipient death = new DeathRecipient() {
10896 public void binderDied() {
10897 synchronized (this) {
10904 who.linkToDeath(death, 0);
10905 } catch (RemoteException e) {
10906 Slog.w(TAG, "hang: given caller IBinder is already dead.");
10910 synchronized (this) {
10911 Watchdog.getInstance().setAllowRestart(allowRestart);
10912 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10913 synchronized (death) {
10914 while (who.isBinderAlive()) {
10917 } catch (InterruptedException e) {
10921 Watchdog.getInstance().setAllowRestart(true);
10926 public void restart() {
10927 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10928 != PackageManager.PERMISSION_GRANTED) {
10929 throw new SecurityException("Requires permission "
10930 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10933 Log.i(TAG, "Sending shutdown broadcast...");
10935 BroadcastReceiver br = new BroadcastReceiver() {
10936 @Override public void onReceive(Context context, Intent intent) {
10937 // Now the broadcast is done, finish up the low-level shutdown.
10938 Log.i(TAG, "Shutting down activity manager...");
10940 Log.i(TAG, "Shutdown complete, restarting!");
10941 Process.killProcess(Process.myPid());
10946 // First send the high-level shut down broadcast.
10947 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10948 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10949 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10950 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10951 mContext.sendOrderedBroadcastAsUser(intent,
10952 UserHandle.ALL, null, br, mHandler, 0, null, null);
10954 br.onReceive(mContext, intent);
10957 private long getLowRamTimeSinceIdle(long now) {
10958 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10962 public void performIdleMaintenance() {
10963 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10964 != PackageManager.PERMISSION_GRANTED) {
10965 throw new SecurityException("Requires permission "
10966 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10969 synchronized (this) {
10970 final long now = SystemClock.uptimeMillis();
10971 final long timeSinceLastIdle = now - mLastIdleTime;
10972 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10973 mLastIdleTime = now;
10974 mLowRamTimeSinceLastIdle = 0;
10975 if (mLowRamStartTime != 0) {
10976 mLowRamStartTime = now;
10979 StringBuilder sb = new StringBuilder(128);
10980 sb.append("Idle maintenance over ");
10981 TimeUtils.formatDuration(timeSinceLastIdle, sb);
10982 sb.append(" low RAM for ");
10983 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10984 Slog.i(TAG, sb.toString());
10986 // If at least 1/3 of our time since the last idle period has been spent
10987 // with RAM low, then we want to kill processes.
10988 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10990 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10991 ProcessRecord proc = mLruProcesses.get(i);
10992 if (proc.notCachedSinceIdle) {
10993 if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10994 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10995 if (doKilling && proc.initialIdlePss != 0
10996 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10997 proc.kill("idle maint (pss " + proc.lastPss
10998 + " from " + proc.initialIdlePss + ")", true);
11001 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11002 proc.notCachedSinceIdle = true;
11003 proc.initialIdlePss = 0;
11004 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11005 isSleeping(), now);
11009 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11010 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11014 private void retrieveSettings() {
11015 final ContentResolver resolver = mContext.getContentResolver();
11016 String debugApp = Settings.Global.getString(
11017 resolver, Settings.Global.DEBUG_APP);
11018 boolean waitForDebugger = Settings.Global.getInt(
11019 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11020 boolean alwaysFinishActivities = Settings.Global.getInt(
11021 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11022 boolean forceRtl = Settings.Global.getInt(
11023 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11024 // Transfer any global setting for forcing RTL layout, into a System Property
11025 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11027 Configuration configuration = new Configuration();
11028 Settings.System.getConfiguration(resolver, configuration);
11030 // This will take care of setting the correct layout direction flags
11031 configuration.setLayoutDirection(configuration.locale);
11034 synchronized (this) {
11035 mDebugApp = mOrigDebugApp = debugApp;
11036 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11037 mAlwaysFinishActivities = alwaysFinishActivities;
11038 // This happens before any activities are started, so we can
11039 // change mConfiguration in-place.
11040 updateConfigurationLocked(configuration, null, false, true);
11041 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
11045 /** Loads resources after the current configuration has been set. */
11046 private void loadResourcesOnSystemReady() {
11047 final Resources res = mContext.getResources();
11048 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11049 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11050 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11053 public boolean testIsSystemReady() {
11054 // no need to synchronize(this) just to read & return the value
11055 return mSystemReady;
11058 private static File getCalledPreBootReceiversFile() {
11059 File dataDir = Environment.getDataDirectory();
11060 File systemDir = new File(dataDir, "system");
11061 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11065 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11066 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11067 File file = getCalledPreBootReceiversFile();
11068 FileInputStream fis = null;
11070 fis = new FileInputStream(file);
11071 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11072 int fvers = dis.readInt();
11073 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11074 String vers = dis.readUTF();
11075 String codename = dis.readUTF();
11076 String build = dis.readUTF();
11077 if (android.os.Build.VERSION.RELEASE.equals(vers)
11078 && android.os.Build.VERSION.CODENAME.equals(codename)
11079 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11080 int num = dis.readInt();
11083 String pkg = dis.readUTF();
11084 String cls = dis.readUTF();
11085 lastDoneReceivers.add(new ComponentName(pkg, cls));
11089 } catch (FileNotFoundException e) {
11090 } catch (IOException e) {
11091 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11096 } catch (IOException e) {
11100 return lastDoneReceivers;
11103 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11104 File file = getCalledPreBootReceiversFile();
11105 FileOutputStream fos = null;
11106 DataOutputStream dos = null;
11108 fos = new FileOutputStream(file);
11109 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11110 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11111 dos.writeUTF(android.os.Build.VERSION.RELEASE);
11112 dos.writeUTF(android.os.Build.VERSION.CODENAME);
11113 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11114 dos.writeInt(list.size());
11115 for (int i=0; i<list.size(); i++) {
11116 dos.writeUTF(list.get(i).getPackageName());
11117 dos.writeUTF(list.get(i).getClassName());
11119 } catch (IOException e) {
11120 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11123 FileUtils.sync(fos);
11127 } catch (IOException e) {
11128 // TODO Auto-generated catch block
11129 e.printStackTrace();
11135 private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11136 ArrayList<ComponentName> doneReceivers, int userId) {
11137 boolean waitingUpdate = false;
11138 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11139 List<ResolveInfo> ris = null;
11141 ris = AppGlobals.getPackageManager().queryIntentReceivers(
11142 intent, null, 0, userId);
11143 } catch (RemoteException e) {
11146 for (int i=ris.size()-1; i>=0; i--) {
11147 if ((ris.get(i).activityInfo.applicationInfo.flags
11148 &ApplicationInfo.FLAG_SYSTEM) == 0) {
11152 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11154 // For User 0, load the version number. When delivering to a new user, deliver
11155 // to all receivers.
11156 if (userId == UserHandle.USER_OWNER) {
11157 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11158 for (int i=0; i<ris.size(); i++) {
11159 ActivityInfo ai = ris.get(i).activityInfo;
11160 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11161 if (lastDoneReceivers.contains(comp)) {
11162 // We already did the pre boot receiver for this app with the current
11163 // platform version, so don't do it again...
11166 // ...however, do keep it as one that has been done, so we don't
11167 // forget about it when rewriting the file of last done receivers.
11168 doneReceivers.add(comp);
11173 // If primary user, send broadcast to all available users, else just to userId
11174 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11175 : new int[] { userId };
11176 for (int i = 0; i < ris.size(); i++) {
11177 ActivityInfo ai = ris.get(i).activityInfo;
11178 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11179 doneReceivers.add(comp);
11180 intent.setComponent(comp);
11181 for (int j=0; j<users.length; j++) {
11182 IIntentReceiver finisher = null;
11183 // On last receiver and user, set up a completion callback
11184 if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
11185 finisher = new IIntentReceiver.Stub() {
11186 public void performReceive(Intent intent, int resultCode,
11187 String data, Bundle extras, boolean ordered,
11188 boolean sticky, int sendingUser) {
11189 // The raw IIntentReceiver interface is called
11190 // with the AM lock held, so redispatch to
11191 // execute our code without the lock.
11192 mHandler.post(onFinishCallback);
11196 Slog.i(TAG, "Sending system update to " + intent.getComponent()
11197 + " for user " + users[j]);
11198 broadcastIntentLocked(null, null, intent, null, finisher,
11199 0, null, null, null, AppOpsManager.OP_NONE,
11200 true, false, MY_PID, Process.SYSTEM_UID,
11202 if (finisher != null) {
11203 waitingUpdate = true;
11209 return waitingUpdate;
11212 public void systemReady(final Runnable goingCallback) {
11213 synchronized(this) {
11214 if (mSystemReady) {
11215 // If we're done calling all the receivers, run the next "boot phase" passed in
11216 // by the SystemServer
11217 if (goingCallback != null) {
11218 goingCallback.run();
11223 // Make sure we have the current profile info, since it is needed for
11224 // security checks.
11225 updateCurrentProfileIdsLocked();
11227 if (mRecentTasks == null) {
11228 mRecentTasks = mTaskPersister.restoreTasksLocked();
11229 if (!mRecentTasks.isEmpty()) {
11230 mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
11232 cleanupRecentTasksLocked(UserHandle.USER_ALL);
11233 mTaskPersister.startPersisting();
11236 // Check to see if there are any update receivers to run.
11238 if (mWaitingUpdate) {
11241 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11242 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11243 public void run() {
11244 synchronized (ActivityManagerService.this) {
11247 writeLastDonePreBootReceivers(doneReceivers);
11248 showBootMessage(mContext.getText(
11249 R.string.android_upgrading_complete),
11251 systemReady(goingCallback);
11253 }, doneReceivers, UserHandle.USER_OWNER);
11255 if (mWaitingUpdate) {
11261 mAppOpsService.systemReady();
11262 mSystemReady = true;
11265 ArrayList<ProcessRecord> procsToKill = null;
11266 synchronized(mPidsSelfLocked) {
11267 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11268 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11269 if (!isAllowedWhileBooting(proc.info)){
11270 if (procsToKill == null) {
11271 procsToKill = new ArrayList<ProcessRecord>();
11273 procsToKill.add(proc);
11278 synchronized(this) {
11279 if (procsToKill != null) {
11280 for (int i=procsToKill.size()-1; i>=0; i--) {
11281 ProcessRecord proc = procsToKill.get(i);
11282 Slog.i(TAG, "Removing system update proc: " + proc);
11283 removeProcessLocked(proc, true, false, "system update done");
11287 // Now that we have cleaned up any update processes, we
11288 // are ready to start launching real processes and know that
11289 // we won't trample on them any more.
11290 mProcessesReady = true;
11293 Slog.i(TAG, "System now ready");
11294 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11295 SystemClock.uptimeMillis());
11297 synchronized(this) {
11298 // Make sure we have no pre-ready processes sitting around.
11300 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11301 ResolveInfo ri = mContext.getPackageManager()
11302 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11304 CharSequence errorMsg = null;
11306 ActivityInfo ai = ri.activityInfo;
11307 ApplicationInfo app = ai.applicationInfo;
11308 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11309 mTopAction = Intent.ACTION_FACTORY_TEST;
11311 mTopComponent = new ComponentName(app.packageName,
11314 errorMsg = mContext.getResources().getText(
11315 com.android.internal.R.string.factorytest_not_system);
11318 errorMsg = mContext.getResources().getText(
11319 com.android.internal.R.string.factorytest_no_action);
11321 if (errorMsg != null) {
11324 mTopComponent = null;
11325 Message msg = Message.obtain();
11326 msg.what = SHOW_FACTORY_ERROR_MSG;
11327 msg.getData().putCharSequence("msg", errorMsg);
11328 mHandler.sendMessage(msg);
11333 retrieveSettings();
11334 loadResourcesOnSystemReady();
11336 synchronized (this) {
11337 readGrantedUriPermissionsLocked();
11340 if (goingCallback != null) goingCallback.run();
11342 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11343 Integer.toString(mCurrentUserId), mCurrentUserId);
11344 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11345 Integer.toString(mCurrentUserId), mCurrentUserId);
11346 mSystemServiceManager.startUser(mCurrentUserId);
11348 synchronized (this) {
11349 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11351 List apps = AppGlobals.getPackageManager().
11352 getPersistentApplications(STOCK_PM_FLAGS);
11353 if (apps != null) {
11354 int N = apps.size();
11356 for (i=0; i<N; i++) {
11357 ApplicationInfo info
11358 = (ApplicationInfo)apps.get(i);
11359 if (info != null &&
11360 !info.packageName.equals("android")) {
11361 addAppLocked(info, false, null /* ABI override */);
11365 } catch (RemoteException ex) {
11366 // pm is in same process, this will never happen.
11370 // Start up initial activity.
11372 startHomeActivityLocked(mCurrentUserId);
11375 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11376 Message msg = Message.obtain();
11377 msg.what = SHOW_UID_ERROR_MSG;
11378 mHandler.sendMessage(msg);
11380 } catch (RemoteException e) {
11383 long ident = Binder.clearCallingIdentity();
11385 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11386 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11387 | Intent.FLAG_RECEIVER_FOREGROUND);
11388 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11389 broadcastIntentLocked(null, null, intent,
11390 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11391 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11392 intent = new Intent(Intent.ACTION_USER_STARTING);
11393 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11394 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11395 broadcastIntentLocked(null, null, intent,
11396 null, new IIntentReceiver.Stub() {
11398 public void performReceive(Intent intent, int resultCode, String data,
11399 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11400 throws RemoteException {
11403 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11404 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11405 } catch (Throwable t) {
11406 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11408 Binder.restoreCallingIdentity(ident);
11410 mStackSupervisor.resumeTopActivitiesLocked();
11411 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11415 private boolean makeAppCrashingLocked(ProcessRecord app,
11416 String shortMsg, String longMsg, String stackTrace) {
11417 app.crashing = true;
11418 app.crashingReport = generateProcessError(app,
11419 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11420 startAppProblemLocked(app);
11421 app.stopFreezingAllLocked();
11422 return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11425 private void makeAppNotRespondingLocked(ProcessRecord app,
11426 String activity, String shortMsg, String longMsg) {
11427 app.notResponding = true;
11428 app.notRespondingReport = generateProcessError(app,
11429 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11430 activity, shortMsg, longMsg, null);
11431 startAppProblemLocked(app);
11432 app.stopFreezingAllLocked();
11436 * Generate a process error record, suitable for attachment to a ProcessRecord.
11438 * @param app The ProcessRecord in which the error occurred.
11439 * @param condition Crashing, Application Not Responding, etc. Values are defined in
11440 * ActivityManager.AppErrorStateInfo
11441 * @param activity The activity associated with the crash, if known.
11442 * @param shortMsg Short message describing the crash.
11443 * @param longMsg Long message describing the crash.
11444 * @param stackTrace Full crash stack trace, may be null.
11446 * @return Returns a fully-formed AppErrorStateInfo record.
11448 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11449 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11450 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11452 report.condition = condition;
11453 report.processName = app.processName;
11454 report.pid = app.pid;
11455 report.uid = app.info.uid;
11456 report.tag = activity;
11457 report.shortMsg = shortMsg;
11458 report.longMsg = longMsg;
11459 report.stackTrace = stackTrace;
11464 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11465 synchronized (this) {
11466 app.crashing = false;
11467 app.crashingReport = null;
11468 app.notResponding = false;
11469 app.notRespondingReport = null;
11470 if (app.anrDialog == fromDialog) {
11471 app.anrDialog = null;
11473 if (app.waitDialog == fromDialog) {
11474 app.waitDialog = null;
11476 if (app.pid > 0 && app.pid != MY_PID) {
11477 handleAppCrashLocked(app, null, null, null);
11478 app.kill("user request after error", true);
11483 private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11484 String stackTrace) {
11485 long now = SystemClock.uptimeMillis();
11488 if (!app.isolated) {
11489 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11493 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11494 // This process loses!
11495 Slog.w(TAG, "Process " + app.info.processName
11496 + " has crashed too many times: killing!");
11497 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11498 app.userId, app.info.processName, app.uid);
11499 mStackSupervisor.handleAppCrashLocked(app);
11500 if (!app.persistent) {
11501 // We don't want to start this process again until the user
11502 // explicitly does so... but for persistent process, we really
11503 // need to keep it running. If a persistent process is actually
11504 // repeatedly crashing, then badness for everyone.
11505 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11506 app.info.processName);
11507 if (!app.isolated) {
11508 // XXX We don't have a way to mark isolated processes
11509 // as bad, since they don't have a peristent identity.
11510 mBadProcesses.put(app.info.processName, app.uid,
11511 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11512 mProcessCrashTimes.remove(app.info.processName, app.uid);
11515 app.removed = true;
11516 // Don't let services in this process be restarted and potentially
11517 // annoy the user repeatedly. Unless it is persistent, since those
11518 // processes run critical code.
11519 removeProcessLocked(app, false, false, "crash");
11520 mStackSupervisor.resumeTopActivitiesLocked();
11523 mStackSupervisor.resumeTopActivitiesLocked();
11525 mStackSupervisor.finishTopRunningActivityLocked(app);
11528 // Bump up the crash count of any services currently running in the proc.
11529 for (int i=app.services.size()-1; i>=0; i--) {
11530 // Any services running in the application need to be placed
11531 // back in the pending list.
11532 ServiceRecord sr = app.services.valueAt(i);
11536 // If the crashing process is what we consider to be the "home process" and it has been
11537 // replaced by a third-party app, clear the package preferred activities from packages
11538 // with a home activity running in the process to prevent a repeatedly crashing app
11539 // from blocking the user to manually clear the list.
11540 final ArrayList<ActivityRecord> activities = app.activities;
11541 if (app == mHomeProcess && activities.size() > 0
11542 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11543 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11544 final ActivityRecord r = activities.get(activityNdx);
11545 if (r.isHomeActivity()) {
11546 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11548 ActivityThread.getPackageManager()
11549 .clearPackagePreferredActivities(r.packageName);
11550 } catch (RemoteException c) {
11551 // pm is in same process, this will never happen.
11557 if (!app.isolated) {
11558 // XXX Can't keep track of crash times for isolated processes,
11559 // because they don't have a perisistent identity.
11560 mProcessCrashTimes.put(app.info.processName, app.uid, now);
11563 if (app.crashHandler != null) mHandler.post(app.crashHandler);
11567 void startAppProblemLocked(ProcessRecord app) {
11568 // If this app is not running under the current user, then we
11569 // can't give it a report button because that would require
11570 // launching the report UI under a different user.
11571 app.errorReportReceiver = null;
11573 for (int userId : mCurrentProfileIds) {
11574 if (app.userId == userId) {
11575 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11576 mContext, app.info.packageName, app.info.flags);
11579 skipCurrentReceiverLocked(app);
11582 void skipCurrentReceiverLocked(ProcessRecord app) {
11583 for (BroadcastQueue queue : mBroadcastQueues) {
11584 queue.skipCurrentReceiverLocked(app);
11589 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11590 * The application process will exit immediately after this call returns.
11591 * @param app object of the crashing app, null for the system server
11592 * @param crashInfo describing the exception
11594 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11595 ProcessRecord r = findAppProcess(app, "Crash");
11596 final String processName = app == null ? "system_server"
11597 : (r == null ? "unknown" : r.processName);
11599 handleApplicationCrashInner("crash", r, processName, crashInfo);
11602 /* Native crash reporting uses this inner version because it needs to be somewhat
11603 * decoupled from the AM-managed cleanup lifecycle
11605 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11606 ApplicationErrorReport.CrashInfo crashInfo) {
11607 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11608 UserHandle.getUserId(Binder.getCallingUid()), processName,
11609 r == null ? -1 : r.info.flags,
11610 crashInfo.exceptionClassName,
11611 crashInfo.exceptionMessage,
11612 crashInfo.throwFileName,
11613 crashInfo.throwLineNumber);
11615 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11617 crashApplication(r, crashInfo);
11620 public void handleApplicationStrictModeViolation(
11623 StrictMode.ViolationInfo info) {
11624 ProcessRecord r = findAppProcess(app, "StrictMode");
11629 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11630 Integer stackFingerprint = info.hashCode();
11631 boolean logIt = true;
11632 synchronized (mAlreadyLoggedViolatedStacks) {
11633 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11635 // TODO: sub-sample into EventLog for these, with
11636 // the info.durationMillis? Then we'd get
11637 // the relative pain numbers, without logging all
11638 // the stack traces repeatedly. We'd want to do
11639 // likewise in the client code, which also does
11640 // dup suppression, before the Binder call.
11642 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11643 mAlreadyLoggedViolatedStacks.clear();
11645 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11649 logStrictModeViolationToDropBox(r, info);
11653 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11654 AppErrorResult result = new AppErrorResult();
11655 synchronized (this) {
11656 final long origId = Binder.clearCallingIdentity();
11658 Message msg = Message.obtain();
11659 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11660 HashMap<String, Object> data = new HashMap<String, Object>();
11661 data.put("result", result);
11662 data.put("app", r);
11663 data.put("violationMask", violationMask);
11664 data.put("info", info);
11666 mHandler.sendMessage(msg);
11668 Binder.restoreCallingIdentity(origId);
11670 int res = result.get();
11671 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11675 // Depending on the policy in effect, there could be a bunch of
11676 // these in quick succession so we try to batch these together to
11677 // minimize disk writes, number of dropbox entries, and maximize
11678 // compression, by having more fewer, larger records.
11679 private void logStrictModeViolationToDropBox(
11680 ProcessRecord process,
11681 StrictMode.ViolationInfo info) {
11682 if (info == null) {
11685 final boolean isSystemApp = process == null ||
11686 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11687 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11688 final String processName = process == null ? "unknown" : process.processName;
11689 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11690 final DropBoxManager dbox = (DropBoxManager)
11691 mContext.getSystemService(Context.DROPBOX_SERVICE);
11693 // Exit early if the dropbox isn't configured to accept this report type.
11694 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11696 boolean bufferWasEmpty;
11697 boolean needsFlush;
11698 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11699 synchronized (sb) {
11700 bufferWasEmpty = sb.length() == 0;
11701 appendDropBoxProcessHeaders(process, processName, sb);
11702 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11703 sb.append("System-App: ").append(isSystemApp).append("\n");
11704 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11705 if (info.violationNumThisLoop != 0) {
11706 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11708 if (info.numAnimationsRunning != 0) {
11709 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11711 if (info.broadcastIntentAction != null) {
11712 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11714 if (info.durationMillis != -1) {
11715 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11717 if (info.numInstances != -1) {
11718 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11720 if (info.tags != null) {
11721 for (String tag : info.tags) {
11722 sb.append("Span-Tag: ").append(tag).append("\n");
11726 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11727 sb.append(info.crashInfo.stackTrace);
11731 // Only buffer up to ~64k. Various logging bits truncate
11733 needsFlush = (sb.length() > 64 * 1024);
11736 // Flush immediately if the buffer's grown too large, or this
11737 // is a non-system app. Non-system apps are isolated with a
11738 // different tag & policy and not batched.
11740 // Batching is useful during internal testing with
11741 // StrictMode settings turned up high. Without batching,
11742 // thousands of separate files could be created on boot.
11743 if (!isSystemApp || needsFlush) {
11744 new Thread("Error dump: " + dropboxTag) {
11746 public void run() {
11748 synchronized (sb) {
11749 report = sb.toString();
11750 sb.delete(0, sb.length());
11753 if (report.length() != 0) {
11754 dbox.addText(dropboxTag, report);
11761 // System app batching:
11762 if (!bufferWasEmpty) {
11763 // An existing dropbox-writing thread is outstanding, so
11764 // we don't need to start it up. The existing thread will
11765 // catch the buffer appends we just did.
11769 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11770 // (After this point, we shouldn't access AMS internal data structures.)
11771 new Thread("Error dump: " + dropboxTag) {
11773 public void run() {
11774 // 5 second sleep to let stacks arrive and be batched together
11776 Thread.sleep(5000); // 5 seconds
11777 } catch (InterruptedException e) {}
11779 String errorReport;
11780 synchronized (mStrictModeBuffer) {
11781 errorReport = mStrictModeBuffer.toString();
11782 if (errorReport.length() == 0) {
11785 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11786 mStrictModeBuffer.trimToSize();
11788 dbox.addText(dropboxTag, errorReport);
11794 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11795 * @param app object of the crashing app, null for the system server
11796 * @param tag reported by the caller
11797 * @param system whether this wtf is coming from the system
11798 * @param crashInfo describing the context of the error
11799 * @return true if the process should exit immediately (WTF is fatal)
11801 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
11802 final ApplicationErrorReport.CrashInfo crashInfo) {
11803 final int callingUid = Binder.getCallingUid();
11804 final int callingPid = Binder.getCallingPid();
11807 // If this is coming from the system, we could very well have low-level
11808 // system locks held, so we want to do this all asynchronously. And we
11809 // never want this to become fatal, so there is that too.
11810 mHandler.post(new Runnable() {
11811 @Override public void run() {
11812 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
11818 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
11821 if (r != null && r.pid != Process.myPid() &&
11822 Settings.Global.getInt(mContext.getContentResolver(),
11823 Settings.Global.WTF_IS_FATAL, 0) != 0) {
11824 crashApplication(r, crashInfo);
11831 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
11832 final ApplicationErrorReport.CrashInfo crashInfo) {
11833 final ProcessRecord r = findAppProcess(app, "WTF");
11834 final String processName = app == null ? "system_server"
11835 : (r == null ? "unknown" : r.processName);
11837 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
11838 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
11840 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11846 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11847 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11849 private ProcessRecord findAppProcess(IBinder app, String reason) {
11854 synchronized (this) {
11855 final int NP = mProcessNames.getMap().size();
11856 for (int ip=0; ip<NP; ip++) {
11857 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11858 final int NA = apps.size();
11859 for (int ia=0; ia<NA; ia++) {
11860 ProcessRecord p = apps.valueAt(ia);
11861 if (p.thread != null && p.thread.asBinder() == app) {
11867 Slog.w(TAG, "Can't find mystery application for " + reason
11868 + " from pid=" + Binder.getCallingPid()
11869 + " uid=" + Binder.getCallingUid() + ": " + app);
11875 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11876 * to append various headers to the dropbox log text.
11878 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11879 StringBuilder sb) {
11880 // Watchdog thread ends up invoking this function (with
11881 // a null ProcessRecord) to add the stack file to dropbox.
11882 // Do not acquire a lock on this (am) in such cases, as it
11883 // could cause a potential deadlock, if and when watchdog
11884 // is invoked due to unavailability of lock on am and it
11885 // would prevent watchdog from killing system_server.
11886 if (process == null) {
11887 sb.append("Process: ").append(processName).append("\n");
11890 // Note: ProcessRecord 'process' is guarded by the service
11891 // instance. (notably process.pkgList, which could otherwise change
11892 // concurrently during execution of this method)
11893 synchronized (this) {
11894 sb.append("Process: ").append(processName).append("\n");
11895 int flags = process.info.flags;
11896 IPackageManager pm = AppGlobals.getPackageManager();
11897 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11898 for (int ip=0; ip<process.pkgList.size(); ip++) {
11899 String pkg = process.pkgList.keyAt(ip);
11900 sb.append("Package: ").append(pkg);
11902 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11904 sb.append(" v").append(pi.versionCode);
11905 if (pi.versionName != null) {
11906 sb.append(" (").append(pi.versionName).append(")");
11909 } catch (RemoteException e) {
11910 Slog.e(TAG, "Error getting package info: " + pkg, e);
11917 private static String processClass(ProcessRecord process) {
11918 if (process == null || process.pid == MY_PID) {
11919 return "system_server";
11920 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11921 return "system_app";
11928 * Write a description of an error (crash, WTF, ANR) to the drop box.
11929 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11930 * @param process which caused the error, null means the system server
11931 * @param activity which triggered the error, null if unknown
11932 * @param parent activity related to the error, null if unknown
11933 * @param subject line related to the error, null if absent
11934 * @param report in long form describing the error, null if absent
11935 * @param logFile to include in the report, null if none
11936 * @param crashInfo giving an application stack trace, null if absent
11938 public void addErrorToDropBox(String eventType,
11939 ProcessRecord process, String processName, ActivityRecord activity,
11940 ActivityRecord parent, String subject,
11941 final String report, final File logFile,
11942 final ApplicationErrorReport.CrashInfo crashInfo) {
11943 // NOTE -- this must never acquire the ActivityManagerService lock,
11944 // otherwise the watchdog may be prevented from resetting the system.
11946 final String dropboxTag = processClass(process) + "_" + eventType;
11947 final DropBoxManager dbox = (DropBoxManager)
11948 mContext.getSystemService(Context.DROPBOX_SERVICE);
11950 // Exit early if the dropbox isn't configured to accept this report type.
11951 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11953 final StringBuilder sb = new StringBuilder(1024);
11954 appendDropBoxProcessHeaders(process, processName, sb);
11955 if (activity != null) {
11956 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11958 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11959 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11961 if (parent != null && parent != activity) {
11962 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11964 if (subject != null) {
11965 sb.append("Subject: ").append(subject).append("\n");
11967 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11968 if (Debug.isDebuggerConnected()) {
11969 sb.append("Debugger: Connected\n");
11973 // Do the rest in a worker thread to avoid blocking the caller on I/O
11974 // (After this point, we shouldn't access AMS internal data structures.)
11975 Thread worker = new Thread("Error dump: " + dropboxTag) {
11977 public void run() {
11978 if (report != null) {
11981 if (logFile != null) {
11983 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11984 "\n\n[[TRUNCATED]]"));
11985 } catch (IOException e) {
11986 Slog.e(TAG, "Error reading " + logFile, e);
11989 if (crashInfo != null && crashInfo.stackTrace != null) {
11990 sb.append(crashInfo.stackTrace);
11993 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11994 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11998 // Merge several logcat streams, and take the last N lines
11999 InputStreamReader input = null;
12001 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12002 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12004 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12006 try { logcat.getOutputStream().close(); } catch (IOException e) {}
12007 try { logcat.getErrorStream().close(); } catch (IOException e) {}
12008 input = new InputStreamReader(logcat.getInputStream());
12011 char[] buf = new char[8192];
12012 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12013 } catch (IOException e) {
12014 Slog.e(TAG, "Error running logcat", e);
12016 if (input != null) try { input.close(); } catch (IOException e) {}
12020 dbox.addText(dropboxTag, sb.toString());
12024 if (process == null) {
12025 // If process is null, we are being called from some internal code
12026 // and may be about to die -- run this synchronously.
12034 * Bring up the "unexpected error" dialog box for a crashing app.
12035 * Deal with edge cases (intercepts from instrumented applications,
12036 * ActivityController, error intent receivers, that sort of thing).
12037 * @param r the application crashing
12038 * @param crashInfo describing the failure
12040 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12041 long timeMillis = System.currentTimeMillis();
12042 String shortMsg = crashInfo.exceptionClassName;
12043 String longMsg = crashInfo.exceptionMessage;
12044 String stackTrace = crashInfo.stackTrace;
12045 if (shortMsg != null && longMsg != null) {
12046 longMsg = shortMsg + ": " + longMsg;
12047 } else if (shortMsg != null) {
12048 longMsg = shortMsg;
12051 AppErrorResult result = new AppErrorResult();
12052 synchronized (this) {
12053 if (mController != null) {
12055 String name = r != null ? r.processName : null;
12056 int pid = r != null ? r.pid : Binder.getCallingPid();
12057 int uid = r != null ? r.info.uid : Binder.getCallingUid();
12058 if (!mController.appCrashed(name, pid,
12059 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12060 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12061 && "Native crash".equals(crashInfo.exceptionClassName)) {
12062 Slog.w(TAG, "Skip killing native crashed app " + name
12063 + "(" + pid + ") during testing");
12065 Slog.w(TAG, "Force-killing crashed app " + name
12066 + " at watcher's request");
12068 r.kill("crash", true);
12071 Process.killProcess(pid);
12072 Process.killProcessGroup(uid, pid);
12077 } catch (RemoteException e) {
12078 mController = null;
12079 Watchdog.getInstance().setActivityController(null);
12083 final long origId = Binder.clearCallingIdentity();
12085 // If this process is running instrumentation, finish it.
12086 if (r != null && r.instrumentationClass != null) {
12087 Slog.w(TAG, "Error in app " + r.processName
12088 + " running instrumentation " + r.instrumentationClass + ":");
12089 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
12090 if (longMsg != null) Slog.w(TAG, " " + longMsg);
12091 Bundle info = new Bundle();
12092 info.putString("shortMsg", shortMsg);
12093 info.putString("longMsg", longMsg);
12094 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12095 Binder.restoreCallingIdentity(origId);
12099 // If we can't identify the process or it's already exceeded its crash quota,
12100 // quit right away without showing a crash dialog.
12101 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12102 Binder.restoreCallingIdentity(origId);
12106 Message msg = Message.obtain();
12107 msg.what = SHOW_ERROR_MSG;
12108 HashMap data = new HashMap();
12109 data.put("result", result);
12110 data.put("app", r);
12112 mHandler.sendMessage(msg);
12114 Binder.restoreCallingIdentity(origId);
12117 int res = result.get();
12119 Intent appErrorIntent = null;
12120 synchronized (this) {
12121 if (r != null && !r.isolated) {
12122 // XXX Can't keep track of crash time for isolated processes,
12123 // since they don't have a persistent identity.
12124 mProcessCrashTimes.put(r.info.processName, r.uid,
12125 SystemClock.uptimeMillis());
12127 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12128 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12132 if (appErrorIntent != null) {
12134 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12135 } catch (ActivityNotFoundException e) {
12136 Slog.w(TAG, "bug report receiver dissappeared", e);
12141 Intent createAppErrorIntentLocked(ProcessRecord r,
12142 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12143 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12144 if (report == null) {
12147 Intent result = new Intent(Intent.ACTION_APP_ERROR);
12148 result.setComponent(r.errorReportReceiver);
12149 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12150 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12154 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12155 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12156 if (r.errorReportReceiver == null) {
12160 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12164 ApplicationErrorReport report = new ApplicationErrorReport();
12165 report.packageName = r.info.packageName;
12166 report.installerPackageName = r.errorReportReceiver.getPackageName();
12167 report.processName = r.processName;
12168 report.time = timeMillis;
12169 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12171 if (r.crashing || r.forceCrashReport) {
12172 report.type = ApplicationErrorReport.TYPE_CRASH;
12173 report.crashInfo = crashInfo;
12174 } else if (r.notResponding) {
12175 report.type = ApplicationErrorReport.TYPE_ANR;
12176 report.anrInfo = new ApplicationErrorReport.AnrInfo();
12178 report.anrInfo.activity = r.notRespondingReport.tag;
12179 report.anrInfo.cause = r.notRespondingReport.shortMsg;
12180 report.anrInfo.info = r.notRespondingReport.longMsg;
12186 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12187 enforceNotIsolatedCaller("getProcessesInErrorState");
12188 // assume our apps are happy - lazy create the list
12189 List<ActivityManager.ProcessErrorStateInfo> errList = null;
12191 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12192 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12193 int userId = UserHandle.getUserId(Binder.getCallingUid());
12195 synchronized (this) {
12197 // iterate across all processes
12198 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12199 ProcessRecord app = mLruProcesses.get(i);
12200 if (!allUsers && app.userId != userId) {
12203 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12204 // This one's in trouble, so we'll generate a report for it
12205 // crashes are higher priority (in case there's a crash *and* an anr)
12206 ActivityManager.ProcessErrorStateInfo report = null;
12207 if (app.crashing) {
12208 report = app.crashingReport;
12209 } else if (app.notResponding) {
12210 report = app.notRespondingReport;
12213 if (report != null) {
12214 if (errList == null) {
12215 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12217 errList.add(report);
12219 Slog.w(TAG, "Missing app error report, app = " + app.processName +
12220 " crashing = " + app.crashing +
12221 " notResponding = " + app.notResponding);
12230 static int procStateToImportance(int procState, int memAdj,
12231 ActivityManager.RunningAppProcessInfo currApp) {
12232 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12233 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12234 currApp.lru = memAdj;
12241 private void fillInProcMemInfo(ProcessRecord app,
12242 ActivityManager.RunningAppProcessInfo outInfo) {
12243 outInfo.pid = app.pid;
12244 outInfo.uid = app.info.uid;
12245 if (mHeavyWeightProcess == app) {
12246 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12248 if (app.persistent) {
12249 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12251 if (app.activities.size() > 0) {
12252 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12254 outInfo.lastTrimLevel = app.trimMemoryLevel;
12255 int adj = app.curAdj;
12256 int procState = app.curProcState;
12257 outInfo.importance = procStateToImportance(procState, adj, outInfo);
12258 outInfo.importanceReasonCode = app.adjTypeCode;
12259 outInfo.processState = app.curProcState;
12262 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12263 enforceNotIsolatedCaller("getRunningAppProcesses");
12265 final int callingUid = Binder.getCallingUid();
12267 // Lazy instantiation of list
12268 List<ActivityManager.RunningAppProcessInfo> runList = null;
12269 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12270 callingUid) == PackageManager.PERMISSION_GRANTED;
12271 final int userId = UserHandle.getUserId(callingUid);
12272 final boolean allUids = isGetTasksAllowed(
12273 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12275 synchronized (this) {
12276 // Iterate across all processes
12277 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12278 ProcessRecord app = mLruProcesses.get(i);
12279 if ((!allUsers && app.userId != userId)
12280 || (!allUids && app.uid != callingUid)) {
12283 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12284 // Generate process state info for running application
12285 ActivityManager.RunningAppProcessInfo currApp =
12286 new ActivityManager.RunningAppProcessInfo(app.processName,
12287 app.pid, app.getPackageList());
12288 fillInProcMemInfo(app, currApp);
12289 if (app.adjSource instanceof ProcessRecord) {
12290 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12291 currApp.importanceReasonImportance =
12292 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12293 app.adjSourceProcState);
12294 } else if (app.adjSource instanceof ActivityRecord) {
12295 ActivityRecord r = (ActivityRecord)app.adjSource;
12296 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12298 if (app.adjTarget instanceof ComponentName) {
12299 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12301 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12302 // + " lru=" + currApp.lru);
12303 if (runList == null) {
12304 runList = new ArrayList<>();
12306 runList.add(currApp);
12313 public List<ApplicationInfo> getRunningExternalApplications() {
12314 enforceNotIsolatedCaller("getRunningExternalApplications");
12315 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12316 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12317 if (runningApps != null && runningApps.size() > 0) {
12318 Set<String> extList = new HashSet<String>();
12319 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12320 if (app.pkgList != null) {
12321 for (String pkg : app.pkgList) {
12326 IPackageManager pm = AppGlobals.getPackageManager();
12327 for (String pkg : extList) {
12329 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12330 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12333 } catch (RemoteException e) {
12341 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12342 enforceNotIsolatedCaller("getMyMemoryState");
12343 synchronized (this) {
12344 ProcessRecord proc;
12345 synchronized (mPidsSelfLocked) {
12346 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12348 fillInProcMemInfo(proc, outInfo);
12353 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12354 if (checkCallingPermission(android.Manifest.permission.DUMP)
12355 != PackageManager.PERMISSION_GRANTED) {
12356 pw.println("Permission Denial: can't dump ActivityManager from from pid="
12357 + Binder.getCallingPid()
12358 + ", uid=" + Binder.getCallingUid()
12359 + " without permission "
12360 + android.Manifest.permission.DUMP);
12364 boolean dumpAll = false;
12365 boolean dumpClient = false;
12366 String dumpPackage = null;
12369 while (opti < args.length) {
12370 String opt = args[opti];
12371 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12375 if ("-a".equals(opt)) {
12377 } else if ("-c".equals(opt)) {
12379 } else if ("-h".equals(opt)) {
12380 pw.println("Activity manager dump options:");
12381 pw.println(" [-a] [-c] [-h] [cmd] ...");
12382 pw.println(" cmd may be one of:");
12383 pw.println(" a[ctivities]: activity stack state");
12384 pw.println(" r[recents]: recent activities state");
12385 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12386 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
12387 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
12388 pw.println(" o[om]: out of memory management");
12389 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
12390 pw.println(" provider [COMP_SPEC]: provider client-side state");
12391 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
12392 pw.println(" service [COMP_SPEC]: service client-side state");
12393 pw.println(" package [PACKAGE_NAME]: all state related to given package");
12394 pw.println(" all: dump all activities");
12395 pw.println(" top: dump the top activity");
12396 pw.println(" write: write all pending state to storage");
12397 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
12398 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
12399 pw.println(" a partial substring in a component name, a");
12400 pw.println(" hex object identifier.");
12401 pw.println(" -a: include all available server state.");
12402 pw.println(" -c: include client state.");
12405 pw.println("Unknown argument: " + opt + "; use -h for help");
12409 long origId = Binder.clearCallingIdentity();
12410 boolean more = false;
12411 // Is the caller requesting to dump a particular piece of data?
12412 if (opti < args.length) {
12413 String cmd = args[opti];
12415 if ("activities".equals(cmd) || "a".equals(cmd)) {
12416 synchronized (this) {
12417 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12419 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12420 synchronized (this) {
12421 dumpRecentsLocked(fd, pw, args, opti, true, null);
12423 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12426 if (opti >= args.length) {
12428 newArgs = EMPTY_STRING_ARRAY;
12432 newArgs = new String[args.length - opti];
12433 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12434 args.length - opti);
12436 synchronized (this) {
12437 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12439 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12442 if (opti >= args.length) {
12444 newArgs = EMPTY_STRING_ARRAY;
12448 newArgs = new String[args.length - opti];
12449 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12450 args.length - opti);
12452 synchronized (this) {
12453 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12455 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12458 if (opti >= args.length) {
12460 newArgs = EMPTY_STRING_ARRAY;
12464 newArgs = new String[args.length - opti];
12465 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12466 args.length - opti);
12468 synchronized (this) {
12469 dumpProcessesLocked(fd, pw, args, opti, true, name);
12471 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12472 synchronized (this) {
12473 dumpOomLocked(fd, pw, args, opti, true);
12475 } else if ("provider".equals(cmd)) {
12478 if (opti >= args.length) {
12480 newArgs = EMPTY_STRING_ARRAY;
12484 newArgs = new String[args.length - opti];
12485 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12487 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12488 pw.println("No providers match: " + name);
12489 pw.println("Use -h for help.");
12491 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12492 synchronized (this) {
12493 dumpProvidersLocked(fd, pw, args, opti, true, null);
12495 } else if ("service".equals(cmd)) {
12498 if (opti >= args.length) {
12500 newArgs = EMPTY_STRING_ARRAY;
12504 newArgs = new String[args.length - opti];
12505 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12506 args.length - opti);
12508 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12509 pw.println("No services match: " + name);
12510 pw.println("Use -h for help.");
12512 } else if ("package".equals(cmd)) {
12514 if (opti >= args.length) {
12515 pw.println("package: no package name specified");
12516 pw.println("Use -h for help.");
12518 dumpPackage = args[opti];
12520 newArgs = new String[args.length - opti];
12521 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12522 args.length - opti);
12527 } else if ("services".equals(cmd) || "s".equals(cmd)) {
12528 synchronized (this) {
12529 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12531 } else if ("write".equals(cmd)) {
12532 mTaskPersister.flush();
12533 pw.println("All tasks persisted.");
12536 // Dumping a single activity?
12537 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12538 pw.println("Bad activity command, or no activities match: " + cmd);
12539 pw.println("Use -h for help.");
12543 Binder.restoreCallingIdentity(origId);
12548 // No piece of data specified, dump everything.
12549 synchronized (this) {
12550 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12553 pw.println("-------------------------------------------------------------------------------");
12555 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12558 pw.println("-------------------------------------------------------------------------------");
12560 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12563 pw.println("-------------------------------------------------------------------------------");
12565 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12568 pw.println("-------------------------------------------------------------------------------");
12570 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12573 pw.println("-------------------------------------------------------------------------------");
12575 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12578 pw.println("-------------------------------------------------------------------------------");
12580 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12582 Binder.restoreCallingIdentity(origId);
12585 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12586 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12587 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12589 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12591 boolean needSep = printedAnything;
12593 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12594 dumpPackage, needSep, " mFocusedActivity: ");
12596 printedAnything = true;
12600 if (dumpPackage == null) {
12605 printedAnything = true;
12606 mStackSupervisor.dump(pw, " ");
12609 if (!printedAnything) {
12610 pw.println(" (nothing)");
12614 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12615 int opti, boolean dumpAll, String dumpPackage) {
12616 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
12618 boolean printedAnything = false;
12620 if (mRecentTasks != null && mRecentTasks.size() > 0) {
12621 boolean printedHeader = false;
12623 final int N = mRecentTasks.size();
12624 for (int i=0; i<N; i++) {
12625 TaskRecord tr = mRecentTasks.get(i);
12626 if (dumpPackage != null) {
12627 if (tr.realActivity == null ||
12628 !dumpPackage.equals(tr.realActivity)) {
12632 if (!printedHeader) {
12633 pw.println(" Recent tasks:");
12634 printedHeader = true;
12635 printedAnything = true;
12637 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
12640 mRecentTasks.get(i).dump(pw, " ");
12645 if (!printedAnything) {
12646 pw.println(" (nothing)");
12650 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12651 int opti, boolean dumpAll, String dumpPackage) {
12652 boolean needSep = false;
12653 boolean printedAnything = false;
12656 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12659 final int NP = mProcessNames.getMap().size();
12660 for (int ip=0; ip<NP; ip++) {
12661 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12662 final int NA = procs.size();
12663 for (int ia=0; ia<NA; ia++) {
12664 ProcessRecord r = procs.valueAt(ia);
12665 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12669 pw.println(" All known processes:");
12671 printedAnything = true;
12673 pw.print(r.persistent ? " *PERS*" : " *APP*");
12674 pw.print(" UID "); pw.print(procs.keyAt(ia));
12675 pw.print(" "); pw.println(r);
12677 if (r.persistent) {
12684 if (mIsolatedProcesses.size() > 0) {
12685 boolean printed = false;
12686 for (int i=0; i<mIsolatedProcesses.size(); i++) {
12687 ProcessRecord r = mIsolatedProcesses.valueAt(i);
12688 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12695 pw.println(" Isolated process list (sorted by uid):");
12696 printedAnything = true;
12700 pw.println(String.format("%sIsolated #%2d: %s",
12701 " ", i, r.toString()));
12705 if (mLruProcesses.size() > 0) {
12709 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12710 pw.print(" total, non-act at ");
12711 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12712 pw.print(", non-svc at ");
12713 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12715 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
12717 printedAnything = true;
12720 if (dumpAll || dumpPackage != null) {
12721 synchronized (mPidsSelfLocked) {
12722 boolean printed = false;
12723 for (int i=0; i<mPidsSelfLocked.size(); i++) {
12724 ProcessRecord r = mPidsSelfLocked.valueAt(i);
12725 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12729 if (needSep) pw.println();
12731 pw.println(" PID mappings:");
12733 printedAnything = true;
12735 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12736 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12741 if (mForegroundProcesses.size() > 0) {
12742 synchronized (mPidsSelfLocked) {
12743 boolean printed = false;
12744 for (int i=0; i<mForegroundProcesses.size(); i++) {
12745 ProcessRecord r = mPidsSelfLocked.get(
12746 mForegroundProcesses.valueAt(i).pid);
12747 if (dumpPackage != null && (r == null
12748 || !r.pkgList.containsKey(dumpPackage))) {
12752 if (needSep) pw.println();
12754 pw.println(" Foreground Processes:");
12756 printedAnything = true;
12758 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
12759 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12764 if (mPersistentStartingProcesses.size() > 0) {
12765 if (needSep) pw.println();
12767 printedAnything = true;
12768 pw.println(" Persisent processes that are starting:");
12769 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
12770 "Starting Norm", "Restarting PERS", dumpPackage);
12773 if (mRemovedProcesses.size() > 0) {
12774 if (needSep) pw.println();
12776 printedAnything = true;
12777 pw.println(" Processes that are being removed:");
12778 dumpProcessList(pw, this, mRemovedProcesses, " ",
12779 "Removed Norm", "Removed PERS", dumpPackage);
12782 if (mProcessesOnHold.size() > 0) {
12783 if (needSep) pw.println();
12785 printedAnything = true;
12786 pw.println(" Processes that are on old until the system is ready:");
12787 dumpProcessList(pw, this, mProcessesOnHold, " ",
12788 "OnHold Norm", "OnHold PERS", dumpPackage);
12791 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12793 if (mProcessCrashTimes.getMap().size() > 0) {
12794 boolean printed = false;
12795 long now = SystemClock.uptimeMillis();
12796 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12797 final int NP = pmap.size();
12798 for (int ip=0; ip<NP; ip++) {
12799 String pname = pmap.keyAt(ip);
12800 SparseArray<Long> uids = pmap.valueAt(ip);
12801 final int N = uids.size();
12802 for (int i=0; i<N; i++) {
12803 int puid = uids.keyAt(i);
12804 ProcessRecord r = mProcessNames.get(pname, puid);
12805 if (dumpPackage != null && (r == null
12806 || !r.pkgList.containsKey(dumpPackage))) {
12810 if (needSep) pw.println();
12812 pw.println(" Time since processes crashed:");
12814 printedAnything = true;
12816 pw.print(" Process "); pw.print(pname);
12817 pw.print(" uid "); pw.print(puid);
12818 pw.print(": last crashed ");
12819 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12820 pw.println(" ago");
12825 if (mBadProcesses.getMap().size() > 0) {
12826 boolean printed = false;
12827 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12828 final int NP = pmap.size();
12829 for (int ip=0; ip<NP; ip++) {
12830 String pname = pmap.keyAt(ip);
12831 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12832 final int N = uids.size();
12833 for (int i=0; i<N; i++) {
12834 int puid = uids.keyAt(i);
12835 ProcessRecord r = mProcessNames.get(pname, puid);
12836 if (dumpPackage != null && (r == null
12837 || !r.pkgList.containsKey(dumpPackage))) {
12841 if (needSep) pw.println();
12843 pw.println(" Bad processes:");
12844 printedAnything = true;
12846 BadProcessInfo info = uids.valueAt(i);
12847 pw.print(" Bad process "); pw.print(pname);
12848 pw.print(" uid "); pw.print(puid);
12849 pw.print(": crashed at time "); pw.println(info.time);
12850 if (info.shortMsg != null) {
12851 pw.print(" Short msg: "); pw.println(info.shortMsg);
12853 if (info.longMsg != null) {
12854 pw.print(" Long msg: "); pw.println(info.longMsg);
12856 if (info.stack != null) {
12857 pw.println(" Stack:");
12859 for (int pos=0; pos<info.stack.length(); pos++) {
12860 if (info.stack.charAt(pos) == '\n') {
12862 pw.write(info.stack, lastPos, pos-lastPos);
12867 if (lastPos < info.stack.length()) {
12869 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12877 if (dumpPackage == null) {
12880 pw.println(" mStartedUsers:");
12881 for (int i=0; i<mStartedUsers.size(); i++) {
12882 UserStartedState uss = mStartedUsers.valueAt(i);
12883 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
12884 pw.print(": "); uss.dump("", pw);
12886 pw.print(" mStartedUserArray: [");
12887 for (int i=0; i<mStartedUserArray.length; i++) {
12888 if (i > 0) pw.print(", ");
12889 pw.print(mStartedUserArray[i]);
12892 pw.print(" mUserLru: [");
12893 for (int i=0; i<mUserLru.size(); i++) {
12894 if (i > 0) pw.print(", ");
12895 pw.print(mUserLru.get(i));
12899 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12901 synchronized (mUserProfileGroupIdsSelfLocked) {
12902 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12903 pw.println(" mUserProfileGroupIds:");
12904 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12905 pw.print(" User #");
12906 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12907 pw.print(" -> profile #");
12908 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12913 if (mHomeProcess != null && (dumpPackage == null
12914 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12919 pw.println(" mHomeProcess: " + mHomeProcess);
12921 if (mPreviousProcess != null && (dumpPackage == null
12922 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12927 pw.println(" mPreviousProcess: " + mPreviousProcess);
12930 StringBuilder sb = new StringBuilder(128);
12931 sb.append(" mPreviousProcessVisibleTime: ");
12932 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12935 if (mHeavyWeightProcess != null && (dumpPackage == null
12936 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12941 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
12943 if (dumpPackage == null) {
12944 pw.println(" mConfiguration: " + mConfiguration);
12947 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12948 if (mCompatModePackages.getPackages().size() > 0) {
12949 boolean printed = false;
12950 for (Map.Entry<String, Integer> entry
12951 : mCompatModePackages.getPackages().entrySet()) {
12952 String pkg = entry.getKey();
12953 int mode = entry.getValue();
12954 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12958 pw.println(" mScreenCompatPackages:");
12961 pw.print(" "); pw.print(pkg); pw.print(": ");
12962 pw.print(mode); pw.println();
12966 if (dumpPackage == null) {
12967 pw.println(" mWakefulness="
12968 + PowerManagerInternal.wakefulnessToString(mWakefulness));
12969 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown=" + mLockScreenShown);
12970 pw.print(" mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12972 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12973 || mOrigWaitForDebugger) {
12974 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12975 || dumpPackage.equals(mOrigDebugApp)) {
12980 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12981 + " mDebugTransient=" + mDebugTransient
12982 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12985 if (mOpenGlTraceApp != null) {
12986 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12991 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
12994 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12995 || mProfileFd != null) {
12996 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13001 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13002 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13003 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13004 + mAutoStopProfiler);
13005 pw.println(" mProfileType=" + mProfileType);
13008 if (dumpPackage == null) {
13009 if (mAlwaysFinishActivities || mController != null) {
13010 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
13011 + " mController=" + mController);
13014 pw.println(" Total persistent processes: " + numPers);
13015 pw.println(" mProcessesReady=" + mProcessesReady
13016 + " mSystemReady=" + mSystemReady
13017 + " mBooted=" + mBooted
13018 + " mFactoryTest=" + mFactoryTest);
13019 pw.println(" mBooting=" + mBooting
13020 + " mCallFinishBooting=" + mCallFinishBooting
13021 + " mBootAnimationComplete=" + mBootAnimationComplete);
13022 pw.print(" mLastPowerCheckRealtime=");
13023 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13025 pw.print(" mLastPowerCheckUptime=");
13026 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13028 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13029 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13030 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13031 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
13032 + " (" + mLruProcesses.size() + " total)"
13033 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13034 + " mNumServiceProcs=" + mNumServiceProcs
13035 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13036 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
13037 + " mLastMemoryLevel" + mLastMemoryLevel
13038 + " mLastNumProcesses" + mLastNumProcesses);
13039 long now = SystemClock.uptimeMillis();
13040 pw.print(" mLastIdleTime=");
13041 TimeUtils.formatDuration(now, mLastIdleTime, pw);
13042 pw.print(" mLowRamSinceLastIdle=");
13043 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13048 if (!printedAnything) {
13049 pw.println(" (nothing)");
13053 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13054 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13055 if (mProcessesToGc.size() > 0) {
13056 boolean printed = false;
13057 long now = SystemClock.uptimeMillis();
13058 for (int i=0; i<mProcessesToGc.size(); i++) {
13059 ProcessRecord proc = mProcessesToGc.get(i);
13060 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13064 if (needSep) pw.println();
13066 pw.println(" Processes that are waiting to GC:");
13069 pw.print(" Process "); pw.println(proc);
13070 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
13071 pw.print(", last gced=");
13072 pw.print(now-proc.lastRequestedGc);
13073 pw.print(" ms ago, last lowMem=");
13074 pw.print(now-proc.lastLowMemory);
13075 pw.println(" ms ago");
13082 void printOomLevel(PrintWriter pw, String name, int adj) {
13086 if (adj < 10) pw.print(' ');
13088 if (adj > -10) pw.print(' ');
13094 pw.print(mProcessList.getMemLevel(adj)/1024);
13095 pw.println(" kB)");
13098 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13099 int opti, boolean dumpAll) {
13100 boolean needSep = false;
13102 if (mLruProcesses.size() > 0) {
13103 if (needSep) pw.println();
13105 pw.println(" OOM levels:");
13106 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13107 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13108 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13109 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13110 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13111 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13112 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13113 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13114 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13115 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13116 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13117 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13118 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13119 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13121 if (needSep) pw.println();
13122 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
13123 pw.print(" total, non-act at ");
13124 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13125 pw.print(", non-svc at ");
13126 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13128 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
13132 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13135 pw.println(" mHomeProcess: " + mHomeProcess);
13136 pw.println(" mPreviousProcess: " + mPreviousProcess);
13137 if (mHeavyWeightProcess != null) {
13138 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13145 * There are three ways to call this:
13146 * - no provider specified: dump all the providers
13147 * - a flattened component name that matched an existing provider was specified as the
13148 * first arg: dump that one provider
13149 * - the first arg isn't the flattened component name of an existing provider:
13150 * dump all providers whose component contains the first arg as a substring
13152 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13153 int opti, boolean dumpAll) {
13154 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13157 static class ItemMatcher {
13158 ArrayList<ComponentName> components;
13159 ArrayList<String> strings;
13160 ArrayList<Integer> objects;
13167 void build(String name) {
13168 ComponentName componentName = ComponentName.unflattenFromString(name);
13169 if (componentName != null) {
13170 if (components == null) {
13171 components = new ArrayList<ComponentName>();
13173 components.add(componentName);
13177 // Not a '/' separated full component name; maybe an object ID?
13179 objectId = Integer.parseInt(name, 16);
13180 if (objects == null) {
13181 objects = new ArrayList<Integer>();
13183 objects.add(objectId);
13185 } catch (RuntimeException e) {
13186 // Not an integer; just do string match.
13187 if (strings == null) {
13188 strings = new ArrayList<String>();
13196 int build(String[] args, int opti) {
13197 for (; opti<args.length; opti++) {
13198 String name = args[opti];
13199 if ("--".equals(name)) {
13207 boolean match(Object object, ComponentName comp) {
13211 if (components != null) {
13212 for (int i=0; i<components.size(); i++) {
13213 if (components.get(i).equals(comp)) {
13218 if (objects != null) {
13219 for (int i=0; i<objects.size(); i++) {
13220 if (System.identityHashCode(object) == objects.get(i)) {
13225 if (strings != null) {
13226 String flat = comp.flattenToString();
13227 for (int i=0; i<strings.size(); i++) {
13228 if (flat.contains(strings.get(i))) {
13238 * There are three things that cmd can be:
13239 * - a flattened component name that matches an existing activity
13240 * - the cmd arg isn't the flattened component name of an existing activity:
13241 * dump all activity whose component contains the cmd as a substring
13242 * - A hex number of the ActivityRecord object instance.
13244 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13245 int opti, boolean dumpAll) {
13246 ArrayList<ActivityRecord> activities;
13248 synchronized (this) {
13249 activities = mStackSupervisor.getDumpActivitiesLocked(name);
13252 if (activities.size() <= 0) {
13256 String[] newArgs = new String[args.length - opti];
13257 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13259 TaskRecord lastTask = null;
13260 boolean needSep = false;
13261 for (int i=activities.size()-1; i>=0; i--) {
13262 ActivityRecord r = activities.get(i);
13267 synchronized (this) {
13268 if (lastTask != r.task) {
13270 pw.print("TASK "); pw.print(lastTask.affinity);
13271 pw.print(" id="); pw.println(lastTask.taskId);
13273 lastTask.dump(pw, " ");
13277 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
13283 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13284 * there is a thread associated with the activity.
13286 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13287 final ActivityRecord r, String[] args, boolean dumpAll) {
13288 String innerPrefix = prefix + " ";
13289 synchronized (this) {
13290 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13291 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13293 if (r.app != null) pw.println(r.app.pid);
13294 else pw.println("(not running)");
13296 r.dump(pw, innerPrefix);
13299 if (r.app != null && r.app.thread != null) {
13300 // flush anything that is already in the PrintWriter since the thread is going
13301 // to write to the file descriptor directly
13304 TransferPipe tp = new TransferPipe();
13306 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
13307 r.appToken, innerPrefix, args);
13312 } catch (IOException e) {
13313 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
13314 } catch (RemoteException e) {
13315 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
13320 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13321 int opti, boolean dumpAll, String dumpPackage) {
13322 boolean needSep = false;
13323 boolean onlyHistory = false;
13324 boolean printedAnything = false;
13326 if ("history".equals(dumpPackage)) {
13327 if (opti < args.length && "-s".equals(args[opti])) {
13330 onlyHistory = true;
13331 dumpPackage = null;
13334 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13335 if (!onlyHistory && dumpAll) {
13336 if (mRegisteredReceivers.size() > 0) {
13337 boolean printed = false;
13338 Iterator it = mRegisteredReceivers.values().iterator();
13339 while (it.hasNext()) {
13340 ReceiverList r = (ReceiverList)it.next();
13341 if (dumpPackage != null && (r.app == null ||
13342 !dumpPackage.equals(r.app.info.packageName))) {
13346 pw.println(" Registered Receivers:");
13349 printedAnything = true;
13351 pw.print(" * "); pw.println(r);
13356 if (mReceiverResolver.dump(pw, needSep ?
13357 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
13358 " ", dumpPackage, false)) {
13360 printedAnything = true;
13364 for (BroadcastQueue q : mBroadcastQueues) {
13365 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13366 printedAnything |= needSep;
13371 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13372 for (int user=0; user<mStickyBroadcasts.size(); user++) {
13377 printedAnything = true;
13378 pw.print(" Sticky broadcasts for user ");
13379 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13380 StringBuilder sb = new StringBuilder(128);
13381 for (Map.Entry<String, ArrayList<Intent>> ent
13382 : mStickyBroadcasts.valueAt(user).entrySet()) {
13383 pw.print(" * Sticky action "); pw.print(ent.getKey());
13386 ArrayList<Intent> intents = ent.getValue();
13387 final int N = intents.size();
13388 for (int i=0; i<N; i++) {
13390 sb.append(" Intent: ");
13391 intents.get(i).toShortString(sb, false, true, false, false);
13392 pw.println(sb.toString());
13393 Bundle bundle = intents.get(i).getExtras();
13394 if (bundle != null) {
13396 pw.println(bundle.toString());
13406 if (!onlyHistory && dumpAll) {
13408 for (BroadcastQueue queue : mBroadcastQueues) {
13409 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
13410 + queue.mBroadcastsScheduled);
13412 pw.println(" mHandler:");
13413 mHandler.dump(new PrintWriterPrinter(pw), " ");
13415 printedAnything = true;
13418 if (!printedAnything) {
13419 pw.println(" (nothing)");
13423 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13424 int opti, boolean dumpAll, String dumpPackage) {
13426 boolean printedAnything = false;
13428 ItemMatcher matcher = new ItemMatcher();
13429 matcher.build(args, opti);
13431 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13433 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13434 printedAnything |= needSep;
13436 if (mLaunchingProviders.size() > 0) {
13437 boolean printed = false;
13438 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13439 ContentProviderRecord r = mLaunchingProviders.get(i);
13440 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13444 if (needSep) pw.println();
13446 pw.println(" Launching content providers:");
13448 printedAnything = true;
13450 pw.print(" Launching #"); pw.print(i); pw.print(": ");
13455 if (mGrantedUriPermissions.size() > 0) {
13456 boolean printed = false;
13458 if (dumpPackage != null) {
13460 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13461 } catch (NameNotFoundException e) {
13465 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13466 int uid = mGrantedUriPermissions.keyAt(i);
13467 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13470 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13472 if (needSep) pw.println();
13474 pw.println(" Granted Uri Permissions:");
13476 printedAnything = true;
13478 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
13479 for (UriPermission perm : perms.values()) {
13480 pw.print(" "); pw.println(perm);
13482 perm.dump(pw, " ");
13488 if (!printedAnything) {
13489 pw.println(" (nothing)");
13493 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13494 int opti, boolean dumpAll, String dumpPackage) {
13495 boolean printed = false;
13497 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13499 if (mIntentSenderRecords.size() > 0) {
13500 Iterator<WeakReference<PendingIntentRecord>> it
13501 = mIntentSenderRecords.values().iterator();
13502 while (it.hasNext()) {
13503 WeakReference<PendingIntentRecord> ref = it.next();
13504 PendingIntentRecord rec = ref != null ? ref.get(): null;
13505 if (dumpPackage != null && (rec == null
13506 || !dumpPackage.equals(rec.key.packageName))) {
13511 pw.print(" * "); pw.println(rec);
13516 pw.print(" * "); pw.println(ref);
13522 pw.println(" (nothing)");
13526 private static final int dumpProcessList(PrintWriter pw,
13527 ActivityManagerService service, List list,
13528 String prefix, String normalLabel, String persistentLabel,
13529 String dumpPackage) {
13531 final int N = list.size()-1;
13532 for (int i=N; i>=0; i--) {
13533 ProcessRecord r = (ProcessRecord)list.get(i);
13534 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13537 pw.println(String.format("%s%s #%2d: %s",
13538 prefix, (r.persistent ? persistentLabel : normalLabel),
13540 if (r.persistent) {
13547 private static final boolean dumpProcessOomList(PrintWriter pw,
13548 ActivityManagerService service, List<ProcessRecord> origList,
13549 String prefix, String normalLabel, String persistentLabel,
13550 boolean inclDetails, String dumpPackage) {
13552 ArrayList<Pair<ProcessRecord, Integer>> list
13553 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13554 for (int i=0; i<origList.size(); i++) {
13555 ProcessRecord r = origList.get(i);
13556 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13559 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13562 if (list.size() <= 0) {
13566 Comparator<Pair<ProcessRecord, Integer>> comparator
13567 = new Comparator<Pair<ProcessRecord, Integer>>() {
13569 public int compare(Pair<ProcessRecord, Integer> object1,
13570 Pair<ProcessRecord, Integer> object2) {
13571 if (object1.first.setAdj != object2.first.setAdj) {
13572 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13574 if (object1.second.intValue() != object2.second.intValue()) {
13575 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13581 Collections.sort(list, comparator);
13583 final long curRealtime = SystemClock.elapsedRealtime();
13584 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13585 final long curUptime = SystemClock.uptimeMillis();
13586 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13588 for (int i=list.size()-1; i>=0; i--) {
13589 ProcessRecord r = list.get(i).first;
13590 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13592 switch (r.setSchedGroup) {
13593 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13596 case Process.THREAD_GROUP_DEFAULT:
13604 if (r.foregroundActivities) {
13606 } else if (r.foregroundServices) {
13611 String procState = ProcessList.makeProcStateString(r.curProcState);
13613 pw.print(r.persistent ? persistentLabel : normalLabel);
13615 int num = (origList.size()-1)-list.get(i).second;
13616 if (num < 10) pw.print(' ');
13621 pw.print(schedGroup);
13623 pw.print(foreground);
13625 pw.print(procState);
13627 if (r.trimMemoryLevel < 10) pw.print(' ');
13628 pw.print(r.trimMemoryLevel);
13630 pw.print(r.toShortString());
13632 pw.print(r.adjType);
13634 if (r.adjSource != null || r.adjTarget != null) {
13637 if (r.adjTarget instanceof ComponentName) {
13638 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13639 } else if (r.adjTarget != null) {
13640 pw.print(r.adjTarget.toString());
13642 pw.print("{null}");
13645 if (r.adjSource instanceof ProcessRecord) {
13647 pw.print(((ProcessRecord)r.adjSource).toShortString());
13649 } else if (r.adjSource != null) {
13650 pw.println(r.adjSource.toString());
13652 pw.println("{null}");
13658 pw.print("oom: max="); pw.print(r.maxAdj);
13659 pw.print(" curRaw="); pw.print(r.curRawAdj);
13660 pw.print(" setRaw="); pw.print(r.setRawAdj);
13661 pw.print(" cur="); pw.print(r.curAdj);
13662 pw.print(" set="); pw.println(r.setAdj);
13665 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13666 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13667 pw.print(" lastPss="); pw.print(r.lastPss);
13668 pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13671 pw.print("cached="); pw.print(r.cached);
13672 pw.print(" empty="); pw.print(r.empty);
13673 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13675 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13676 if (r.lastWakeTime != 0) {
13678 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13679 synchronized (stats) {
13680 wtime = stats.getProcessWakeTime(r.info.uid,
13681 r.pid, curRealtime);
13683 long timeUsed = wtime - r.lastWakeTime;
13686 pw.print("keep awake over ");
13687 TimeUtils.formatDuration(realtimeSince, pw);
13688 pw.print(" used ");
13689 TimeUtils.formatDuration(timeUsed, pw);
13691 pw.print((timeUsed*100)/realtimeSince);
13694 if (r.lastCpuTime != 0) {
13695 long timeUsed = r.curCpuTime - r.lastCpuTime;
13698 pw.print("run cpu over ");
13699 TimeUtils.formatDuration(uptimeSince, pw);
13700 pw.print(" used ");
13701 TimeUtils.formatDuration(timeUsed, pw);
13703 pw.print((timeUsed*100)/uptimeSince);
13712 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
13714 ArrayList<ProcessRecord> procs;
13715 synchronized (this) {
13716 if (args != null && args.length > start
13717 && args[start].charAt(0) != '-') {
13718 procs = new ArrayList<ProcessRecord>();
13721 pid = Integer.parseInt(args[start]);
13722 } catch (NumberFormatException e) {
13724 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13725 ProcessRecord proc = mLruProcesses.get(i);
13726 if (proc.pid == pid) {
13728 } else if (allPkgs && proc.pkgList != null
13729 && proc.pkgList.containsKey(args[start])) {
13731 } else if (proc.processName.equals(args[start])) {
13735 if (procs.size() <= 0) {
13739 procs = new ArrayList<ProcessRecord>(mLruProcesses);
13745 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13746 PrintWriter pw, String[] args) {
13747 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13748 if (procs == null) {
13749 pw.println("No process found for: " + args[0]);
13753 long uptime = SystemClock.uptimeMillis();
13754 long realtime = SystemClock.elapsedRealtime();
13755 pw.println("Applications Graphics Acceleration Info:");
13756 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13758 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13759 ProcessRecord r = procs.get(i);
13760 if (r.thread != null) {
13761 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13764 TransferPipe tp = new TransferPipe();
13766 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13771 } catch (IOException e) {
13772 pw.println("Failure while dumping the app: " + r);
13774 } catch (RemoteException e) {
13775 pw.println("Got a RemoteException while dumping the app " + r);
13782 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13783 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
13784 if (procs == null) {
13785 pw.println("No process found for: " + args[0]);
13789 pw.println("Applications Database Info:");
13791 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13792 ProcessRecord r = procs.get(i);
13793 if (r.thread != null) {
13794 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13797 TransferPipe tp = new TransferPipe();
13799 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13804 } catch (IOException e) {
13805 pw.println("Failure while dumping the app: " + r);
13807 } catch (RemoteException e) {
13808 pw.println("Got a RemoteException while dumping the app " + r);
13815 final static class MemItem {
13816 final boolean isProc;
13817 final String label;
13818 final String shortLabel;
13821 final boolean hasActivities;
13822 ArrayList<MemItem> subitems;
13824 public MemItem(String _label, String _shortLabel, long _pss, int _id,
13825 boolean _hasActivities) {
13828 shortLabel = _shortLabel;
13831 hasActivities = _hasActivities;
13834 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13837 shortLabel = _shortLabel;
13840 hasActivities = false;
13844 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13845 ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13846 if (sort && !isCompact) {
13847 Collections.sort(items, new Comparator<MemItem>() {
13849 public int compare(MemItem lhs, MemItem rhs) {
13850 if (lhs.pss < rhs.pss) {
13852 } else if (lhs.pss > rhs.pss) {
13860 for (int i=0; i<items.size(); i++) {
13861 MemItem mi = items.get(i);
13863 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13864 } else if (mi.isProc) {
13865 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13866 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13867 pw.println(mi.hasActivities ? ",a" : ",e");
13869 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13870 pw.println(mi.pss);
13872 if (mi.subitems != null) {
13873 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
13879 // These are in KB.
13880 static final long[] DUMP_MEM_BUCKETS = new long[] {
13881 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13882 120*1024, 160*1024, 200*1024,
13883 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13884 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13887 static final void appendMemBucket(StringBuilder out, long memKB, String label,
13888 boolean stackLike) {
13889 int start = label.lastIndexOf('.');
13890 if (start >= 0) start++;
13892 int end = label.length();
13893 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13894 if (DUMP_MEM_BUCKETS[i] >= memKB) {
13895 long bucket = DUMP_MEM_BUCKETS[i]/1024;
13896 out.append(bucket);
13897 out.append(stackLike ? "MB." : "MB ");
13898 out.append(label, start, end);
13902 out.append(memKB/1024);
13903 out.append(stackLike ? "MB." : "MB ");
13904 out.append(label, start, end);
13907 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13908 ProcessList.NATIVE_ADJ,
13909 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
13910 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13911 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13912 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13913 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13914 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13916 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13918 "System", "Persistent", "Persistent Service", "Foreground",
13919 "Visible", "Perceptible",
13920 "Heavy Weight", "Backup",
13921 "A Services", "Home",
13922 "Previous", "B Services", "Cached"
13924 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13926 "sys", "pers", "persvc", "fore",
13929 "servicea", "home",
13930 "prev", "serviceb", "cached"
13933 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13934 long realtime, boolean isCheckinRequest, boolean isCompact) {
13935 if (isCheckinRequest || isCompact) {
13936 // short checkin version
13937 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13939 pw.println("Applications Memory Usage (kB):");
13940 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13944 final void dumpApplicationMemoryUsage(FileDescriptor fd,
13945 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13946 boolean dumpDetails = false;
13947 boolean dumpFullDetails = false;
13948 boolean dumpDalvik = false;
13949 boolean oomOnly = false;
13950 boolean isCompact = false;
13951 boolean localOnly = false;
13952 boolean packages = false;
13955 while (opti < args.length) {
13956 String opt = args[opti];
13957 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13961 if ("-a".equals(opt)) {
13962 dumpDetails = true;
13963 dumpFullDetails = true;
13965 } else if ("-d".equals(opt)) {
13967 } else if ("-c".equals(opt)) {
13969 } else if ("--oom".equals(opt)) {
13971 } else if ("--local".equals(opt)) {
13973 } else if ("--package".equals(opt)) {
13975 } else if ("-h".equals(opt)) {
13976 pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13977 pw.println(" -a: include all available information for each process.");
13978 pw.println(" -d: include dalvik details when dumping process details.");
13979 pw.println(" -c: dump in a compact machine-parseable representation.");
13980 pw.println(" --oom: only show processes organized by oom adj.");
13981 pw.println(" --local: only collect details locally, don't call process.");
13982 pw.println(" --package: interpret process arg as package, dumping all");
13983 pw.println(" processes that have loaded that package.");
13984 pw.println("If [process] is specified it can be the name or ");
13985 pw.println("pid of a specific process to dump.");
13988 pw.println("Unknown argument: " + opt + "; use -h for help");
13992 final boolean isCheckinRequest = scanArgs(args, "--checkin");
13993 long uptime = SystemClock.uptimeMillis();
13994 long realtime = SystemClock.elapsedRealtime();
13995 final long[] tmpLong = new long[1];
13997 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
13998 if (procs == null) {
13999 // No Java processes. Maybe they want to print a native process.
14000 if (args != null && args.length > opti
14001 && args[opti].charAt(0) != '-') {
14002 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14003 = new ArrayList<ProcessCpuTracker.Stats>();
14004 updateCpuStatsNow();
14007 findPid = Integer.parseInt(args[opti]);
14008 } catch (NumberFormatException e) {
14010 synchronized (mProcessCpuTracker) {
14011 final int N = mProcessCpuTracker.countStats();
14012 for (int i=0; i<N; i++) {
14013 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14014 if (st.pid == findPid || (st.baseName != null
14015 && st.baseName.equals(args[opti]))) {
14016 nativeProcs.add(st);
14020 if (nativeProcs.size() > 0) {
14021 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14023 Debug.MemoryInfo mi = null;
14024 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14025 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14026 final int pid = r.pid;
14027 if (!isCheckinRequest && dumpDetails) {
14028 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14031 mi = new Debug.MemoryInfo();
14033 if (dumpDetails || (!brief && !oomOnly)) {
14034 Debug.getMemoryInfo(pid, mi);
14036 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14037 mi.dalvikPrivateDirty = (int)tmpLong[0];
14039 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14040 dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14041 if (isCheckinRequest) {
14048 pw.println("No process found for: " + args[opti]);
14052 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14053 dumpDetails = true;
14056 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14058 String[] innerArgs = new String[args.length-opti];
14059 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14061 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14062 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14063 long nativePss=0, dalvikPss=0, otherPss=0;
14064 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14066 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14067 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14068 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14071 long cachedPss = 0;
14073 Debug.MemoryInfo mi = null;
14074 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14075 final ProcessRecord r = procs.get(i);
14076 final IApplicationThread thread;
14079 final boolean hasActivities;
14080 synchronized (this) {
14083 oomAdj = r.getSetAdjWithServices();
14084 hasActivities = r.activities.size() > 0;
14086 if (thread != null) {
14087 if (!isCheckinRequest && dumpDetails) {
14088 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14091 mi = new Debug.MemoryInfo();
14093 if (dumpDetails || (!brief && !oomOnly)) {
14094 Debug.getMemoryInfo(pid, mi);
14096 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
14097 mi.dalvikPrivateDirty = (int)tmpLong[0];
14101 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14102 dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
14103 if (isCheckinRequest) {
14109 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14110 dumpDalvik, innerArgs);
14111 } catch (RemoteException e) {
14112 if (!isCheckinRequest) {
14113 pw.println("Got RemoteException!");
14120 final long myTotalPss = mi.getTotalPss();
14121 final long myTotalUss = mi.getTotalUss();
14123 synchronized (this) {
14124 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14125 // Record this for posterity if the process has been stable.
14126 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14130 if (!isCheckinRequest && mi != null) {
14131 totalPss += myTotalPss;
14132 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14133 (hasActivities ? " / activities)" : ")"),
14134 r.processName, myTotalPss, pid, hasActivities);
14135 procMems.add(pssItem);
14136 procMemsMap.put(pid, pssItem);
14138 nativePss += mi.nativePss;
14139 dalvikPss += mi.dalvikPss;
14140 otherPss += mi.otherPss;
14141 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14142 long mem = mi.getOtherPss(j);
14147 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14148 cachedPss += myTotalPss;
14151 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14152 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14153 || oomIndex == (oomPss.length-1)) {
14154 oomPss[oomIndex] += myTotalPss;
14155 if (oomProcs[oomIndex] == null) {
14156 oomProcs[oomIndex] = new ArrayList<MemItem>();
14158 oomProcs[oomIndex].add(pssItem);
14166 long nativeProcTotalPss = 0;
14168 if (!isCheckinRequest && procs.size() > 1 && !packages) {
14169 // If we are showing aggregations, also look for native processes to
14170 // include so that our aggregations are more accurate.
14171 updateCpuStatsNow();
14172 synchronized (mProcessCpuTracker) {
14173 final int N = mProcessCpuTracker.countStats();
14174 for (int i=0; i<N; i++) {
14175 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14176 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14178 mi = new Debug.MemoryInfo();
14180 if (!brief && !oomOnly) {
14181 Debug.getMemoryInfo(st.pid, mi);
14183 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
14184 mi.nativePrivateDirty = (int)tmpLong[0];
14187 final long myTotalPss = mi.getTotalPss();
14188 totalPss += myTotalPss;
14189 nativeProcTotalPss += myTotalPss;
14191 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14192 st.name, myTotalPss, st.pid, false);
14193 procMems.add(pssItem);
14195 nativePss += mi.nativePss;
14196 dalvikPss += mi.dalvikPss;
14197 otherPss += mi.otherPss;
14198 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14199 long mem = mi.getOtherPss(j);
14203 oomPss[0] += myTotalPss;
14204 if (oomProcs[0] == null) {
14205 oomProcs[0] = new ArrayList<MemItem>();
14207 oomProcs[0].add(pssItem);
14212 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14214 catMems.add(new MemItem("Native", "Native", nativePss, -1));
14215 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
14216 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14217 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14218 String label = Debug.MemoryInfo.getOtherLabel(j);
14219 catMems.add(new MemItem(label, label, miscPss[j], j));
14222 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14223 for (int j=0; j<oomPss.length; j++) {
14224 if (oomPss[j] != 0) {
14225 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14226 : DUMP_MEM_OOM_LABEL[j];
14227 MemItem item = new MemItem(label, label, oomPss[j],
14228 DUMP_MEM_OOM_ADJ[j]);
14229 item.subitems = oomProcs[j];
14234 if (!brief && !oomOnly && !isCompact) {
14236 pw.println("Total PSS by process:");
14237 dumpMemItems(pw, " ", "proc", procMems, true, isCompact);
14241 pw.println("Total PSS by OOM adjustment:");
14243 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact);
14244 if (!brief && !oomOnly) {
14245 PrintWriter out = categoryPw != null ? categoryPw : pw;
14248 out.println("Total PSS by category:");
14250 dumpMemItems(out, " ", "cat", catMems, true, isCompact);
14255 MemInfoReader memInfo = new MemInfoReader();
14256 memInfo.readMemInfo();
14257 if (nativeProcTotalPss > 0) {
14258 synchronized (this) {
14259 mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
14260 memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
14261 memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
14262 nativeProcTotalPss);
14267 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
14268 pw.print(" kB (status ");
14269 switch (mLastMemoryLevel) {
14270 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
14271 pw.println("normal)");
14273 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
14274 pw.println("moderate)");
14276 case ProcessStats.ADJ_MEM_FACTOR_LOW:
14277 pw.println("low)");
14279 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
14280 pw.println("critical)");
14283 pw.print(mLastMemoryLevel);
14287 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
14288 + memInfo.getFreeSizeKb()); pw.print(" kB (");
14289 pw.print(cachedPss); pw.print(" cached pss + ");
14290 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
14291 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
14293 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
14294 pw.print(cachedPss + memInfo.getCachedSizeKb()
14295 + memInfo.getFreeSizeKb()); pw.print(",");
14296 pw.println(totalPss - cachedPss);
14300 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
14301 + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
14302 + memInfo.getSlabSizeKb()); pw.print(" kB (");
14303 pw.print(totalPss - cachedPss); pw.print(" used pss + ");
14304 pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
14305 pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
14306 pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
14307 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
14308 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
14309 - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
14310 - memInfo.getSlabSizeKb()); pw.println(" kB");
14313 if (memInfo.getZramTotalSizeKb() != 0) {
14315 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
14316 pw.print(" kB physical used for ");
14317 pw.print(memInfo.getSwapTotalSizeKb()
14318 - memInfo.getSwapFreeSizeKb());
14319 pw.print(" kB in swap (");
14320 pw.print(memInfo.getSwapTotalSizeKb());
14321 pw.println(" kB total swap)");
14323 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
14324 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
14325 pw.println(memInfo.getSwapFreeSizeKb());
14328 final int[] SINGLE_LONG_FORMAT = new int[] {
14329 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14331 long[] longOut = new long[1];
14332 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14333 SINGLE_LONG_FORMAT, null, longOut, null);
14334 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14336 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14337 SINGLE_LONG_FORMAT, null, longOut, null);
14338 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14340 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14341 SINGLE_LONG_FORMAT, null, longOut, null);
14342 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14344 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14345 SINGLE_LONG_FORMAT, null, longOut, null);
14346 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14348 if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14349 pw.print(" KSM: "); pw.print(sharing);
14350 pw.print(" kB saved from shared ");
14351 pw.print(shared); pw.println(" kB");
14352 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; ");
14353 pw.print(voltile); pw.println(" kB volatile");
14355 pw.print(" Tuning: ");
14356 pw.print(ActivityManager.staticGetMemoryClass());
14357 pw.print(" (large ");
14358 pw.print(ActivityManager.staticGetLargeMemoryClass());
14359 pw.print("), oom ");
14360 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14362 pw.print(", restore limit ");
14363 pw.print(mProcessList.getCachedRestoreThresholdKb());
14365 if (ActivityManager.isLowRamDeviceStatic()) {
14366 pw.print(" (low-ram)");
14368 if (ActivityManager.isHighEndGfx()) {
14369 pw.print(" (high-end-gfx)");
14373 pw.print("ksm,"); pw.print(sharing); pw.print(",");
14374 pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14375 pw.println(voltile);
14376 pw.print("tuning,");
14377 pw.print(ActivityManager.staticGetMemoryClass());
14379 pw.print(ActivityManager.staticGetLargeMemoryClass());
14381 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14382 if (ActivityManager.isLowRamDeviceStatic()) {
14383 pw.print(",low-ram");
14385 if (ActivityManager.isHighEndGfx()) {
14386 pw.print(",high-end-gfx");
14395 * Searches array of arguments for the specified string
14396 * @param args array of argument strings
14397 * @param value value to search for
14398 * @return true if the value is contained in the array
14400 private static boolean scanArgs(String[] args, String value) {
14401 if (args != null) {
14402 for (String arg : args) {
14403 if (value.equals(arg)) {
14411 private final boolean removeDyingProviderLocked(ProcessRecord proc,
14412 ContentProviderRecord cpr, boolean always) {
14413 final boolean inLaunching = mLaunchingProviders.contains(cpr);
14415 if (!inLaunching || always) {
14416 synchronized (cpr) {
14417 cpr.launchingApp = null;
14420 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14421 String names[] = cpr.info.authority.split(";");
14422 for (int j = 0; j < names.length; j++) {
14423 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14427 for (int i=0; i<cpr.connections.size(); i++) {
14428 ContentProviderConnection conn = cpr.connections.get(i);
14429 if (conn.waiting) {
14430 // If this connection is waiting for the provider, then we don't
14431 // need to mess with its process unless we are always removing
14432 // or for some reason the provider is not currently launching.
14433 if (inLaunching && !always) {
14437 ProcessRecord capp = conn.client;
14439 if (conn.stableCount > 0) {
14440 if (!capp.persistent && capp.thread != null
14442 && capp.pid != MY_PID) {
14443 capp.kill("depends on provider "
14444 + cpr.name.flattenToShortString()
14445 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14447 } else if (capp.thread != null && conn.provider.provider != null) {
14449 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14450 } catch (RemoteException e) {
14452 // In the protocol here, we don't expect the client to correctly
14453 // clean up this connection, we'll just remove it.
14454 cpr.connections.remove(i);
14455 conn.client.conProviders.remove(conn);
14459 if (inLaunching && always) {
14460 mLaunchingProviders.remove(cpr);
14462 return inLaunching;
14466 * Main code for cleaning up a process when it has gone away. This is
14467 * called both as a result of the process dying, or directly when stopping
14468 * a process when running in single process mode.
14470 * @return Returns true if the given process has been restarted, so the
14471 * app that was passed in must remain on the process lists.
14473 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
14474 boolean restarting, boolean allowRestart, int index) {
14476 removeLruProcessLocked(app);
14477 ProcessList.remove(app.pid);
14480 mProcessesToGc.remove(app);
14481 mPendingPssProcesses.remove(app);
14483 // Dismiss any open dialogs.
14484 if (app.crashDialog != null && !app.forceCrashReport) {
14485 app.crashDialog.dismiss();
14486 app.crashDialog = null;
14488 if (app.anrDialog != null) {
14489 app.anrDialog.dismiss();
14490 app.anrDialog = null;
14492 if (app.waitDialog != null) {
14493 app.waitDialog.dismiss();
14494 app.waitDialog = null;
14497 app.crashing = false;
14498 app.notResponding = false;
14500 app.resetPackageList(mProcessStats);
14501 app.unlinkDeathRecipient();
14502 app.makeInactive(mProcessStats);
14503 app.waitingToKill = null;
14504 app.forcingToForeground = null;
14505 updateProcessForegroundLocked(app, false, false);
14506 app.foregroundActivities = false;
14507 app.hasShownUi = false;
14508 app.treatLikeActivity = false;
14509 app.hasAboveClient = false;
14510 app.hasClientActivities = false;
14512 mServices.killServicesLocked(app, allowRestart);
14514 boolean restart = false;
14516 // Remove published content providers.
14517 for (int i=app.pubProviders.size()-1; i>=0; i--) {
14518 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14519 final boolean always = app.bad || !allowRestart;
14520 if (removeDyingProviderLocked(app, cpr, always) || always) {
14521 // We left the provider in the launching list, need to
14526 cpr.provider = null;
14529 app.pubProviders.clear();
14531 // Take care of any launching providers waiting for this process.
14532 if (checkAppInLaunchingProvidersLocked(app, false)) {
14536 // Unregister from connected content providers.
14537 if (!app.conProviders.isEmpty()) {
14538 for (int i=0; i<app.conProviders.size(); i++) {
14539 ContentProviderConnection conn = app.conProviders.get(i);
14540 conn.provider.connections.remove(conn);
14542 app.conProviders.clear();
14545 // At this point there may be remaining entries in mLaunchingProviders
14546 // where we were the only one waiting, so they are no longer of use.
14547 // Look for these and clean up if found.
14548 // XXX Commented out for now. Trying to figure out a way to reproduce
14549 // the actual situation to identify what is actually going on.
14551 for (int i=0; i<mLaunchingProviders.size(); i++) {
14552 ContentProviderRecord cpr = (ContentProviderRecord)
14553 mLaunchingProviders.get(i);
14554 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14555 synchronized (cpr) {
14556 cpr.launchingApp = null;
14563 skipCurrentReceiverLocked(app);
14565 // Unregister any receivers.
14566 for (int i=app.receivers.size()-1; i>=0; i--) {
14567 removeReceiverLocked(app.receivers.valueAt(i));
14569 app.receivers.clear();
14571 // If the app is undergoing backup, tell the backup manager about it
14572 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14573 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14574 + mBackupTarget.appInfo + " died during backup");
14576 IBackupManager bm = IBackupManager.Stub.asInterface(
14577 ServiceManager.getService(Context.BACKUP_SERVICE));
14578 bm.agentDisconnected(app.info.packageName);
14579 } catch (RemoteException e) {
14580 // can't happen; backup manager is local
14584 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14585 ProcessChangeItem item = mPendingProcessChanges.get(i);
14586 if (item.pid == app.pid) {
14587 mPendingProcessChanges.remove(i);
14588 mAvailProcessChanges.add(item);
14591 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14593 // If the caller is restarting this app, then leave it in its
14594 // current lists and let the caller take care of it.
14599 if (!app.persistent || app.isolated) {
14600 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14601 "Removing non-persistent process during cleanup: " + app);
14602 mProcessNames.remove(app.processName, app.uid);
14603 mIsolatedProcesses.remove(app.uid);
14604 if (mHeavyWeightProcess == app) {
14605 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14606 mHeavyWeightProcess.userId, 0));
14607 mHeavyWeightProcess = null;
14609 } else if (!app.removed) {
14610 // This app is persistent, so we need to keep its record around.
14611 // If it is not already on the pending app list, add it there
14612 // and start a new process for it.
14613 if (mPersistentStartingProcesses.indexOf(app) < 0) {
14614 mPersistentStartingProcesses.add(app);
14618 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14619 "Clean-up removing on hold: " + app);
14620 mProcessesOnHold.remove(app);
14622 if (app == mHomeProcess) {
14623 mHomeProcess = null;
14625 if (app == mPreviousProcess) {
14626 mPreviousProcess = null;
14629 if (restart && !app.isolated) {
14630 // We have components that still need to be running in the
14631 // process, so re-launch it.
14633 ProcessList.remove(app.pid);
14635 mProcessNames.put(app.processName, app.uid, app);
14636 startProcessLocked(app, "restart", app.processName);
14638 } else if (app.pid > 0 && app.pid != MY_PID) {
14641 synchronized (mPidsSelfLocked) {
14642 mPidsSelfLocked.remove(app.pid);
14643 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14645 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14646 if (app.isolated) {
14647 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14654 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14655 // Look through the content providers we are waiting to have launched,
14656 // and if any run in this process then either schedule a restart of
14657 // the process or kill the client waiting for it if this process has
14659 int NL = mLaunchingProviders.size();
14660 boolean restart = false;
14661 for (int i=0; i<NL; i++) {
14662 ContentProviderRecord cpr = mLaunchingProviders.get(i);
14663 if (cpr.launchingApp == app) {
14664 if (!alwaysBad && !app.bad) {
14667 removeDyingProviderLocked(app, cpr, true);
14668 // cpr should have been removed from mLaunchingProviders
14669 NL = mLaunchingProviders.size();
14677 // =========================================================
14679 // =========================================================
14682 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14684 enforceNotIsolatedCaller("getServices");
14685 synchronized (this) {
14686 return mServices.getRunningServiceInfoLocked(maxNum, flags);
14691 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14692 enforceNotIsolatedCaller("getRunningServiceControlPanel");
14693 synchronized (this) {
14694 return mServices.getRunningServiceControlPanelLocked(name);
14699 public ComponentName startService(IApplicationThread caller, Intent service,
14700 String resolvedType, int userId) {
14701 enforceNotIsolatedCaller("startService");
14702 // Refuse possible leaked file descriptors
14703 if (service != null && service.hasFileDescriptors() == true) {
14704 throw new IllegalArgumentException("File descriptors passed in Intent");
14708 Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14709 synchronized(this) {
14710 final int callingPid = Binder.getCallingPid();
14711 final int callingUid = Binder.getCallingUid();
14712 final long origId = Binder.clearCallingIdentity();
14713 ComponentName res = mServices.startServiceLocked(caller, service,
14714 resolvedType, callingPid, callingUid, userId);
14715 Binder.restoreCallingIdentity(origId);
14720 ComponentName startServiceInPackage(int uid,
14721 Intent service, String resolvedType, int userId) {
14722 synchronized(this) {
14724 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14725 final long origId = Binder.clearCallingIdentity();
14726 ComponentName res = mServices.startServiceLocked(null, service,
14727 resolvedType, -1, uid, userId);
14728 Binder.restoreCallingIdentity(origId);
14734 public int stopService(IApplicationThread caller, Intent service,
14735 String resolvedType, int userId) {
14736 enforceNotIsolatedCaller("stopService");
14737 // Refuse possible leaked file descriptors
14738 if (service != null && service.hasFileDescriptors() == true) {
14739 throw new IllegalArgumentException("File descriptors passed in Intent");
14742 synchronized(this) {
14743 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14748 public IBinder peekService(Intent service, String resolvedType) {
14749 enforceNotIsolatedCaller("peekService");
14750 // Refuse possible leaked file descriptors
14751 if (service != null && service.hasFileDescriptors() == true) {
14752 throw new IllegalArgumentException("File descriptors passed in Intent");
14754 synchronized(this) {
14755 return mServices.peekServiceLocked(service, resolvedType);
14760 public boolean stopServiceToken(ComponentName className, IBinder token,
14762 synchronized(this) {
14763 return mServices.stopServiceTokenLocked(className, token, startId);
14768 public void setServiceForeground(ComponentName className, IBinder token,
14769 int id, Notification notification, boolean removeNotification) {
14770 synchronized(this) {
14771 mServices.setServiceForegroundLocked(className, token, id, notification,
14772 removeNotification);
14777 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14778 boolean requireFull, String name, String callerPackage) {
14779 return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14780 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14783 int unsafeConvertIncomingUser(int userId) {
14784 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14785 ? mCurrentUserId : userId;
14788 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14789 int allowMode, String name, String callerPackage) {
14790 final int callingUserId = UserHandle.getUserId(callingUid);
14791 if (callingUserId == userId) {
14795 // Note that we may be accessing mCurrentUserId outside of a lock...
14796 // shouldn't be a big deal, if this is being called outside
14797 // of a locked context there is intrinsically a race with
14798 // the value the caller will receive and someone else changing it.
14799 // We assume that USER_CURRENT_OR_SELF will use the current user; later
14800 // we will switch to the calling user if access to the current user fails.
14801 int targetUserId = unsafeConvertIncomingUser(userId);
14803 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14804 final boolean allow;
14805 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14806 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14807 // If the caller has this permission, they always pass go. And collect $200.
14809 } else if (allowMode == ALLOW_FULL_ONLY) {
14810 // We require full access, sucks to be you.
14812 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14813 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14814 // If the caller does not have either permission, they are always doomed.
14816 } else if (allowMode == ALLOW_NON_FULL) {
14817 // We are blanket allowing non-full access, you lucky caller!
14819 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14820 // We may or may not allow this depending on whether the two users are
14821 // in the same profile.
14822 synchronized (mUserProfileGroupIdsSelfLocked) {
14823 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14824 UserInfo.NO_PROFILE_GROUP_ID);
14825 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14826 UserInfo.NO_PROFILE_GROUP_ID);
14827 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14828 && callingProfile == targetProfile;
14831 throw new IllegalArgumentException("Unknown mode: " + allowMode);
14834 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14835 // In this case, they would like to just execute as their
14836 // owner user instead of failing.
14837 targetUserId = callingUserId;
14839 StringBuilder builder = new StringBuilder(128);
14840 builder.append("Permission Denial: ");
14841 builder.append(name);
14842 if (callerPackage != null) {
14843 builder.append(" from ");
14844 builder.append(callerPackage);
14846 builder.append(" asks to run as user ");
14847 builder.append(userId);
14848 builder.append(" but is calling from user ");
14849 builder.append(UserHandle.getUserId(callingUid));
14850 builder.append("; this requires ");
14851 builder.append(INTERACT_ACROSS_USERS_FULL);
14852 if (allowMode != ALLOW_FULL_ONLY) {
14853 builder.append(" or ");
14854 builder.append(INTERACT_ACROSS_USERS);
14856 String msg = builder.toString();
14858 throw new SecurityException(msg);
14862 if (!allowAll && targetUserId < 0) {
14863 throw new IllegalArgumentException(
14864 "Call does not support special user #" + targetUserId);
14866 // Check shell permission
14867 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
14868 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
14870 throw new SecurityException("Shell does not have permission to access user "
14871 + targetUserId + "\n " + Debug.getCallers(3));
14874 return targetUserId;
14877 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14878 String className, int flags) {
14879 boolean result = false;
14880 // For apps that don't have pre-defined UIDs, check for permission
14881 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14882 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14883 if (ActivityManager.checkUidPermission(
14884 INTERACT_ACROSS_USERS,
14885 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14886 ComponentName comp = new ComponentName(aInfo.packageName, className);
14887 String msg = "Permission Denial: Component " + comp.flattenToShortString()
14888 + " requests FLAG_SINGLE_USER, but app does not hold "
14889 + INTERACT_ACROSS_USERS;
14891 throw new SecurityException(msg);
14893 // Permission passed
14896 } else if ("system".equals(componentProcessName)) {
14898 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14899 // Phone app and persistent apps are allowed to export singleuser providers.
14900 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14901 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14904 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14905 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14911 * Checks to see if the caller is in the same app as the singleton
14912 * component, or the component is in a special app. It allows special apps
14913 * to export singleton components but prevents exporting singleton
14914 * components for regular apps.
14916 boolean isValidSingletonCall(int callingUid, int componentUid) {
14917 int componentAppId = UserHandle.getAppId(componentUid);
14918 return UserHandle.isSameApp(callingUid, componentUid)
14919 || componentAppId == Process.SYSTEM_UID
14920 || componentAppId == Process.PHONE_UID
14921 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14922 == PackageManager.PERMISSION_GRANTED;
14925 public int bindService(IApplicationThread caller, IBinder token,
14926 Intent service, String resolvedType,
14927 IServiceConnection connection, int flags, int userId) {
14928 enforceNotIsolatedCaller("bindService");
14930 // Refuse possible leaked file descriptors
14931 if (service != null && service.hasFileDescriptors() == true) {
14932 throw new IllegalArgumentException("File descriptors passed in Intent");
14935 synchronized(this) {
14936 return mServices.bindServiceLocked(caller, token, service, resolvedType,
14937 connection, flags, userId);
14941 public boolean unbindService(IServiceConnection connection) {
14942 synchronized (this) {
14943 return mServices.unbindServiceLocked(connection);
14947 public void publishService(IBinder token, Intent intent, IBinder service) {
14948 // Refuse possible leaked file descriptors
14949 if (intent != null && intent.hasFileDescriptors() == true) {
14950 throw new IllegalArgumentException("File descriptors passed in Intent");
14953 synchronized(this) {
14954 if (!(token instanceof ServiceRecord)) {
14955 throw new IllegalArgumentException("Invalid service token");
14957 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14961 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14962 // Refuse possible leaked file descriptors
14963 if (intent != null && intent.hasFileDescriptors() == true) {
14964 throw new IllegalArgumentException("File descriptors passed in Intent");
14967 synchronized(this) {
14968 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14972 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14973 synchronized(this) {
14974 if (!(token instanceof ServiceRecord)) {
14975 throw new IllegalArgumentException("Invalid service token");
14977 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14981 // =========================================================
14982 // BACKUP AND RESTORE
14983 // =========================================================
14985 // Cause the target app to be launched if necessary and its backup agent
14986 // instantiated. The backup agent will invoke backupAgentCreated() on the
14987 // activity manager to announce its creation.
14988 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14989 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14990 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14992 synchronized(this) {
14993 // !!! TODO: currently no check here that we're already bound
14994 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14995 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14996 synchronized (stats) {
14997 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
15000 // Backup agent is now in use, its package can't be stopped.
15002 AppGlobals.getPackageManager().setPackageStoppedState(
15003 app.packageName, false, UserHandle.getUserId(app.uid));
15004 } catch (RemoteException e) {
15005 } catch (IllegalArgumentException e) {
15006 Slog.w(TAG, "Failed trying to unstop package "
15007 + app.packageName + ": " + e);
15010 BackupRecord r = new BackupRecord(ss, app, backupMode);
15011 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
15012 ? new ComponentName(app.packageName, app.backupAgentName)
15013 : new ComponentName("android", "FullBackupAgent");
15014 // startProcessLocked() returns existing proc's record if it's already running
15015 ProcessRecord proc = startProcessLocked(app.processName, app,
15016 false, 0, "backup", hostingName, false, false, false);
15017 if (proc == null) {
15018 Slog.e(TAG, "Unable to start backup agent process " + r);
15024 mBackupAppName = app.packageName;
15026 // Try not to kill the process during backup
15027 updateOomAdjLocked(proc);
15029 // If the process is already attached, schedule the creation of the backup agent now.
15030 // If it is not yet live, this will be done when it attaches to the framework.
15031 if (proc.thread != null) {
15032 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
15034 proc.thread.scheduleCreateBackupAgent(app,
15035 compatibilityInfoForPackageLocked(app), backupMode);
15036 } catch (RemoteException e) {
15037 // Will time out on the backup manager side
15040 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
15042 // Invariants: at this point, the target app process exists and the application
15043 // is either already running or in the process of coming up. mBackupTarget and
15044 // mBackupAppName describe the app, so that when it binds back to the AM we
15045 // know that it's scheduled for a backup-agent operation.
15052 public void clearPendingBackup() {
15053 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
15054 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
15056 synchronized (this) {
15057 mBackupTarget = null;
15058 mBackupAppName = null;
15062 // A backup agent has just come up
15063 public void backupAgentCreated(String agentPackageName, IBinder agent) {
15064 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
15067 synchronized(this) {
15068 if (!agentPackageName.equals(mBackupAppName)) {
15069 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
15074 long oldIdent = Binder.clearCallingIdentity();
15076 IBackupManager bm = IBackupManager.Stub.asInterface(
15077 ServiceManager.getService(Context.BACKUP_SERVICE));
15078 bm.agentConnected(agentPackageName, agent);
15079 } catch (RemoteException e) {
15080 // can't happen; the backup manager service is local
15081 } catch (Exception e) {
15082 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
15083 e.printStackTrace();
15085 Binder.restoreCallingIdentity(oldIdent);
15089 // done with this agent
15090 public void unbindBackupAgent(ApplicationInfo appInfo) {
15091 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
15092 if (appInfo == null) {
15093 Slog.w(TAG, "unbind backup agent for null app");
15097 synchronized(this) {
15099 if (mBackupAppName == null) {
15100 Slog.w(TAG, "Unbinding backup agent with no active backup");
15104 if (!mBackupAppName.equals(appInfo.packageName)) {
15105 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
15109 // Not backing this app up any more; reset its OOM adjustment
15110 final ProcessRecord proc = mBackupTarget.app;
15111 updateOomAdjLocked(proc);
15113 // If the app crashed during backup, 'thread' will be null here
15114 if (proc.thread != null) {
15116 proc.thread.scheduleDestroyBackupAgent(appInfo,
15117 compatibilityInfoForPackageLocked(appInfo));
15118 } catch (Exception e) {
15119 Slog.e(TAG, "Exception when unbinding backup agent:");
15120 e.printStackTrace();
15124 mBackupTarget = null;
15125 mBackupAppName = null;
15129 // =========================================================
15131 // =========================================================
15133 private final List getStickiesLocked(String action, IntentFilter filter,
15134 List cur, int userId) {
15135 final ContentResolver resolver = mContext.getContentResolver();
15136 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15137 if (stickies == null) {
15140 final ArrayList<Intent> list = stickies.get(action);
15141 if (list == null) {
15144 int N = list.size();
15145 for (int i=0; i<N; i++) {
15146 Intent intent = list.get(i);
15147 if (filter.match(resolver, intent, true, TAG) >= 0) {
15149 cur = new ArrayList<Intent>();
15157 boolean isPendingBroadcastProcessLocked(int pid) {
15158 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
15159 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
15162 void skipPendingBroadcastLocked(int pid) {
15163 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
15164 for (BroadcastQueue queue : mBroadcastQueues) {
15165 queue.skipPendingBroadcastLocked(pid);
15169 // The app just attached; send any pending broadcasts that it should receive
15170 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
15171 boolean didSomething = false;
15172 for (BroadcastQueue queue : mBroadcastQueues) {
15173 didSomething |= queue.sendPendingBroadcastsLocked(app);
15175 return didSomething;
15178 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
15179 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
15180 enforceNotIsolatedCaller("registerReceiver");
15183 synchronized(this) {
15184 ProcessRecord callerApp = null;
15185 if (caller != null) {
15186 callerApp = getRecordForAppLocked(caller);
15187 if (callerApp == null) {
15188 throw new SecurityException(
15189 "Unable to find app for caller " + caller
15190 + " (pid=" + Binder.getCallingPid()
15191 + ") when registering receiver " + receiver);
15193 if (callerApp.info.uid != Process.SYSTEM_UID &&
15194 !callerApp.pkgList.containsKey(callerPackage) &&
15195 !"android".equals(callerPackage)) {
15196 throw new SecurityException("Given caller package " + callerPackage
15197 + " is not running in process " + callerApp);
15199 callingUid = callerApp.info.uid;
15200 callingPid = callerApp.pid;
15202 callerPackage = null;
15203 callingUid = Binder.getCallingUid();
15204 callingPid = Binder.getCallingPid();
15207 userId = this.handleIncomingUser(callingPid, callingUid, userId,
15208 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
15210 List allSticky = null;
15212 // Look for any matching sticky broadcasts...
15213 Iterator actions = filter.actionsIterator();
15214 if (actions != null) {
15215 while (actions.hasNext()) {
15216 String action = (String)actions.next();
15217 allSticky = getStickiesLocked(action, filter, allSticky,
15218 UserHandle.USER_ALL);
15219 allSticky = getStickiesLocked(action, filter, allSticky,
15220 UserHandle.getUserId(callingUid));
15223 allSticky = getStickiesLocked(null, filter, allSticky,
15224 UserHandle.USER_ALL);
15225 allSticky = getStickiesLocked(null, filter, allSticky,
15226 UserHandle.getUserId(callingUid));
15229 // The first sticky in the list is returned directly back to
15231 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
15233 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
15236 if (receiver == null) {
15241 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
15243 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
15245 if (rl.app != null) {
15246 rl.app.receivers.add(rl);
15249 receiver.asBinder().linkToDeath(rl, 0);
15250 } catch (RemoteException e) {
15253 rl.linkedToDeath = true;
15255 mRegisteredReceivers.put(receiver.asBinder(), rl);
15256 } else if (rl.uid != callingUid) {
15257 throw new IllegalArgumentException(
15258 "Receiver requested to register for uid " + callingUid
15259 + " was previously registered for uid " + rl.uid);
15260 } else if (rl.pid != callingPid) {
15261 throw new IllegalArgumentException(
15262 "Receiver requested to register for pid " + callingPid
15263 + " was previously registered for pid " + rl.pid);
15264 } else if (rl.userId != userId) {
15265 throw new IllegalArgumentException(
15266 "Receiver requested to register for user " + userId
15267 + " was previously registered for user " + rl.userId);
15269 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
15270 permission, callingUid, userId);
15272 if (!bf.debugCheck()) {
15273 Slog.w(TAG, "==> For Dynamic broadast");
15275 mReceiverResolver.addFilter(bf);
15277 // Enqueue broadcasts for all existing stickies that match
15279 if (allSticky != null) {
15280 ArrayList receivers = new ArrayList();
15283 int N = allSticky.size();
15284 for (int i=0; i<N; i++) {
15285 Intent intent = (Intent)allSticky.get(i);
15286 BroadcastQueue queue = broadcastQueueForIntent(intent);
15287 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
15288 null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
15289 null, null, false, true, true, -1);
15290 queue.enqueueParallelBroadcastLocked(r);
15291 queue.scheduleBroadcastsLocked();
15299 public void unregisterReceiver(IIntentReceiver receiver) {
15300 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
15302 final long origId = Binder.clearCallingIdentity();
15304 boolean doTrim = false;
15306 synchronized(this) {
15307 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
15309 if (rl.curBroadcast != null) {
15310 BroadcastRecord r = rl.curBroadcast;
15311 final boolean doNext = finishReceiverLocked(
15312 receiver.asBinder(), r.resultCode, r.resultData,
15313 r.resultExtras, r.resultAbort);
15316 r.queue.processNextBroadcast(false);
15320 if (rl.app != null) {
15321 rl.app.receivers.remove(rl);
15323 removeReceiverLocked(rl);
15324 if (rl.linkedToDeath) {
15325 rl.linkedToDeath = false;
15326 rl.receiver.asBinder().unlinkToDeath(rl, 0);
15331 // If we actually concluded any broadcasts, we might now be able
15332 // to trim the recipients' apps from our working set
15334 trimApplications();
15339 Binder.restoreCallingIdentity(origId);
15343 void removeReceiverLocked(ReceiverList rl) {
15344 mRegisteredReceivers.remove(rl.receiver.asBinder());
15346 for (int i=0; i<N; i++) {
15347 mReceiverResolver.removeFilter(rl.get(i));
15351 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15352 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15353 ProcessRecord r = mLruProcesses.get(i);
15354 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15356 r.thread.dispatchPackageBroadcast(cmd, packages);
15357 } catch (RemoteException ex) {
15363 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15364 int callingUid, int[] users) {
15365 List<ResolveInfo> receivers = null;
15367 HashSet<ComponentName> singleUserReceivers = null;
15368 boolean scannedFirstReceivers = false;
15369 for (int user : users) {
15370 // Skip users that have Shell restrictions
15371 if (callingUid == Process.SHELL_UID
15372 && getUserManagerLocked().hasUserRestriction(
15373 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
15376 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15377 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15378 if (user != 0 && newReceivers != null) {
15379 // If this is not the primary user, we need to check for
15380 // any receivers that should be filtered out.
15381 for (int i=0; i<newReceivers.size(); i++) {
15382 ResolveInfo ri = newReceivers.get(i);
15383 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15384 newReceivers.remove(i);
15389 if (newReceivers != null && newReceivers.size() == 0) {
15390 newReceivers = null;
15392 if (receivers == null) {
15393 receivers = newReceivers;
15394 } else if (newReceivers != null) {
15395 // We need to concatenate the additional receivers
15396 // found with what we have do far. This would be easy,
15397 // but we also need to de-dup any receivers that are
15399 if (!scannedFirstReceivers) {
15400 // Collect any single user receivers we had already retrieved.
15401 scannedFirstReceivers = true;
15402 for (int i=0; i<receivers.size(); i++) {
15403 ResolveInfo ri = receivers.get(i);
15404 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15405 ComponentName cn = new ComponentName(
15406 ri.activityInfo.packageName, ri.activityInfo.name);
15407 if (singleUserReceivers == null) {
15408 singleUserReceivers = new HashSet<ComponentName>();
15410 singleUserReceivers.add(cn);
15414 // Add the new results to the existing results, tracking
15415 // and de-dupping single user receivers.
15416 for (int i=0; i<newReceivers.size(); i++) {
15417 ResolveInfo ri = newReceivers.get(i);
15418 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15419 ComponentName cn = new ComponentName(
15420 ri.activityInfo.packageName, ri.activityInfo.name);
15421 if (singleUserReceivers == null) {
15422 singleUserReceivers = new HashSet<ComponentName>();
15424 if (!singleUserReceivers.contains(cn)) {
15425 singleUserReceivers.add(cn);
15434 } catch (RemoteException ex) {
15435 // pm is in same process, this will never happen.
15440 private final int broadcastIntentLocked(ProcessRecord callerApp,
15441 String callerPackage, Intent intent, String resolvedType,
15442 IIntentReceiver resultTo, int resultCode, String resultData,
15443 Bundle map, String requiredPermission, int appOp,
15444 boolean ordered, boolean sticky, int callingPid, int callingUid,
15446 intent = new Intent(intent);
15448 // By default broadcasts do not go to stopped apps.
15449 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15451 if (DEBUG_BROADCAST_LIGHT) Slog.v(
15452 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15453 + " ordered=" + ordered + " userid=" + userId);
15454 if ((resultTo != null) && !ordered) {
15455 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15458 userId = handleIncomingUser(callingPid, callingUid, userId,
15459 true, ALLOW_NON_FULL, "broadcast", callerPackage);
15461 // Make sure that the user who is receiving this broadcast is started.
15462 // If not, we will just skip it.
15464 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15465 if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15466 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15467 Slog.w(TAG, "Skipping broadcast of " + intent
15468 + ": user " + userId + " is stopped");
15469 return ActivityManager.BROADCAST_SUCCESS;
15474 * Prevent non-system code (defined here to be non-persistent
15475 * processes) from sending protected broadcasts.
15477 int callingAppId = UserHandle.getAppId(callingUid);
15478 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15479 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15480 || callingAppId == Process.NFC_UID || callingUid == 0) {
15482 } else if (callerApp == null || !callerApp.persistent) {
15484 if (AppGlobals.getPackageManager().isProtectedBroadcast(
15485 intent.getAction())) {
15486 String msg = "Permission Denial: not allowed to send broadcast "
15487 + intent.getAction() + " from pid="
15488 + callingPid + ", uid=" + callingUid;
15490 throw new SecurityException(msg);
15491 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15492 // Special case for compatibility: we don't want apps to send this,
15493 // but historically it has not been protected and apps may be using it
15494 // to poke their own app widget. So, instead of making it protected,
15495 // just limit it to the caller.
15496 if (callerApp == null) {
15497 String msg = "Permission Denial: not allowed to send broadcast "
15498 + intent.getAction() + " from unknown caller.";
15500 throw new SecurityException(msg);
15501 } else if (intent.getComponent() != null) {
15502 // They are good enough to send to an explicit component... verify
15503 // it is being sent to the calling app.
15504 if (!intent.getComponent().getPackageName().equals(
15505 callerApp.info.packageName)) {
15506 String msg = "Permission Denial: not allowed to send broadcast "
15507 + intent.getAction() + " to "
15508 + intent.getComponent().getPackageName() + " from "
15509 + callerApp.info.packageName;
15511 throw new SecurityException(msg);
15514 // Limit broadcast to their own package.
15515 intent.setPackage(callerApp.info.packageName);
15518 } catch (RemoteException e) {
15519 Slog.w(TAG, "Remote exception", e);
15520 return ActivityManager.BROADCAST_SUCCESS;
15524 // Handle special intents: if this broadcast is from the package
15525 // manager about a package being removed, we need to remove all of
15526 // its activities from the history stack.
15527 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15528 intent.getAction());
15529 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15530 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15531 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15532 || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15534 if (checkComponentPermission(
15535 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15536 callingPid, callingUid, -1, true)
15537 == PackageManager.PERMISSION_GRANTED) {
15539 final Bundle intentExtras = intent.getExtras();
15540 final int uid = intentExtras != null
15541 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15543 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15544 synchronized (bs) {
15545 bs.removeUidStatsLocked(uid);
15547 mAppOpsService.uidRemoved(uid);
15550 // If resources are unavailable just force stop all
15551 // those packages and flush the attribute cache as well.
15552 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15553 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15554 if (list != null && (list.length > 0)) {
15555 for (String pkg : list) {
15556 forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15557 "storage unmount");
15559 cleanupRecentTasksLocked(UserHandle.USER_ALL);
15560 sendPackageBroadcastLocked(
15561 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15563 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15564 intent.getAction())) {
15565 cleanupRecentTasksLocked(UserHandle.USER_ALL);
15567 Uri data = intent.getData();
15569 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15570 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15571 intent.getAction());
15572 boolean fullUninstall = removed &&
15573 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15574 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15575 forceStopPackageLocked(ssp, UserHandle.getAppId(
15576 intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15577 false, fullUninstall, userId,
15578 removed ? "pkg removed" : "pkg changed");
15581 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15582 new String[] {ssp}, userId);
15583 if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15584 mAppOpsService.packageRemoved(
15585 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15587 // Remove all permissions granted from/to this package
15588 removeUriPermissionsForPackageLocked(ssp, userId, true);
15595 String msg = "Permission Denial: " + intent.getAction()
15596 + " broadcast from " + callerPackage + " (pid=" + callingPid
15597 + ", uid=" + callingUid + ")"
15599 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15601 throw new SecurityException(msg);
15604 // Special case for adding a package: by default turn on compatibility
15606 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15607 Uri data = intent.getData();
15609 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15610 mCompatModePackages.handlePackageAddedLocked(ssp,
15611 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15616 * If this is the time zone changed action, queue up a message that will reset the timezone
15617 * of all currently running processes. This message will get queued up before the broadcast
15620 if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15621 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15625 * If the user set the time, let all running processes know.
15627 if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15628 final int is24Hour = intent.getBooleanExtra(
15629 Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15630 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15631 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15632 synchronized (stats) {
15633 stats.noteCurrentTimeChangedLocked();
15637 if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15638 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15641 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15642 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15643 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15646 // Add to the sticky list if requested.
15648 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15649 callingPid, callingUid)
15650 != PackageManager.PERMISSION_GRANTED) {
15651 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15652 + callingPid + ", uid=" + callingUid
15653 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15655 throw new SecurityException(msg);
15657 if (requiredPermission != null) {
15658 Slog.w(TAG, "Can't broadcast sticky intent " + intent
15659 + " and enforce permission " + requiredPermission);
15660 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15662 if (intent.getComponent() != null) {
15663 throw new SecurityException(
15664 "Sticky broadcasts can't target a specific component");
15666 // We use userId directly here, since the "all" target is maintained
15667 // as a separate set of sticky broadcasts.
15668 if (userId != UserHandle.USER_ALL) {
15669 // But first, if this is not a broadcast to all users, then
15670 // make sure it doesn't conflict with an existing broadcast to
15672 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15673 UserHandle.USER_ALL);
15674 if (stickies != null) {
15675 ArrayList<Intent> list = stickies.get(intent.getAction());
15676 if (list != null) {
15677 int N = list.size();
15679 for (i=0; i<N; i++) {
15680 if (intent.filterEquals(list.get(i))) {
15681 throw new IllegalArgumentException(
15682 "Sticky broadcast " + intent + " for user "
15683 + userId + " conflicts with existing global broadcast");
15689 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15690 if (stickies == null) {
15691 stickies = new ArrayMap<String, ArrayList<Intent>>();
15692 mStickyBroadcasts.put(userId, stickies);
15694 ArrayList<Intent> list = stickies.get(intent.getAction());
15695 if (list == null) {
15696 list = new ArrayList<Intent>();
15697 stickies.put(intent.getAction(), list);
15699 int N = list.size();
15701 for (i=0; i<N; i++) {
15702 if (intent.filterEquals(list.get(i))) {
15703 // This sticky already exists, replace it.
15704 list.set(i, new Intent(intent));
15709 list.add(new Intent(intent));
15714 if (userId == UserHandle.USER_ALL) {
15715 // Caller wants broadcast to go to all started users.
15716 users = mStartedUserArray;
15718 // Caller wants broadcast to go to one specific user.
15719 users = new int[] {userId};
15722 // Figure out who all will receive this broadcast.
15723 List receivers = null;
15724 List<BroadcastFilter> registeredReceivers = null;
15725 // Need to resolve the intent to interested receivers...
15726 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15728 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
15730 if (intent.getComponent() == null) {
15731 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
15732 // Query one target user at a time, excluding shell-restricted users
15733 UserManagerService ums = getUserManagerLocked();
15734 for (int i = 0; i < users.length; i++) {
15735 if (ums.hasUserRestriction(
15736 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
15739 List<BroadcastFilter> registeredReceiversForUser =
15740 mReceiverResolver.queryIntent(intent,
15741 resolvedType, false, users[i]);
15742 if (registeredReceivers == null) {
15743 registeredReceivers = registeredReceiversForUser;
15744 } else if (registeredReceiversForUser != null) {
15745 registeredReceivers.addAll(registeredReceiversForUser);
15749 registeredReceivers = mReceiverResolver.queryIntent(intent,
15750 resolvedType, false, userId);
15754 final boolean replacePending =
15755 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15757 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15758 + " replacePending=" + replacePending);
15760 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15761 if (!ordered && NR > 0) {
15762 // If we are not serializing this broadcast, then send the
15763 // registered receivers separately so they don't wait for the
15764 // components to be launched.
15765 final BroadcastQueue queue = broadcastQueueForIntent(intent);
15766 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15767 callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15768 appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15769 ordered, sticky, false, userId);
15770 if (DEBUG_BROADCAST) Slog.v(
15771 TAG, "Enqueueing parallel broadcast " + r);
15772 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15774 queue.enqueueParallelBroadcastLocked(r);
15775 queue.scheduleBroadcastsLocked();
15777 registeredReceivers = null;
15781 // Merge into one list.
15783 if (receivers != null) {
15784 // A special case for PACKAGE_ADDED: do not allow the package
15785 // being added to see this broadcast. This prevents them from
15786 // using this as a back door to get run as soon as they are
15787 // installed. Maybe in the future we want to have a special install
15788 // broadcast or such for apps, but we'd like to deliberately make
15790 String skipPackages[] = null;
15791 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15792 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15793 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15794 Uri data = intent.getData();
15795 if (data != null) {
15796 String pkgName = data.getSchemeSpecificPart();
15797 if (pkgName != null) {
15798 skipPackages = new String[] { pkgName };
15801 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15802 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15804 if (skipPackages != null && (skipPackages.length > 0)) {
15805 for (String skipPackage : skipPackages) {
15806 if (skipPackage != null) {
15807 int NT = receivers.size();
15808 for (int it=0; it<NT; it++) {
15809 ResolveInfo curt = (ResolveInfo)receivers.get(it);
15810 if (curt.activityInfo.packageName.equals(skipPackage)) {
15811 receivers.remove(it);
15820 int NT = receivers != null ? receivers.size() : 0;
15822 ResolveInfo curt = null;
15823 BroadcastFilter curr = null;
15824 while (it < NT && ir < NR) {
15825 if (curt == null) {
15826 curt = (ResolveInfo)receivers.get(it);
15828 if (curr == null) {
15829 curr = registeredReceivers.get(ir);
15831 if (curr.getPriority() >= curt.priority) {
15832 // Insert this broadcast record into the final list.
15833 receivers.add(it, curr);
15839 // Skip to the next ResolveInfo in the final list.
15846 if (receivers == null) {
15847 receivers = new ArrayList();
15849 receivers.add(registeredReceivers.get(ir));
15853 if ((receivers != null && receivers.size() > 0)
15854 || resultTo != null) {
15855 BroadcastQueue queue = broadcastQueueForIntent(intent);
15856 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15857 callerPackage, callingPid, callingUid, resolvedType,
15858 requiredPermission, appOp, receivers, resultTo, resultCode,
15859 resultData, map, ordered, sticky, false, userId);
15860 if (DEBUG_BROADCAST) Slog.v(
15861 TAG, "Enqueueing ordered broadcast " + r
15862 + ": prev had " + queue.mOrderedBroadcasts.size());
15863 if (DEBUG_BROADCAST) {
15864 int seq = r.intent.getIntExtra("seq", -1);
15865 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15867 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15869 queue.enqueueOrderedBroadcastLocked(r);
15870 queue.scheduleBroadcastsLocked();
15874 return ActivityManager.BROADCAST_SUCCESS;
15877 final Intent verifyBroadcastLocked(Intent intent) {
15878 // Refuse possible leaked file descriptors
15879 if (intent != null && intent.hasFileDescriptors() == true) {
15880 throw new IllegalArgumentException("File descriptors passed in Intent");
15883 int flags = intent.getFlags();
15885 if (!mProcessesReady) {
15886 // if the caller really truly claims to know what they're doing, go
15887 // ahead and allow the broadcast without launching any receivers
15888 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15889 intent = new Intent(intent);
15890 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15891 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15892 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15893 + " before boot completion");
15894 throw new IllegalStateException("Cannot broadcast before boot completed");
15898 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15899 throw new IllegalArgumentException(
15900 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15906 public final int broadcastIntent(IApplicationThread caller,
15907 Intent intent, String resolvedType, IIntentReceiver resultTo,
15908 int resultCode, String resultData, Bundle map,
15909 String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15910 enforceNotIsolatedCaller("broadcastIntent");
15911 synchronized(this) {
15912 intent = verifyBroadcastLocked(intent);
15914 final ProcessRecord callerApp = getRecordForAppLocked(caller);
15915 final int callingPid = Binder.getCallingPid();
15916 final int callingUid = Binder.getCallingUid();
15917 final long origId = Binder.clearCallingIdentity();
15918 int res = broadcastIntentLocked(callerApp,
15919 callerApp != null ? callerApp.info.packageName : null,
15920 intent, resolvedType, resultTo,
15921 resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15922 callingPid, callingUid, userId);
15923 Binder.restoreCallingIdentity(origId);
15928 int broadcastIntentInPackage(String packageName, int uid,
15929 Intent intent, String resolvedType, IIntentReceiver resultTo,
15930 int resultCode, String resultData, Bundle map,
15931 String requiredPermission, boolean serialized, boolean sticky, int userId) {
15932 synchronized(this) {
15933 intent = verifyBroadcastLocked(intent);
15935 final long origId = Binder.clearCallingIdentity();
15936 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15937 resultTo, resultCode, resultData, map, requiredPermission,
15938 AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15939 Binder.restoreCallingIdentity(origId);
15944 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15945 // Refuse possible leaked file descriptors
15946 if (intent != null && intent.hasFileDescriptors() == true) {
15947 throw new IllegalArgumentException("File descriptors passed in Intent");
15950 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15951 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15953 synchronized(this) {
15954 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15955 != PackageManager.PERMISSION_GRANTED) {
15956 String msg = "Permission Denial: unbroadcastIntent() from pid="
15957 + Binder.getCallingPid()
15958 + ", uid=" + Binder.getCallingUid()
15959 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15961 throw new SecurityException(msg);
15963 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15964 if (stickies != null) {
15965 ArrayList<Intent> list = stickies.get(intent.getAction());
15966 if (list != null) {
15967 int N = list.size();
15969 for (i=0; i<N; i++) {
15970 if (intent.filterEquals(list.get(i))) {
15975 if (list.size() <= 0) {
15976 stickies.remove(intent.getAction());
15979 if (stickies.size() <= 0) {
15980 mStickyBroadcasts.remove(userId);
15986 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15987 String resultData, Bundle resultExtras, boolean resultAbort) {
15988 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15990 Slog.w(TAG, "finishReceiver called but not found on queue");
15994 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15997 void backgroundServicesFinishedLocked(int userId) {
15998 for (BroadcastQueue queue : mBroadcastQueues) {
15999 queue.backgroundServicesFinishedLocked(userId);
16003 public void finishReceiver(IBinder who, int resultCode, String resultData,
16004 Bundle resultExtras, boolean resultAbort) {
16005 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
16007 // Refuse possible leaked file descriptors
16008 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
16009 throw new IllegalArgumentException("File descriptors passed in Bundle");
16012 final long origId = Binder.clearCallingIdentity();
16014 boolean doNext = false;
16017 synchronized(this) {
16018 r = broadcastRecordForReceiverLocked(who);
16020 doNext = r.queue.finishReceiverLocked(r, resultCode,
16021 resultData, resultExtras, resultAbort, true);
16026 r.queue.processNextBroadcast(false);
16028 trimApplications();
16030 Binder.restoreCallingIdentity(origId);
16034 // =========================================================
16036 // =========================================================
16038 public boolean startInstrumentation(ComponentName className,
16039 String profileFile, int flags, Bundle arguments,
16040 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
16041 int userId, String abiOverride) {
16042 enforceNotIsolatedCaller("startInstrumentation");
16043 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16044 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
16045 // Refuse possible leaked file descriptors
16046 if (arguments != null && arguments.hasFileDescriptors()) {
16047 throw new IllegalArgumentException("File descriptors passed in Bundle");
16050 synchronized(this) {
16051 InstrumentationInfo ii = null;
16052 ApplicationInfo ai = null;
16054 ii = mContext.getPackageManager().getInstrumentationInfo(
16055 className, STOCK_PM_FLAGS);
16056 ai = AppGlobals.getPackageManager().getApplicationInfo(
16057 ii.targetPackage, STOCK_PM_FLAGS, userId);
16058 } catch (PackageManager.NameNotFoundException e) {
16059 } catch (RemoteException e) {
16062 reportStartInstrumentationFailure(watcher, className,
16063 "Unable to find instrumentation info for: " + className);
16067 reportStartInstrumentationFailure(watcher, className,
16068 "Unable to find instrumentation target package: " + ii.targetPackage);
16072 int match = mContext.getPackageManager().checkSignatures(
16073 ii.targetPackage, ii.packageName);
16074 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
16075 String msg = "Permission Denial: starting instrumentation "
16076 + className + " from pid="
16077 + Binder.getCallingPid()
16078 + ", uid=" + Binder.getCallingPid()
16079 + " not allowed because package " + ii.packageName
16080 + " does not have a signature matching the target "
16081 + ii.targetPackage;
16082 reportStartInstrumentationFailure(watcher, className, msg);
16083 throw new SecurityException(msg);
16086 final long origId = Binder.clearCallingIdentity();
16087 // Instrumentation can kill and relaunch even persistent processes
16088 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
16090 ProcessRecord app = addAppLocked(ai, false, abiOverride);
16091 app.instrumentationClass = className;
16092 app.instrumentationInfo = ai;
16093 app.instrumentationProfileFile = profileFile;
16094 app.instrumentationArguments = arguments;
16095 app.instrumentationWatcher = watcher;
16096 app.instrumentationUiAutomationConnection = uiAutomationConnection;
16097 app.instrumentationResultClass = className;
16098 Binder.restoreCallingIdentity(origId);
16105 * Report errors that occur while attempting to start Instrumentation. Always writes the
16106 * error to the logs, but if somebody is watching, send the report there too. This enables
16107 * the "am" command to report errors with more information.
16109 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
16110 * @param cn The component name of the instrumentation.
16111 * @param report The error report.
16113 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
16114 ComponentName cn, String report) {
16115 Slog.w(TAG, report);
16117 if (watcher != null) {
16118 Bundle results = new Bundle();
16119 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
16120 results.putString("Error", report);
16121 watcher.instrumentationStatus(cn, -1, results);
16123 } catch (RemoteException e) {
16128 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
16129 if (app.instrumentationWatcher != null) {
16131 // NOTE: IInstrumentationWatcher *must* be oneway here
16132 app.instrumentationWatcher.instrumentationFinished(
16133 app.instrumentationClass,
16136 } catch (RemoteException e) {
16139 if (app.instrumentationUiAutomationConnection != null) {
16141 app.instrumentationUiAutomationConnection.shutdown();
16142 } catch (RemoteException re) {
16145 // Only a UiAutomation can set this flag and now that
16146 // it is finished we make sure it is reset to its default.
16147 mUserIsMonkey = false;
16149 app.instrumentationWatcher = null;
16150 app.instrumentationUiAutomationConnection = null;
16151 app.instrumentationClass = null;
16152 app.instrumentationInfo = null;
16153 app.instrumentationProfileFile = null;
16154 app.instrumentationArguments = null;
16156 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
16160 public void finishInstrumentation(IApplicationThread target,
16161 int resultCode, Bundle results) {
16162 int userId = UserHandle.getCallingUserId();
16163 // Refuse possible leaked file descriptors
16164 if (results != null && results.hasFileDescriptors()) {
16165 throw new IllegalArgumentException("File descriptors passed in Intent");
16168 synchronized(this) {
16169 ProcessRecord app = getRecordForAppLocked(target);
16171 Slog.w(TAG, "finishInstrumentation: no app for " + target);
16174 final long origId = Binder.clearCallingIdentity();
16175 finishInstrumentationLocked(app, resultCode, results);
16176 Binder.restoreCallingIdentity(origId);
16180 // =========================================================
16182 // =========================================================
16184 public ConfigurationInfo getDeviceConfigurationInfo() {
16185 ConfigurationInfo config = new ConfigurationInfo();
16186 synchronized (this) {
16187 config.reqTouchScreen = mConfiguration.touchscreen;
16188 config.reqKeyboardType = mConfiguration.keyboard;
16189 config.reqNavigation = mConfiguration.navigation;
16190 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
16191 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
16192 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
16194 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
16195 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
16196 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
16198 config.reqGlEsVersion = GL_ES_VERSION;
16203 ActivityStack getFocusedStack() {
16204 return mStackSupervisor.getFocusedStack();
16207 public Configuration getConfiguration() {
16209 synchronized(this) {
16210 ci = new Configuration(mConfiguration);
16215 public void updatePersistentConfiguration(Configuration values) {
16216 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16217 "updateConfiguration()");
16218 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
16219 "updateConfiguration()");
16220 if (values == null) {
16221 throw new NullPointerException("Configuration must not be null");
16224 synchronized(this) {
16225 final long origId = Binder.clearCallingIdentity();
16226 updateConfigurationLocked(values, null, true, false);
16227 Binder.restoreCallingIdentity(origId);
16231 public void updateConfiguration(Configuration values) {
16232 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
16233 "updateConfiguration()");
16235 synchronized(this) {
16236 if (values == null && mWindowManager != null) {
16237 // sentinel: fetch the current configuration from the window manager
16238 values = mWindowManager.computeNewConfiguration();
16241 if (mWindowManager != null) {
16242 mProcessList.applyDisplaySize(mWindowManager);
16245 final long origId = Binder.clearCallingIdentity();
16246 if (values != null) {
16247 Settings.System.clearConfiguration(values);
16249 updateConfigurationLocked(values, null, false, false);
16250 Binder.restoreCallingIdentity(origId);
16255 * Do either or both things: (1) change the current configuration, and (2)
16256 * make sure the given activity is running with the (now) current
16257 * configuration. Returns true if the activity has been left running, or
16258 * false if <var>starting</var> is being destroyed to match the new
16260 * @param persistent TODO
16262 boolean updateConfigurationLocked(Configuration values,
16263 ActivityRecord starting, boolean persistent, boolean initLocale) {
16266 if (values != null) {
16267 Configuration newConfig = new Configuration(mConfiguration);
16268 changes = newConfig.updateFrom(values);
16269 if (changes != 0) {
16270 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
16271 Slog.i(TAG, "Updating configuration to: " + values);
16274 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
16276 if (values.locale != null && !initLocale) {
16277 saveLocaleLocked(values.locale,
16278 !values.locale.equals(mConfiguration.locale),
16279 values.userSetLocale);
16282 mConfigurationSeq++;
16283 if (mConfigurationSeq <= 0) {
16284 mConfigurationSeq = 1;
16286 newConfig.seq = mConfigurationSeq;
16287 mConfiguration = newConfig;
16288 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
16289 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
16290 //mUsageStatsService.noteStartConfig(newConfig);
16292 final Configuration configCopy = new Configuration(mConfiguration);
16294 // TODO: If our config changes, should we auto dismiss any currently
16295 // showing dialogs?
16296 mShowDialogs = shouldShowDialogs(newConfig);
16298 AttributeCache ac = AttributeCache.instance();
16300 ac.updateConfiguration(configCopy);
16303 // Make sure all resources in our process are updated
16304 // right now, so that anyone who is going to retrieve
16305 // resource values after we return will be sure to get
16306 // the new ones. This is especially important during
16307 // boot, where the first config change needs to guarantee
16308 // all resources have that config before following boot
16309 // code is executed.
16310 mSystemThread.applyConfigurationToResources(configCopy);
16312 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
16313 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
16314 msg.obj = new Configuration(configCopy);
16315 mHandler.sendMessage(msg);
16318 for (int i=mLruProcesses.size()-1; i>=0; i--) {
16319 ProcessRecord app = mLruProcesses.get(i);
16321 if (app.thread != null) {
16322 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
16323 + app.processName + " new config " + mConfiguration);
16324 app.thread.scheduleConfigurationChanged(configCopy);
16326 } catch (Exception e) {
16329 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
16330 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16331 | Intent.FLAG_RECEIVER_REPLACE_PENDING
16332 | Intent.FLAG_RECEIVER_FOREGROUND);
16333 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
16334 null, AppOpsManager.OP_NONE, false, false, MY_PID,
16335 Process.SYSTEM_UID, UserHandle.USER_ALL);
16336 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
16337 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
16338 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16339 broadcastIntentLocked(null, null, intent,
16340 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16341 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16346 boolean kept = true;
16347 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
16348 // mainStack is null during startup.
16349 if (mainStack != null) {
16350 if (changes != 0 && starting == null) {
16351 // If the configuration changed, and the caller is not already
16352 // in the process of starting an activity, then find the top
16353 // activity to check if its configuration needs to change.
16354 starting = mainStack.topRunningActivityLocked(null);
16357 if (starting != null) {
16358 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
16359 // And we need to make sure at this point that all other activities
16360 // are made visible with the correct configuration.
16361 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
16365 if (values != null && mWindowManager != null) {
16366 mWindowManager.setNewConfiguration(mConfiguration);
16373 * Decide based on the configuration whether we should shouw the ANR,
16374 * crash, etc dialogs. The idea is that if there is no affordnace to
16375 * press the on-screen buttons, we shouldn't show the dialog.
16377 * A thought: SystemUI might also want to get told about this, the Power
16378 * dialog / global actions also might want different behaviors.
16380 private static final boolean shouldShowDialogs(Configuration config) {
16381 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16382 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16386 * Save the locale. You must be inside a synchronized (this) block.
16388 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16390 SystemProperties.set("user.language", l.getLanguage());
16391 SystemProperties.set("user.region", l.getCountry());
16395 SystemProperties.set("persist.sys.language", l.getLanguage());
16396 SystemProperties.set("persist.sys.country", l.getCountry());
16397 SystemProperties.set("persist.sys.localevar", l.getVariant());
16399 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG, l));
16404 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16405 synchronized (this) {
16406 ActivityRecord srec = ActivityRecord.forToken(token);
16407 if (srec.task != null && srec.task.stack != null) {
16408 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16414 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16415 Intent resultData) {
16417 synchronized (this) {
16418 final ActivityStack stack = ActivityRecord.getStackLocked(token);
16419 if (stack != null) {
16420 return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16426 public int getLaunchedFromUid(IBinder activityToken) {
16427 ActivityRecord srec = ActivityRecord.forToken(activityToken);
16428 if (srec == null) {
16431 return srec.launchedFromUid;
16434 public String getLaunchedFromPackage(IBinder activityToken) {
16435 ActivityRecord srec = ActivityRecord.forToken(activityToken);
16436 if (srec == null) {
16439 return srec.launchedFromPackage;
16442 // =========================================================
16443 // LIFETIME MANAGEMENT
16444 // =========================================================
16446 // Returns which broadcast queue the app is the current [or imminent] receiver
16447 // on, or 'null' if the app is not an active broadcast recipient.
16448 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16449 BroadcastRecord r = app.curReceiver;
16454 // It's not the current receiver, but it might be starting up to become one
16455 synchronized (this) {
16456 for (BroadcastQueue queue : mBroadcastQueues) {
16457 r = queue.mPendingBroadcast;
16458 if (r != null && r.curApp == app) {
16459 // found it; report which queue it's in
16468 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16469 boolean doingAll, long now) {
16470 if (mAdjSeq == app.adjSeq) {
16471 // This adjustment has already been computed.
16472 return app.curRawAdj;
16475 if (app.thread == null) {
16476 app.adjSeq = mAdjSeq;
16477 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16478 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16479 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16482 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16483 app.adjSource = null;
16484 app.adjTarget = null;
16486 app.cached = false;
16488 final int activitiesSize = app.activities.size();
16490 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16491 // The max adjustment doesn't allow this app to be anything
16492 // below foreground, so it is not worth doing work for it.
16493 app.adjType = "fixed";
16494 app.adjSeq = mAdjSeq;
16495 app.curRawAdj = app.maxAdj;
16496 app.foregroundActivities = false;
16497 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16498 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16499 // System processes can do UI, and when they do we want to have
16500 // them trim their memory after the user leaves the UI. To
16501 // facilitate this, here we need to determine whether or not it
16502 // is currently showing UI.
16503 app.systemNoUi = true;
16504 if (app == TOP_APP) {
16505 app.systemNoUi = false;
16506 } else if (activitiesSize > 0) {
16507 for (int j = 0; j < activitiesSize; j++) {
16508 final ActivityRecord r = app.activities.get(j);
16510 app.systemNoUi = false;
16514 if (!app.systemNoUi) {
16515 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16517 return (app.curAdj=app.maxAdj);
16520 app.systemNoUi = false;
16522 // Determine the importance of the process, starting with most
16523 // important to least, and assign an appropriate OOM adjustment.
16527 boolean foregroundActivities = false;
16528 BroadcastQueue queue;
16529 if (app == TOP_APP) {
16530 // The last app on the list is the foreground app.
16531 adj = ProcessList.FOREGROUND_APP_ADJ;
16532 schedGroup = Process.THREAD_GROUP_DEFAULT;
16533 app.adjType = "top-activity";
16534 foregroundActivities = true;
16535 procState = ActivityManager.PROCESS_STATE_TOP;
16536 } else if (app.instrumentationClass != null) {
16537 // Don't want to kill running instrumentation.
16538 adj = ProcessList.FOREGROUND_APP_ADJ;
16539 schedGroup = Process.THREAD_GROUP_DEFAULT;
16540 app.adjType = "instrumentation";
16541 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16542 } else if ((queue = isReceivingBroadcast(app)) != null) {
16543 // An app that is currently receiving a broadcast also
16544 // counts as being in the foreground for OOM killer purposes.
16545 // It's placed in a sched group based on the nature of the
16546 // broadcast as reflected by which queue it's active in.
16547 adj = ProcessList.FOREGROUND_APP_ADJ;
16548 schedGroup = (queue == mFgBroadcastQueue)
16549 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16550 app.adjType = "broadcast";
16551 procState = ActivityManager.PROCESS_STATE_RECEIVER;
16552 } else if (app.executingServices.size() > 0) {
16553 // An app that is currently executing a service callback also
16554 // counts as being in the foreground.
16555 adj = ProcessList.FOREGROUND_APP_ADJ;
16556 schedGroup = app.execServicesFg ?
16557 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16558 app.adjType = "exec-service";
16559 procState = ActivityManager.PROCESS_STATE_SERVICE;
16560 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16562 // As far as we know the process is empty. We may change our mind later.
16563 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16564 // At this point we don't actually know the adjustment. Use the cached adj
16565 // value that the caller wants us to.
16567 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16570 app.adjType = "cch-empty";
16573 // Examine all activities if not already foreground.
16574 if (!foregroundActivities && activitiesSize > 0) {
16575 for (int j = 0; j < activitiesSize; j++) {
16576 final ActivityRecord r = app.activities.get(j);
16577 if (r.app != app) {
16578 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16583 // App has a visible activity; only upgrade adjustment.
16584 if (adj > ProcessList.VISIBLE_APP_ADJ) {
16585 adj = ProcessList.VISIBLE_APP_ADJ;
16586 app.adjType = "visible";
16588 if (procState > ActivityManager.PROCESS_STATE_TOP) {
16589 procState = ActivityManager.PROCESS_STATE_TOP;
16591 schedGroup = Process.THREAD_GROUP_DEFAULT;
16592 app.cached = false;
16594 foregroundActivities = true;
16596 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16597 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16598 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16599 app.adjType = "pausing";
16601 if (procState > ActivityManager.PROCESS_STATE_TOP) {
16602 procState = ActivityManager.PROCESS_STATE_TOP;
16604 schedGroup = Process.THREAD_GROUP_DEFAULT;
16605 app.cached = false;
16607 foregroundActivities = true;
16608 } else if (r.state == ActivityState.STOPPING) {
16609 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16610 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16611 app.adjType = "stopping";
16613 // For the process state, we will at this point consider the
16614 // process to be cached. It will be cached either as an activity
16615 // or empty depending on whether the activity is finishing. We do
16616 // this so that we can treat the process as cached for purposes of
16617 // memory trimming (determing current memory level, trim command to
16618 // send to process) since there can be an arbitrary number of stopping
16619 // processes and they should soon all go into the cached state.
16620 if (!r.finishing) {
16621 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16622 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16625 app.cached = false;
16627 foregroundActivities = true;
16629 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16630 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16631 app.adjType = "cch-act";
16637 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16638 if (app.foregroundServices) {
16639 // The user is aware of this app, so make it visible.
16640 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16641 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16642 app.cached = false;
16643 app.adjType = "fg-service";
16644 schedGroup = Process.THREAD_GROUP_DEFAULT;
16645 } else if (app.forcingToForeground != null) {
16646 // The user is aware of this app, so make it visible.
16647 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16648 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16649 app.cached = false;
16650 app.adjType = "force-fg";
16651 app.adjSource = app.forcingToForeground;
16652 schedGroup = Process.THREAD_GROUP_DEFAULT;
16656 if (app == mHeavyWeightProcess) {
16657 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16658 // We don't want to kill the current heavy-weight process.
16659 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16660 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16661 app.cached = false;
16662 app.adjType = "heavy";
16664 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16665 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16669 if (app == mHomeProcess) {
16670 if (adj > ProcessList.HOME_APP_ADJ) {
16671 // This process is hosting what we currently consider to be the
16672 // home app, so we don't want to let it go into the background.
16673 adj = ProcessList.HOME_APP_ADJ;
16674 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16675 app.cached = false;
16676 app.adjType = "home";
16678 if (procState > ActivityManager.PROCESS_STATE_HOME) {
16679 procState = ActivityManager.PROCESS_STATE_HOME;
16683 if (app == mPreviousProcess && app.activities.size() > 0) {
16684 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16685 // This was the previous process that showed UI to the user.
16686 // We want to try to keep it around more aggressively, to give
16687 // a good experience around switching between two apps.
16688 adj = ProcessList.PREVIOUS_APP_ADJ;
16689 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16690 app.cached = false;
16691 app.adjType = "previous";
16693 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16694 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16698 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16699 + " reason=" + app.adjType);
16701 // By default, we use the computed adjustment. It may be changed if
16702 // there are applications dependent on our services or providers, but
16703 // this gives us a baseline and makes sure we don't get into an
16704 // infinite recursion.
16705 app.adjSeq = mAdjSeq;
16706 app.curRawAdj = adj;
16707 app.hasStartedServices = false;
16709 if (mBackupTarget != null && app == mBackupTarget.app) {
16710 // If possible we want to avoid killing apps while they're being backed up
16711 if (adj > ProcessList.BACKUP_APP_ADJ) {
16712 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16713 adj = ProcessList.BACKUP_APP_ADJ;
16714 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16715 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16717 app.adjType = "backup";
16718 app.cached = false;
16720 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16721 procState = ActivityManager.PROCESS_STATE_BACKUP;
16725 boolean mayBeTop = false;
16727 for (int is = app.services.size()-1;
16728 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16729 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16730 || procState > ActivityManager.PROCESS_STATE_TOP);
16732 ServiceRecord s = app.services.valueAt(is);
16733 if (s.startRequested) {
16734 app.hasStartedServices = true;
16735 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16736 procState = ActivityManager.PROCESS_STATE_SERVICE;
16738 if (app.hasShownUi && app != mHomeProcess) {
16739 // If this process has shown some UI, let it immediately
16740 // go to the LRU list because it may be pretty heavy with
16741 // UI stuff. We'll tag it with a label just to help
16742 // debug and understand what is going on.
16743 if (adj > ProcessList.SERVICE_ADJ) {
16744 app.adjType = "cch-started-ui-services";
16747 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16748 // This service has seen some activity within
16749 // recent memory, so we will keep its process ahead
16750 // of the background processes.
16751 if (adj > ProcessList.SERVICE_ADJ) {
16752 adj = ProcessList.SERVICE_ADJ;
16753 app.adjType = "started-services";
16754 app.cached = false;
16757 // If we have let the service slide into the background
16758 // state, still have some text describing what it is doing
16759 // even though the service no longer has an impact.
16760 if (adj > ProcessList.SERVICE_ADJ) {
16761 app.adjType = "cch-started-services";
16765 for (int conni = s.connections.size()-1;
16766 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16767 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16768 || procState > ActivityManager.PROCESS_STATE_TOP);
16770 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16772 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16773 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16774 || procState > ActivityManager.PROCESS_STATE_TOP);
16776 // XXX should compute this based on the max of
16777 // all connected clients.
16778 ConnectionRecord cr = clist.get(i);
16779 if (cr.binding.client == app) {
16780 // Binding to ourself is not interesting.
16783 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16784 ProcessRecord client = cr.binding.client;
16785 int clientAdj = computeOomAdjLocked(client, cachedAdj,
16786 TOP_APP, doingAll, now);
16787 int clientProcState = client.curProcState;
16788 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16789 // If the other app is cached for any reason, for purposes here
16790 // we are going to consider it empty. The specific cached state
16791 // doesn't propagate except under certain conditions.
16792 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16794 String adjType = null;
16795 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16796 // Not doing bind OOM management, so treat
16797 // this guy more like a started service.
16798 if (app.hasShownUi && app != mHomeProcess) {
16799 // If this process has shown some UI, let it immediately
16800 // go to the LRU list because it may be pretty heavy with
16801 // UI stuff. We'll tag it with a label just to help
16802 // debug and understand what is going on.
16803 if (adj > clientAdj) {
16804 adjType = "cch-bound-ui-services";
16806 app.cached = false;
16808 clientProcState = procState;
16810 if (now >= (s.lastActivity
16811 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16812 // This service has not seen activity within
16813 // recent memory, so allow it to drop to the
16814 // LRU list if there is no other reason to keep
16815 // it around. We'll also tag it with a label just
16816 // to help debug and undertand what is going on.
16817 if (adj > clientAdj) {
16818 adjType = "cch-bound-services";
16824 if (adj > clientAdj) {
16825 // If this process has recently shown UI, and
16826 // the process that is binding to it is less
16827 // important than being visible, then we don't
16828 // care about the binding as much as we care
16829 // about letting this process get into the LRU
16830 // list to be killed and restarted if needed for
16832 if (app.hasShownUi && app != mHomeProcess
16833 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16834 adjType = "cch-bound-ui-services";
16836 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16837 |Context.BIND_IMPORTANT)) != 0) {
16838 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
16839 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
16840 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16841 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16842 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16843 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16844 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16847 if (adj > ProcessList.VISIBLE_APP_ADJ) {
16848 adj = ProcessList.VISIBLE_APP_ADJ;
16851 if (!client.cached) {
16852 app.cached = false;
16854 adjType = "service";
16857 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16858 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16859 schedGroup = Process.THREAD_GROUP_DEFAULT;
16861 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16862 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16863 // Special handling of clients who are in the top state.
16864 // We *may* want to consider this process to be in the
16865 // top state as well, but only if there is not another
16866 // reason for it to be running. Being on the top is a
16867 // special state, meaning you are specifically running
16868 // for the current top app. If the process is already
16869 // running in the background for some other reason, it
16870 // is more important to continue considering it to be
16871 // in the background state.
16873 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16875 // Special handling for above-top states (persistent
16876 // processes). These should not bring the current process
16877 // into the top state, since they are not on top. Instead
16878 // give them the best state after that.
16880 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16884 if (clientProcState <
16885 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16887 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16890 if (procState > clientProcState) {
16891 procState = clientProcState;
16893 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16894 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16895 app.pendingUiClean = true;
16897 if (adjType != null) {
16898 app.adjType = adjType;
16899 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16900 .REASON_SERVICE_IN_USE;
16901 app.adjSource = cr.binding.client;
16902 app.adjSourceProcState = clientProcState;
16903 app.adjTarget = s.name;
16906 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16907 app.treatLikeActivity = true;
16909 final ActivityRecord a = cr.activity;
16910 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16911 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16912 (a.visible || a.state == ActivityState.RESUMED
16913 || a.state == ActivityState.PAUSING)) {
16914 adj = ProcessList.FOREGROUND_APP_ADJ;
16915 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16916 schedGroup = Process.THREAD_GROUP_DEFAULT;
16918 app.cached = false;
16919 app.adjType = "service";
16920 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16921 .REASON_SERVICE_IN_USE;
16923 app.adjSourceProcState = procState;
16924 app.adjTarget = s.name;
16931 for (int provi = app.pubProviders.size()-1;
16932 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16933 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16934 || procState > ActivityManager.PROCESS_STATE_TOP);
16936 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16937 for (int i = cpr.connections.size()-1;
16938 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16939 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16940 || procState > ActivityManager.PROCESS_STATE_TOP);
16942 ContentProviderConnection conn = cpr.connections.get(i);
16943 ProcessRecord client = conn.client;
16944 if (client == app) {
16945 // Being our own client is not interesting.
16948 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16949 int clientProcState = client.curProcState;
16950 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16951 // If the other app is cached for any reason, for purposes here
16952 // we are going to consider it empty.
16953 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16955 if (adj > clientAdj) {
16956 if (app.hasShownUi && app != mHomeProcess
16957 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16958 app.adjType = "cch-ui-provider";
16960 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16961 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16962 app.adjType = "provider";
16964 app.cached &= client.cached;
16965 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16966 .REASON_PROVIDER_IN_USE;
16967 app.adjSource = client;
16968 app.adjSourceProcState = clientProcState;
16969 app.adjTarget = cpr.name;
16971 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16972 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16973 // Special handling of clients who are in the top state.
16974 // We *may* want to consider this process to be in the
16975 // top state as well, but only if there is not another
16976 // reason for it to be running. Being on the top is a
16977 // special state, meaning you are specifically running
16978 // for the current top app. If the process is already
16979 // running in the background for some other reason, it
16980 // is more important to continue considering it to be
16981 // in the background state.
16983 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16985 // Special handling for above-top states (persistent
16986 // processes). These should not bring the current process
16987 // into the top state, since they are not on top. Instead
16988 // give them the best state after that.
16990 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16993 if (procState > clientProcState) {
16994 procState = clientProcState;
16996 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16997 schedGroup = Process.THREAD_GROUP_DEFAULT;
17000 // If the provider has external (non-framework) process
17001 // dependencies, ensure that its adjustment is at least
17002 // FOREGROUND_APP_ADJ.
17003 if (cpr.hasExternalProcessHandles()) {
17004 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
17005 adj = ProcessList.FOREGROUND_APP_ADJ;
17006 schedGroup = Process.THREAD_GROUP_DEFAULT;
17007 app.cached = false;
17008 app.adjType = "provider";
17009 app.adjTarget = cpr.name;
17011 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
17012 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17017 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
17018 // A client of one of our services or providers is in the top state. We
17019 // *may* want to be in the top state, but not if we are already running in
17020 // the background for some other reason. For the decision here, we are going
17021 // to pick out a few specific states that we want to remain in when a client
17022 // is top (states that tend to be longer-term) and otherwise allow it to go
17023 // to the top state.
17024 switch (procState) {
17025 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
17026 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
17027 case ActivityManager.PROCESS_STATE_SERVICE:
17028 // These all are longer-term states, so pull them up to the top
17029 // of the background states, but not all the way to the top state.
17030 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17033 // Otherwise, top is a better choice, so take it.
17034 procState = ActivityManager.PROCESS_STATE_TOP;
17039 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
17040 if (app.hasClientActivities) {
17041 // This is a cached process, but with client activities. Mark it so.
17042 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
17043 app.adjType = "cch-client-act";
17044 } else if (app.treatLikeActivity) {
17045 // This is a cached process, but somebody wants us to treat it like it has
17046 // an activity, okay!
17047 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17048 app.adjType = "cch-as-act";
17052 if (adj == ProcessList.SERVICE_ADJ) {
17054 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
17055 mNewNumServiceProcs++;
17056 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
17057 if (!app.serviceb) {
17058 // This service isn't far enough down on the LRU list to
17059 // normally be a B service, but if we are low on RAM and it
17060 // is large we want to force it down since we would prefer to
17061 // keep launcher over it.
17062 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
17063 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
17064 app.serviceHighRam = true;
17065 app.serviceb = true;
17066 //Slog.i(TAG, "ADJ " + app + " high ram!");
17068 mNewNumAServiceProcs++;
17069 //Slog.i(TAG, "ADJ " + app + " not high ram!");
17072 app.serviceHighRam = false;
17075 if (app.serviceb) {
17076 adj = ProcessList.SERVICE_B_ADJ;
17080 app.curRawAdj = adj;
17082 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
17083 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
17084 if (adj > app.maxAdj) {
17086 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
17087 schedGroup = Process.THREAD_GROUP_DEFAULT;
17091 // Do final modification to adj. Everything we do between here and applying
17092 // the final setAdj must be done in this function, because we will also use
17093 // it when computing the final cached adj later. Note that we don't need to
17094 // worry about this for max adj above, since max adj will always be used to
17095 // keep it out of the cached vaues.
17096 app.curAdj = app.modifyRawOomAdj(adj);
17097 app.curSchedGroup = schedGroup;
17098 app.curProcState = procState;
17099 app.foregroundActivities = foregroundActivities;
17101 return app.curRawAdj;
17105 * Schedule PSS collection of a process.
17107 void requestPssLocked(ProcessRecord proc, int procState) {
17108 if (mPendingPssProcesses.contains(proc)) {
17111 if (mPendingPssProcesses.size() == 0) {
17112 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17114 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
17115 proc.pssProcState = procState;
17116 mPendingPssProcesses.add(proc);
17120 * Schedule PSS collection of all processes.
17122 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
17124 if (now < (mLastFullPssTime +
17125 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
17129 if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs! memLowered=" + memLowered);
17130 mLastFullPssTime = now;
17131 mFullPssPending = true;
17132 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
17133 mPendingPssProcesses.clear();
17134 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17135 ProcessRecord app = mLruProcesses.get(i);
17136 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
17137 app.pssProcState = app.setProcState;
17138 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17139 isSleeping(), now);
17140 mPendingPssProcesses.add(app);
17143 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
17147 * Ask a given process to GC right now.
17149 final void performAppGcLocked(ProcessRecord app) {
17151 app.lastRequestedGc = SystemClock.uptimeMillis();
17152 if (app.thread != null) {
17153 if (app.reportLowMemory) {
17154 app.reportLowMemory = false;
17155 app.thread.scheduleLowMemory();
17157 app.thread.processInBackground();
17160 } catch (Exception e) {
17166 * Returns true if things are idle enough to perform GCs.
17168 private final boolean canGcNowLocked() {
17169 boolean processingBroadcasts = false;
17170 for (BroadcastQueue q : mBroadcastQueues) {
17171 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
17172 processingBroadcasts = true;
17175 return !processingBroadcasts
17176 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
17180 * Perform GCs on all processes that are waiting for it, but only
17181 * if things are idle.
17183 final void performAppGcsLocked() {
17184 final int N = mProcessesToGc.size();
17188 if (canGcNowLocked()) {
17189 while (mProcessesToGc.size() > 0) {
17190 ProcessRecord proc = mProcessesToGc.remove(0);
17191 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
17192 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
17193 <= SystemClock.uptimeMillis()) {
17194 // To avoid spamming the system, we will GC processes one
17195 // at a time, waiting a few seconds between each.
17196 performAppGcLocked(proc);
17197 scheduleAppGcsLocked();
17200 // It hasn't been long enough since we last GCed this
17201 // process... put it in the list to wait for its time.
17202 addProcessToGcListLocked(proc);
17208 scheduleAppGcsLocked();
17213 * If all looks good, perform GCs on all processes waiting for them.
17215 final void performAppGcsIfAppropriateLocked() {
17216 if (canGcNowLocked()) {
17217 performAppGcsLocked();
17220 // Still not idle, wait some more.
17221 scheduleAppGcsLocked();
17225 * Schedule the execution of all pending app GCs.
17227 final void scheduleAppGcsLocked() {
17228 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
17230 if (mProcessesToGc.size() > 0) {
17231 // Schedule a GC for the time to the next process.
17232 ProcessRecord proc = mProcessesToGc.get(0);
17233 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
17235 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
17236 long now = SystemClock.uptimeMillis();
17237 if (when < (now+GC_TIMEOUT)) {
17238 when = now + GC_TIMEOUT;
17240 mHandler.sendMessageAtTime(msg, when);
17245 * Add a process to the array of processes waiting to be GCed. Keeps the
17246 * list in sorted order by the last GC time. The process can't already be
17249 final void addProcessToGcListLocked(ProcessRecord proc) {
17250 boolean added = false;
17251 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
17252 if (mProcessesToGc.get(i).lastRequestedGc <
17253 proc.lastRequestedGc) {
17255 mProcessesToGc.add(i+1, proc);
17260 mProcessesToGc.add(0, proc);
17265 * Set up to ask a process to GC itself. This will either do it
17266 * immediately, or put it on the list of processes to gc the next
17267 * time things are idle.
17269 final void scheduleAppGcLocked(ProcessRecord app) {
17270 long now = SystemClock.uptimeMillis();
17271 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
17274 if (!mProcessesToGc.contains(app)) {
17275 addProcessToGcListLocked(app);
17276 scheduleAppGcsLocked();
17280 final void checkExcessivePowerUsageLocked(boolean doKills) {
17281 updateCpuStatsNow();
17283 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17284 boolean doWakeKills = doKills;
17285 boolean doCpuKills = doKills;
17286 if (mLastPowerCheckRealtime == 0) {
17287 doWakeKills = false;
17289 if (mLastPowerCheckUptime == 0) {
17290 doCpuKills = false;
17292 if (stats.isScreenOn()) {
17293 doWakeKills = false;
17295 final long curRealtime = SystemClock.elapsedRealtime();
17296 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
17297 final long curUptime = SystemClock.uptimeMillis();
17298 final long uptimeSince = curUptime - mLastPowerCheckUptime;
17299 mLastPowerCheckRealtime = curRealtime;
17300 mLastPowerCheckUptime = curUptime;
17301 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
17302 doWakeKills = false;
17304 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
17305 doCpuKills = false;
17307 int i = mLruProcesses.size();
17310 ProcessRecord app = mLruProcesses.get(i);
17311 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17313 synchronized (stats) {
17314 wtime = stats.getProcessWakeTime(app.info.uid,
17315 app.pid, curRealtime);
17317 long wtimeUsed = wtime - app.lastWakeTime;
17318 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
17320 StringBuilder sb = new StringBuilder(128);
17321 sb.append("Wake for ");
17322 app.toShortString(sb);
17323 sb.append(": over ");
17324 TimeUtils.formatDuration(realtimeSince, sb);
17325 sb.append(" used ");
17326 TimeUtils.formatDuration(wtimeUsed, sb);
17328 sb.append((wtimeUsed*100)/realtimeSince);
17330 Slog.i(TAG, sb.toString());
17332 sb.append("CPU for ");
17333 app.toShortString(sb);
17334 sb.append(": over ");
17335 TimeUtils.formatDuration(uptimeSince, sb);
17336 sb.append(" used ");
17337 TimeUtils.formatDuration(cputimeUsed, sb);
17339 sb.append((cputimeUsed*100)/uptimeSince);
17341 Slog.i(TAG, sb.toString());
17343 // If a process has held a wake lock for more
17344 // than 50% of the time during this period,
17345 // that sounds bad. Kill!
17346 if (doWakeKills && realtimeSince > 0
17347 && ((wtimeUsed*100)/realtimeSince) >= 50) {
17348 synchronized (stats) {
17349 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
17350 realtimeSince, wtimeUsed);
17352 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
17353 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
17354 } else if (doCpuKills && uptimeSince > 0
17355 && ((cputimeUsed*100)/uptimeSince) >= 25) {
17356 synchronized (stats) {
17357 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
17358 uptimeSince, cputimeUsed);
17360 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
17361 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
17363 app.lastWakeTime = wtime;
17364 app.lastCpuTime = app.curCpuTime;
17370 private final boolean applyOomAdjLocked(ProcessRecord app,
17371 ProcessRecord TOP_APP, boolean doingAll, long now) {
17372 boolean success = true;
17374 if (app.curRawAdj != app.setRawAdj) {
17375 app.setRawAdj = app.curRawAdj;
17380 if (app.curAdj != app.setAdj) {
17381 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17382 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17383 TAG, "Set " + app.pid + " " + app.processName +
17384 " adj " + app.curAdj + ": " + app.adjType);
17385 app.setAdj = app.curAdj;
17388 if (app.setSchedGroup != app.curSchedGroup) {
17389 app.setSchedGroup = app.curSchedGroup;
17390 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17391 "Setting process group of " + app.processName
17392 + " to " + app.curSchedGroup);
17393 if (app.waitingToKill != null &&
17394 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17395 app.kill(app.waitingToKill, true);
17399 long oldId = Binder.clearCallingIdentity();
17401 Process.setProcessGroup(app.pid, app.curSchedGroup);
17402 } catch (Exception e) {
17403 Slog.w(TAG, "Failed setting process group of " + app.pid
17404 + " to " + app.curSchedGroup);
17405 e.printStackTrace();
17407 Binder.restoreCallingIdentity(oldId);
17410 if (app.thread != null) {
17412 app.thread.setSchedulingGroup(app.curSchedGroup);
17413 } catch (RemoteException e) {
17417 Process.setSwappiness(app.pid,
17418 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17421 if (app.repForegroundActivities != app.foregroundActivities) {
17422 app.repForegroundActivities = app.foregroundActivities;
17423 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17425 if (app.repProcState != app.curProcState) {
17426 app.repProcState = app.curProcState;
17427 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17428 if (app.thread != null) {
17431 //RuntimeException h = new RuntimeException("here");
17432 Slog.i(TAG, "Sending new process state " + app.repProcState
17433 + " to " + app /*, h*/);
17435 app.thread.setProcessState(app.repProcState);
17436 } catch (RemoteException e) {
17440 if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17441 app.setProcState)) {
17442 app.lastStateTime = now;
17443 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17444 isSleeping(), now);
17445 if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17446 + ProcessList.makeProcStateString(app.setProcState) + " to "
17447 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17448 + (app.nextPssTime-now) + ": " + app);
17450 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17451 && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17452 requestPssLocked(app, app.setProcState);
17453 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17454 isSleeping(), now);
17455 } else if (false && DEBUG_PSS) {
17456 Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17459 if (app.setProcState != app.curProcState) {
17460 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17461 "Proc state change of " + app.processName
17462 + " to " + app.curProcState);
17463 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17464 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17465 if (setImportant && !curImportant) {
17466 // This app is no longer something we consider important enough to allow to
17467 // use arbitrary amounts of battery power. Note
17468 // its current wake lock time to later know to kill it if
17469 // it is not behaving well.
17470 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17471 synchronized (stats) {
17472 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17473 app.pid, SystemClock.elapsedRealtime());
17475 app.lastCpuTime = app.curCpuTime;
17478 app.setProcState = app.curProcState;
17479 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17480 app.notCachedSinceIdle = false;
17483 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17485 app.procStateChanged = true;
17489 if (changes != 0) {
17490 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17491 int i = mPendingProcessChanges.size()-1;
17492 ProcessChangeItem item = null;
17494 item = mPendingProcessChanges.get(i);
17495 if (item.pid == app.pid) {
17496 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17502 // No existing item in pending changes; need a new one.
17503 final int NA = mAvailProcessChanges.size();
17505 item = mAvailProcessChanges.remove(NA-1);
17506 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17508 item = new ProcessChangeItem();
17509 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17512 item.pid = app.pid;
17513 item.uid = app.info.uid;
17514 if (mPendingProcessChanges.size() == 0) {
17515 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17516 "*** Enqueueing dispatch processes changed!");
17517 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17519 mPendingProcessChanges.add(item);
17521 item.changes |= changes;
17522 item.processState = app.repProcState;
17523 item.foregroundActivities = app.repForegroundActivities;
17524 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17525 + Integer.toHexString(System.identityHashCode(item))
17526 + " " + app.toShortString() + ": changes=" + item.changes
17527 + " procState=" + item.processState
17528 + " foreground=" + item.foregroundActivities
17529 + " type=" + app.adjType + " source=" + app.adjSource
17530 + " target=" + app.adjTarget);
17536 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17537 if (proc.thread != null) {
17538 if (proc.baseProcessTracker != null) {
17539 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17541 if (proc.repProcState >= 0) {
17542 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17543 proc.repProcState);
17548 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17549 ProcessRecord TOP_APP, boolean doingAll, long now) {
17550 if (app.thread == null) {
17554 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17556 return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17559 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17561 if (isForeground != proc.foregroundServices) {
17562 proc.foregroundServices = isForeground;
17563 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17565 if (isForeground) {
17566 if (curProcs == null) {
17567 curProcs = new ArrayList<ProcessRecord>();
17568 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17570 if (!curProcs.contains(proc)) {
17571 curProcs.add(proc);
17572 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17573 proc.info.packageName, proc.info.uid);
17576 if (curProcs != null) {
17577 if (curProcs.remove(proc)) {
17578 mBatteryStatsService.noteEvent(
17579 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17580 proc.info.packageName, proc.info.uid);
17581 if (curProcs.size() <= 0) {
17582 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17588 updateOomAdjLocked();
17593 private final ActivityRecord resumedAppLocked() {
17594 ActivityRecord act = mStackSupervisor.resumedAppLocked();
17598 pkg = act.packageName;
17599 uid = act.info.applicationInfo.uid;
17604 // Has the UID or resumed package name changed?
17605 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17606 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17607 if (mCurResumedPackage != null) {
17608 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17609 mCurResumedPackage, mCurResumedUid);
17611 mCurResumedPackage = pkg;
17612 mCurResumedUid = uid;
17613 if (mCurResumedPackage != null) {
17614 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17615 mCurResumedPackage, mCurResumedUid);
17621 final boolean updateOomAdjLocked(ProcessRecord app) {
17622 final ActivityRecord TOP_ACT = resumedAppLocked();
17623 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17624 final boolean wasCached = app.cached;
17628 // This is the desired cached adjusment we want to tell it to use.
17629 // If our app is currently cached, we know it, and that is it. Otherwise,
17630 // we don't know it yet, and it needs to now be cached we will then
17631 // need to do a complete oom adj.
17632 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17633 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17634 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17635 SystemClock.uptimeMillis());
17636 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17637 // Changed to/from cached state, so apps after it in the LRU
17638 // list may also be changed.
17639 updateOomAdjLocked();
17644 final void updateOomAdjLocked() {
17645 final ActivityRecord TOP_ACT = resumedAppLocked();
17646 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17647 final long now = SystemClock.uptimeMillis();
17648 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17649 final int N = mLruProcesses.size();
17652 RuntimeException e = new RuntimeException();
17653 e.fillInStackTrace();
17654 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17658 mNewNumServiceProcs = 0;
17659 mNewNumAServiceProcs = 0;
17661 final int emptyProcessLimit;
17662 final int cachedProcessLimit;
17663 if (mProcessLimit <= 0) {
17664 emptyProcessLimit = cachedProcessLimit = 0;
17665 } else if (mProcessLimit == 1) {
17666 emptyProcessLimit = 1;
17667 cachedProcessLimit = 0;
17669 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17670 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17673 // Let's determine how many processes we have running vs.
17674 // how many slots we have for background processes; we may want
17675 // to put multiple processes in a slot of there are enough of
17677 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17678 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17679 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17680 if (numEmptyProcs > cachedProcessLimit) {
17681 // If there are more empty processes than our limit on cached
17682 // processes, then use the cached process limit for the factor.
17683 // This ensures that the really old empty processes get pushed
17684 // down to the bottom, so if we are running low on memory we will
17685 // have a better chance at keeping around more cached processes
17686 // instead of a gazillion empty processes.
17687 numEmptyProcs = cachedProcessLimit;
17689 int emptyFactor = numEmptyProcs/numSlots;
17690 if (emptyFactor < 1) emptyFactor = 1;
17691 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17692 if (cachedFactor < 1) cachedFactor = 1;
17693 int stepCached = 0;
17697 int numTrimming = 0;
17699 mNumNonCachedProcs = 0;
17700 mNumCachedHiddenProcs = 0;
17702 // First update the OOM adjustment for each of the
17703 // application processes based on their current state.
17704 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17705 int nextCachedAdj = curCachedAdj+1;
17706 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17707 int nextEmptyAdj = curEmptyAdj+2;
17708 for (int i=N-1; i>=0; i--) {
17709 ProcessRecord app = mLruProcesses.get(i);
17710 if (!app.killedByAm && app.thread != null) {
17711 app.procStateChanged = false;
17712 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17714 // If we haven't yet assigned the final cached adj
17715 // to the process, do that now.
17716 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17717 switch (app.curProcState) {
17718 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17719 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17720 // This process is a cached process holding activities...
17721 // assign it the next cached value for that type, and then
17722 // step that cached level.
17723 app.curRawAdj = curCachedAdj;
17724 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17725 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17726 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17728 if (curCachedAdj != nextCachedAdj) {
17730 if (stepCached >= cachedFactor) {
17732 curCachedAdj = nextCachedAdj;
17733 nextCachedAdj += 2;
17734 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17735 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17741 // For everything else, assign next empty cached process
17742 // level and bump that up. Note that this means that
17743 // long-running services that have dropped down to the
17744 // cached level will be treated as empty (since their process
17745 // state is still as a service), which is what we want.
17746 app.curRawAdj = curEmptyAdj;
17747 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17748 if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17749 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17751 if (curEmptyAdj != nextEmptyAdj) {
17753 if (stepEmpty >= emptyFactor) {
17755 curEmptyAdj = nextEmptyAdj;
17757 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17758 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17766 applyOomAdjLocked(app, TOP_APP, true, now);
17768 // Count the number of process types.
17769 switch (app.curProcState) {
17770 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17771 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17772 mNumCachedHiddenProcs++;
17774 if (numCached > cachedProcessLimit) {
17775 app.kill("cached #" + numCached, true);
17778 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17779 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17780 && app.lastActivityTime < oldTime) {
17781 app.kill("empty for "
17782 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17783 / 1000) + "s", true);
17786 if (numEmpty > emptyProcessLimit) {
17787 app.kill("empty #" + numEmpty, true);
17792 mNumNonCachedProcs++;
17796 if (app.isolated && app.services.size() <= 0) {
17797 // If this is an isolated process, and there are no
17798 // services running in it, then the process is no longer
17799 // needed. We agressively kill these because we can by
17800 // definition not re-use the same process again, and it is
17801 // good to avoid having whatever code was running in them
17802 // left sitting around after no longer needed.
17803 app.kill("isolated not needed", true);
17806 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17807 && !app.killedByAm) {
17813 mNumServiceProcs = mNewNumServiceProcs;
17815 // Now determine the memory trimming level of background processes.
17816 // Unfortunately we need to start at the back of the list to do this
17817 // properly. We only do this if the number of background apps we
17818 // are managing to keep around is less than half the maximum we desire;
17819 // if we are keeping a good number around, we'll let them use whatever
17820 // memory they want.
17821 final int numCachedAndEmpty = numCached + numEmpty;
17823 if (numCached <= ProcessList.TRIM_CACHED_APPS
17824 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17825 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17826 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17827 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17828 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17830 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17833 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17835 // We always allow the memory level to go up (better). We only allow it to go
17836 // down if we are in a state where that is allowed, *and* the total number of processes
17837 // has gone down since last time.
17838 if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17839 + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17840 + " last=" + mLastNumProcesses);
17841 if (memFactor > mLastMemoryLevel) {
17842 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17843 memFactor = mLastMemoryLevel;
17844 if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17847 mLastMemoryLevel = memFactor;
17848 mLastNumProcesses = mLruProcesses.size();
17849 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17850 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17851 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17852 if (mLowRamStartTime == 0) {
17853 mLowRamStartTime = now;
17857 switch (memFactor) {
17858 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17859 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17861 case ProcessStats.ADJ_MEM_FACTOR_LOW:
17862 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17865 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17868 int factor = numTrimming/3;
17870 if (mHomeProcess != null) minFactor++;
17871 if (mPreviousProcess != null) minFactor++;
17872 if (factor < minFactor) factor = minFactor;
17873 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17874 for (int i=N-1; i>=0; i--) {
17875 ProcessRecord app = mLruProcesses.get(i);
17876 if (allChanged || app.procStateChanged) {
17877 setProcessTrackerStateLocked(app, trackerMemFactor, now);
17878 app.procStateChanged = false;
17880 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17881 && !app.killedByAm) {
17882 if (app.trimMemoryLevel < curLevel && app.thread != null) {
17884 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17885 "Trimming memory of " + app.processName
17886 + " to " + curLevel);
17887 app.thread.scheduleTrimMemory(curLevel);
17888 } catch (RemoteException e) {
17891 // For now we won't do this; our memory trimming seems
17892 // to be good enough at this point that destroying
17893 // activities causes more harm than good.
17894 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17895 && app != mHomeProcess && app != mPreviousProcess) {
17896 // Need to do this on its own message because the stack may not
17897 // be in a consistent state at this point.
17898 // For these apps we will also finish their activities
17899 // to help them free memory.
17900 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17904 app.trimMemoryLevel = curLevel;
17906 if (step >= factor) {
17908 switch (curLevel) {
17909 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17910 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17912 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17913 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17917 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17918 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17919 && app.thread != null) {
17921 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17922 "Trimming memory of heavy-weight " + app.processName
17923 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17924 app.thread.scheduleTrimMemory(
17925 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17926 } catch (RemoteException e) {
17929 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17931 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17932 || app.systemNoUi) && app.pendingUiClean) {
17933 // If this application is now in the background and it
17934 // had done UI, then give it the special trim level to
17935 // have it free UI resources.
17936 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17937 if (app.trimMemoryLevel < level && app.thread != null) {
17939 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17940 "Trimming memory of bg-ui " + app.processName
17942 app.thread.scheduleTrimMemory(level);
17943 } catch (RemoteException e) {
17946 app.pendingUiClean = false;
17948 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17950 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17951 "Trimming memory of fg " + app.processName
17952 + " to " + fgTrimLevel);
17953 app.thread.scheduleTrimMemory(fgTrimLevel);
17954 } catch (RemoteException e) {
17957 app.trimMemoryLevel = fgTrimLevel;
17961 if (mLowRamStartTime != 0) {
17962 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17963 mLowRamStartTime = 0;
17965 for (int i=N-1; i>=0; i--) {
17966 ProcessRecord app = mLruProcesses.get(i);
17967 if (allChanged || app.procStateChanged) {
17968 setProcessTrackerStateLocked(app, trackerMemFactor, now);
17969 app.procStateChanged = false;
17971 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17972 || app.systemNoUi) && app.pendingUiClean) {
17973 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17974 && app.thread != null) {
17976 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17977 "Trimming memory of ui hidden " + app.processName
17978 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17979 app.thread.scheduleTrimMemory(
17980 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17981 } catch (RemoteException e) {
17984 app.pendingUiClean = false;
17986 app.trimMemoryLevel = 0;
17990 if (mAlwaysFinishActivities) {
17991 // Need to do this on its own message because the stack may not
17992 // be in a consistent state at this point.
17993 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17997 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
18000 if (mProcessStats.shouldWriteNowLocked(now)) {
18001 mHandler.post(new Runnable() {
18002 @Override public void run() {
18003 synchronized (ActivityManagerService.this) {
18004 mProcessStats.writeStateAsyncLocked();
18010 if (DEBUG_OOM_ADJ) {
18012 RuntimeException here = new RuntimeException("here");
18013 here.fillInStackTrace();
18014 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms", here);
18016 Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
18021 final void trimApplications() {
18022 synchronized (this) {
18025 // First remove any unused application processes whose package
18026 // has been removed.
18027 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
18028 final ProcessRecord app = mRemovedProcesses.get(i);
18029 if (app.activities.size() == 0
18030 && app.curReceiver == null && app.services.size() == 0) {
18032 TAG, "Exiting empty application process "
18033 + app.processName + " ("
18034 + (app.thread != null ? app.thread.asBinder() : null)
18036 if (app.pid > 0 && app.pid != MY_PID) {
18037 app.kill("empty", false);
18040 app.thread.scheduleExit();
18041 } catch (Exception e) {
18042 // Ignore exceptions.
18045 cleanUpApplicationRecordLocked(app, false, true, -1);
18046 mRemovedProcesses.remove(i);
18048 if (app.persistent) {
18049 addAppLocked(app.info, false, null /* ABI override */);
18054 // Now update the oom adj for all processes.
18055 updateOomAdjLocked();
18059 /** This method sends the specified signal to each of the persistent apps */
18060 public void signalPersistentProcesses(int sig) throws RemoteException {
18061 if (sig != Process.SIGNAL_USR1) {
18062 throw new SecurityException("Only SIGNAL_USR1 is allowed");
18065 synchronized (this) {
18066 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
18067 != PackageManager.PERMISSION_GRANTED) {
18068 throw new SecurityException("Requires permission "
18069 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
18072 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
18073 ProcessRecord r = mLruProcesses.get(i);
18074 if (r.thread != null && r.persistent) {
18075 Process.sendSignal(r.pid, sig);
18081 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
18082 if (proc == null || proc == mProfileProc) {
18083 proc = mProfileProc;
18084 profileType = mProfileType;
18085 clearProfilerLocked();
18087 if (proc == null) {
18091 proc.thread.profilerControl(false, null, profileType);
18092 } catch (RemoteException e) {
18093 throw new IllegalStateException("Process disappeared");
18097 private void clearProfilerLocked() {
18098 if (mProfileFd != null) {
18100 mProfileFd.close();
18101 } catch (IOException e) {
18104 mProfileApp = null;
18105 mProfileProc = null;
18106 mProfileFile = null;
18108 mAutoStopProfiler = false;
18109 mSamplingInterval = 0;
18112 public boolean profileControl(String process, int userId, boolean start,
18113 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
18116 synchronized (this) {
18117 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18118 // its own permission.
18119 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18120 != PackageManager.PERMISSION_GRANTED) {
18121 throw new SecurityException("Requires permission "
18122 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18125 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
18126 throw new IllegalArgumentException("null profile info or fd");
18129 ProcessRecord proc = null;
18130 if (process != null) {
18131 proc = findProcessLocked(process, userId, "profileControl");
18134 if (start && (proc == null || proc.thread == null)) {
18135 throw new IllegalArgumentException("Unknown process: " + process);
18139 stopProfilerLocked(null, 0);
18140 setProfileApp(proc.info, proc.processName, profilerInfo);
18141 mProfileProc = proc;
18142 mProfileType = profileType;
18143 ParcelFileDescriptor fd = profilerInfo.profileFd;
18146 } catch (IOException e) {
18149 profilerInfo.profileFd = fd;
18150 proc.thread.profilerControl(start, profilerInfo, profileType);
18154 stopProfilerLocked(proc, profileType);
18155 if (profilerInfo != null && profilerInfo.profileFd != null) {
18157 profilerInfo.profileFd.close();
18158 } catch (IOException e) {
18165 } catch (RemoteException e) {
18166 throw new IllegalStateException("Process disappeared");
18168 if (profilerInfo != null && profilerInfo.profileFd != null) {
18170 profilerInfo.profileFd.close();
18171 } catch (IOException e) {
18177 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
18178 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18179 userId, true, ALLOW_FULL_ONLY, callName, null);
18180 ProcessRecord proc = null;
18182 int pid = Integer.parseInt(process);
18183 synchronized (mPidsSelfLocked) {
18184 proc = mPidsSelfLocked.get(pid);
18186 } catch (NumberFormatException e) {
18189 if (proc == null) {
18190 ArrayMap<String, SparseArray<ProcessRecord>> all
18191 = mProcessNames.getMap();
18192 SparseArray<ProcessRecord> procs = all.get(process);
18193 if (procs != null && procs.size() > 0) {
18194 proc = procs.valueAt(0);
18195 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
18196 for (int i=1; i<procs.size(); i++) {
18197 ProcessRecord thisProc = procs.valueAt(i);
18198 if (thisProc.userId == userId) {
18210 public boolean dumpHeap(String process, int userId, boolean managed,
18211 String path, ParcelFileDescriptor fd) throws RemoteException {
18214 synchronized (this) {
18215 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
18216 // its own permission (same as profileControl).
18217 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
18218 != PackageManager.PERMISSION_GRANTED) {
18219 throw new SecurityException("Requires permission "
18220 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
18224 throw new IllegalArgumentException("null fd");
18227 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
18228 if (proc == null || proc.thread == null) {
18229 throw new IllegalArgumentException("Unknown process: " + process);
18232 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18233 if (!isDebuggable) {
18234 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
18235 throw new SecurityException("Process not debuggable: " + proc);
18239 proc.thread.dumpHeap(managed, path, fd);
18243 } catch (RemoteException e) {
18244 throw new IllegalStateException("Process disappeared");
18249 } catch (IOException e) {
18255 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
18256 public void monitor() {
18257 synchronized (this) { }
18260 void onCoreSettingsChange(Bundle settings) {
18261 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18262 ProcessRecord processRecord = mLruProcesses.get(i);
18264 if (processRecord.thread != null) {
18265 processRecord.thread.setCoreSettings(settings);
18267 } catch (RemoteException re) {
18273 // Multi-user methods
18276 * Start user, if its not already running, but don't bring it to foreground.
18279 public boolean startUserInBackground(final int userId) {
18280 return startUser(userId, /* foreground */ false);
18284 * Start user, if its not already running, and bring it to foreground.
18286 boolean startUserInForeground(final int userId, Dialog dlg) {
18287 boolean result = startUser(userId, /* foreground */ true);
18293 * Refreshes the list of users related to the current user when either a
18294 * user switch happens or when a new related user is started in the
18297 private void updateCurrentProfileIdsLocked() {
18298 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18299 mCurrentUserId, false /* enabledOnly */);
18300 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
18301 for (int i = 0; i < currentProfileIds.length; i++) {
18302 currentProfileIds[i] = profiles.get(i).id;
18304 mCurrentProfileIds = currentProfileIds;
18306 synchronized (mUserProfileGroupIdsSelfLocked) {
18307 mUserProfileGroupIdsSelfLocked.clear();
18308 final List<UserInfo> users = getUserManagerLocked().getUsers(false);
18309 for (int i = 0; i < users.size(); i++) {
18310 UserInfo user = users.get(i);
18311 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
18312 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
18318 private Set getProfileIdsLocked(int userId) {
18319 Set userIds = new HashSet<Integer>();
18320 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18321 userId, false /* enabledOnly */);
18322 for (UserInfo user : profiles) {
18323 userIds.add(Integer.valueOf(user.id));
18329 public boolean switchUser(final int userId) {
18330 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18332 synchronized (this) {
18333 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18334 if (userInfo == null) {
18335 Slog.w(TAG, "No user info for user #" + userId);
18338 if (userInfo.isManagedProfile()) {
18339 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18342 userName = userInfo.name;
18343 mTargetUserId = userId;
18345 mHandler.removeMessages(START_USER_SWITCH_MSG);
18346 mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
18350 private void showUserSwitchDialog(int userId, String userName) {
18351 // The dialog will show and then initiate the user switch by calling startUserInForeground
18352 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
18353 true /* above system */);
18357 private boolean startUser(final int userId, final boolean foreground) {
18358 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18359 != PackageManager.PERMISSION_GRANTED) {
18360 String msg = "Permission Denial: switchUser() from pid="
18361 + Binder.getCallingPid()
18362 + ", uid=" + Binder.getCallingUid()
18363 + " requires " + INTERACT_ACROSS_USERS_FULL;
18365 throw new SecurityException(msg);
18368 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
18370 final long ident = Binder.clearCallingIdentity();
18372 synchronized (this) {
18373 final int oldUserId = mCurrentUserId;
18374 if (oldUserId == userId) {
18378 mStackSupervisor.setLockTaskModeLocked(null, false);
18380 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18381 if (userInfo == null) {
18382 Slog.w(TAG, "No user info for user #" + userId);
18385 if (foreground && userInfo.isManagedProfile()) {
18386 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18391 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18392 R.anim.screen_user_enter);
18395 boolean needStart = false;
18397 // If the user we are switching to is not currently started, then
18398 // we need to start it now.
18399 if (mStartedUsers.get(userId) == null) {
18400 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18401 updateStartedUserArrayLocked();
18405 final Integer userIdInt = Integer.valueOf(userId);
18406 mUserLru.remove(userIdInt);
18407 mUserLru.add(userIdInt);
18410 mCurrentUserId = userId;
18411 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
18412 updateCurrentProfileIdsLocked();
18413 mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18414 // Once the internal notion of the active user has switched, we lock the device
18415 // with the option to show the user switcher on the keyguard.
18416 mWindowManager.lockNow(null);
18418 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18419 updateCurrentProfileIdsLocked();
18420 mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18421 mUserLru.remove(currentUserIdInt);
18422 mUserLru.add(currentUserIdInt);
18425 final UserStartedState uss = mStartedUsers.get(userId);
18427 // Make sure user is in the started state. If it is currently
18428 // stopping, we need to knock that off.
18429 if (uss.mState == UserStartedState.STATE_STOPPING) {
18430 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18431 // so we can just fairly silently bring the user back from
18432 // the almost-dead.
18433 uss.mState = UserStartedState.STATE_RUNNING;
18434 updateStartedUserArrayLocked();
18436 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18437 // This means ACTION_SHUTDOWN has been sent, so we will
18438 // need to treat this as a new boot of the user.
18439 uss.mState = UserStartedState.STATE_BOOTING;
18440 updateStartedUserArrayLocked();
18444 if (uss.mState == UserStartedState.STATE_BOOTING) {
18445 // Booting up a new user, need to tell system services about it.
18446 // Note that this is on the same handler as scheduling of broadcasts,
18447 // which is important because it needs to go first.
18448 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18452 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18454 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18455 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18456 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18457 oldUserId, userId, uss));
18458 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18459 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18463 // Send USER_STARTED broadcast
18464 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18465 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18466 | Intent.FLAG_RECEIVER_FOREGROUND);
18467 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18468 broadcastIntentLocked(null, null, intent,
18469 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18470 false, false, MY_PID, Process.SYSTEM_UID, userId);
18473 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18474 if (userId != UserHandle.USER_OWNER) {
18475 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18476 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18477 broadcastIntentLocked(null, null, intent, null,
18478 new IIntentReceiver.Stub() {
18479 public void performReceive(Intent intent, int resultCode,
18480 String data, Bundle extras, boolean ordered,
18481 boolean sticky, int sendingUser) {
18482 onUserInitialized(uss, foreground, oldUserId, userId);
18484 }, 0, null, null, null, AppOpsManager.OP_NONE,
18485 true, false, MY_PID, Process.SYSTEM_UID,
18487 uss.initializing = true;
18489 getUserManagerLocked().makeInitialized(userInfo.id);
18494 if (!uss.initializing) {
18495 moveUserToForeground(uss, oldUserId, userId);
18498 mStackSupervisor.startBackgroundUserLocked(userId, uss);
18502 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18503 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18504 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18505 broadcastIntentLocked(null, null, intent,
18506 null, new IIntentReceiver.Stub() {
18508 public void performReceive(Intent intent, int resultCode, String data,
18509 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18510 throws RemoteException {
18513 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18514 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18518 Binder.restoreCallingIdentity(ident);
18524 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18525 long ident = Binder.clearCallingIdentity();
18528 if (oldUserId >= 0) {
18529 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18530 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18531 int count = profiles.size();
18532 for (int i = 0; i < count; i++) {
18533 int profileUserId = profiles.get(i).id;
18534 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18535 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18536 | Intent.FLAG_RECEIVER_FOREGROUND);
18537 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18538 broadcastIntentLocked(null, null, intent,
18539 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18540 false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18543 if (newUserId >= 0) {
18544 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18545 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18546 int count = profiles.size();
18547 for (int i = 0; i < count; i++) {
18548 int profileUserId = profiles.get(i).id;
18549 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18550 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18551 | Intent.FLAG_RECEIVER_FOREGROUND);
18552 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18553 broadcastIntentLocked(null, null, intent,
18554 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18555 false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18557 intent = new Intent(Intent.ACTION_USER_SWITCHED);
18558 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18559 | Intent.FLAG_RECEIVER_FOREGROUND);
18560 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18561 broadcastIntentLocked(null, null, intent,
18562 null, null, 0, null, null,
18563 android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18564 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18567 Binder.restoreCallingIdentity(ident);
18571 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18572 final int newUserId) {
18573 final int N = mUserSwitchObservers.beginBroadcast();
18575 final IRemoteCallback callback = new IRemoteCallback.Stub() {
18578 public void sendResult(Bundle data) throws RemoteException {
18579 synchronized (ActivityManagerService.this) {
18580 if (mCurUserSwitchCallback == this) {
18583 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18589 synchronized (this) {
18590 uss.switching = true;
18591 mCurUserSwitchCallback = callback;
18593 for (int i=0; i<N; i++) {
18595 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18596 newUserId, callback);
18597 } catch (RemoteException e) {
18601 synchronized (this) {
18602 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18605 mUserSwitchObservers.finishBroadcast();
18608 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18609 synchronized (this) {
18610 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18611 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18615 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18616 mCurUserSwitchCallback = null;
18617 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18618 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18619 oldUserId, newUserId, uss));
18622 void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18623 synchronized (this) {
18625 moveUserToForeground(uss, oldUserId, newUserId);
18629 completeSwitchAndInitalize(uss, newUserId, true, false);
18632 void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18633 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18635 startHomeActivityLocked(newUserId);
18637 mStackSupervisor.resumeTopActivitiesLocked();
18639 EventLogTags.writeAmSwitchUser(newUserId);
18640 getUserManagerLocked().userForeground(newUserId);
18641 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18644 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18645 completeSwitchAndInitalize(uss, newUserId, false, true);
18648 void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18649 boolean clearInitializing, boolean clearSwitching) {
18650 boolean unfrozen = false;
18651 synchronized (this) {
18652 if (clearInitializing) {
18653 uss.initializing = false;
18654 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18656 if (clearSwitching) {
18657 uss.switching = false;
18659 if (!uss.switching && !uss.initializing) {
18660 mWindowManager.stopFreezingScreen();
18665 final int N = mUserSwitchObservers.beginBroadcast();
18666 for (int i=0; i<N; i++) {
18668 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18669 } catch (RemoteException e) {
18672 mUserSwitchObservers.finishBroadcast();
18676 void scheduleStartProfilesLocked() {
18677 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18678 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18679 DateUtils.SECOND_IN_MILLIS);
18683 void startProfilesLocked() {
18684 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18685 List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18686 mCurrentUserId, false /* enabledOnly */);
18687 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18688 for (UserInfo user : profiles) {
18689 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18690 && user.id != mCurrentUserId) {
18694 final int n = toStart.size();
18696 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18697 startUserInBackground(toStart.get(i).id);
18700 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18704 void finishUserBoot(UserStartedState uss) {
18705 synchronized (this) {
18706 if (uss.mState == UserStartedState.STATE_BOOTING
18707 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18708 uss.mState = UserStartedState.STATE_RUNNING;
18709 final int userId = uss.mHandle.getIdentifier();
18710 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18711 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18712 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18713 broadcastIntentLocked(null, null, intent,
18714 null, null, 0, null, null,
18715 android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18716 true, false, MY_PID, Process.SYSTEM_UID, userId);
18721 void finishUserSwitch(UserStartedState uss) {
18722 synchronized (this) {
18723 finishUserBoot(uss);
18725 startProfilesLocked();
18727 int num = mUserLru.size();
18729 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18730 Integer oldUserId = mUserLru.get(i);
18731 UserStartedState oldUss = mStartedUsers.get(oldUserId);
18732 if (oldUss == null) {
18733 // Shouldn't happen, but be sane if it does.
18734 mUserLru.remove(i);
18738 if (oldUss.mState == UserStartedState.STATE_STOPPING
18739 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18740 // This user is already stopping, doesn't count.
18745 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18746 // Owner and current can't be stopped, but count as running.
18750 // This is a user to be stopped.
18751 stopUserLocked(oldUserId, null);
18759 public int stopUser(final int userId, final IStopUserCallback callback) {
18760 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18761 != PackageManager.PERMISSION_GRANTED) {
18762 String msg = "Permission Denial: switchUser() from pid="
18763 + Binder.getCallingPid()
18764 + ", uid=" + Binder.getCallingUid()
18765 + " requires " + INTERACT_ACROSS_USERS_FULL;
18767 throw new SecurityException(msg);
18770 throw new IllegalArgumentException("Can't stop primary user " + userId);
18772 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
18773 synchronized (this) {
18774 return stopUserLocked(userId, callback);
18778 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18779 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18780 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
18781 return ActivityManager.USER_OP_IS_CURRENT;
18784 final UserStartedState uss = mStartedUsers.get(userId);
18786 // User is not started, nothing to do... but we do need to
18787 // callback if requested.
18788 if (callback != null) {
18789 mHandler.post(new Runnable() {
18791 public void run() {
18793 callback.userStopped(userId);
18794 } catch (RemoteException e) {
18799 return ActivityManager.USER_OP_SUCCESS;
18802 if (callback != null) {
18803 uss.mStopCallbacks.add(callback);
18806 if (uss.mState != UserStartedState.STATE_STOPPING
18807 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18808 uss.mState = UserStartedState.STATE_STOPPING;
18809 updateStartedUserArrayLocked();
18811 long ident = Binder.clearCallingIdentity();
18813 // We are going to broadcast ACTION_USER_STOPPING and then
18814 // once that is done send a final ACTION_SHUTDOWN and then
18816 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18817 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18818 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18819 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18820 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18821 // This is the result receiver for the final shutdown broadcast.
18822 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18824 public void performReceive(Intent intent, int resultCode, String data,
18825 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18826 finishUserStop(uss);
18829 // This is the result receiver for the initial stopping broadcast.
18830 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18832 public void performReceive(Intent intent, int resultCode, String data,
18833 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18835 synchronized (ActivityManagerService.this) {
18836 if (uss.mState != UserStartedState.STATE_STOPPING) {
18837 // Whoops, we are being started back up. Abort, abort!
18840 uss.mState = UserStartedState.STATE_SHUTDOWN;
18842 mBatteryStatsService.noteEvent(
18843 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18844 Integer.toString(userId), userId);
18845 mSystemServiceManager.stopUser(userId);
18846 broadcastIntentLocked(null, null, shutdownIntent,
18847 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18848 true, false, MY_PID, Process.SYSTEM_UID, userId);
18851 // Kick things off.
18852 broadcastIntentLocked(null, null, stoppingIntent,
18853 null, stoppingReceiver, 0, null, null,
18854 INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18855 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18857 Binder.restoreCallingIdentity(ident);
18861 return ActivityManager.USER_OP_SUCCESS;
18864 void finishUserStop(UserStartedState uss) {
18865 final int userId = uss.mHandle.getIdentifier();
18867 ArrayList<IStopUserCallback> callbacks;
18868 synchronized (this) {
18869 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18870 if (mStartedUsers.get(userId) != uss) {
18872 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18876 // User can no longer run.
18877 mStartedUsers.remove(userId);
18878 mUserLru.remove(Integer.valueOf(userId));
18879 updateStartedUserArrayLocked();
18881 // Clean up all state and processes associated with the user.
18882 // Kill all the processes for the user.
18883 forceStopUserLocked(userId, "finish user");
18886 // Explicitly remove the old information in mRecentTasks.
18887 removeRecentTasksForUserLocked(userId);
18890 for (int i=0; i<callbacks.size(); i++) {
18892 if (stopped) callbacks.get(i).userStopped(userId);
18893 else callbacks.get(i).userStopAborted(userId);
18894 } catch (RemoteException e) {
18899 mSystemServiceManager.cleanupUser(userId);
18900 synchronized (this) {
18901 mStackSupervisor.removeUserLocked(userId);
18907 public UserInfo getCurrentUser() {
18908 if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18909 != PackageManager.PERMISSION_GRANTED) && (
18910 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18911 != PackageManager.PERMISSION_GRANTED)) {
18912 String msg = "Permission Denial: getCurrentUser() from pid="
18913 + Binder.getCallingPid()
18914 + ", uid=" + Binder.getCallingUid()
18915 + " requires " + INTERACT_ACROSS_USERS;
18917 throw new SecurityException(msg);
18919 synchronized (this) {
18920 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18921 return getUserManagerLocked().getUserInfo(userId);
18925 int getCurrentUserIdLocked() {
18926 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
18930 public boolean isUserRunning(int userId, boolean orStopped) {
18931 if (checkCallingPermission(INTERACT_ACROSS_USERS)
18932 != PackageManager.PERMISSION_GRANTED) {
18933 String msg = "Permission Denial: isUserRunning() from pid="
18934 + Binder.getCallingPid()
18935 + ", uid=" + Binder.getCallingUid()
18936 + " requires " + INTERACT_ACROSS_USERS;
18938 throw new SecurityException(msg);
18940 synchronized (this) {
18941 return isUserRunningLocked(userId, orStopped);
18945 boolean isUserRunningLocked(int userId, boolean orStopped) {
18946 UserStartedState state = mStartedUsers.get(userId);
18947 if (state == null) {
18953 return state.mState != UserStartedState.STATE_STOPPING
18954 && state.mState != UserStartedState.STATE_SHUTDOWN;
18958 public int[] getRunningUserIds() {
18959 if (checkCallingPermission(INTERACT_ACROSS_USERS)
18960 != PackageManager.PERMISSION_GRANTED) {
18961 String msg = "Permission Denial: isUserRunning() from pid="
18962 + Binder.getCallingPid()
18963 + ", uid=" + Binder.getCallingUid()
18964 + " requires " + INTERACT_ACROSS_USERS;
18966 throw new SecurityException(msg);
18968 synchronized (this) {
18969 return mStartedUserArray;
18973 private void updateStartedUserArrayLocked() {
18975 for (int i=0; i<mStartedUsers.size(); i++) {
18976 UserStartedState uss = mStartedUsers.valueAt(i);
18977 // This list does not include stopping users.
18978 if (uss.mState != UserStartedState.STATE_STOPPING
18979 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18983 mStartedUserArray = new int[num];
18985 for (int i=0; i<mStartedUsers.size(); i++) {
18986 UserStartedState uss = mStartedUsers.valueAt(i);
18987 if (uss.mState != UserStartedState.STATE_STOPPING
18988 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18989 mStartedUserArray[num] = mStartedUsers.keyAt(i);
18996 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18997 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18998 != PackageManager.PERMISSION_GRANTED) {
18999 String msg = "Permission Denial: registerUserSwitchObserver() from pid="
19000 + Binder.getCallingPid()
19001 + ", uid=" + Binder.getCallingUid()
19002 + " requires " + INTERACT_ACROSS_USERS_FULL;
19004 throw new SecurityException(msg);
19007 mUserSwitchObservers.register(observer);
19011 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
19012 mUserSwitchObservers.unregister(observer);
19015 private boolean userExists(int userId) {
19019 UserManagerService ums = getUserManagerLocked();
19020 return ums != null ? (ums.getUserInfo(userId) != null) : false;
19023 int[] getUsersLocked() {
19024 UserManagerService ums = getUserManagerLocked();
19025 return ums != null ? ums.getUserIds() : new int[] { 0 };
19028 UserManagerService getUserManagerLocked() {
19029 if (mUserManager == null) {
19030 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
19031 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
19033 return mUserManager;
19036 private int applyUserId(int uid, int userId) {
19037 return UserHandle.getUid(userId, uid);
19040 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
19041 if (info == null) return null;
19042 ApplicationInfo newInfo = new ApplicationInfo(info);
19043 newInfo.uid = applyUserId(info.uid, userId);
19044 newInfo.dataDir = USER_DATA_DIR + userId + "/"
19045 + info.packageName;
19049 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
19051 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
19055 ActivityInfo info = new ActivityInfo(aInfo);
19056 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
19060 private final class LocalService extends ActivityManagerInternal {
19062 public void onWakefulnessChanged(int wakefulness) {
19063 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
19067 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
19068 String processName, String abiOverride, int uid, Runnable crashHandler) {
19069 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
19070 processName, abiOverride, uid, crashHandler);
19075 * An implementation of IAppTask, that allows an app to manage its own tasks via
19076 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
19077 * only the process that calls getAppTasks() can call the AppTask methods.
19079 class AppTaskImpl extends IAppTask.Stub {
19080 private int mTaskId;
19081 private int mCallingUid;
19083 public AppTaskImpl(int taskId, int callingUid) {
19085 mCallingUid = callingUid;
19088 private void checkCaller() {
19089 if (mCallingUid != Binder.getCallingUid()) {
19090 throw new SecurityException("Caller " + mCallingUid
19091 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
19096 public void finishAndRemoveTask() {
19099 synchronized (ActivityManagerService.this) {
19100 long origId = Binder.clearCallingIdentity();
19102 TaskRecord tr = recentTaskForIdLocked(mTaskId);
19104 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19106 // Only kill the process if we are not a new document
19107 int flags = tr.getBaseIntent().getFlags();
19108 boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
19109 Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
19110 removeTaskByIdLocked(mTaskId,
19111 !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
19113 Binder.restoreCallingIdentity(origId);
19119 public ActivityManager.RecentTaskInfo getTaskInfo() {
19122 synchronized (ActivityManagerService.this) {
19123 long origId = Binder.clearCallingIdentity();
19125 TaskRecord tr = recentTaskForIdLocked(mTaskId);
19127 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19129 return createRecentTaskInfoFromTaskRecord(tr);
19131 Binder.restoreCallingIdentity(origId);
19137 public void moveToFront() {
19140 final TaskRecord tr;
19141 synchronized (ActivityManagerService.this) {
19142 tr = recentTaskForIdLocked(mTaskId);
19144 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19146 if (tr.getRootActivity() != null) {
19147 moveTaskToFrontLocked(tr.taskId, 0, null);
19152 startActivityFromRecentsInner(tr.taskId, null);
19156 public int startActivity(IBinder whoThread, String callingPackage,
19157 Intent intent, String resolvedType, Bundle options) {
19160 int callingUser = UserHandle.getCallingUserId();
19162 IApplicationThread appThread;
19163 synchronized (ActivityManagerService.this) {
19164 tr = recentTaskForIdLocked(mTaskId);
19166 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19168 appThread = ApplicationThreadNative.asInterface(whoThread);
19169 if (appThread == null) {
19170 throw new IllegalArgumentException("Bad app thread " + appThread);
19173 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
19174 resolvedType, null, null, null, null, 0, 0, null, null,
19175 null, options, callingUser, null, tr);
19179 public void setExcludeFromRecents(boolean exclude) {
19182 synchronized (ActivityManagerService.this) {
19183 long origId = Binder.clearCallingIdentity();
19185 TaskRecord tr = recentTaskForIdLocked(mTaskId);
19187 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
19189 Intent intent = tr.getBaseIntent();
19191 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19193 intent.setFlags(intent.getFlags()
19194 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
19197 Binder.restoreCallingIdentity(origId);