2 * Copyright (C) 2006-2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.am;
19 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24 import static com.android.internal.util.XmlUtils.readIntAttribute;
25 import static com.android.internal.util.XmlUtils.readLongAttribute;
26 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27 import static com.android.internal.util.XmlUtils.writeIntAttribute;
28 import static com.android.internal.util.XmlUtils.writeLongAttribute;
29 import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30 import static com.android.server.am.ActivityManagerDebugConfig.*;
31 import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
32 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
33 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
34 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
35 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
36 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
37 import static org.xmlpull.v1.XmlPullParser.START_TAG;
39 import android.Manifest;
40 import android.app.AppOpsManager;
41 import android.app.ApplicationThreadNative;
42 import android.app.BroadcastOptions;
43 import android.app.IActivityContainer;
44 import android.app.IActivityContainerCallback;
45 import android.app.IAppTask;
46 import android.app.ITaskStackListener;
47 import android.app.ProfilerInfo;
48 import android.app.assist.AssistContent;
49 import android.app.assist.AssistStructure;
50 import android.app.usage.UsageEvents;
51 import android.app.usage.UsageStatsManagerInternal;
52 import android.appwidget.AppWidgetManager;
53 import android.content.pm.PermissionInfo;
54 import android.content.res.Resources;
55 import android.graphics.Bitmap;
56 import android.graphics.Point;
57 import android.graphics.Rect;
58 import android.os.BatteryStats;
59 import android.os.PersistableBundle;
60 import android.os.PowerManager;
61 import android.os.Trace;
62 import android.os.TransactionTooLargeException;
63 import android.os.WorkSource;
64 import android.os.storage.IMountService;
65 import android.os.storage.MountServiceInternal;
66 import android.os.storage.StorageManager;
67 import android.service.voice.IVoiceInteractionSession;
68 import android.service.voice.VoiceInteractionSession;
69 import android.util.ArrayMap;
70 import android.util.ArraySet;
71 import android.util.DebugUtils;
72 import android.util.SparseIntArray;
73 import android.view.Display;
75 import com.android.internal.R;
76 import com.android.internal.annotations.GuardedBy;
77 import com.android.internal.app.AssistUtils;
78 import com.android.internal.app.DumpHeapActivity;
79 import com.android.internal.app.IAppOpsService;
80 import com.android.internal.app.IVoiceInteractor;
81 import com.android.internal.app.ProcessMap;
82 import com.android.internal.app.ProcessStats;
83 import com.android.internal.os.BackgroundThread;
84 import com.android.internal.os.BatteryStatsImpl;
85 import com.android.internal.os.IResultReceiver;
86 import com.android.internal.os.ProcessCpuTracker;
87 import com.android.internal.os.TransferPipe;
88 import com.android.internal.os.Zygote;
89 import com.android.internal.util.ArrayUtils;
90 import com.android.internal.util.FastPrintWriter;
91 import com.android.internal.util.FastXmlSerializer;
92 import com.android.internal.util.MemInfoReader;
93 import com.android.internal.util.Preconditions;
94 import com.android.server.AppOpsService;
95 import com.android.server.AttributeCache;
96 import com.android.server.DeviceIdleController;
97 import com.android.server.IntentResolver;
98 import com.android.server.LocalServices;
99 import com.android.server.ServiceThread;
100 import com.android.server.SystemService;
101 import com.android.server.SystemServiceManager;
102 import com.android.server.Watchdog;
103 import com.android.server.am.ActivityStack.ActivityState;
104 import com.android.server.firewall.IntentFirewall;
105 import com.android.server.pm.Installer;
106 import com.android.server.pm.UserManagerService;
107 import com.android.server.statusbar.StatusBarManagerInternal;
108 import com.android.server.wm.AppTransition;
109 import com.android.server.wm.WindowManagerService;
110 import com.google.android.collect.Lists;
111 import com.google.android.collect.Maps;
113 import libcore.io.IoUtils;
114 import libcore.util.EmptyArray;
116 import org.xmlpull.v1.XmlPullParser;
117 import org.xmlpull.v1.XmlPullParserException;
118 import org.xmlpull.v1.XmlSerializer;
120 import android.app.Activity;
121 import android.app.ActivityManager;
122 import android.app.ActivityManager.RunningTaskInfo;
123 import android.app.ActivityManager.StackInfo;
124 import android.app.ActivityManagerInternal;
125 import android.app.ActivityManagerInternal.SleepToken;
126 import android.app.ActivityManagerNative;
127 import android.app.ActivityOptions;
128 import android.app.ActivityThread;
129 import android.app.AlertDialog;
130 import android.app.AppGlobals;
131 import android.app.ApplicationErrorReport;
132 import android.app.Dialog;
133 import android.app.IActivityController;
134 import android.app.IApplicationThread;
135 import android.app.IInstrumentationWatcher;
136 import android.app.INotificationManager;
137 import android.app.IProcessObserver;
138 import android.app.IServiceConnection;
139 import android.app.IStopUserCallback;
140 import android.app.IUidObserver;
141 import android.app.IUiAutomationConnection;
142 import android.app.IUserSwitchObserver;
143 import android.app.Instrumentation;
144 import android.app.Notification;
145 import android.app.NotificationManager;
146 import android.app.PendingIntent;
147 import android.app.backup.IBackupManager;
148 import android.app.admin.DevicePolicyManager;
149 import android.content.ActivityNotFoundException;
150 import android.content.BroadcastReceiver;
151 import android.content.ClipData;
152 import android.content.ComponentCallbacks2;
153 import android.content.ComponentName;
154 import android.content.ContentProvider;
155 import android.content.ContentResolver;
156 import android.content.Context;
157 import android.content.DialogInterface;
158 import android.content.IContentProvider;
159 import android.content.IIntentReceiver;
160 import android.content.IIntentSender;
161 import android.content.Intent;
162 import android.content.IntentFilter;
163 import android.content.IntentSender;
164 import android.content.pm.ActivityInfo;
165 import android.content.pm.ApplicationInfo;
166 import android.content.pm.ConfigurationInfo;
167 import android.content.pm.IPackageDataObserver;
168 import android.content.pm.IPackageManager;
169 import android.content.pm.InstrumentationInfo;
170 import android.content.pm.PackageInfo;
171 import android.content.pm.PackageManager;
172 import android.content.pm.ParceledListSlice;
173 import android.content.pm.UserInfo;
174 import android.content.pm.PackageManager.NameNotFoundException;
175 import android.content.pm.PathPermission;
176 import android.content.pm.ProviderInfo;
177 import android.content.pm.ResolveInfo;
178 import android.content.pm.ServiceInfo;
179 import android.content.res.CompatibilityInfo;
180 import android.content.res.Configuration;
181 import android.net.Proxy;
182 import android.net.ProxyInfo;
183 import android.net.Uri;
184 import android.os.Binder;
185 import android.os.Build;
186 import android.os.Bundle;
187 import android.os.Debug;
188 import android.os.DropBoxManager;
189 import android.os.Environment;
190 import android.os.FactoryTest;
191 import android.os.FileObserver;
192 import android.os.FileUtils;
193 import android.os.Handler;
194 import android.os.IBinder;
195 import android.os.IPermissionController;
196 import android.os.IProcessInfoService;
197 import android.os.IRemoteCallback;
198 import android.os.IUserManager;
199 import android.os.Looper;
200 import android.os.Message;
201 import android.os.Parcel;
202 import android.os.ParcelFileDescriptor;
203 import android.os.PowerManagerInternal;
204 import android.os.Process;
205 import android.os.RemoteCallbackList;
206 import android.os.RemoteException;
207 import android.os.SELinux;
208 import android.os.ServiceManager;
209 import android.os.StrictMode;
210 import android.os.SystemClock;
211 import android.os.SystemProperties;
212 import android.os.UpdateLock;
213 import android.os.UserHandle;
214 import android.os.UserManager;
215 import android.provider.Settings;
216 import android.text.format.DateUtils;
217 import android.text.format.Time;
218 import android.util.AtomicFile;
219 import android.util.EventLog;
220 import android.util.Log;
221 import android.util.Pair;
222 import android.util.PrintWriterPrinter;
223 import android.util.Slog;
224 import android.util.SparseArray;
225 import android.util.TimeUtils;
226 import android.util.Xml;
227 import android.view.Gravity;
228 import android.view.LayoutInflater;
229 import android.view.View;
230 import android.view.WindowManager;
232 import dalvik.system.VMRuntime;
234 import java.io.BufferedInputStream;
235 import java.io.BufferedOutputStream;
236 import java.io.DataInputStream;
237 import java.io.DataOutputStream;
239 import java.io.FileDescriptor;
240 import java.io.FileInputStream;
241 import java.io.FileNotFoundException;
242 import java.io.FileOutputStream;
243 import java.io.IOException;
244 import java.io.InputStreamReader;
245 import java.io.PrintWriter;
246 import java.io.StringWriter;
247 import java.lang.ref.WeakReference;
248 import java.nio.charset.StandardCharsets;
249 import java.util.ArrayList;
250 import java.util.Arrays;
251 import java.util.Collections;
252 import java.util.Comparator;
253 import java.util.HashMap;
254 import java.util.HashSet;
255 import java.util.Iterator;
256 import java.util.List;
257 import java.util.Locale;
258 import java.util.Map;
259 import java.util.Set;
260 import java.util.concurrent.atomic.AtomicBoolean;
261 import java.util.concurrent.atomic.AtomicLong;
263 public final class ActivityManagerService extends ActivityManagerNative
264 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
266 // File that stores last updated system version and called preboot receivers
267 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
269 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
270 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
271 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
272 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
273 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
274 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
275 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
276 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
277 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
278 private static final String TAG_LRU = TAG + POSTFIX_LRU;
279 private static final String TAG_MU = TAG + POSTFIX_MU;
280 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
281 private static final String TAG_POWER = TAG + POSTFIX_POWER;
282 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
283 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
284 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
285 private static final String TAG_PSS = TAG + POSTFIX_PSS;
286 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
287 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
288 private static final String TAG_STACK = TAG + POSTFIX_STACK;
289 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
290 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
291 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
292 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
293 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
295 /** Control over CPU and battery monitoring */
296 // write battery stats every 30 minutes.
297 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
298 static final boolean MONITOR_CPU_USAGE = true;
299 // don't sample cpu less than every 5 seconds.
300 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
301 // wait possibly forever for next cpu sample.
302 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
303 static final boolean MONITOR_THREAD_CPU_USAGE = false;
305 // The flags that are set for all calls we make to the package manager.
306 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
308 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
310 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
312 // Amount of time after a call to stopAppSwitches() during which we will
313 // prevent further untrusted switches from happening.
314 static final long APP_SWITCH_DELAY_TIME = 5*1000;
316 // How long we wait for a launched process to attach to the activity manager
317 // before we decide it's never going to come up for real.
318 static final int PROC_START_TIMEOUT = 10*1000;
319 // How long we wait for an attached process to publish its content providers
320 // before we decide it must be hung.
321 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
323 // How long we wait for a launched process to attach to the activity manager
324 // before we decide it's never going to come up for real, when the process was
325 // started with a wrapper for instrumentation (such as Valgrind) because it
326 // could take much longer than usual.
327 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
329 // How long to wait after going idle before forcing apps to GC.
330 static final int GC_TIMEOUT = 5*1000;
332 // The minimum amount of time between successive GC requests for a process.
333 static final int GC_MIN_INTERVAL = 60*1000;
335 // The minimum amount of time between successive PSS requests for a process.
336 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
338 // The minimum amount of time between successive PSS requests for a process
339 // when the request is due to the memory state being lowered.
340 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
342 // The rate at which we check for apps using excessive power -- 15 mins.
343 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
345 // The minimum sample duration we will allow before deciding we have
346 // enough data on wake locks to start killing things.
347 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
349 // The minimum sample duration we will allow before deciding we have
350 // enough data on CPU usage to start killing things.
351 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
353 // How long we allow a receiver to run before giving up on it.
354 static final int BROADCAST_FG_TIMEOUT = 10*1000;
355 static final int BROADCAST_BG_TIMEOUT = 60*1000;
357 // How long we wait until we timeout on key dispatching.
358 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
360 // How long we wait until we timeout on key dispatching during instrumentation.
361 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
363 // Amount of time we wait for observers to handle a user switch before
364 // giving up on them and unfreezing the screen.
365 static final int USER_SWITCH_TIMEOUT = 2*1000;
367 // This is the amount of time an app needs to be running a foreground service before
368 // we will consider it to be doing interaction for usage stats.
369 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
371 // Maximum amount of time we will allow to elapse before re-reporting usage stats
372 // interaction with foreground processes.
373 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
375 // Maximum number of users we allow to be running at a time.
376 static final int MAX_RUNNING_USERS = 3;
378 // How long to wait in getAssistContextExtras for the activity and foreground services
379 // to respond with the result.
380 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
382 // How long top wait when going through the modern assist (which doesn't need to block
383 // on getting this result before starting to launch its UI).
384 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
386 // Maximum number of persisted Uri grants a package is allowed
387 static final int MAX_PERSISTED_URI_GRANTS = 128;
389 static final int MY_PID = Process.myPid();
391 static final String[] EMPTY_STRING_ARRAY = new String[0];
393 // How many bytes to write into the dropbox log before truncating
394 static final int DROPBOX_MAX_SIZE = 256 * 1024;
396 // Access modes for handleIncomingUser.
397 static final int ALLOW_NON_FULL = 0;
398 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
399 static final int ALLOW_FULL_ONLY = 2;
401 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
403 // Delay in notifying task stack change listeners (in millis)
404 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
406 // Necessary ApplicationInfo flags to mark an app as persistent
407 private static final int PERSISTENT_MASK =
408 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
411 // Delay to disable app launch boost
412 static final int APP_BOOST_MESSAGE_DELAY = 3000;
413 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
414 static final int APP_BOOST_TIMEOUT = 2500;
416 private static native int nativeMigrateToBoost();
417 private static native int nativeMigrateFromBoost();
418 private boolean mIsBoosted = false;
419 private long mBoostStartTime = 0;
421 /** All system services */
422 SystemServiceManager mSystemServiceManager;
424 private Installer mInstaller;
426 /** Run all ActivityStacks through this */
427 ActivityStackSupervisor mStackSupervisor;
429 /** Task stack change listeners. */
430 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
431 new RemoteCallbackList<ITaskStackListener>();
433 public IntentFirewall mIntentFirewall;
435 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
436 // default actuion automatically. Important for devices without direct input
438 private boolean mShowDialogs = true;
440 BroadcastQueue mFgBroadcastQueue;
441 BroadcastQueue mBgBroadcastQueue;
442 // Convenient for easy iteration over the queues. Foreground is first
443 // so that dispatch of foreground broadcasts gets precedence.
444 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
446 BroadcastQueue broadcastQueueForIntent(Intent intent) {
447 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
448 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
449 "Broadcast intent " + intent + " on "
450 + (isFg ? "foreground" : "background") + " queue");
451 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
455 * Activity we have told the window manager to have key focus.
457 ActivityRecord mFocusedActivity = null;
460 * User id of the last activity mFocusedActivity was set to.
462 private int mLastFocusedUserId;
465 * If non-null, we are tracking the time the user spends in the currently focused app.
467 private AppTimeTracker mCurAppTimeTracker;
470 * List of intents that were used to start the most recent tasks.
472 private final RecentTasks mRecentTasks;
475 * For addAppTask: cached of the last activity component that was added.
477 ComponentName mLastAddedTaskComponent;
480 * For addAppTask: cached of the last activity uid that was added.
482 int mLastAddedTaskUid;
485 * For addAppTask: cached of the last ActivityInfo that was added.
487 ActivityInfo mLastAddedTaskActivity;
490 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
492 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
495 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
497 String mDeviceOwnerName;
499 public class PendingAssistExtras extends Binder implements Runnable {
500 public final ActivityRecord activity;
501 public final Bundle extras;
502 public final Intent intent;
503 public final String hint;
504 public final IResultReceiver receiver;
505 public final int userHandle;
506 public boolean haveResult = false;
507 public Bundle result = null;
508 public AssistStructure structure = null;
509 public AssistContent content = null;
510 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
511 String _hint, IResultReceiver _receiver, int _userHandle) {
512 activity = _activity;
516 receiver = _receiver;
517 userHandle = _userHandle;
521 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
522 synchronized (this) {
526 pendingAssistExtrasTimedOut(this);
530 final ArrayList<PendingAssistExtras> mPendingAssistExtras
531 = new ArrayList<PendingAssistExtras>();
534 * Process management.
536 final ProcessList mProcessList = new ProcessList();
539 * All of the applications we currently have running organized by name.
540 * The keys are strings of the application package name (as
541 * returned by the package manager), and the keys are ApplicationRecord
544 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
547 * Tracking long-term execution of processes to look for abuse and other
550 final ProcessStatsService mProcessStats;
553 * The currently running isolated processes.
555 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
558 * Counter for assigning isolated process uids, to avoid frequently reusing the
561 int mNextIsolatedProcessUid = 0;
564 * The currently running heavy-weight process, if any.
566 ProcessRecord mHeavyWeightProcess = null;
569 * The last time that various processes have crashed.
571 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
574 * Information about a process that is currently marked as bad.
576 static final class BadProcessInfo {
577 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
579 this.shortMsg = shortMsg;
580 this.longMsg = longMsg;
585 final String shortMsg;
586 final String longMsg;
591 * Set of applications that we consider to be bad, and will reject
592 * incoming broadcasts from (which the user has no control over).
593 * Processes are added to this set when they have crashed twice within
594 * a minimum amount of time; they are removed from it when they are
595 * later restarted (hopefully due to some user action). The value is the
596 * time it was added to the list.
598 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
601 * All of the processes we currently have running organized by pid.
602 * The keys are the pid running the application.
604 * <p>NOTE: This object is protected by its own lock, NOT the global
605 * activity manager lock!
607 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
610 * All of the processes that have been forced to be foreground. The key
611 * is the pid of the caller who requested it (we hold a death
614 abstract class ForegroundToken implements IBinder.DeathRecipient {
618 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
621 * List of records for processes that someone had tried to start before the
622 * system was ready. We don't start them at that point, but ensure they
623 * are started by the time booting is complete.
625 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
628 * List of persistent applications that are in the process
631 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
634 * Processes that are being forcibly torn down.
636 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
639 * List of running applications, sorted by recent usage.
640 * The first entry in the list is the least recently used.
642 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
645 * Where in mLruProcesses that the processes hosting activities start.
647 int mLruProcessActivityStart = 0;
650 * Where in mLruProcesses that the processes hosting services start.
651 * This is after (lower index) than mLruProcessesActivityStart.
653 int mLruProcessServiceStart = 0;
656 * List of processes that should gc as soon as things are idle.
658 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
661 * Processes we want to collect PSS data from.
663 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
666 * Last time we requested PSS data of all processes.
668 long mLastFullPssTime = SystemClock.uptimeMillis();
671 * If set, the next time we collect PSS data we should do a full collection
672 * with data from native processes and the kernel.
674 boolean mFullPssPending = false;
677 * This is the process holding what we currently consider to be
678 * the "home" activity.
680 ProcessRecord mHomeProcess;
683 * This is the process holding the activity the user last visited that
684 * is in a different process from the one they are currently in.
686 ProcessRecord mPreviousProcess;
689 * The time at which the previous process was last visible.
691 long mPreviousProcessVisibleTime;
694 * Track all uids that have actively running processes.
696 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
699 * Which users have been started, so are allowed to run code.
701 final SparseArray<UserState> mStartedUsers = new SparseArray<>();
704 * LRU list of history of current users. Most recently current is at the end.
706 final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
709 * Constant array of the users that are currently started.
711 int[] mStartedUserArray = new int[] { 0 };
714 * Registered observers of the user switching mechanics.
716 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
717 = new RemoteCallbackList<IUserSwitchObserver>();
720 * Currently active user switch.
722 Object mCurUserSwitchCallback;
725 * Packages that the user has asked to have run in screen size
726 * compatibility mode instead of filling the screen.
728 final CompatModePackages mCompatModePackages;
731 * Set of IntentSenderRecord objects that are currently active.
733 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
734 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
737 * Fingerprints (hashCode()) of stack traces that we've
738 * already logged DropBox entries for. Guarded by itself. If
739 * something (rogue user app) forces this over
740 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
742 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
743 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
746 * Strict Mode background batched logging state.
748 * The string buffer is guarded by itself, and its lock is also
749 * used to determine if another batched write is already
752 private final StringBuilder mStrictModeBuffer = new StringBuilder();
755 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
756 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
758 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
761 * Resolver for broadcast intents to registered receivers.
762 * Holds BroadcastFilter (subclass of IntentFilter).
764 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
765 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
767 protected boolean allowFilterResult(
768 BroadcastFilter filter, List<BroadcastFilter> dest) {
769 IBinder target = filter.receiverList.receiver.asBinder();
770 for (int i = dest.size() - 1; i >= 0; i--) {
771 if (dest.get(i).receiverList.receiver.asBinder() == target) {
779 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
780 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
781 || userId == filter.owningUserId) {
782 return super.newResult(filter, match, userId);
788 protected BroadcastFilter[] newArray(int size) {
789 return new BroadcastFilter[size];
793 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
794 return packageName.equals(filter.packageName);
799 * State of all active sticky broadcasts per user. Keys are the action of the
800 * sticky Intent, values are an ArrayList of all broadcasted intents with
801 * that action (which should usually be one). The SparseArray is keyed
802 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
803 * for stickies that are sent to all users.
805 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
806 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
808 final ActiveServices mServices;
810 final static class Association {
811 final int mSourceUid;
812 final String mSourceProcess;
813 final int mTargetUid;
814 final ComponentName mTargetComponent;
815 final String mTargetProcess;
823 Association(int sourceUid, String sourceProcess, int targetUid,
824 ComponentName targetComponent, String targetProcess) {
825 mSourceUid = sourceUid;
826 mSourceProcess = sourceProcess;
827 mTargetUid = targetUid;
828 mTargetComponent = targetComponent;
829 mTargetProcess = targetProcess;
834 * When service association tracking is enabled, this is all of the associations we
835 * have seen. Mapping is target uid -> target component -> source uid -> source process name
836 * -> association data.
838 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
839 mAssociations = new SparseArray<>();
840 boolean mTrackingAssociations;
843 * Backup/restore process management
845 String mBackupAppName = null;
846 BackupRecord mBackupTarget = null;
848 final ProviderMap mProviderMap;
851 * List of content providers who have clients waiting for them. The
852 * application is currently being launched and the provider will be
853 * removed from this list once it is published.
855 final ArrayList<ContentProviderRecord> mLaunchingProviders
856 = new ArrayList<ContentProviderRecord>();
859 * File storing persisted {@link #mGrantedUriPermissions}.
861 private final AtomicFile mGrantFile;
863 /** XML constants used in {@link #mGrantFile} */
864 private static final String TAG_URI_GRANTS = "uri-grants";
865 private static final String TAG_URI_GRANT = "uri-grant";
866 private static final String ATTR_USER_HANDLE = "userHandle";
867 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
868 private static final String ATTR_TARGET_USER_ID = "targetUserId";
869 private static final String ATTR_SOURCE_PKG = "sourcePkg";
870 private static final String ATTR_TARGET_PKG = "targetPkg";
871 private static final String ATTR_URI = "uri";
872 private static final String ATTR_MODE_FLAGS = "modeFlags";
873 private static final String ATTR_CREATED_TIME = "createdTime";
874 private static final String ATTR_PREFIX = "prefix";
877 * Global set of specific {@link Uri} permissions that have been granted.
878 * This optimized lookup structure maps from {@link UriPermission#targetUid}
879 * to {@link UriPermission#uri} to {@link UriPermission}.
882 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
883 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
885 public static class GrantUri {
886 public final int sourceUserId;
887 public final Uri uri;
888 public boolean prefix;
890 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
891 this.sourceUserId = sourceUserId;
893 this.prefix = prefix;
897 public int hashCode() {
899 hashCode = 31 * hashCode + sourceUserId;
900 hashCode = 31 * hashCode + uri.hashCode();
901 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
906 public boolean equals(Object o) {
907 if (o instanceof GrantUri) {
908 GrantUri other = (GrantUri) o;
909 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
910 && prefix == other.prefix;
916 public String toString() {
917 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
918 if (prefix) result += " [prefix]";
922 public String toSafeString() {
923 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
924 if (prefix) result += " [prefix]";
928 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
929 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
930 ContentProvider.getUriWithoutUserId(uri), false);
934 CoreSettingsObserver mCoreSettingsObserver;
937 * Thread-local storage used to carry caller permissions over through
938 * indirect content-provider access.
940 private class Identity {
941 public final IBinder token;
942 public final int pid;
943 public final int uid;
945 Identity(IBinder _token, int _pid, int _uid) {
952 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
955 * All information we have collected about the runtime performance of
956 * any user id that can impact battery performance.
958 final BatteryStatsService mBatteryStatsService;
961 * Information about component usage
963 UsageStatsManagerInternal mUsageStatsService;
966 * Access to DeviceIdleController service.
968 DeviceIdleController.LocalService mLocalDeviceIdleController;
971 * Information about and control over application operations
973 final AppOpsService mAppOpsService;
976 * Save recent tasks information across reboots.
978 final TaskPersister mTaskPersister;
981 * Current configuration information. HistoryRecord objects are given
982 * a reference to this object to indicate which configuration they are
983 * currently running in, so this object must be kept immutable.
985 Configuration mConfiguration = new Configuration();
988 * Current sequencing integer of the configuration, for skipping old
991 int mConfigurationSeq = 0;
994 * Hardware-reported OpenGLES version.
996 final int GL_ES_VERSION;
999 * List of initialization arguments to pass to all processes when binding applications to them.
1000 * For example, references to the commonly used services.
1002 HashMap<String, IBinder> mAppBindArgs;
1005 * Temporary to avoid allocations. Protected by main lock.
1007 final StringBuilder mStringBuilder = new StringBuilder(256);
1010 * Used to control how we initialize the service.
1012 ComponentName mTopComponent;
1013 String mTopAction = Intent.ACTION_MAIN;
1015 boolean mProcessesReady = false;
1016 boolean mSystemReady = false;
1017 boolean mBooting = false;
1018 boolean mCallFinishBooting = false;
1019 boolean mBootAnimationComplete = false;
1020 boolean mWaitingUpdate = false;
1021 boolean mDidUpdate = false;
1022 boolean mOnBattery = false;
1023 boolean mLaunchWarningShown = false;
1029 boolean mCheckedForSetup;
1032 * The time at which we will allow normal application switches again,
1033 * after a call to {@link #stopAppSwitches()}.
1035 long mAppSwitchesAllowedTime;
1038 * This is set to true after the first switch after mAppSwitchesAllowedTime
1039 * is set; any switches after that will clear the time.
1041 boolean mDidAppSwitch;
1044 * Last time (in realtime) at which we checked for power usage.
1046 long mLastPowerCheckRealtime;
1049 * Last time (in uptime) at which we checked for power usage.
1051 long mLastPowerCheckUptime;
1054 * Set while we are wanting to sleep, to prevent any
1055 * activities from being started/resumed.
1057 private boolean mSleeping = false;
1060 * The process state used for processes that are running the top activities.
1061 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1063 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1066 * Set while we are running a voice interaction. This overrides
1067 * sleeping while it is active.
1069 private IVoiceInteractionSession mRunningVoice;
1072 * For some direct access we need to power manager.
1074 PowerManagerInternal mLocalPowerManager;
1077 * We want to hold a wake lock while running a voice interaction session, since
1078 * this may happen with the screen off and we need to keep the CPU running to
1079 * be able to continue to interact with the user.
1081 PowerManager.WakeLock mVoiceWakeLock;
1084 * State of external calls telling us if the device is awake or asleep.
1086 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1089 * A list of tokens that cause the top activity to be put to sleep.
1090 * They are used by components that may hide and block interaction with underlying
1093 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1095 static final int LOCK_SCREEN_HIDDEN = 0;
1096 static final int LOCK_SCREEN_LEAVING = 1;
1097 static final int LOCK_SCREEN_SHOWN = 2;
1099 * State of external call telling us if the lock screen is shown.
1101 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1104 * Set if we are shutting down the system, similar to sleeping.
1106 boolean mShuttingDown = false;
1109 * Current sequence id for oom_adj computation traversal.
1114 * Current sequence id for process LRU updating.
1119 * Keep track of the non-cached/empty process we last found, to help
1120 * determine how to distribute cached/empty processes next time.
1122 int mNumNonCachedProcs = 0;
1125 * Keep track of the number of cached hidden procs, to balance oom adj
1126 * distribution between those and empty procs.
1128 int mNumCachedHiddenProcs = 0;
1131 * Keep track of the number of service processes we last found, to
1132 * determine on the next iteration which should be B services.
1134 int mNumServiceProcs = 0;
1135 int mNewNumAServiceProcs = 0;
1136 int mNewNumServiceProcs = 0;
1139 * Allow the current computed overall memory level of the system to go down?
1140 * This is set to false when we are killing processes for reasons other than
1141 * memory management, so that the now smaller process list will not be taken as
1142 * an indication that memory is tighter.
1144 boolean mAllowLowerMemLevel = false;
1147 * The last computed memory level, for holding when we are in a state that
1148 * processes are going away for other reasons.
1150 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1153 * The last total number of process we have, to determine if changes actually look
1154 * like a shrinking number of process due to lower RAM.
1156 int mLastNumProcesses;
1159 * The uptime of the last time we performed idle maintenance.
1161 long mLastIdleTime = SystemClock.uptimeMillis();
1164 * Total time spent with RAM that has been added in the past since the last idle time.
1166 long mLowRamTimeSinceLastIdle = 0;
1169 * If RAM is currently low, when that horrible situation started.
1171 long mLowRamStartTime = 0;
1174 * For reporting to battery stats the current top application.
1176 private String mCurResumedPackage = null;
1177 private int mCurResumedUid = -1;
1180 * For reporting to battery stats the apps currently running foreground
1181 * service. The ProcessMap is package/uid tuples; each of these contain
1182 * an array of the currently foreground processes.
1184 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1185 = new ProcessMap<ArrayList<ProcessRecord>>();
1188 * This is set if we had to do a delayed dexopt of an app before launching
1189 * it, to increase the ANR timeouts in that case.
1194 * Set if the systemServer made a call to enterSafeMode.
1199 * If true, we are running under a test environment so will sample PSS from processes
1200 * much more rapidly to try to collect better data when the tests are rapidly
1201 * running through apps.
1203 boolean mTestPssMode = false;
1205 String mDebugApp = null;
1206 boolean mWaitForDebugger = false;
1207 boolean mDebugTransient = false;
1208 String mOrigDebugApp = null;
1209 boolean mOrigWaitForDebugger = false;
1210 boolean mAlwaysFinishActivities = false;
1211 IActivityController mController = null;
1212 String mProfileApp = null;
1213 ProcessRecord mProfileProc = null;
1214 String mProfileFile;
1215 ParcelFileDescriptor mProfileFd;
1216 int mSamplingInterval = 0;
1217 boolean mAutoStopProfiler = false;
1218 int mProfileType = 0;
1219 String mOpenGlTraceApp = null;
1220 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1221 String mMemWatchDumpProcName;
1222 String mMemWatchDumpFile;
1223 int mMemWatchDumpPid;
1224 int mMemWatchDumpUid;
1226 final long[] mTmpLong = new long[1];
1228 static final class ProcessChangeItem {
1229 static final int CHANGE_ACTIVITIES = 1<<0;
1230 static final int CHANGE_PROCESS_STATE = 1<<1;
1235 boolean foregroundActivities;
1238 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1239 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1241 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1242 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1244 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1245 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1247 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1248 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1251 * Runtime CPU use collection thread. This object's lock is used to
1252 * perform synchronization with the thread (notifying it to run).
1254 final Thread mProcessCpuThread;
1257 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1258 * Must acquire this object's lock when accessing it.
1259 * NOTE: this lock will be held while doing long operations (trawling
1260 * through all processes in /proc), so it should never be acquired by
1261 * any critical paths such as when holding the main activity manager lock.
1263 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1264 MONITOR_THREAD_CPU_USAGE);
1265 final AtomicLong mLastCpuTime = new AtomicLong(0);
1266 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1268 long mLastWriteTime = 0;
1271 * Used to retain an update lock when the foreground activity is in
1274 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1277 * Set to true after the system has finished booting.
1279 boolean mBooted = false;
1281 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1282 int mProcessLimitOverride = -1;
1284 WindowManagerService mWindowManager;
1286 final ActivityThread mSystemThread;
1288 // Holds the current foreground user's id
1289 int mCurrentUserId = 0;
1290 // Holds the target user's id during a user switch
1291 int mTargetUserId = UserHandle.USER_NULL;
1292 // If there are multiple profiles for the current user, their ids are here
1293 // Currently only the primary user can have managed profiles
1294 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1297 * Mapping from each known user ID to the profile group ID it is associated with.
1299 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1301 private UserManagerService mUserManager;
1303 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1304 final ProcessRecord mApp;
1306 final IApplicationThread mAppThread;
1308 AppDeathRecipient(ProcessRecord app, int pid,
1309 IApplicationThread thread) {
1310 if (DEBUG_ALL) Slog.v(
1311 TAG, "New death recipient " + this
1312 + " for thread " + thread.asBinder());
1315 mAppThread = thread;
1319 public void binderDied() {
1320 if (DEBUG_ALL) Slog.v(
1321 TAG, "Death received in " + this
1322 + " for thread " + mAppThread.asBinder());
1323 synchronized(ActivityManagerService.this) {
1324 appDiedLocked(mApp, mPid, mAppThread, true);
1329 static final int SHOW_ERROR_MSG = 1;
1330 static final int SHOW_NOT_RESPONDING_MSG = 2;
1331 static final int SHOW_FACTORY_ERROR_MSG = 3;
1332 static final int UPDATE_CONFIGURATION_MSG = 4;
1333 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1334 static final int WAIT_FOR_DEBUGGER_MSG = 6;
1335 static final int SERVICE_TIMEOUT_MSG = 12;
1336 static final int UPDATE_TIME_ZONE = 13;
1337 static final int SHOW_UID_ERROR_MSG = 14;
1338 static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1339 static final int PROC_START_TIMEOUT_MSG = 20;
1340 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1341 static final int KILL_APPLICATION_MSG = 22;
1342 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1343 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1344 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1345 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1346 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1347 static final int CLEAR_DNS_CACHE_MSG = 28;
1348 static final int UPDATE_HTTP_PROXY_MSG = 29;
1349 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1350 static final int DISPATCH_PROCESSES_CHANGED = 31;
1351 static final int DISPATCH_PROCESS_DIED = 32;
1352 static final int REPORT_MEM_USAGE_MSG = 33;
1353 static final int REPORT_USER_SWITCH_MSG = 34;
1354 static final int CONTINUE_USER_SWITCH_MSG = 35;
1355 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1356 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1357 static final int PERSIST_URI_GRANTS_MSG = 38;
1358 static final int REQUEST_ALL_PSS_MSG = 39;
1359 static final int START_PROFILES_MSG = 40;
1360 static final int UPDATE_TIME = 41;
1361 static final int SYSTEM_USER_START_MSG = 42;
1362 static final int SYSTEM_USER_CURRENT_MSG = 43;
1363 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1364 static final int FINISH_BOOTING_MSG = 45;
1365 static final int START_USER_SWITCH_MSG = 46;
1366 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1367 static final int DISMISS_DIALOG_MSG = 48;
1368 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1369 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1370 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1371 static final int DELETE_DUMPHEAP_MSG = 52;
1372 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1373 static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1374 static final int REPORT_TIME_TRACKER_MSG = 55;
1375 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1376 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1377 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1378 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1380 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1381 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1382 static final int FIRST_COMPAT_MODE_MSG = 300;
1383 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1385 CompatModeDialog mCompatModeDialog;
1386 long mLastMemUsageReportTime = 0;
1389 * Flag whether the current user is a "monkey", i.e. whether
1390 * the UI is driven by a UI automation tool.
1392 private boolean mUserIsMonkey;
1394 /** Flag whether the device has a Recents UI */
1395 boolean mHasRecents;
1397 /** The dimensions of the thumbnails in the Recents UI. */
1398 int mThumbnailWidth;
1399 int mThumbnailHeight;
1401 final ServiceThread mHandlerThread;
1402 final MainHandler mHandler;
1403 final UiHandler mUiHandler;
1405 final class UiHandler extends Handler {
1406 public UiHandler() {
1407 super(com.android.server.UiThread.get().getLooper(), null, true);
1411 public void handleMessage(Message msg) {
1413 case SHOW_ERROR_MSG: {
1414 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1415 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1416 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1417 synchronized (ActivityManagerService.this) {
1418 ProcessRecord proc = (ProcessRecord)data.get("app");
1419 AppErrorResult res = (AppErrorResult) data.get("result");
1420 if (proc != null && proc.crashDialog != null) {
1421 Slog.e(TAG, "App already has crash dialog: " + proc);
1427 boolean isBackground = (UserHandle.getAppId(proc.uid)
1428 >= Process.FIRST_APPLICATION_UID
1429 && proc.pid != MY_PID);
1430 for (int userId : mCurrentProfileIds) {
1431 isBackground &= (proc.userId != userId);
1433 if (isBackground && !showBackground) {
1434 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1440 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1441 Dialog d = new AppErrorDialog(mContext,
1442 ActivityManagerService.this, res, proc);
1444 proc.crashDialog = d;
1446 // The device is asleep, so just pretend that the user
1447 // saw a crash dialog and hit "force quit".
1454 ensureBootCompleted();
1456 case SHOW_NOT_RESPONDING_MSG: {
1457 synchronized (ActivityManagerService.this) {
1458 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1459 ProcessRecord proc = (ProcessRecord)data.get("app");
1460 if (proc != null && proc.anrDialog != null) {
1461 Slog.e(TAG, "App already has anr dialog: " + proc);
1465 Intent intent = new Intent("android.intent.action.ANR");
1466 if (!mProcessesReady) {
1467 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1468 | Intent.FLAG_RECEIVER_FOREGROUND);
1470 broadcastIntentLocked(null, null, intent,
1471 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1472 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1475 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1476 mContext, proc, (ActivityRecord)data.get("activity"),
1481 // Just kill the app if there is no dialog to be shown.
1482 killAppAtUsersRequest(proc, null);
1486 ensureBootCompleted();
1488 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1489 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1490 synchronized (ActivityManagerService.this) {
1491 ProcessRecord proc = (ProcessRecord) data.get("app");
1493 Slog.e(TAG, "App not found when showing strict mode dialog.");
1496 if (proc.crashDialog != null) {
1497 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1500 AppErrorResult res = (AppErrorResult) data.get("result");
1501 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1502 Dialog d = new StrictModeViolationDialog(mContext,
1503 ActivityManagerService.this, res, proc);
1505 proc.crashDialog = d;
1507 // The device is asleep, so just pretend that the user
1508 // saw a crash dialog and hit "force quit".
1512 ensureBootCompleted();
1514 case SHOW_FACTORY_ERROR_MSG: {
1515 Dialog d = new FactoryErrorDialog(
1516 mContext, msg.getData().getCharSequence("msg"));
1518 ensureBootCompleted();
1520 case WAIT_FOR_DEBUGGER_MSG: {
1521 synchronized (ActivityManagerService.this) {
1522 ProcessRecord app = (ProcessRecord)msg.obj;
1523 if (msg.arg1 != 0) {
1524 if (!app.waitedForDebugger) {
1525 Dialog d = new AppWaitingForDebuggerDialog(
1526 ActivityManagerService.this,
1529 app.waitedForDebugger = true;
1533 if (app.waitDialog != null) {
1534 app.waitDialog.dismiss();
1535 app.waitDialog = null;
1540 case SHOW_UID_ERROR_MSG: {
1542 AlertDialog d = new BaseErrorDialog(mContext);
1543 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1544 d.setCancelable(false);
1545 d.setTitle(mContext.getText(R.string.android_system_label));
1546 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1547 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1548 obtainMessage(DISMISS_DIALOG_MSG, d));
1552 case SHOW_FINGERPRINT_ERROR_MSG: {
1554 AlertDialog d = new BaseErrorDialog(mContext);
1555 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1556 d.setCancelable(false);
1557 d.setTitle(mContext.getText(R.string.android_system_label));
1558 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1559 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1560 obtainMessage(DISMISS_DIALOG_MSG, d));
1564 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1565 synchronized (ActivityManagerService.this) {
1566 ActivityRecord ar = (ActivityRecord) msg.obj;
1567 if (mCompatModeDialog != null) {
1568 if (mCompatModeDialog.mAppInfo.packageName.equals(
1569 ar.info.applicationInfo.packageName)) {
1572 mCompatModeDialog.dismiss();
1573 mCompatModeDialog = null;
1575 if (ar != null && false) {
1576 if (mCompatModePackages.getPackageAskCompatModeLocked(
1578 int mode = mCompatModePackages.computeCompatModeLocked(
1579 ar.info.applicationInfo);
1580 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1581 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1582 mCompatModeDialog = new CompatModeDialog(
1583 ActivityManagerService.this, mContext,
1584 ar.info.applicationInfo);
1585 mCompatModeDialog.show();
1592 case START_USER_SWITCH_MSG: {
1593 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1596 case DISMISS_DIALOG_MSG: {
1597 final Dialog d = (Dialog) msg.obj;
1601 case DISPATCH_PROCESSES_CHANGED: {
1602 dispatchProcessesChanged();
1605 case DISPATCH_PROCESS_DIED: {
1606 final int pid = msg.arg1;
1607 final int uid = msg.arg2;
1608 dispatchProcessDied(pid, uid);
1611 case DISPATCH_UIDS_CHANGED_MSG: {
1612 dispatchUidsChanged();
1618 final class MainHandler extends Handler {
1619 public MainHandler(Looper looper) {
1620 super(looper, null, true);
1624 public void handleMessage(Message msg) {
1626 case UPDATE_CONFIGURATION_MSG: {
1627 final ContentResolver resolver = mContext.getContentResolver();
1628 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1630 case GC_BACKGROUND_PROCESSES_MSG: {
1631 synchronized (ActivityManagerService.this) {
1632 performAppGcsIfAppropriateLocked();
1635 case SERVICE_TIMEOUT_MSG: {
1638 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1640 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1643 mServices.serviceTimeout((ProcessRecord)msg.obj);
1645 case UPDATE_TIME_ZONE: {
1646 synchronized (ActivityManagerService.this) {
1647 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1648 ProcessRecord r = mLruProcesses.get(i);
1649 if (r.thread != null) {
1651 r.thread.updateTimeZone();
1652 } catch (RemoteException ex) {
1653 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1659 case CLEAR_DNS_CACHE_MSG: {
1660 synchronized (ActivityManagerService.this) {
1661 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1662 ProcessRecord r = mLruProcesses.get(i);
1663 if (r.thread != null) {
1665 r.thread.clearDnsCache();
1666 } catch (RemoteException ex) {
1667 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1673 case UPDATE_HTTP_PROXY_MSG: {
1674 ProxyInfo proxy = (ProxyInfo)msg.obj;
1677 String exclList = "";
1678 Uri pacFileUrl = Uri.EMPTY;
1679 if (proxy != null) {
1680 host = proxy.getHost();
1681 port = Integer.toString(proxy.getPort());
1682 exclList = proxy.getExclusionListAsString();
1683 pacFileUrl = proxy.getPacFileUrl();
1685 synchronized (ActivityManagerService.this) {
1686 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1687 ProcessRecord r = mLruProcesses.get(i);
1688 if (r.thread != null) {
1690 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1691 } catch (RemoteException ex) {
1692 Slog.w(TAG, "Failed to update http proxy for: " +
1693 r.info.processName);
1699 case PROC_START_TIMEOUT_MSG: {
1702 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1704 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1707 ProcessRecord app = (ProcessRecord)msg.obj;
1708 synchronized (ActivityManagerService.this) {
1709 processStartTimedOutLocked(app);
1712 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1713 ProcessRecord app = (ProcessRecord)msg.obj;
1714 synchronized (ActivityManagerService.this) {
1715 processContentProviderPublishTimedOutLocked(app);
1718 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1719 synchronized (ActivityManagerService.this) {
1720 mStackSupervisor.doPendingActivityLaunchesLocked(true);
1723 case KILL_APPLICATION_MSG: {
1724 synchronized (ActivityManagerService.this) {
1725 int appid = msg.arg1;
1726 boolean restart = (msg.arg2 == 1);
1727 Bundle bundle = (Bundle)msg.obj;
1728 String pkg = bundle.getString("pkg");
1729 String reason = bundle.getString("reason");
1730 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1731 false, UserHandle.USER_ALL, reason);
1734 case FINALIZE_PENDING_INTENT_MSG: {
1735 ((PendingIntentRecord)msg.obj).completeFinalize();
1737 case POST_HEAVY_NOTIFICATION_MSG: {
1738 INotificationManager inm = NotificationManager.getService();
1743 ActivityRecord root = (ActivityRecord)msg.obj;
1744 ProcessRecord process = root.app;
1745 if (process == null) {
1750 Context context = mContext.createPackageContext(process.info.packageName, 0);
1751 String text = mContext.getString(R.string.heavy_weight_notification,
1752 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1753 Notification notification = new Notification.Builder(context)
1754 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1758 .setColor(mContext.getColor(
1759 com.android.internal.R.color.system_notification_accent_color))
1760 .setContentTitle(text)
1762 mContext.getText(R.string.heavy_weight_notification_detail))
1763 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1764 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1765 new UserHandle(root.userId)))
1768 int[] outId = new int[1];
1769 inm.enqueueNotificationWithTag("android", "android", null,
1770 R.string.heavy_weight_notification,
1771 notification, outId, root.userId);
1772 } catch (RuntimeException e) {
1773 Slog.w(ActivityManagerService.TAG,
1774 "Error showing notification for heavy-weight app", e);
1775 } catch (RemoteException e) {
1777 } catch (NameNotFoundException e) {
1778 Slog.w(TAG, "Unable to create context for heavy notification", e);
1781 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1782 INotificationManager inm = NotificationManager.getService();
1787 inm.cancelNotificationWithTag("android", null,
1788 R.string.heavy_weight_notification, msg.arg1);
1789 } catch (RuntimeException e) {
1790 Slog.w(ActivityManagerService.TAG,
1791 "Error canceling notification for service", e);
1792 } catch (RemoteException e) {
1795 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1796 synchronized (ActivityManagerService.this) {
1797 checkExcessivePowerUsageLocked(true);
1798 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1799 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1800 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1803 case REPORT_MEM_USAGE_MSG: {
1804 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1805 Thread thread = new Thread() {
1806 @Override public void run() {
1807 reportMemUsage(memInfos);
1813 case REPORT_USER_SWITCH_MSG: {
1814 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1817 case CONTINUE_USER_SWITCH_MSG: {
1818 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1821 case USER_SWITCH_TIMEOUT_MSG: {
1822 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1825 case IMMERSIVE_MODE_LOCK_MSG: {
1826 final boolean nextState = (msg.arg1 != 0);
1827 if (mUpdateLock.isHeld() != nextState) {
1828 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1829 "Applying new update lock state '" + nextState
1830 + "' for " + (ActivityRecord)msg.obj);
1832 mUpdateLock.acquire();
1834 mUpdateLock.release();
1839 case PERSIST_URI_GRANTS_MSG: {
1840 writeGrantedUriPermissions();
1843 case REQUEST_ALL_PSS_MSG: {
1844 synchronized (ActivityManagerService.this) {
1845 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1849 case START_PROFILES_MSG: {
1850 synchronized (ActivityManagerService.this) {
1851 startProfilesLocked();
1856 synchronized (ActivityManagerService.this) {
1857 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1858 ProcessRecord r = mLruProcesses.get(i);
1859 if (r.thread != null) {
1861 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1862 } catch (RemoteException ex) {
1863 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1870 case SYSTEM_USER_START_MSG: {
1871 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1872 Integer.toString(msg.arg1), msg.arg1);
1873 mSystemServiceManager.startUser(msg.arg1);
1876 case SYSTEM_USER_CURRENT_MSG: {
1877 mBatteryStatsService.noteEvent(
1878 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1879 Integer.toString(msg.arg2), msg.arg2);
1880 mBatteryStatsService.noteEvent(
1881 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1882 Integer.toString(msg.arg1), msg.arg1);
1883 mSystemServiceManager.switchUser(msg.arg1);
1886 case ENTER_ANIMATION_COMPLETE_MSG: {
1887 synchronized (ActivityManagerService.this) {
1888 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1889 if (r != null && r.app != null && r.app.thread != null) {
1891 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1892 } catch (RemoteException e) {
1898 case FINISH_BOOTING_MSG: {
1899 if (msg.arg1 != 0) {
1902 if (msg.arg2 != 0) {
1903 enableScreenAfterBoot();
1907 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1909 Locale l = (Locale) msg.obj;
1910 IBinder service = ServiceManager.getService("mount");
1911 IMountService mountService = IMountService.Stub.asInterface(service);
1912 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1913 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1914 } catch (RemoteException e) {
1915 Log.e(TAG, "Error storing locale for decryption UI", e);
1919 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1920 synchronized (ActivityManagerService.this) {
1921 int i = mTaskStackListeners.beginBroadcast();
1925 // Make a one-way callback to the listener
1926 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1927 } catch (RemoteException e){
1928 // Handled by the RemoteCallbackList
1931 mTaskStackListeners.finishBroadcast();
1935 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1936 final int uid = msg.arg1;
1937 final byte[] firstPacket = (byte[]) msg.obj;
1939 synchronized (mPidsSelfLocked) {
1940 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1941 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1944 p.thread.notifyCleartextNetwork(firstPacket);
1945 } catch (RemoteException ignored) {
1952 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1953 final String procName;
1955 final long memLimit;
1956 final String reportPackage;
1957 synchronized (ActivityManagerService.this) {
1958 procName = mMemWatchDumpProcName;
1959 uid = mMemWatchDumpUid;
1960 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1962 val = mMemWatchProcesses.get(procName, 0);
1965 memLimit = val.first;
1966 reportPackage = val.second;
1969 reportPackage = null;
1972 if (procName == null) {
1976 if (DEBUG_PSS) Slog.d(TAG_PSS,
1977 "Showing dump heap notification from " + procName + "/" + uid);
1979 INotificationManager inm = NotificationManager.getService();
1984 String text = mContext.getString(R.string.dump_heap_notification, procName);
1987 Intent deleteIntent = new Intent();
1988 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1989 Intent intent = new Intent();
1990 intent.setClassName("android", DumpHeapActivity.class.getName());
1991 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1992 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1993 if (reportPackage != null) {
1994 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1996 int userId = UserHandle.getUserId(uid);
1997 Notification notification = new Notification.Builder(mContext)
1998 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2001 .setAutoCancel(true)
2003 .setColor(mContext.getColor(
2004 com.android.internal.R.color.system_notification_accent_color))
2005 .setContentTitle(text)
2007 mContext.getText(R.string.dump_heap_notification_detail))
2008 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2009 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2010 new UserHandle(userId)))
2011 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2012 deleteIntent, 0, UserHandle.OWNER))
2016 int[] outId = new int[1];
2017 inm.enqueueNotificationWithTag("android", "android", null,
2018 R.string.dump_heap_notification,
2019 notification, outId, userId);
2020 } catch (RuntimeException e) {
2021 Slog.w(ActivityManagerService.TAG,
2022 "Error showing notification for dump heap", e);
2023 } catch (RemoteException e) {
2026 case DELETE_DUMPHEAP_MSG: {
2027 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2028 DumpHeapActivity.JAVA_URI,
2029 Intent.FLAG_GRANT_READ_URI_PERMISSION
2030 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2031 UserHandle.myUserId());
2032 synchronized (ActivityManagerService.this) {
2033 mMemWatchDumpFile = null;
2034 mMemWatchDumpProcName = null;
2035 mMemWatchDumpPid = -1;
2036 mMemWatchDumpUid = -1;
2039 case FOREGROUND_PROFILE_CHANGED_MSG: {
2040 dispatchForegroundProfileChanged(msg.arg1);
2042 case REPORT_TIME_TRACKER_MSG: {
2043 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2044 tracker.deliverResult(mContext);
2046 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2047 dispatchUserSwitchComplete(msg.arg1);
2049 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2050 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2052 connection.shutdown();
2053 } catch (RemoteException e) {
2054 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2056 // Only a UiAutomation can set this flag and now that
2057 // it is finished we make sure it is reset to its default.
2058 mUserIsMonkey = false;
2060 case APP_BOOST_DEACTIVATE_MSG : {
2061 synchronized(ActivityManagerService.this) {
2063 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2064 nativeMigrateFromBoost();
2066 mBoostStartTime = 0;
2068 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2069 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2078 static final int COLLECT_PSS_BG_MSG = 1;
2080 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2082 public void handleMessage(Message msg) {
2084 case COLLECT_PSS_BG_MSG: {
2085 long start = SystemClock.uptimeMillis();
2086 MemInfoReader memInfo = null;
2087 synchronized (ActivityManagerService.this) {
2088 if (mFullPssPending) {
2089 mFullPssPending = false;
2090 memInfo = new MemInfoReader();
2093 if (memInfo != null) {
2094 updateCpuStatsNow();
2095 long nativeTotalPss = 0;
2096 synchronized (mProcessCpuTracker) {
2097 final int N = mProcessCpuTracker.countStats();
2098 for (int j=0; j<N; j++) {
2099 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2100 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2101 // This is definitely an application process; skip it.
2104 synchronized (mPidsSelfLocked) {
2105 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2106 // This is one of our own processes; skip it.
2110 nativeTotalPss += Debug.getPss(st.pid, null, null);
2113 memInfo.readMemInfo();
2114 synchronized (ActivityManagerService.this) {
2115 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2116 + (SystemClock.uptimeMillis()-start) + "ms");
2117 final long cachedKb = memInfo.getCachedSizeKb();
2118 final long freeKb = memInfo.getFreeSizeKb();
2119 final long zramKb = memInfo.getZramTotalSizeKb();
2120 final long kernelKb = memInfo.getKernelUsedSizeKb();
2121 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2122 kernelKb*1024, nativeTotalPss*1024);
2123 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2129 long[] tmp = new long[1];
2135 synchronized (ActivityManagerService.this) {
2136 if (mPendingPssProcesses.size() <= 0) {
2137 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2138 "Collected PSS of " + num + " processes in "
2139 + (SystemClock.uptimeMillis() - start) + "ms");
2140 mPendingPssProcesses.clear();
2143 proc = mPendingPssProcesses.remove(0);
2144 procState = proc.pssProcState;
2145 lastPssTime = proc.lastPssTime;
2146 if (proc.thread != null && procState == proc.setProcState
2147 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2148 < SystemClock.uptimeMillis()) {
2156 long pss = Debug.getPss(pid, tmp, null);
2157 synchronized (ActivityManagerService.this) {
2158 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2159 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2161 recordPssSampleLocked(proc, procState, pss, tmp[0],
2162 SystemClock.uptimeMillis());
2172 public void setSystemProcess() {
2174 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2175 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2176 ServiceManager.addService("meminfo", new MemBinder(this));
2177 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2178 ServiceManager.addService("dbinfo", new DbBinder(this));
2179 if (MONITOR_CPU_USAGE) {
2180 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2182 ServiceManager.addService("permission", new PermissionController(this));
2183 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2185 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2186 "android", STOCK_PM_FLAGS);
2187 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2189 synchronized (this) {
2190 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2191 app.persistent = true;
2193 app.maxAdj = ProcessList.SYSTEM_ADJ;
2194 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2195 synchronized (mPidsSelfLocked) {
2196 mPidsSelfLocked.put(app.pid, app);
2198 updateLruProcessLocked(app, false, null);
2199 updateOomAdjLocked();
2201 } catch (PackageManager.NameNotFoundException e) {
2202 throw new RuntimeException(
2203 "Unable to find android system package", e);
2207 public void setWindowManager(WindowManagerService wm) {
2208 mWindowManager = wm;
2209 mStackSupervisor.setWindowManager(wm);
2212 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2213 mUsageStatsService = usageStatsManager;
2216 public void startObservingNativeCrashes() {
2217 final NativeCrashListener ncl = new NativeCrashListener(this);
2221 public IAppOpsService getAppOpsService() {
2222 return mAppOpsService;
2225 static class MemBinder extends Binder {
2226 ActivityManagerService mActivityManagerService;
2227 MemBinder(ActivityManagerService activityManagerService) {
2228 mActivityManagerService = activityManagerService;
2232 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2233 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2234 != PackageManager.PERMISSION_GRANTED) {
2235 pw.println("Permission Denial: can't dump meminfo from from pid="
2236 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2237 + " without permission " + android.Manifest.permission.DUMP);
2241 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2245 static class GraphicsBinder extends Binder {
2246 ActivityManagerService mActivityManagerService;
2247 GraphicsBinder(ActivityManagerService activityManagerService) {
2248 mActivityManagerService = activityManagerService;
2252 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2253 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2254 != PackageManager.PERMISSION_GRANTED) {
2255 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2256 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2257 + " without permission " + android.Manifest.permission.DUMP);
2261 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2265 static class DbBinder extends Binder {
2266 ActivityManagerService mActivityManagerService;
2267 DbBinder(ActivityManagerService activityManagerService) {
2268 mActivityManagerService = activityManagerService;
2272 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2273 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2274 != PackageManager.PERMISSION_GRANTED) {
2275 pw.println("Permission Denial: can't dump dbinfo from from pid="
2276 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2277 + " without permission " + android.Manifest.permission.DUMP);
2281 mActivityManagerService.dumpDbInfo(fd, pw, args);
2285 static class CpuBinder extends Binder {
2286 ActivityManagerService mActivityManagerService;
2287 CpuBinder(ActivityManagerService activityManagerService) {
2288 mActivityManagerService = activityManagerService;
2292 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2293 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2294 != PackageManager.PERMISSION_GRANTED) {
2295 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2296 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2297 + " without permission " + android.Manifest.permission.DUMP);
2301 synchronized (mActivityManagerService.mProcessCpuTracker) {
2302 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2303 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2304 SystemClock.uptimeMillis()));
2309 public static final class Lifecycle extends SystemService {
2310 private final ActivityManagerService mService;
2312 public Lifecycle(Context context) {
2314 mService = new ActivityManagerService(context);
2318 public void onStart() {
2322 public ActivityManagerService getService() {
2327 // Note: This method is invoked on the main thread but may need to attach various
2328 // handlers to other threads. So take care to be explicit about the looper.
2329 public ActivityManagerService(Context systemContext) {
2330 mContext = systemContext;
2331 mFactoryTest = FactoryTest.getMode();
2332 mSystemThread = ActivityThread.currentActivityThread();
2334 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2336 mHandlerThread = new ServiceThread(TAG,
2337 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2338 mHandlerThread.start();
2339 mHandler = new MainHandler(mHandlerThread.getLooper());
2340 mUiHandler = new UiHandler();
2342 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2343 "foreground", BROADCAST_FG_TIMEOUT, false);
2344 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2345 "background", BROADCAST_BG_TIMEOUT, true);
2346 mBroadcastQueues[0] = mFgBroadcastQueue;
2347 mBroadcastQueues[1] = mBgBroadcastQueue;
2349 mServices = new ActiveServices(this);
2350 mProviderMap = new ProviderMap(this);
2352 // TODO: Move creation of battery stats service outside of activity manager service.
2353 File dataDir = Environment.getDataDirectory();
2354 File systemDir = new File(dataDir, "system");
2356 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2357 mBatteryStatsService.getActiveStatistics().readLocked();
2358 mBatteryStatsService.scheduleWriteToDisk();
2359 mOnBattery = DEBUG_POWER ? true
2360 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2361 mBatteryStatsService.getActiveStatistics().setCallback(this);
2363 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2365 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2367 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2369 // User 0 is the first and only user that runs at boot.
2370 mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2371 mUserLru.add(UserHandle.USER_OWNER);
2372 updateStartedUserArrayLocked();
2374 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2375 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2377 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2379 mConfiguration.setToDefaults();
2380 mConfiguration.setLocale(Locale.getDefault());
2382 mConfigurationSeq = mConfiguration.seq = 1;
2383 mProcessCpuTracker.init();
2385 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2386 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2387 mRecentTasks = new RecentTasks(this);
2388 mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2389 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2391 mProcessCpuThread = new Thread("CpuTracker") {
2397 synchronized(this) {
2398 final long now = SystemClock.uptimeMillis();
2399 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2400 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2401 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2402 // + ", write delay=" + nextWriteDelay);
2403 if (nextWriteDelay < nextCpuDelay) {
2404 nextCpuDelay = nextWriteDelay;
2406 if (nextCpuDelay > 0) {
2407 mProcessCpuMutexFree.set(true);
2408 this.wait(nextCpuDelay);
2411 } catch (InterruptedException e) {
2413 updateCpuStatsNow();
2414 } catch (Exception e) {
2415 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2421 Watchdog.getInstance().addMonitor(this);
2422 Watchdog.getInstance().addThread(mHandler);
2425 public void setSystemServiceManager(SystemServiceManager mgr) {
2426 mSystemServiceManager = mgr;
2429 public void setInstaller(Installer installer) {
2430 mInstaller = installer;
2433 private void start() {
2434 Process.removeAllProcessGroups();
2435 mProcessCpuThread.start();
2437 mBatteryStatsService.publish(mContext);
2438 mAppOpsService.publish(mContext);
2439 Slog.d("AppOps", "AppOpsService published");
2440 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2443 public void initPowerManagement() {
2444 mStackSupervisor.initPowerManagement();
2445 mBatteryStatsService.initPowerManagement();
2446 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2447 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2448 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2449 mVoiceWakeLock.setReferenceCounted(false);
2453 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2454 throws RemoteException {
2455 if (code == SYSPROPS_TRANSACTION) {
2456 // We need to tell all apps about the system property change.
2457 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2458 synchronized(this) {
2459 final int NP = mProcessNames.getMap().size();
2460 for (int ip=0; ip<NP; ip++) {
2461 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2462 final int NA = apps.size();
2463 for (int ia=0; ia<NA; ia++) {
2464 ProcessRecord app = apps.valueAt(ia);
2465 if (app.thread != null) {
2466 procs.add(app.thread.asBinder());
2472 int N = procs.size();
2473 for (int i=0; i<N; i++) {
2474 Parcel data2 = Parcel.obtain();
2476 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2477 } catch (RemoteException e) {
2483 return super.onTransact(code, data, reply, flags);
2484 } catch (RuntimeException e) {
2485 // The activity manager only throws security exceptions, so let's
2487 if (!(e instanceof SecurityException)) {
2488 Slog.wtf(TAG, "Activity Manager Crash", e);
2494 void updateCpuStats() {
2495 final long now = SystemClock.uptimeMillis();
2496 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2499 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2500 synchronized (mProcessCpuThread) {
2501 mProcessCpuThread.notify();
2506 void updateCpuStatsNow() {
2507 synchronized (mProcessCpuTracker) {
2508 mProcessCpuMutexFree.set(false);
2509 final long now = SystemClock.uptimeMillis();
2510 boolean haveNewCpuStats = false;
2512 if (MONITOR_CPU_USAGE &&
2513 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2514 mLastCpuTime.set(now);
2515 mProcessCpuTracker.update();
2516 if (mProcessCpuTracker.hasGoodLastStats()) {
2517 haveNewCpuStats = true;
2518 //Slog.i(TAG, mProcessCpu.printCurrentState());
2519 //Slog.i(TAG, "Total CPU usage: "
2520 // + mProcessCpu.getTotalCpuPercent() + "%");
2522 // Slog the cpu usage if the property is set.
2523 if ("true".equals(SystemProperties.get("events.cpu"))) {
2524 int user = mProcessCpuTracker.getLastUserTime();
2525 int system = mProcessCpuTracker.getLastSystemTime();
2526 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2527 int irq = mProcessCpuTracker.getLastIrqTime();
2528 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2529 int idle = mProcessCpuTracker.getLastIdleTime();
2531 int total = user + system + iowait + irq + softIrq + idle;
2532 if (total == 0) total = 1;
2534 EventLog.writeEvent(EventLogTags.CPU,
2535 ((user+system+iowait+irq+softIrq) * 100) / total,
2536 (user * 100) / total,
2537 (system * 100) / total,
2538 (iowait * 100) / total,
2539 (irq * 100) / total,
2540 (softIrq * 100) / total);
2545 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2546 synchronized(bstats) {
2547 synchronized(mPidsSelfLocked) {
2548 if (haveNewCpuStats) {
2549 if (bstats.startAddingCpuLocked()) {
2552 final int N = mProcessCpuTracker.countStats();
2553 for (int i=0; i<N; i++) {
2554 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2558 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2559 totalUTime += st.rel_utime;
2560 totalSTime += st.rel_stime;
2562 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2563 if (ps == null || !ps.isActive()) {
2564 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2565 pr.info.uid, pr.processName);
2567 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2568 pr.curCpuTime += st.rel_utime + st.rel_stime;
2570 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2571 if (ps == null || !ps.isActive()) {
2572 st.batteryStats = ps = bstats.getProcessStatsLocked(
2573 bstats.mapUid(st.uid), st.name);
2575 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2578 final int userTime = mProcessCpuTracker.getLastUserTime();
2579 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2580 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2581 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2582 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2583 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2584 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2585 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2590 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2591 mLastWriteTime = now;
2592 mBatteryStatsService.scheduleWriteToDisk();
2599 public void batteryNeedsCpuUpdate() {
2600 updateCpuStatsNow();
2604 public void batteryPowerChanged(boolean onBattery) {
2605 // When plugging in, update the CPU stats first before changing
2607 updateCpuStatsNow();
2608 synchronized (this) {
2609 synchronized(mPidsSelfLocked) {
2610 mOnBattery = DEBUG_POWER ? true : onBattery;
2616 public void batterySendBroadcast(Intent intent) {
2617 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2618 AppOpsManager.OP_NONE, null, false, false,
2619 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2623 * Initialize the application bind args. These are passed to each
2624 * process when the bindApplication() IPC is sent to the process. They're
2625 * lazily setup to make sure the services are running when they're asked for.
2627 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2628 if (mAppBindArgs == null) {
2629 mAppBindArgs = new HashMap<>();
2631 // Isolated processes won't get this optimization, so that we don't
2632 // violate the rules about which services they have access to.
2634 // Setup the application init args
2635 mAppBindArgs.put("package", ServiceManager.getService("package"));
2636 mAppBindArgs.put("window", ServiceManager.getService("window"));
2637 mAppBindArgs.put(Context.ALARM_SERVICE,
2638 ServiceManager.getService(Context.ALARM_SERVICE));
2641 return mAppBindArgs;
2644 final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2645 if (r != null && mFocusedActivity != r) {
2646 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2647 ActivityRecord last = mFocusedActivity;
2648 mFocusedActivity = r;
2649 if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2650 && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2651 if (mCurAppTimeTracker != r.appTimeTracker) {
2652 // We are switching app tracking. Complete the current one.
2653 if (mCurAppTimeTracker != null) {
2654 mCurAppTimeTracker.stop();
2655 mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2656 mCurAppTimeTracker).sendToTarget();
2657 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2658 mCurAppTimeTracker = null;
2660 if (r.appTimeTracker != null) {
2661 mCurAppTimeTracker = r.appTimeTracker;
2662 startTimeTrackingFocusedActivityLocked();
2665 startTimeTrackingFocusedActivityLocked();
2668 r.appTimeTracker = null;
2670 if (r.task != null && r.task.voiceInteractor != null) {
2671 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2673 finishRunningVoiceLocked();
2674 if (last != null && last.task.voiceSession != null) {
2675 // We had been in a voice interaction session, but now focused has
2676 // move to something different. Just finish the session, we can't
2677 // return to it and retain the proper state and synchronization with
2678 // the voice interaction service.
2679 finishVoiceTask(last.task.voiceSession);
2682 if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2683 mWindowManager.setFocusedApp(r.appToken, true);
2685 applyUpdateLockStateLocked(r);
2686 if (mFocusedActivity.userId != mLastFocusedUserId) {
2687 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2688 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2689 mFocusedActivity.userId, 0));
2690 mLastFocusedUserId = mFocusedActivity.userId;
2693 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2694 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2695 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2698 final void clearFocusedActivity(ActivityRecord r) {
2699 if (mFocusedActivity == r) {
2700 ActivityStack stack = mStackSupervisor.getFocusedStack();
2701 if (stack != null) {
2702 ActivityRecord top = stack.topActivity();
2703 if (top != null && top.userId != mLastFocusedUserId) {
2704 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2705 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2707 mLastFocusedUserId = top.userId;
2710 mFocusedActivity = null;
2711 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2716 public void setFocusedStack(int stackId) {
2717 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2718 synchronized (ActivityManagerService.this) {
2719 ActivityStack stack = mStackSupervisor.getStack(stackId);
2720 if (stack != null) {
2721 ActivityRecord r = stack.topRunningActivityLocked(null);
2723 setFocusedActivityLocked(r, "setFocusedStack");
2724 mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2730 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2732 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2733 synchronized (ActivityManagerService.this) {
2734 if (listener != null) {
2735 mTaskStackListeners.register(listener);
2741 public void notifyActivityDrawn(IBinder token) {
2742 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2743 synchronized (this) {
2744 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2746 r.task.stack.notifyActivityDrawnLocked(r);
2751 final void applyUpdateLockStateLocked(ActivityRecord r) {
2752 // Modifications to the UpdateLock state are done on our handler, outside
2753 // the activity manager's locks. The new state is determined based on the
2754 // state *now* of the relevant activity record. The object is passed to
2755 // the handler solely for logging detail, not to be consulted/modified.
2756 final boolean nextState = r != null && r.immersive;
2757 mHandler.sendMessage(
2758 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2761 final void showAskCompatModeDialogLocked(ActivityRecord r) {
2762 Message msg = Message.obtain();
2763 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2764 msg.obj = r.task.askedCompatMode ? null : r;
2765 mUiHandler.sendMessage(msg);
2768 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2769 String what, Object obj, ProcessRecord srcApp) {
2770 app.lastActivityTime = now;
2772 if (app.activities.size() > 0) {
2773 // Don't want to touch dependent processes that are hosting activities.
2777 int lrui = mLruProcesses.lastIndexOf(app);
2779 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2780 + what + " " + obj + " from " + srcApp);
2784 if (lrui >= index) {
2785 // Don't want to cause this to move dependent processes *back* in the
2786 // list as if they were less frequently used.
2790 if (lrui >= mLruProcessActivityStart) {
2791 // Don't want to touch dependent processes that are hosting activities.
2795 mLruProcesses.remove(lrui);
2799 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2800 + " in LRU list: " + app);
2801 mLruProcesses.add(index, app);
2805 private static void killProcessGroup(int uid, int pid) {
2806 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2807 Process.killProcessGroup(uid, pid);
2808 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2811 final void removeLruProcessLocked(ProcessRecord app) {
2812 int lrui = mLruProcesses.lastIndexOf(app);
2815 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2816 Process.killProcessQuiet(app.pid);
2817 killProcessGroup(app.info.uid, app.pid);
2819 if (lrui <= mLruProcessActivityStart) {
2820 mLruProcessActivityStart--;
2822 if (lrui <= mLruProcessServiceStart) {
2823 mLruProcessServiceStart--;
2825 mLruProcesses.remove(lrui);
2829 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2830 ProcessRecord client) {
2831 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2832 || app.treatLikeActivity;
2833 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2834 if (!activityChange && hasActivity) {
2835 // The process has activities, so we are only allowing activity-based adjustments
2836 // to move it. It should be kept in the front of the list with other
2837 // processes that have activities, and we don't want those to change their
2838 // order except due to activity operations.
2843 final long now = SystemClock.uptimeMillis();
2844 app.lastActivityTime = now;
2846 // First a quick reject: if the app is already at the position we will
2847 // put it, then there is nothing to do.
2849 final int N = mLruProcesses.size();
2850 if (N > 0 && mLruProcesses.get(N-1) == app) {
2851 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2855 if (mLruProcessServiceStart > 0
2856 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2857 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2862 int lrui = mLruProcesses.lastIndexOf(app);
2864 if (app.persistent && lrui >= 0) {
2865 // We don't care about the position of persistent processes, as long as
2866 // they are in the list.
2867 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2871 /* In progress: compute new position first, so we can avoid doing work
2872 if the process is not actually going to move. Not yet working.
2875 boolean inActivity = false, inService = false;
2877 // Process has activities, put it at the very tipsy-top.
2878 addIndex = mLruProcesses.size();
2879 nextIndex = mLruProcessServiceStart;
2881 } else if (hasService) {
2882 // Process has services, put it at the top of the service list.
2883 addIndex = mLruProcessActivityStart;
2884 nextIndex = mLruProcessServiceStart;
2888 // Process not otherwise of interest, it goes to the top of the non-service area.
2889 addIndex = mLruProcessServiceStart;
2890 if (client != null) {
2891 int clientIndex = mLruProcesses.lastIndexOf(client);
2892 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2894 if (clientIndex >= 0 && addIndex > clientIndex) {
2895 addIndex = clientIndex;
2898 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2901 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2902 + mLruProcessActivityStart + "): " + app);
2906 if (lrui < mLruProcessActivityStart) {
2907 mLruProcessActivityStart--;
2909 if (lrui < mLruProcessServiceStart) {
2910 mLruProcessServiceStart--;
2913 if (addIndex > lrui) {
2916 if (nextIndex > lrui) {
2920 mLruProcesses.remove(lrui);
2924 mLruProcesses.add(addIndex, app);
2926 mLruProcessActivityStart++;
2929 mLruProcessActivityStart++;
2935 final int N = mLruProcesses.size();
2936 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2937 // Process doesn't have activities, but has clients with
2938 // activities... move it up, but one below the top (the top
2939 // should always have a real activity).
2940 if (DEBUG_LRU) Slog.d(TAG_LRU,
2941 "Adding to second-top of LRU activity list: " + app);
2942 mLruProcesses.add(N - 1, app);
2943 // To keep it from spamming the LRU list (by making a bunch of clients),
2944 // we will push down any other entries owned by the app.
2945 final int uid = app.info.uid;
2946 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2947 ProcessRecord subProc = mLruProcesses.get(i);
2948 if (subProc.info.uid == uid) {
2949 // We want to push this one down the list. If the process after
2950 // it is for the same uid, however, don't do so, because we don't
2951 // want them internally to be re-ordered.
2952 if (mLruProcesses.get(i - 1).info.uid != uid) {
2953 if (DEBUG_LRU) Slog.d(TAG_LRU,
2954 "Pushing uid " + uid + " swapping at " + i + ": "
2955 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2956 ProcessRecord tmp = mLruProcesses.get(i);
2957 mLruProcesses.set(i, mLruProcesses.get(i - 1));
2958 mLruProcesses.set(i - 1, tmp);
2962 // A gap, we can stop here.
2967 // Process has activities, put it at the very tipsy-top.
2968 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2969 mLruProcesses.add(app);
2971 nextIndex = mLruProcessServiceStart;
2972 } else if (hasService) {
2973 // Process has services, put it at the top of the service list.
2974 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2975 mLruProcesses.add(mLruProcessActivityStart, app);
2976 nextIndex = mLruProcessServiceStart;
2977 mLruProcessActivityStart++;
2979 // Process not otherwise of interest, it goes to the top of the non-service area.
2980 int index = mLruProcessServiceStart;
2981 if (client != null) {
2982 // If there is a client, don't allow the process to be moved up higher
2983 // in the list than that client.
2984 int clientIndex = mLruProcesses.lastIndexOf(client);
2985 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2986 + " when updating " + app);
2987 if (clientIndex <= lrui) {
2988 // Don't allow the client index restriction to push it down farther in the
2989 // list than it already is.
2992 if (clientIndex >= 0 && index > clientIndex) {
2993 index = clientIndex;
2996 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2997 mLruProcesses.add(index, app);
2998 nextIndex = index-1;
2999 mLruProcessActivityStart++;
3000 mLruProcessServiceStart++;
3003 // If the app is currently using a content provider or service,
3004 // bump those processes as well.
3005 for (int j=app.connections.size()-1; j>=0; j--) {
3006 ConnectionRecord cr = app.connections.valueAt(j);
3007 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3008 && cr.binding.service.app != null
3009 && cr.binding.service.app.lruSeq != mLruSeq
3010 && !cr.binding.service.app.persistent) {
3011 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3012 "service connection", cr, app);
3015 for (int j=app.conProviders.size()-1; j>=0; j--) {
3016 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3017 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3018 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3019 "provider reference", cpr, app);
3024 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3025 if (uid == Process.SYSTEM_UID) {
3026 // The system gets to run in any process. If there are multiple
3027 // processes with the same uid, just pick the first (this
3028 // should never happen).
3029 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3030 if (procs == null) return null;
3031 final int procCount = procs.size();
3032 for (int i = 0; i < procCount; i++) {
3033 final int procUid = procs.keyAt(i);
3034 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3035 // Don't use an app process or different user process for system component.
3038 return procs.valueAt(i);
3041 ProcessRecord proc = mProcessNames.get(processName, uid);
3042 if (false && proc != null && !keepIfLarge
3043 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3044 && proc.lastCachedPss >= 4000) {
3045 // Turn this condition on to cause killing to happen regularly, for testing.
3046 if (proc.baseProcessTracker != null) {
3047 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3049 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3050 } else if (proc != null && !keepIfLarge
3051 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3052 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3053 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3054 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3055 if (proc.baseProcessTracker != null) {
3056 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3058 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3064 void ensurePackageDexOpt(String packageName) {
3065 IPackageManager pm = AppGlobals.getPackageManager();
3067 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3070 } catch (RemoteException e) {
3074 boolean isNextTransitionForward() {
3075 int transit = mWindowManager.getPendingAppTransition();
3076 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3077 || transit == AppTransition.TRANSIT_TASK_OPEN
3078 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3081 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3082 String processName, String abiOverride, int uid, Runnable crashHandler) {
3083 synchronized(this) {
3084 ApplicationInfo info = new ApplicationInfo();
3085 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3086 // For isolated processes, the former contains the parent's uid and the latter the
3087 // actual uid of the isolated process.
3088 // In the special case introduced by this method (which is, starting an isolated
3089 // process directly from the SystemServer without an actual parent app process) the
3090 // closest thing to a parent's uid is SYSTEM_UID.
3091 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3092 // the |isolated| logic in the ProcessRecord constructor.
3093 info.uid = Process.SYSTEM_UID;
3094 info.processName = processName;
3095 info.className = entryPoint;
3096 info.packageName = "android";
3097 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3098 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3099 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3100 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3102 return proc != null ? proc.pid : 0;
3106 final ProcessRecord startProcessLocked(String processName,
3107 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3108 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3109 boolean isolated, boolean keepIfLarge) {
3110 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3111 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3112 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3113 null /* crashHandler */);
3116 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3117 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3118 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3119 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3120 long startTime = SystemClock.elapsedRealtime();
3123 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3124 checkTime(startTime, "startProcess: after getProcessRecord");
3126 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3127 // If we are in the background, then check to see if this process
3128 // is bad. If so, we will just silently fail.
3129 if (mBadProcesses.get(info.processName, info.uid) != null) {
3130 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3131 + "/" + info.processName);
3135 // When the user is explicitly starting a process, then clear its
3136 // crash count so that we won't make it bad until they see at
3137 // least one crash dialog again, and make the process good again
3138 // if it had been bad.
3139 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3140 + "/" + info.processName);
3141 mProcessCrashTimes.remove(info.processName, info.uid);
3142 if (mBadProcesses.get(info.processName, info.uid) != null) {
3143 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3144 UserHandle.getUserId(info.uid), info.uid,
3146 mBadProcesses.remove(info.processName, info.uid);
3153 // If this is an isolated process, it can't re-use an existing process.
3157 // app launch boost for big.little configurations
3158 // use cpusets to migrate freshly launched tasks to big cores
3159 synchronized(ActivityManagerService.this) {
3160 nativeMigrateToBoost();
3162 mBoostStartTime = SystemClock.uptimeMillis();
3163 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3164 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3167 // We don't have to do anything more if:
3168 // (1) There is an existing application record; and
3169 // (2) The caller doesn't think it is dead, OR there is no thread
3170 // object attached to it so we know it couldn't have crashed; and
3171 // (3) There is a pid assigned to it, so it is either starting or
3173 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3174 + " app=" + app + " knownToBeDead=" + knownToBeDead
3175 + " thread=" + (app != null ? app.thread : null)
3176 + " pid=" + (app != null ? app.pid : -1));
3177 if (app != null && app.pid > 0) {
3178 if (!knownToBeDead || app.thread == null) {
3179 // We already have the app running, or are waiting for it to
3180 // come up (we have a pid but not yet its thread), so keep it.
3181 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3182 // If this is a new package in the process, add the package to the list
3183 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3184 checkTime(startTime, "startProcess: done, added package to proc");
3188 // An application record is attached to a previous process,
3190 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3191 checkTime(startTime, "startProcess: bad proc running, killing");
3192 killProcessGroup(app.info.uid, app.pid);
3193 handleAppDiedLocked(app, true, true);
3194 checkTime(startTime, "startProcess: done killing old proc");
3197 String hostingNameStr = hostingName != null
3198 ? hostingName.flattenToShortString() : null;
3201 checkTime(startTime, "startProcess: creating new process record");
3202 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3204 Slog.w(TAG, "Failed making new process record for "
3205 + processName + "/" + info.uid + " isolated=" + isolated);
3208 app.crashHandler = crashHandler;
3209 checkTime(startTime, "startProcess: done creating new process record");
3211 // If this is a new package in the process, add the package to the list
3212 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3213 checkTime(startTime, "startProcess: added package to existing proc");
3216 // If the system is not ready yet, then hold off on starting this
3217 // process until it is.
3218 if (!mProcessesReady
3219 && !isAllowedWhileBooting(info)
3220 && !allowWhileBooting) {
3221 if (!mProcessesOnHold.contains(app)) {
3222 mProcessesOnHold.add(app);
3224 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3225 "System not ready, putting on hold: " + app);
3226 checkTime(startTime, "startProcess: returning with proc on hold");
3230 checkTime(startTime, "startProcess: stepping in to startProcess");
3232 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3233 checkTime(startTime, "startProcess: done starting proc!");
3234 return (app.pid != 0) ? app : null;
3237 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3238 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3241 private final void startProcessLocked(ProcessRecord app,
3242 String hostingType, String hostingNameStr) {
3243 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3244 null /* entryPoint */, null /* entryPointArgs */);
3247 private final void startProcessLocked(ProcessRecord app, String hostingType,
3248 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3249 long startTime = SystemClock.elapsedRealtime();
3250 if (app.pid > 0 && app.pid != MY_PID) {
3251 checkTime(startTime, "startProcess: removing from pids map");
3252 synchronized (mPidsSelfLocked) {
3253 mPidsSelfLocked.remove(app.pid);
3254 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3256 checkTime(startTime, "startProcess: done removing from pids map");
3260 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3261 "startProcessLocked removing on hold: " + app);
3262 mProcessesOnHold.remove(app);
3264 checkTime(startTime, "startProcess: starting to update cpu stats");
3266 checkTime(startTime, "startProcess: done updating cpu stats");
3270 if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3271 // This is caught below as if we had failed to fork zygote
3272 throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3274 } catch (RemoteException e) {
3275 throw e.rethrowAsRuntimeException();
3280 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3281 if (!app.isolated) {
3282 int[] permGids = null;
3284 checkTime(startTime, "startProcess: getting gids from package manager");
3285 final IPackageManager pm = AppGlobals.getPackageManager();
3286 permGids = pm.getPackageGids(app.info.packageName, app.userId);
3287 MountServiceInternal mountServiceInternal = LocalServices.getService(
3288 MountServiceInternal.class);
3289 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3290 app.info.packageName);
3291 } catch (RemoteException e) {
3292 throw e.rethrowAsRuntimeException();
3296 * Add shared application and profile GIDs so applications can share some
3297 * resources like shared libraries and access user-wide resources
3299 if (ArrayUtils.isEmpty(permGids)) {
3302 gids = new int[permGids.length + 2];
3303 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3305 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3306 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3308 checkTime(startTime, "startProcess: building args");
3309 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3310 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3311 && mTopComponent != null
3312 && app.processName.equals(mTopComponent.getPackageName())) {
3315 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3316 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3321 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3322 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3323 // Also turn on CheckJNI for debuggable apps. It's quite
3324 // awkward to turn on otherwise.
3325 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3327 // Run the app in safe mode if its manifest requests so or the
3328 // system is booted in safe mode.
3329 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3330 mSafeMode == true) {
3331 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3333 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3334 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3336 String jitDebugProperty = SystemProperties.get("debug.usejit");
3337 if ("true".equals(jitDebugProperty)) {
3338 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3339 } else if (!"false".equals(jitDebugProperty)) {
3340 // If we didn't force disable by setting false, defer to the dalvik vm options.
3341 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3342 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3345 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3346 if ("true".equals(genDebugInfoProperty)) {
3347 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3349 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3350 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3352 if ("1".equals(SystemProperties.get("debug.assert"))) {
3353 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3356 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3357 if (requiredAbi == null) {
3358 requiredAbi = Build.SUPPORTED_ABIS[0];
3361 String instructionSet = null;
3362 if (app.info.primaryCpuAbi != null) {
3363 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3367 app.requiredAbi = requiredAbi;
3368 app.instructionSet = instructionSet;
3370 // Start the process. It will either succeed and return a result containing
3371 // the PID of the new process, or else throw a RuntimeException.
3372 boolean isActivityProcess = (entryPoint == null);
3373 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3374 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3376 checkTime(startTime, "startProcess: asking zygote to start proc");
3377 Process.ProcessStartResult startResult = Process.start(entryPoint,
3378 app.processName, uid, uid, gids, debugFlags, mountExternal,
3379 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3380 app.info.dataDir, entryPointArgs);
3381 checkTime(startTime, "startProcess: returned from zygote!");
3382 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3385 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3387 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3388 checkTime(startTime, "startProcess: done updating battery stats");
3390 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3391 UserHandle.getUserId(uid), startResult.pid, uid,
3392 app.processName, hostingType,
3393 hostingNameStr != null ? hostingNameStr : "");
3395 if (app.persistent) {
3396 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3399 checkTime(startTime, "startProcess: building log message");
3400 StringBuilder buf = mStringBuilder;
3402 buf.append("Start proc ");
3403 buf.append(startResult.pid);
3405 buf.append(app.processName);
3407 UserHandle.formatUid(buf, uid);
3408 if (!isActivityProcess) {
3410 buf.append(entryPoint);
3413 buf.append(" for ");
3414 buf.append(hostingType);
3415 if (hostingNameStr != null) {
3417 buf.append(hostingNameStr);
3419 Slog.i(TAG, buf.toString());
3420 app.setPid(startResult.pid);
3421 app.usingWrapper = startResult.usingWrapper;
3422 app.removed = false;
3424 app.killedByAm = false;
3425 checkTime(startTime, "startProcess: starting to update pids map");
3426 synchronized (mPidsSelfLocked) {
3427 this.mPidsSelfLocked.put(startResult.pid, app);
3428 if (isActivityProcess) {
3429 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3431 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3432 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3435 checkTime(startTime, "startProcess: done updating pids map");
3436 } catch (RuntimeException e) {
3437 // XXX do better error recovery.
3439 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3441 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3443 Slog.e(TAG, "Failure starting process " + app.processName, e);
3447 void updateUsageStats(ActivityRecord component, boolean resumed) {
3448 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3449 "updateUsageStats: comp=" + component + "res=" + resumed);
3450 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3452 if (mUsageStatsService != null) {
3453 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3454 UsageEvents.Event.MOVE_TO_FOREGROUND);
3456 synchronized (stats) {
3457 stats.noteActivityResumedLocked(component.app.uid);
3460 if (mUsageStatsService != null) {
3461 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3462 UsageEvents.Event.MOVE_TO_BACKGROUND);
3464 synchronized (stats) {
3465 stats.noteActivityPausedLocked(component.app.uid);
3470 Intent getHomeIntent() {
3471 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3472 intent.setComponent(mTopComponent);
3473 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3474 intent.addCategory(Intent.CATEGORY_HOME);
3479 boolean startHomeActivityLocked(int userId, String reason) {
3480 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3481 && mTopAction == null) {
3482 // We are running in factory test mode, but unable to find
3483 // the factory test app, so just sit around displaying the
3484 // error message and don't try to start anything.
3487 Intent intent = getHomeIntent();
3488 ActivityInfo aInfo =
3489 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3490 if (aInfo != null) {
3491 intent.setComponent(new ComponentName(
3492 aInfo.applicationInfo.packageName, aInfo.name));
3493 // Don't do this if the home app is currently being
3495 aInfo = new ActivityInfo(aInfo);
3496 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3497 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3498 aInfo.applicationInfo.uid, true);
3499 if (app == null || app.instrumentationClass == null) {
3500 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3501 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3508 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3509 ActivityInfo ai = null;
3510 ComponentName comp = intent.getComponent();
3514 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3516 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3518 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3522 ai = info.activityInfo;
3525 } catch (RemoteException e) {
3533 * Starts the "new version setup screen" if appropriate.
3535 void startSetupActivityLocked() {
3536 // Only do this once per boot.
3537 if (mCheckedForSetup) {
3541 // We will show this screen if the current one is a different
3542 // version than the last one shown, and we are not running in
3543 // low-level factory test mode.
3544 final ContentResolver resolver = mContext.getContentResolver();
3545 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3546 Settings.Global.getInt(resolver,
3547 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3548 mCheckedForSetup = true;
3550 // See if we should be showing the platform update setup UI.
3551 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3552 List<ResolveInfo> ris = mContext.getPackageManager()
3553 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3555 // We don't allow third party apps to replace this.
3556 ResolveInfo ri = null;
3557 for (int i=0; ris != null && i<ris.size(); i++) {
3558 if ((ris.get(i).activityInfo.applicationInfo.flags
3559 & ApplicationInfo.FLAG_SYSTEM) != 0) {
3566 String vers = ri.activityInfo.metaData != null
3567 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3569 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3570 vers = ri.activityInfo.applicationInfo.metaData.getString(
3571 Intent.METADATA_SETUP_VERSION);
3573 String lastVers = Settings.Secure.getString(
3574 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3575 if (vers != null && !vers.equals(lastVers)) {
3576 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3577 intent.setComponent(new ComponentName(
3578 ri.activityInfo.packageName, ri.activityInfo.name));
3579 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3580 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3587 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3588 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3591 void enforceNotIsolatedCaller(String caller) {
3592 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3593 throw new SecurityException("Isolated process not allowed to call " + caller);
3597 void enforceShellRestriction(String restriction, int userHandle) {
3598 if (Binder.getCallingUid() == Process.SHELL_UID) {
3600 || mUserManager.hasUserRestriction(restriction, userHandle)) {
3601 throw new SecurityException("Shell does not have permission to access user "
3608 public int getFrontActivityScreenCompatMode() {
3609 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3610 synchronized (this) {
3611 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3616 public void setFrontActivityScreenCompatMode(int mode) {
3617 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3618 "setFrontActivityScreenCompatMode");
3619 synchronized (this) {
3620 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3625 public int getPackageScreenCompatMode(String packageName) {
3626 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3627 synchronized (this) {
3628 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3633 public void setPackageScreenCompatMode(String packageName, int mode) {
3634 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3635 "setPackageScreenCompatMode");
3636 synchronized (this) {
3637 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3642 public boolean getPackageAskScreenCompat(String packageName) {
3643 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3644 synchronized (this) {
3645 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3650 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3651 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3652 "setPackageAskScreenCompat");
3653 synchronized (this) {
3654 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3658 private boolean hasUsageStatsPermission(String callingPackage) {
3659 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3660 Binder.getCallingUid(), callingPackage);
3661 if (mode == AppOpsManager.MODE_DEFAULT) {
3662 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3663 == PackageManager.PERMISSION_GRANTED;
3665 return mode == AppOpsManager.MODE_ALLOWED;
3669 public int getPackageProcessState(String packageName, String callingPackage) {
3670 if (!hasUsageStatsPermission(callingPackage)) {
3671 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3672 "getPackageProcessState");
3675 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3676 synchronized (this) {
3677 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3678 final ProcessRecord proc = mLruProcesses.get(i);
3679 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3680 || procState > proc.setProcState) {
3681 boolean found = false;
3682 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3683 if (proc.pkgList.keyAt(j).equals(packageName)) {
3684 procState = proc.setProcState;
3688 if (proc.pkgDeps != null && !found) {
3689 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3690 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3691 procState = proc.setProcState;
3703 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3704 synchronized (this) {
3705 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3709 if (app.trimMemoryLevel < level && app.thread != null &&
3710 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3711 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3713 app.thread.scheduleTrimMemory(level);
3714 app.trimMemoryLevel = level;
3716 } catch (RemoteException e) {
3717 // Fallthrough to failure case.
3724 private void dispatchProcessesChanged() {
3726 synchronized (this) {
3727 N = mPendingProcessChanges.size();
3728 if (mActiveProcessChanges.length < N) {
3729 mActiveProcessChanges = new ProcessChangeItem[N];
3731 mPendingProcessChanges.toArray(mActiveProcessChanges);
3732 mPendingProcessChanges.clear();
3733 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3734 "*** Delivering " + N + " process changes");
3737 int i = mProcessObservers.beginBroadcast();
3740 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3741 if (observer != null) {
3743 for (int j=0; j<N; j++) {
3744 ProcessChangeItem item = mActiveProcessChanges[j];
3745 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3746 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3747 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3748 + item.uid + ": " + item.foregroundActivities);
3749 observer.onForegroundActivitiesChanged(item.pid, item.uid,
3750 item.foregroundActivities);
3752 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3753 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3754 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3755 + ": " + item.processState);
3756 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3759 } catch (RemoteException e) {
3763 mProcessObservers.finishBroadcast();
3765 synchronized (this) {
3766 for (int j=0; j<N; j++) {
3767 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3772 private void dispatchProcessDied(int pid, int uid) {
3773 int i = mProcessObservers.beginBroadcast();
3776 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3777 if (observer != null) {
3779 observer.onProcessDied(pid, uid);
3780 } catch (RemoteException e) {
3784 mProcessObservers.finishBroadcast();
3787 private void dispatchUidsChanged() {
3789 synchronized (this) {
3790 N = mPendingUidChanges.size();
3791 if (mActiveUidChanges.length < N) {
3792 mActiveUidChanges = new UidRecord.ChangeItem[N];
3794 for (int i=0; i<N; i++) {
3795 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3796 mActiveUidChanges[i] = change;
3797 change.uidRecord.pendingChange = null;
3798 change.uidRecord = null;
3800 mPendingUidChanges.clear();
3801 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3802 "*** Delivering " + N + " uid changes");
3805 if (mLocalPowerManager != null) {
3806 for (int j=0; j<N; j++) {
3807 UidRecord.ChangeItem item = mActiveUidChanges[j];
3809 mLocalPowerManager.uidGone(item.uid);
3811 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3816 int i = mUidObservers.beginBroadcast();
3819 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3820 if (observer != null) {
3822 for (int j=0; j<N; j++) {
3823 UidRecord.ChangeItem item = mActiveUidChanges[j];
3825 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3826 "UID gone uid=" + item.uid);
3827 observer.onUidGone(item.uid);
3829 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3830 "UID CHANGED uid=" + item.uid
3831 + ": " + item.processState);
3832 observer.onUidStateChanged(item.uid, item.processState);
3835 } catch (RemoteException e) {
3839 mUidObservers.finishBroadcast();
3841 synchronized (this) {
3842 for (int j=0; j<N; j++) {
3843 mAvailUidChanges.add(mActiveUidChanges[j]);
3849 public final int startActivity(IApplicationThread caller, String callingPackage,
3850 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3851 int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3852 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3853 resultWho, requestCode, startFlags, profilerInfo, options,
3854 UserHandle.getCallingUserId());
3858 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3859 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3860 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3861 enforceNotIsolatedCaller("startActivity");
3862 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3863 false, ALLOW_FULL_ONLY, "startActivity", null);
3864 // TODO: Switch to user app stacks here.
3865 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3866 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3867 profilerInfo, null, null, options, false, userId, null, null);
3871 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3872 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3873 int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3876 // This is very dangerous -- it allows you to perform a start activity (including
3877 // permission grants) as any app that may launch one of your own activities. So
3878 // we will only allow this to be done from activities that are part of the core framework,
3879 // and then only when they are running as the system.
3880 final ActivityRecord sourceRecord;
3881 final int targetUid;
3882 final String targetPackage;
3883 synchronized (this) {
3884 if (resultTo == null) {
3885 throw new SecurityException("Must be called from an activity");
3887 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3888 if (sourceRecord == null) {
3889 throw new SecurityException("Called with bad activity token: " + resultTo);
3891 if (!sourceRecord.info.packageName.equals("android")) {
3892 throw new SecurityException(
3893 "Must be called from an activity that is declared in the android package");
3895 if (sourceRecord.app == null) {
3896 throw new SecurityException("Called without a process attached to activity");
3898 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3899 // This is still okay, as long as this activity is running under the
3900 // uid of the original calling activity.
3901 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3902 throw new SecurityException(
3903 "Calling activity in uid " + sourceRecord.app.uid
3904 + " must be system uid or original calling uid "
3905 + sourceRecord.launchedFromUid);
3908 if (ignoreTargetSecurity) {
3909 if (intent.getComponent() == null) {
3910 throw new SecurityException(
3911 "Component must be specified with ignoreTargetSecurity");
3913 if (intent.getSelector() != null) {
3914 throw new SecurityException(
3915 "Selector not allowed with ignoreTargetSecurity");
3918 targetUid = sourceRecord.launchedFromUid;
3919 targetPackage = sourceRecord.launchedFromPackage;
3922 if (userId == UserHandle.USER_NULL) {
3923 userId = UserHandle.getUserId(sourceRecord.app.uid);
3926 // TODO: Switch to user app stacks here.
3928 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3929 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3930 null, null, options, ignoreTargetSecurity, userId, null, null);
3932 } catch (SecurityException e) {
3933 // XXX need to figure out how to propagate to original app.
3934 // A SecurityException here is generally actually a fault of the original
3935 // calling activity (such as a fairly granting permissions), so propagate it
3938 StringBuilder msg = new StringBuilder();
3939 msg.append("While launching");
3940 msg.append(intent.toString());
3942 msg.append(e.getMessage());
3949 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3950 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3951 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3952 enforceNotIsolatedCaller("startActivityAndWait");
3953 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3954 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3955 WaitResult res = new WaitResult();
3956 // TODO: Switch to user app stacks here.
3957 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3958 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3959 options, false, userId, null, null);
3964 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3965 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3966 int startFlags, Configuration config, Bundle options, int userId) {
3967 enforceNotIsolatedCaller("startActivityWithConfig");
3968 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3969 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3970 // TODO: Switch to user app stacks here.
3971 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3972 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3973 null, null, config, options, false, userId, null, null);
3978 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3979 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3980 int requestCode, int flagsMask, int flagsValues, Bundle options)
3981 throws TransactionTooLargeException {
3982 enforceNotIsolatedCaller("startActivityIntentSender");
3983 // Refuse possible leaked file descriptors
3984 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3985 throw new IllegalArgumentException("File descriptors passed in Intent");
3988 IIntentSender sender = intent.getTarget();
3989 if (!(sender instanceof PendingIntentRecord)) {
3990 throw new IllegalArgumentException("Bad PendingIntent object");
3993 PendingIntentRecord pir = (PendingIntentRecord)sender;
3995 synchronized (this) {
3996 // If this is coming from the currently resumed activity, it is
3997 // effectively saying that app switches are allowed at this point.
3998 final ActivityStack stack = getFocusedStack();
3999 if (stack.mResumedActivity != null &&
4000 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4001 mAppSwitchesAllowedTime = 0;
4004 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4005 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
4010 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4011 Intent intent, String resolvedType, IVoiceInteractionSession session,
4012 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4013 Bundle options, int userId) {
4014 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4015 != PackageManager.PERMISSION_GRANTED) {
4016 String msg = "Permission Denial: startVoiceActivity() from pid="
4017 + Binder.getCallingPid()
4018 + ", uid=" + Binder.getCallingUid()
4019 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4021 throw new SecurityException(msg);
4023 if (session == null || interactor == null) {
4024 throw new NullPointerException("null session or interactor");
4026 userId = handleIncomingUser(callingPid, callingUid, userId,
4027 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
4028 // TODO: Switch to user app stacks here.
4029 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4030 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4031 null, options, false, userId, null, null);
4035 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4036 synchronized (this) {
4037 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4039 mVoiceWakeLock.acquire();
4041 mVoiceWakeLock.release();
4048 public boolean startNextMatchingActivity(IBinder callingActivity,
4049 Intent intent, Bundle options) {
4050 // Refuse possible leaked file descriptors
4051 if (intent != null && intent.hasFileDescriptors() == true) {
4052 throw new IllegalArgumentException("File descriptors passed in Intent");
4055 synchronized (this) {
4056 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4058 ActivityOptions.abort(options);
4061 if (r.app == null || r.app.thread == null) {
4062 // The caller is not running... d'oh!
4063 ActivityOptions.abort(options);
4066 intent = new Intent(intent);
4067 // The caller is not allowed to change the data.
4068 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4069 // And we are resetting to find the next component...
4070 intent.setComponent(null);
4072 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4074 ActivityInfo aInfo = null;
4076 List<ResolveInfo> resolves =
4077 AppGlobals.getPackageManager().queryIntentActivities(
4078 intent, r.resolvedType,
4079 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4080 UserHandle.getCallingUserId());
4082 // Look for the original activity in the list...
4083 final int N = resolves != null ? resolves.size() : 0;
4084 for (int i=0; i<N; i++) {
4085 ResolveInfo rInfo = resolves.get(i);
4086 if (rInfo.activityInfo.packageName.equals(r.packageName)
4087 && rInfo.activityInfo.name.equals(r.info.name)) {
4088 // We found the current one... the next matching is
4092 aInfo = resolves.get(i).activityInfo;
4095 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4096 + "/" + r.info.name);
4097 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4098 + "/" + aInfo.name);
4103 } catch (RemoteException e) {
4106 if (aInfo == null) {
4107 // Nobody who is next!
4108 ActivityOptions.abort(options);
4109 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4113 intent.setComponent(new ComponentName(
4114 aInfo.applicationInfo.packageName, aInfo.name));
4115 intent.setFlags(intent.getFlags()&~(
4116 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4117 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4118 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4119 Intent.FLAG_ACTIVITY_NEW_TASK));
4121 // Okay now we need to start the new activity, replacing the
4122 // currently running activity. This is a little tricky because
4123 // we want to start the new one as if the current one is finished,
4124 // but not finish the current one first so that there is no flicker.
4126 final boolean wasFinishing = r.finishing;
4129 // Propagate reply information over to the new activity.
4130 final ActivityRecord resultTo = r.resultTo;
4131 final String resultWho = r.resultWho;
4132 final int requestCode = r.requestCode;
4134 if (resultTo != null) {
4135 resultTo.removeResultsLocked(r, resultWho, requestCode);
4138 final long origId = Binder.clearCallingIdentity();
4139 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4140 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4141 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4142 -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4143 Binder.restoreCallingIdentity(origId);
4145 r.finishing = wasFinishing;
4146 if (res != ActivityManager.START_SUCCESS) {
4154 public final int startActivityFromRecents(int taskId, Bundle options) {
4155 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4156 String msg = "Permission Denial: startActivityFromRecents called without " +
4157 START_TASKS_FROM_RECENTS;
4159 throw new SecurityException(msg);
4161 return startActivityFromRecentsInner(taskId, options);
4164 final int startActivityFromRecentsInner(int taskId, Bundle options) {
4165 final TaskRecord task;
4166 final int callingUid;
4167 final String callingPackage;
4168 final Intent intent;
4170 synchronized (this) {
4171 task = mStackSupervisor.anyTaskForIdLocked(taskId);
4173 throw new IllegalArgumentException("Task " + taskId + " not found.");
4175 if (task.getRootActivity() != null) {
4176 moveTaskToFrontLocked(task.taskId, 0, null);
4177 return ActivityManager.START_TASK_TO_FRONT;
4179 callingUid = task.mCallingUid;
4180 callingPackage = task.mCallingPackage;
4181 intent = task.intent;
4182 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4183 userId = task.userId;
4185 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4186 options, userId, null, task);
4189 final int startActivityInPackage(int uid, String callingPackage,
4190 Intent intent, String resolvedType, IBinder resultTo,
4191 String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4192 IActivityContainer container, TaskRecord inTask) {
4194 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4195 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4197 // TODO: Switch to user app stacks here.
4198 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4199 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4200 null, null, null, options, false, userId, container, inTask);
4205 public final int startActivities(IApplicationThread caller, String callingPackage,
4206 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4208 enforceNotIsolatedCaller("startActivities");
4209 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4210 false, ALLOW_FULL_ONLY, "startActivity", null);
4211 // TODO: Switch to user app stacks here.
4212 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4213 resolvedTypes, resultTo, options, userId);
4217 final int startActivitiesInPackage(int uid, String callingPackage,
4218 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4219 Bundle options, int userId) {
4221 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4222 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4223 // TODO: Switch to user app stacks here.
4224 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4225 resultTo, options, userId);
4230 public void reportActivityFullyDrawn(IBinder token) {
4231 synchronized (this) {
4232 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4236 r.reportFullyDrawnLocked();
4241 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4242 synchronized (this) {
4243 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4247 if (r.task != null && r.task.mResizeable) {
4248 // Fixed screen orientation isn't supported with resizeable activities.
4251 final long origId = Binder.clearCallingIdentity();
4252 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4253 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4254 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4255 if (config != null) {
4256 r.frozenBeforeDestroy = true;
4257 if (!updateConfigurationLocked(config, r, false, false)) {
4258 mStackSupervisor.resumeTopActivitiesLocked();
4261 Binder.restoreCallingIdentity(origId);
4266 public int getRequestedOrientation(IBinder token) {
4267 synchronized (this) {
4268 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4270 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4272 return mWindowManager.getAppOrientation(r.appToken);
4277 * This is the internal entry point for handling Activity.finish().
4279 * @param token The Binder token referencing the Activity we want to finish.
4280 * @param resultCode Result code, if any, from this Activity.
4281 * @param resultData Result data (Intent), if any, from this Activity.
4282 * @param finishTask Whether to finish the task associated with this Activity. Only applies to
4283 * the root Activity in the task.
4285 * @return Returns true if the activity successfully finished, or false if it is still running.
4288 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4289 boolean finishTask) {
4290 // Refuse possible leaked file descriptors
4291 if (resultData != null && resultData.hasFileDescriptors() == true) {
4292 throw new IllegalArgumentException("File descriptors passed in Intent");
4295 synchronized(this) {
4296 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4300 // Keep track of the root activity of the task before we finish it
4301 TaskRecord tr = r.task;
4302 ActivityRecord rootR = tr.getRootActivity();
4303 if (rootR == null) {
4304 Slog.w(TAG, "Finishing task with all activities already finished");
4306 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4308 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4309 mStackSupervisor.isLastLockedTask(tr)) {
4310 Slog.i(TAG, "Not finishing task in lock task mode");
4311 mStackSupervisor.showLockTaskToast();
4314 if (mController != null) {
4315 // Find the first activity that is not finishing.
4316 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4318 // ask watcher if this is allowed
4319 boolean resumeOK = true;
4321 resumeOK = mController.activityResuming(next.packageName);
4322 } catch (RemoteException e) {
4324 Watchdog.getInstance().setActivityController(null);
4328 Slog.i(TAG, "Not finishing activity because controller resumed");
4333 final long origId = Binder.clearCallingIdentity();
4336 if (finishTask && r == rootR) {
4337 // If requested, remove the task that is associated to this activity only if it
4338 // was the root activity in the task. The result code and data is ignored
4339 // because we don't support returning them across task boundaries.
4340 res = removeTaskByIdLocked(tr.taskId, false);
4342 Slog.i(TAG, "Removing task failed to finish activity");
4345 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4346 resultData, "app-request", true);
4348 Slog.i(TAG, "Failed to finish by app-request");
4353 Binder.restoreCallingIdentity(origId);
4359 public final void finishHeavyWeightApp() {
4360 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4361 != PackageManager.PERMISSION_GRANTED) {
4362 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4363 + Binder.getCallingPid()
4364 + ", uid=" + Binder.getCallingUid()
4365 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4367 throw new SecurityException(msg);
4370 synchronized(this) {
4371 if (mHeavyWeightProcess == null) {
4375 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4376 for (int i = 0; i < activities.size(); i++) {
4377 ActivityRecord r = activities.get(i);
4378 if (!r.finishing && r.isInStackLocked()) {
4379 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4380 null, "finish-heavy", true);
4384 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4385 mHeavyWeightProcess.userId, 0));
4386 mHeavyWeightProcess = null;
4391 public void crashApplication(int uid, int initialPid, String packageName,
4393 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4394 != PackageManager.PERMISSION_GRANTED) {
4395 String msg = "Permission Denial: crashApplication() from pid="
4396 + Binder.getCallingPid()
4397 + ", uid=" + Binder.getCallingUid()
4398 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4400 throw new SecurityException(msg);
4403 synchronized(this) {
4404 ProcessRecord proc = null;
4406 // Figure out which process to kill. We don't trust that initialPid
4407 // still has any relation to current pids, so must scan through the
4409 synchronized (mPidsSelfLocked) {
4410 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4411 ProcessRecord p = mPidsSelfLocked.valueAt(i);
4415 if (p.pid == initialPid) {
4419 if (p.pkgList.containsKey(packageName)) {
4426 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4427 + " initialPid=" + initialPid
4428 + " packageName=" + packageName);
4432 if (proc.thread != null) {
4433 if (proc.pid == Process.myPid()) {
4434 Log.w(TAG, "crashApplication: trying to crash self!");
4437 long ident = Binder.clearCallingIdentity();
4439 proc.thread.scheduleCrash(message);
4440 } catch (RemoteException e) {
4442 Binder.restoreCallingIdentity(ident);
4448 public final void finishSubActivity(IBinder token, String resultWho,
4450 synchronized(this) {
4451 final long origId = Binder.clearCallingIdentity();
4452 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4454 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4456 Binder.restoreCallingIdentity(origId);
4461 public boolean finishActivityAffinity(IBinder token) {
4462 synchronized(this) {
4463 final long origId = Binder.clearCallingIdentity();
4465 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4470 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4472 final TaskRecord task = r.task;
4473 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4474 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4475 mStackSupervisor.showLockTaskToast();
4478 return task.stack.finishActivityAffinityLocked(r);
4480 Binder.restoreCallingIdentity(origId);
4486 public void finishVoiceTask(IVoiceInteractionSession session) {
4487 synchronized(this) {
4488 final long origId = Binder.clearCallingIdentity();
4490 mStackSupervisor.finishVoiceTask(session);
4492 Binder.restoreCallingIdentity(origId);
4499 public boolean releaseActivityInstance(IBinder token) {
4500 synchronized(this) {
4501 final long origId = Binder.clearCallingIdentity();
4503 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4507 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4509 Binder.restoreCallingIdentity(origId);
4515 public void releaseSomeActivities(IApplicationThread appInt) {
4516 synchronized(this) {
4517 final long origId = Binder.clearCallingIdentity();
4519 ProcessRecord app = getRecordForAppLocked(appInt);
4520 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4522 Binder.restoreCallingIdentity(origId);
4528 public boolean willActivityBeVisible(IBinder token) {
4529 synchronized(this) {
4530 ActivityStack stack = ActivityRecord.getStackLocked(token);
4531 if (stack != null) {
4532 return stack.willActivityBeVisibleLocked(token);
4539 public void overridePendingTransition(IBinder token, String packageName,
4540 int enterAnim, int exitAnim) {
4541 synchronized(this) {
4542 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4547 final long origId = Binder.clearCallingIdentity();
4549 if (self.state == ActivityState.RESUMED
4550 || self.state == ActivityState.PAUSING) {
4551 mWindowManager.overridePendingAppTransition(packageName,
4552 enterAnim, exitAnim, null);
4555 Binder.restoreCallingIdentity(origId);
4560 * Main function for removing an existing process from the activity manager
4561 * as a result of that process going away. Clears out all connections
4564 private final void handleAppDiedLocked(ProcessRecord app,
4565 boolean restarting, boolean allowRestart) {
4567 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4568 if (!kept && !restarting) {
4569 removeLruProcessLocked(app);
4571 ProcessList.remove(pid);
4575 if (mProfileProc == app) {
4576 clearProfilerLocked();
4579 // Remove this application's activities from active lists.
4580 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4582 app.activities.clear();
4584 if (app.instrumentationClass != null) {
4585 Slog.w(TAG, "Crash of app " + app.processName
4586 + " running instrumentation " + app.instrumentationClass);
4587 Bundle info = new Bundle();
4588 info.putString("shortMsg", "Process crashed.");
4589 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4592 if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4593 // If there was nothing to resume, and we are not already
4594 // restarting this process, but there is a visible activity that
4595 // is hosted by the process... then make sure all visible
4596 // activities are running, taking care of restarting this
4598 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4602 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4603 IBinder threadBinder = thread.asBinder();
4604 // Find the application record.
4605 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4606 ProcessRecord rec = mLruProcesses.get(i);
4607 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4614 final ProcessRecord getRecordForAppLocked(
4615 IApplicationThread thread) {
4616 if (thread == null) {
4620 int appIndex = getLRURecordIndexForAppLocked(thread);
4621 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4624 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4625 // If there are no longer any background processes running,
4626 // and the app that died was not running instrumentation,
4627 // then tell everyone we are now low on memory.
4628 boolean haveBg = false;
4629 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4630 ProcessRecord rec = mLruProcesses.get(i);
4631 if (rec.thread != null
4632 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4639 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4641 long now = SystemClock.uptimeMillis();
4642 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4645 mLastMemUsageReportTime = now;
4648 final ArrayList<ProcessMemInfo> memInfos
4649 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4650 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4651 long now = SystemClock.uptimeMillis();
4652 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4653 ProcessRecord rec = mLruProcesses.get(i);
4654 if (rec == dyingProc || rec.thread == null) {
4658 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4659 rec.setProcState, rec.adjType, rec.makeAdjReason()));
4661 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4662 // The low memory report is overriding any current
4663 // state for a GC request. Make sure to do
4664 // heavy/important/visible/foreground processes first.
4665 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4666 rec.lastRequestedGc = 0;
4668 rec.lastRequestedGc = rec.lastLowMemory;
4670 rec.reportLowMemory = true;
4671 rec.lastLowMemory = now;
4672 mProcessesToGc.remove(rec);
4673 addProcessToGcListLocked(rec);
4677 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4678 mHandler.sendMessage(msg);
4680 scheduleAppGcsLocked();
4684 final void appDiedLocked(ProcessRecord app) {
4685 appDiedLocked(app, app.pid, app.thread, false);
4688 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4689 boolean fromBinderDied) {
4690 // First check if this ProcessRecord is actually active for the pid.
4691 synchronized (mPidsSelfLocked) {
4692 ProcessRecord curProc = mPidsSelfLocked.get(pid);
4693 if (curProc != app) {
4694 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4699 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4700 synchronized (stats) {
4701 stats.noteProcessDiedLocked(app.info.uid, pid);
4705 if (!fromBinderDied) {
4706 Process.killProcessQuiet(pid);
4708 killProcessGroup(app.info.uid, pid);
4712 // Clean up already done if the process has been re-started.
4713 if (app.pid == pid && app.thread != null &&
4714 app.thread.asBinder() == thread.asBinder()) {
4715 boolean doLowMem = app.instrumentationClass == null;
4716 boolean doOomAdj = doLowMem;
4717 if (!app.killedByAm) {
4718 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4720 mAllowLowerMemLevel = true;
4722 // Note that we always want to do oom adj to update our state with the
4723 // new number of procs.
4724 mAllowLowerMemLevel = false;
4727 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4728 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4729 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4730 handleAppDiedLocked(app, false, true);
4733 updateOomAdjLocked();
4736 doLowMemReportIfNeededLocked(app);
4738 } else if (app.pid != pid) {
4739 // A new process has already been started.
4740 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4741 + ") has died and restarted (pid " + app.pid + ").");
4742 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4743 } else if (DEBUG_PROCESSES) {
4744 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4745 + thread.asBinder());
4750 * If a stack trace dump file is configured, dump process stack traces.
4751 * @param clearTraces causes the dump file to be erased prior to the new
4752 * traces being written, if true; when false, the new traces will be
4753 * appended to any existing file content.
4754 * @param firstPids of dalvik VM processes to dump stack traces for first
4755 * @param lastPids of dalvik VM processes to dump stack traces for last
4756 * @param nativeProcs optional list of native process names to dump stack crawls
4757 * @return file containing stack traces, or null if no dump file is configured
4759 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4760 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4761 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4762 if (tracesPath == null || tracesPath.length() == 0) {
4766 File tracesFile = new File(tracesPath);
4768 File tracesDir = tracesFile.getParentFile();
4769 if (!tracesDir.exists()) {
4771 if (!SELinux.restorecon(tracesDir)) {
4775 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4777 if (clearTraces && tracesFile.exists()) tracesFile.delete();
4778 tracesFile.createNewFile();
4779 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4780 } catch (IOException e) {
4781 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4785 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4789 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4790 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4791 // Use a FileObserver to detect when traces finish writing.
4792 // The order of traces is considered important to maintain for legibility.
4793 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4795 public synchronized void onEvent(int event, String path) { notify(); }
4799 observer.startWatching();
4801 // First collect all of the stacks of the most important pids.
4802 if (firstPids != null) {
4804 int num = firstPids.size();
4805 for (int i = 0; i < num; i++) {
4806 synchronized (observer) {
4807 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4808 observer.wait(200); // Wait for write-close, give up after 200msec
4811 } catch (InterruptedException e) {
4816 // Next collect the stacks of the native pids
4817 if (nativeProcs != null) {
4818 int[] pids = Process.getPidsForCommands(nativeProcs);
4820 for (int pid : pids) {
4821 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4826 // Lastly, measure CPU usage.
4827 if (processCpuTracker != null) {
4828 processCpuTracker.init();
4830 processCpuTracker.update();
4832 synchronized (processCpuTracker) {
4833 processCpuTracker.wait(500); // measure over 1/2 second.
4835 } catch (InterruptedException e) {
4837 processCpuTracker.update();
4839 // We'll take the stack crawls of just the top apps using CPU.
4840 final int N = processCpuTracker.countWorkingStats();
4842 for (int i=0; i<N && numProcs<5; i++) {
4843 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4844 if (lastPids.indexOfKey(stats.pid) >= 0) {
4847 synchronized (observer) {
4848 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4849 observer.wait(200); // Wait for write-close, give up after 200msec
4851 } catch (InterruptedException e) {
4859 observer.stopWatching();
4863 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4864 if (true || IS_USER_BUILD) {
4867 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4868 if (tracesPath == null || tracesPath.length() == 0) {
4872 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4873 StrictMode.allowThreadDiskWrites();
4875 final File tracesFile = new File(tracesPath);
4876 final File tracesDir = tracesFile.getParentFile();
4877 final File tracesTmp = new File(tracesDir, "__tmp__");
4879 if (!tracesDir.exists()) {
4881 if (!SELinux.restorecon(tracesDir.getPath())) {
4885 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4887 if (tracesFile.exists()) {
4889 tracesFile.renameTo(tracesTmp);
4891 StringBuilder sb = new StringBuilder();
4892 Time tobj = new Time();
4893 tobj.set(System.currentTimeMillis());
4894 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4896 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4897 sb.append(" since ");
4899 FileOutputStream fos = new FileOutputStream(tracesFile);
4900 fos.write(sb.toString().getBytes());
4902 fos.write("\n*** No application process!".getBytes());
4905 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4906 } catch (IOException e) {
4907 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4912 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4913 firstPids.add(app.pid);
4914 dumpStackTraces(tracesPath, firstPids, null, null, null);
4917 File lastTracesFile = null;
4918 File curTracesFile = null;
4919 for (int i=9; i>=0; i--) {
4920 String name = String.format(Locale.US, "slow%02d.txt", i);
4921 curTracesFile = new File(tracesDir, name);
4922 if (curTracesFile.exists()) {
4923 if (lastTracesFile != null) {
4924 curTracesFile.renameTo(lastTracesFile);
4926 curTracesFile.delete();
4929 lastTracesFile = curTracesFile;
4931 tracesFile.renameTo(curTracesFile);
4932 if (tracesTmp.exists()) {
4933 tracesTmp.renameTo(tracesFile);
4936 StrictMode.setThreadPolicy(oldPolicy);
4940 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4941 ActivityRecord parent, boolean aboveSystem, final String annotation) {
4942 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4943 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4945 if (mController != null) {
4947 // 0 == continue, -1 = kill process immediately
4948 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4949 if (res < 0 && app.pid != MY_PID) {
4950 app.kill("anr", true);
4952 } catch (RemoteException e) {
4954 Watchdog.getInstance().setActivityController(null);
4958 long anrTime = SystemClock.uptimeMillis();
4959 if (MONITOR_CPU_USAGE) {
4960 updateCpuStatsNow();
4963 synchronized (this) {
4964 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4965 if (mShuttingDown) {
4966 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4968 } else if (app.notResponding) {
4969 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4971 } else if (app.crashing) {
4972 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4976 // In case we come through here for the same app before completing
4977 // this one, mark as anring now so we will bail out.
4978 app.notResponding = true;
4980 // Log the ANR to the event log.
4981 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4982 app.processName, app.info.flags, annotation);
4984 // Dump thread traces as quickly as we can, starting with "interesting" processes.
4985 firstPids.add(app.pid);
4987 int parentPid = app.pid;
4988 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4989 if (parentPid != app.pid) firstPids.add(parentPid);
4991 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4993 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4994 ProcessRecord r = mLruProcesses.get(i);
4995 if (r != null && r.thread != null) {
4997 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5001 lastPids.put(pid, Boolean.TRUE);
5008 // Log the ANR to the main log.
5009 StringBuilder info = new StringBuilder();
5011 info.append("ANR in ").append(app.processName);
5012 if (activity != null && activity.shortComponentName != null) {
5013 info.append(" (").append(activity.shortComponentName).append(")");
5016 info.append("PID: ").append(app.pid).append("\n");
5017 if (annotation != null) {
5018 info.append("Reason: ").append(annotation).append("\n");
5020 if (parent != null && parent != activity) {
5021 info.append("Parent: ").append(parent.shortComponentName).append("\n");
5024 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5026 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5027 NATIVE_STACKS_OF_INTEREST);
5029 String cpuInfo = null;
5030 if (MONITOR_CPU_USAGE) {
5031 updateCpuStatsNow();
5032 synchronized (mProcessCpuTracker) {
5033 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5035 info.append(processCpuTracker.printCurrentLoad());
5036 info.append(cpuInfo);
5039 info.append(processCpuTracker.printCurrentState(anrTime));
5041 Slog.e(TAG, info.toString());
5042 if (tracesFile == null) {
5043 // There is no trace file, so dump (only) the alleged culprit's threads to the log
5044 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5047 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5048 cpuInfo, tracesFile, null);
5050 if (mController != null) {
5052 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5053 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5055 if (res < 0 && app.pid != MY_PID) {
5056 app.kill("anr", true);
5058 synchronized (this) {
5059 mServices.scheduleServiceTimeoutLocked(app);
5064 } catch (RemoteException e) {
5066 Watchdog.getInstance().setActivityController(null);
5070 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5071 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5072 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5074 synchronized (this) {
5075 mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5077 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5078 app.kill("bg anr", true);
5082 // Set the app's notResponding state, and look up the errorReportReceiver
5083 makeAppNotRespondingLocked(app,
5084 activity != null ? activity.shortComponentName : null,
5085 annotation != null ? "ANR " + annotation : "ANR",
5088 // Bring up the infamous App Not Responding dialog
5089 Message msg = Message.obtain();
5090 HashMap<String, Object> map = new HashMap<String, Object>();
5091 msg.what = SHOW_NOT_RESPONDING_MSG;
5093 msg.arg1 = aboveSystem ? 1 : 0;
5094 map.put("app", app);
5095 if (activity != null) {
5096 map.put("activity", activity);
5099 mUiHandler.sendMessage(msg);
5103 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5104 if (!mLaunchWarningShown) {
5105 mLaunchWarningShown = true;
5106 mUiHandler.post(new Runnable() {
5109 synchronized (ActivityManagerService.this) {
5110 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5112 mUiHandler.postDelayed(new Runnable() {
5115 synchronized (ActivityManagerService.this) {
5117 mLaunchWarningShown = false;
5128 public boolean clearApplicationUserData(final String packageName,
5129 final IPackageDataObserver observer, int userId) {
5130 enforceNotIsolatedCaller("clearApplicationUserData");
5131 if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5132 throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5134 int uid = Binder.getCallingUid();
5135 int pid = Binder.getCallingPid();
5136 userId = handleIncomingUser(pid, uid,
5137 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5138 long callingId = Binder.clearCallingIdentity();
5140 IPackageManager pm = AppGlobals.getPackageManager();
5142 synchronized(this) {
5144 pkgUid = pm.getPackageUid(packageName, userId);
5145 } catch (RemoteException e) {
5148 Slog.w(TAG, "Invalid packageName: " + packageName);
5149 if (observer != null) {
5151 observer.onRemoveCompleted(packageName, false);
5152 } catch (RemoteException e) {
5153 Slog.i(TAG, "Observer no longer exists.");
5158 if (uid == pkgUid || checkComponentPermission(
5159 android.Manifest.permission.CLEAR_APP_USER_DATA,
5161 == PackageManager.PERMISSION_GRANTED) {
5162 forceStopPackageLocked(packageName, pkgUid, "clear data");
5164 throw new SecurityException("PID " + pid + " does not have permission "
5165 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5166 + " of package " + packageName);
5169 // Remove all tasks match the cleared application package and user
5170 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5171 final TaskRecord tr = mRecentTasks.get(i);
5172 final String taskPackageName =
5173 tr.getBaseIntent().getComponent().getPackageName();
5174 if (tr.userId != userId) continue;
5175 if (!taskPackageName.equals(packageName)) continue;
5176 removeTaskByIdLocked(tr.taskId, false);
5181 // Clear application user data
5182 pm.clearApplicationUserData(packageName, observer, userId);
5184 synchronized(this) {
5185 // Remove all permissions granted from/to this package
5186 removeUriPermissionsForPackageLocked(packageName, userId, true);
5189 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5190 Uri.fromParts("package", packageName, null));
5191 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5192 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5193 null, null, 0, null, null, null, null, false, false, userId);
5194 } catch (RemoteException e) {
5197 Binder.restoreCallingIdentity(callingId);
5203 public void killBackgroundProcesses(final String packageName, int userId) {
5204 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5205 != PackageManager.PERMISSION_GRANTED &&
5206 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5207 != PackageManager.PERMISSION_GRANTED) {
5208 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5209 + Binder.getCallingPid()
5210 + ", uid=" + Binder.getCallingUid()
5211 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5213 throw new SecurityException(msg);
5216 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5217 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5218 long callingId = Binder.clearCallingIdentity();
5220 IPackageManager pm = AppGlobals.getPackageManager();
5221 synchronized(this) {
5224 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5225 } catch (RemoteException e) {
5228 Slog.w(TAG, "Invalid packageName: " + packageName);
5231 killPackageProcessesLocked(packageName, appId, userId,
5232 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5235 Binder.restoreCallingIdentity(callingId);
5240 public void killAllBackgroundProcesses() {
5241 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5242 != PackageManager.PERMISSION_GRANTED) {
5243 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5244 + Binder.getCallingPid()
5245 + ", uid=" + Binder.getCallingUid()
5246 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5248 throw new SecurityException(msg);
5251 long callingId = Binder.clearCallingIdentity();
5253 synchronized(this) {
5254 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5255 final int NP = mProcessNames.getMap().size();
5256 for (int ip=0; ip<NP; ip++) {
5257 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5258 final int NA = apps.size();
5259 for (int ia=0; ia<NA; ia++) {
5260 ProcessRecord app = apps.valueAt(ia);
5261 if (app.persistent) {
5262 // we don't kill persistent processes
5267 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5274 int N = procs.size();
5275 for (int i=0; i<N; i++) {
5276 removeProcessLocked(procs.get(i), false, true, "kill all background");
5278 mAllowLowerMemLevel = true;
5279 updateOomAdjLocked();
5280 doLowMemReportIfNeededLocked(null);
5283 Binder.restoreCallingIdentity(callingId);
5288 public void forceStopPackage(final String packageName, int userId) {
5289 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5290 != PackageManager.PERMISSION_GRANTED) {
5291 String msg = "Permission Denial: forceStopPackage() from pid="
5292 + Binder.getCallingPid()
5293 + ", uid=" + Binder.getCallingUid()
5294 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5296 throw new SecurityException(msg);
5298 final int callingPid = Binder.getCallingPid();
5299 userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5300 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5301 long callingId = Binder.clearCallingIdentity();
5303 IPackageManager pm = AppGlobals.getPackageManager();
5304 synchronized(this) {
5305 int[] users = userId == UserHandle.USER_ALL
5306 ? getUsersLocked() : new int[] { userId };
5307 for (int user : users) {
5310 pkgUid = pm.getPackageUid(packageName, user);
5311 } catch (RemoteException e) {
5314 Slog.w(TAG, "Invalid packageName: " + packageName);
5318 pm.setPackageStoppedState(packageName, true, user);
5319 } catch (RemoteException e) {
5320 } catch (IllegalArgumentException e) {
5321 Slog.w(TAG, "Failed trying to unstop package "
5322 + packageName + ": " + e);
5324 if (isUserRunningLocked(user, false)) {
5325 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5330 Binder.restoreCallingIdentity(callingId);
5335 public void addPackageDependency(String packageName) {
5336 synchronized (this) {
5337 int callingPid = Binder.getCallingPid();
5338 if (callingPid == Process.myPid()) {
5343 synchronized (mPidsSelfLocked) {
5344 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5347 if (proc.pkgDeps == null) {
5348 proc.pkgDeps = new ArraySet<String>(1);
5350 proc.pkgDeps.add(packageName);
5356 * The pkg name and app id have to be specified.
5359 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5363 // Make sure the uid is valid.
5365 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5368 int callerUid = Binder.getCallingUid();
5369 // Only the system server can kill an application
5370 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5371 // Post an aysnc message to kill the application
5372 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5375 Bundle bundle = new Bundle();
5376 bundle.putString("pkg", pkg);
5377 bundle.putString("reason", reason);
5379 mHandler.sendMessage(msg);
5381 throw new SecurityException(callerUid + " cannot kill pkg: " +
5387 public void closeSystemDialogs(String reason) {
5388 enforceNotIsolatedCaller("closeSystemDialogs");
5390 final int pid = Binder.getCallingPid();
5391 final int uid = Binder.getCallingUid();
5392 final long origId = Binder.clearCallingIdentity();
5394 synchronized (this) {
5395 // Only allow this from foreground processes, so that background
5396 // applications can't abuse it to prevent system UI from being shown.
5397 if (uid >= Process.FIRST_APPLICATION_UID) {
5399 synchronized (mPidsSelfLocked) {
5400 proc = mPidsSelfLocked.get(pid);
5402 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5403 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5404 + " from background process " + proc);
5408 closeSystemDialogsLocked(reason);
5411 Binder.restoreCallingIdentity(origId);
5415 void closeSystemDialogsLocked(String reason) {
5416 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5417 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5418 | Intent.FLAG_RECEIVER_FOREGROUND);
5419 if (reason != null) {
5420 intent.putExtra("reason", reason);
5422 mWindowManager.closeSystemDialogs(reason);
5424 mStackSupervisor.closeSystemDialogsLocked();
5426 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5427 AppOpsManager.OP_NONE, null, false, false,
5428 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5432 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5433 enforceNotIsolatedCaller("getProcessMemoryInfo");
5434 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5435 for (int i=pids.length-1; i>=0; i--) {
5438 synchronized (this) {
5439 synchronized (mPidsSelfLocked) {
5440 proc = mPidsSelfLocked.get(pids[i]);
5441 oomAdj = proc != null ? proc.setAdj : 0;
5444 infos[i] = new Debug.MemoryInfo();
5445 Debug.getMemoryInfo(pids[i], infos[i]);
5447 synchronized (this) {
5448 if (proc.thread != null && proc.setAdj == oomAdj) {
5449 // Record this for posterity if the process has been stable.
5450 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5451 infos[i].getTotalUss(), false, proc.pkgList);
5460 public long[] getProcessPss(int[] pids) {
5461 enforceNotIsolatedCaller("getProcessPss");
5462 long[] pss = new long[pids.length];
5463 for (int i=pids.length-1; i>=0; i--) {
5466 synchronized (this) {
5467 synchronized (mPidsSelfLocked) {
5468 proc = mPidsSelfLocked.get(pids[i]);
5469 oomAdj = proc != null ? proc.setAdj : 0;
5472 long[] tmpUss = new long[1];
5473 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5475 synchronized (this) {
5476 if (proc.thread != null && proc.setAdj == oomAdj) {
5477 // Record this for posterity if the process has been stable.
5478 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5487 public void killApplicationProcess(String processName, int uid) {
5488 if (processName == null) {
5492 int callerUid = Binder.getCallingUid();
5493 // Only the system server can kill an application
5494 if (callerUid == Process.SYSTEM_UID) {
5495 synchronized (this) {
5496 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5497 if (app != null && app.thread != null) {
5499 app.thread.scheduleSuicide();
5500 } catch (RemoteException e) {
5501 // If the other end already died, then our work here is done.
5504 Slog.w(TAG, "Process/uid not found attempting kill of "
5505 + processName + " / " + uid);
5509 throw new SecurityException(callerUid + " cannot kill app process: " +
5514 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5515 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5516 false, true, false, false, UserHandle.getUserId(uid), reason);
5517 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5518 Uri.fromParts("package", packageName, null));
5519 if (!mProcessesReady) {
5520 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5521 | Intent.FLAG_RECEIVER_FOREGROUND);
5523 intent.putExtra(Intent.EXTRA_UID, uid);
5524 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5525 broadcastIntentLocked(null, null, intent,
5526 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5527 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5530 private void forceStopUserLocked(int userId, String reason) {
5531 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5532 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5533 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5534 | Intent.FLAG_RECEIVER_FOREGROUND);
5535 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5536 broadcastIntentLocked(null, null, intent,
5537 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5538 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5541 private final boolean killPackageProcessesLocked(String packageName, int appId,
5542 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5543 boolean doit, boolean evenPersistent, String reason) {
5544 ArrayList<ProcessRecord> procs = new ArrayList<>();
5546 // Remove all processes this package may have touched: all with the
5547 // same UID (except for the system or root user), and all whose name
5548 // matches the package name.
5549 final int NP = mProcessNames.getMap().size();
5550 for (int ip=0; ip<NP; ip++) {
5551 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5552 final int NA = apps.size();
5553 for (int ia=0; ia<NA; ia++) {
5554 ProcessRecord app = apps.valueAt(ia);
5555 if (app.persistent && !evenPersistent) {
5556 // we don't kill persistent processes
5566 // Skip process if it doesn't meet our oom adj requirement.
5567 if (app.setAdj < minOomAdj) {
5571 // If no package is specified, we call all processes under the
5573 if (packageName == null) {
5574 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5577 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5580 // Package has been specified, we want to hit all processes
5581 // that match it. We need to qualify this by the processes
5582 // that are running under the specified app and user ID.
5584 final boolean isDep = app.pkgDeps != null
5585 && app.pkgDeps.contains(packageName);
5586 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5589 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5592 if (!app.pkgList.containsKey(packageName) && !isDep) {
5597 // Process has passed all conditions, kill it!
5606 int N = procs.size();
5607 for (int i=0; i<N; i++) {
5608 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5610 updateOomAdjLocked();
5614 private void cleanupDisabledPackageComponentsLocked(
5615 String packageName, int userId, boolean killProcess, String[] changedClasses) {
5617 Set<String> disabledClasses = null;
5618 boolean packageDisabled = false;
5619 IPackageManager pm = AppGlobals.getPackageManager();
5621 if (changedClasses == null) {
5622 // Nothing changed...
5626 // Determine enable/disable state of the package and its components.
5627 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5628 for (int i = changedClasses.length - 1; i >= 0; i--) {
5629 final String changedClass = changedClasses[i];
5631 if (changedClass.equals(packageName)) {
5633 // Entire package setting changed
5634 enabled = pm.getApplicationEnabledSetting(packageName,
5635 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5636 } catch (Exception e) {
5637 // No such package/component; probably racing with uninstall. In any
5638 // event it means we have nothing further to do here.
5641 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5642 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5643 if (packageDisabled) {
5644 // Entire package is disabled.
5645 // No need to continue to check component states.
5646 disabledClasses = null;
5651 enabled = pm.getComponentEnabledSetting(
5652 new ComponentName(packageName, changedClass),
5653 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5654 } catch (Exception e) {
5655 // As above, probably racing with uninstall.
5658 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5659 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5660 if (disabledClasses == null) {
5661 disabledClasses = new ArraySet<>(changedClasses.length);
5663 disabledClasses.add(changedClass);
5668 if (!packageDisabled && disabledClasses == null) {
5669 // Nothing to do here...
5673 // Clean-up disabled activities.
5674 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5675 packageName, disabledClasses, true, false, userId) && mBooted) {
5676 mStackSupervisor.resumeTopActivitiesLocked();
5677 mStackSupervisor.scheduleIdleLocked();
5680 // Clean-up disabled tasks
5681 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5683 // Clean-up disabled services.
5684 mServices.bringDownDisabledPackageServicesLocked(
5685 packageName, disabledClasses, userId, false, killProcess, true);
5687 // Clean-up disabled providers.
5688 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5689 mProviderMap.collectPackageProvidersLocked(
5690 packageName, disabledClasses, true, false, userId, providers);
5691 for (int i = providers.size() - 1; i >= 0; i--) {
5692 removeDyingProviderLocked(null, providers.get(i), true);
5695 // Clean-up disabled broadcast receivers.
5696 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5697 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5698 packageName, disabledClasses, userId, true);
5703 private final boolean forceStopPackageLocked(String packageName, int appId,
5704 boolean callerWillRestart, boolean purgeCache, boolean doit,
5705 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5708 if (userId == UserHandle.USER_ALL && packageName == null) {
5709 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5712 if (appId < 0 && packageName != null) {
5714 appId = UserHandle.getAppId(
5715 AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5716 } catch (RemoteException e) {
5721 if (packageName != null) {
5722 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5723 + " user=" + userId + ": " + reason);
5725 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5728 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5729 for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5730 SparseArray<Long> ba = pmap.valueAt(ip);
5731 for (i = ba.size() - 1; i >= 0; i--) {
5732 boolean remove = false;
5733 final int entUid = ba.keyAt(i);
5734 if (packageName != null) {
5735 if (userId == UserHandle.USER_ALL) {
5736 if (UserHandle.getAppId(entUid) == appId) {
5740 if (entUid == UserHandle.getUid(userId, appId)) {
5744 } else if (UserHandle.getUserId(entUid) == userId) {
5751 if (ba.size() == 0) {
5757 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5758 -100, callerWillRestart, true, doit, evenPersistent,
5759 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5761 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5762 packageName, null, doit, evenPersistent, userId)) {
5766 didSomething = true;
5769 if (mServices.bringDownDisabledPackageServicesLocked(
5770 packageName, null, userId, evenPersistent, true, doit)) {
5774 didSomething = true;
5777 if (packageName == null) {
5778 // Remove all sticky broadcasts from this user.
5779 mStickyBroadcasts.remove(userId);
5782 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5783 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5784 userId, providers)) {
5788 didSomething = true;
5790 for (i = providers.size() - 1; i >= 0; i--) {
5791 removeDyingProviderLocked(null, providers.get(i), true);
5794 // Remove transient permissions granted from/to this package/user
5795 removeUriPermissionsForPackageLocked(packageName, userId, false);
5798 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5799 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5800 packageName, null, userId, doit);
5804 if (packageName == null || uninstalling) {
5805 // Remove pending intents. For now we only do this when force
5806 // stopping users, because we have some problems when doing this
5807 // for packages -- app widgets are not currently cleaned up for
5808 // such packages, so they can be left with bad pending intents.
5809 if (mIntentSenderRecords.size() > 0) {
5810 Iterator<WeakReference<PendingIntentRecord>> it
5811 = mIntentSenderRecords.values().iterator();
5812 while (it.hasNext()) {
5813 WeakReference<PendingIntentRecord> wpir = it.next();
5818 PendingIntentRecord pir = wpir.get();
5823 if (packageName == null) {
5824 // Stopping user, remove all objects for the user.
5825 if (pir.key.userId != userId) {
5826 // Not the same user, skip it.
5830 if (UserHandle.getAppId(pir.uid) != appId) {
5831 // Different app id, skip it.
5834 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5835 // Different user, skip it.
5838 if (!pir.key.packageName.equals(packageName)) {
5839 // Different package, skip it.
5846 didSomething = true;
5848 pir.canceled = true;
5849 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5850 pir.key.activity.pendingResults.remove(pir.ref);
5857 if (purgeCache && packageName != null) {
5858 AttributeCache ac = AttributeCache.instance();
5860 ac.removePackage(packageName);
5864 mStackSupervisor.resumeTopActivitiesLocked();
5865 mStackSupervisor.scheduleIdleLocked();
5869 return didSomething;
5872 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5873 ProcessRecord old = mProcessNames.remove(name, uid);
5875 old.uidRecord.numProcs--;
5876 if (old.uidRecord.numProcs == 0) {
5877 // No more processes using this uid, tell clients it is gone.
5878 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5879 "No more processes in " + old.uidRecord);
5880 enqueueUidChangeLocked(old.uidRecord, true);
5881 mActiveUids.remove(uid);
5883 old.uidRecord = null;
5885 mIsolatedProcesses.remove(uid);
5889 private final void addProcessNameLocked(ProcessRecord proc) {
5890 // We shouldn't already have a process under this name, but just in case we
5891 // need to clean up whatever may be there now.
5892 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5893 if (old == proc && proc.persistent) {
5894 // We are re-adding a persistent process. Whatevs! Just leave it there.
5895 Slog.w(TAG, "Re-adding persistent process " + proc);
5896 } else if (old != null) {
5897 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5899 UidRecord uidRec = mActiveUids.get(proc.uid);
5900 if (uidRec == null) {
5901 uidRec = new UidRecord(proc.uid);
5902 // This is the first appearance of the uid, report it now!
5903 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5904 "Creating new process uid: " + uidRec);
5905 mActiveUids.put(proc.uid, uidRec);
5906 enqueueUidChangeLocked(uidRec, false);
5908 proc.uidRecord = uidRec;
5910 mProcessNames.put(proc.processName, proc.uid, proc);
5911 if (proc.isolated) {
5912 mIsolatedProcesses.put(proc.uid, proc);
5916 private final boolean removeProcessLocked(ProcessRecord app,
5917 boolean callerWillRestart, boolean allowRestart, String reason) {
5918 final String name = app.processName;
5919 final int uid = app.uid;
5920 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5921 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5923 removeProcessNameLocked(name, uid);
5924 if (mHeavyWeightProcess == app) {
5925 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5926 mHeavyWeightProcess.userId, 0));
5927 mHeavyWeightProcess = null;
5929 boolean needRestart = false;
5930 if (app.pid > 0 && app.pid != MY_PID) {
5932 synchronized (mPidsSelfLocked) {
5933 mPidsSelfLocked.remove(pid);
5934 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5936 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5938 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5940 boolean willRestart = false;
5941 if (app.persistent && !app.isolated) {
5942 if (!callerWillRestart) {
5948 app.kill(reason, true);
5949 handleAppDiedLocked(app, willRestart, allowRestart);
5951 removeLruProcessLocked(app);
5952 addAppLocked(app.info, false, null /* ABI override */);
5955 mRemovedProcesses.add(app);
5961 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
5962 cleanupAppInLaunchingProvidersLocked(app, true);
5963 removeProcessLocked(app, false, true, "timeout publishing content providers");
5966 private final void processStartTimedOutLocked(ProcessRecord app) {
5967 final int pid = app.pid;
5968 boolean gone = false;
5969 synchronized (mPidsSelfLocked) {
5970 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5971 if (knownApp != null && knownApp.thread == null) {
5972 mPidsSelfLocked.remove(pid);
5978 Slog.w(TAG, "Process " + app + " failed to attach");
5979 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5980 pid, app.uid, app.processName);
5981 removeProcessNameLocked(app.processName, app.uid);
5982 if (mHeavyWeightProcess == app) {
5983 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5984 mHeavyWeightProcess.userId, 0));
5985 mHeavyWeightProcess = null;
5987 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5989 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5991 // Take care of any launching providers waiting for this process.
5992 cleanupAppInLaunchingProvidersLocked(app, true);
5993 // Take care of any services that are waiting for the process.
5994 mServices.processStartTimedOutLocked(app);
5995 app.kill("start timeout", true);
5996 removeLruProcessLocked(app);
5997 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5998 Slog.w(TAG, "Unattached app died before backup, skipping");
6000 IBackupManager bm = IBackupManager.Stub.asInterface(
6001 ServiceManager.getService(Context.BACKUP_SERVICE));
6002 bm.agentDisconnected(app.info.packageName);
6003 } catch (RemoteException e) {
6004 // Can't happen; the backup manager is local
6007 if (isPendingBroadcastProcessLocked(pid)) {
6008 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6009 skipPendingBroadcastLocked(pid);
6012 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6016 private final boolean attachApplicationLocked(IApplicationThread thread,
6019 // Find the application record that is being attached... either via
6020 // the pid if we are running in multiple processes, or just pull the
6021 // next app record if we are emulating process with anonymous threads.
6023 if (pid != MY_PID && pid >= 0) {
6024 synchronized (mPidsSelfLocked) {
6025 app = mPidsSelfLocked.get(pid);
6032 Slog.w(TAG, "No pending application record for pid " + pid
6033 + " (IApplicationThread " + thread + "); dropping process");
6034 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6035 if (pid > 0 && pid != MY_PID) {
6036 Process.killProcessQuiet(pid);
6037 //TODO: killProcessGroup(app.info.uid, pid);
6040 thread.scheduleExit();
6041 } catch (Exception e) {
6042 // Ignore exceptions.
6048 // If this application record is still attached to a previous
6049 // process, clean it up now.
6050 if (app.thread != null) {
6051 handleAppDiedLocked(app, true, true);
6054 // Tell the process all about itself.
6056 if (DEBUG_ALL) Slog.v(
6057 TAG, "Binding process pid " + pid + " to record " + app);
6059 final String processName = app.processName;
6061 AppDeathRecipient adr = new AppDeathRecipient(
6063 thread.asBinder().linkToDeath(adr, 0);
6064 app.deathRecipient = adr;
6065 } catch (RemoteException e) {
6066 app.resetPackageList(mProcessStats);
6067 startProcessLocked(app, "link fail", processName);
6071 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6073 app.makeActive(thread, mProcessStats);
6074 app.curAdj = app.setAdj = -100;
6075 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6076 app.forcingToForeground = null;
6077 updateProcessForegroundLocked(app, false, false);
6078 app.hasShownUi = false;
6079 app.debugging = false;
6081 app.killedByAm = false;
6083 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6085 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6086 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6088 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6089 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6091 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6095 Slog.i(TAG, "Launching preboot mode app: " + app);
6098 if (DEBUG_ALL) Slog.v(
6099 TAG, "New app record " + app
6100 + " thread=" + thread.asBinder() + " pid=" + pid);
6102 int testMode = IApplicationThread.DEBUG_OFF;
6103 if (mDebugApp != null && mDebugApp.equals(processName)) {
6104 testMode = mWaitForDebugger
6105 ? IApplicationThread.DEBUG_WAIT
6106 : IApplicationThread.DEBUG_ON;
6107 app.debugging = true;
6108 if (mDebugTransient) {
6109 mDebugApp = mOrigDebugApp;
6110 mWaitForDebugger = mOrigWaitForDebugger;
6113 String profileFile = app.instrumentationProfileFile;
6114 ParcelFileDescriptor profileFd = null;
6115 int samplingInterval = 0;
6116 boolean profileAutoStop = false;
6117 if (mProfileApp != null && mProfileApp.equals(processName)) {
6119 profileFile = mProfileFile;
6120 profileFd = mProfileFd;
6121 samplingInterval = mSamplingInterval;
6122 profileAutoStop = mAutoStopProfiler;
6124 boolean enableOpenGlTrace = false;
6125 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6126 enableOpenGlTrace = true;
6127 mOpenGlTraceApp = null;
6130 // If the app is being launched for restore or full backup, set it up specially
6131 boolean isRestrictedBackupMode = false;
6132 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6133 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6134 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6135 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6138 ensurePackageDexOpt(app.instrumentationInfo != null
6139 ? app.instrumentationInfo.packageName
6140 : app.info.packageName);
6141 if (app.instrumentationClass != null) {
6142 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6144 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6145 + processName + " with config " + mConfiguration);
6146 ApplicationInfo appInfo = app.instrumentationInfo != null
6147 ? app.instrumentationInfo : app.info;
6148 app.compat = compatibilityInfoForPackageLocked(appInfo);
6149 if (profileFd != null) {
6150 profileFd = profileFd.dup();
6152 ProfilerInfo profilerInfo = profileFile == null ? null
6153 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6154 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6155 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6156 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6157 isRestrictedBackupMode || !normalMode, app.persistent,
6158 new Configuration(mConfiguration), app.compat,
6159 getCommonServicesLocked(app.isolated),
6160 mCoreSettingsObserver.getCoreSettingsLocked());
6161 updateLruProcessLocked(app, false, null);
6162 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6163 } catch (Exception e) {
6164 // todo: Yikes! What should we do? For now we will try to
6165 // start another process, but that could easily get us in
6166 // an infinite loop of restarting processes...
6167 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6169 app.resetPackageList(mProcessStats);
6170 app.unlinkDeathRecipient();
6171 startProcessLocked(app, "bind fail", processName);
6175 // Remove this record from the list of starting applications.
6176 mPersistentStartingProcesses.remove(app);
6177 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6178 "Attach application locked removing on hold: " + app);
6179 mProcessesOnHold.remove(app);
6181 boolean badApp = false;
6182 boolean didSomething = false;
6184 // See if the top visible activity is waiting to run in this process...
6187 if (mStackSupervisor.attachApplicationLocked(app)) {
6188 didSomething = true;
6190 } catch (Exception e) {
6191 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6196 // Find any services that should be running in this process...
6199 didSomething |= mServices.attachApplicationLocked(app, processName);
6200 } catch (Exception e) {
6201 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6206 // Check if a next-broadcast receiver is in this process...
6207 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6209 didSomething |= sendPendingBroadcastsLocked(app);
6210 } catch (Exception e) {
6211 // If the app died trying to launch the receiver we declare it 'bad'
6212 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6217 // Check whether the next backup agent is in this process...
6218 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6219 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6220 "New app is backup target, launching agent for " + app);
6221 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6223 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6224 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6225 mBackupTarget.backupMode);
6226 } catch (Exception e) {
6227 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6233 app.kill("error during init", true);
6234 handleAppDiedLocked(app, false, true);
6238 if (!didSomething) {
6239 updateOomAdjLocked();
6246 public final void attachApplication(IApplicationThread thread) {
6247 synchronized (this) {
6248 int callingPid = Binder.getCallingPid();
6249 final long origId = Binder.clearCallingIdentity();
6250 attachApplicationLocked(thread, callingPid);
6251 Binder.restoreCallingIdentity(origId);
6256 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6257 final long origId = Binder.clearCallingIdentity();
6258 synchronized (this) {
6259 ActivityStack stack = ActivityRecord.getStackLocked(token);
6260 if (stack != null) {
6262 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6263 if (stopProfiling) {
6264 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6267 } catch (IOException e) {
6269 clearProfilerLocked();
6274 Binder.restoreCallingIdentity(origId);
6277 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6278 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6279 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6282 void enableScreenAfterBoot() {
6283 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6284 SystemClock.uptimeMillis());
6285 mWindowManager.enableScreenAfterBoot();
6287 synchronized (this) {
6288 updateEventDispatchingLocked();
6293 public void showBootMessage(final CharSequence msg, final boolean always) {
6294 if (Binder.getCallingUid() != Process.myUid()) {
6295 // These days only the core system can call this, so apps can't get in
6296 // the way of what we show about running them.
6298 mWindowManager.showBootMessage(msg, always);
6302 public void keyguardWaitingForActivityDrawn() {
6303 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6304 final long token = Binder.clearCallingIdentity();
6306 synchronized (this) {
6307 if (DEBUG_LOCKSCREEN) logLockScreen("");
6308 mWindowManager.keyguardWaitingForActivityDrawn();
6309 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6310 mLockScreenShown = LOCK_SCREEN_LEAVING;
6311 updateSleepIfNeededLocked();
6315 Binder.restoreCallingIdentity(token);
6320 public void keyguardGoingAway(boolean disableWindowAnimations,
6321 boolean keyguardGoingToNotificationShade) {
6322 enforceNotIsolatedCaller("keyguardGoingAway");
6323 final long token = Binder.clearCallingIdentity();
6325 synchronized (this) {
6326 if (DEBUG_LOCKSCREEN) logLockScreen("");
6327 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6328 keyguardGoingToNotificationShade);
6329 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6330 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6331 updateSleepIfNeededLocked();
6335 Binder.restoreCallingIdentity(token);
6339 final void finishBooting() {
6340 synchronized (this) {
6341 if (!mBootAnimationComplete) {
6342 mCallFinishBooting = true;
6345 mCallFinishBooting = false;
6348 ArraySet<String> completedIsas = new ArraySet<String>();
6349 for (String abi : Build.SUPPORTED_ABIS) {
6350 Process.establishZygoteConnectionForAbi(abi);
6351 final String instructionSet = VMRuntime.getInstructionSet(abi);
6352 if (!completedIsas.contains(instructionSet)) {
6353 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6354 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6356 completedIsas.add(instructionSet);
6360 IntentFilter pkgFilter = new IntentFilter();
6361 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6362 pkgFilter.addDataScheme("package");
6363 mContext.registerReceiver(new BroadcastReceiver() {
6365 public void onReceive(Context context, Intent intent) {
6366 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6368 for (String pkg : pkgs) {
6369 synchronized (ActivityManagerService.this) {
6370 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6371 0, "query restart")) {
6372 setResultCode(Activity.RESULT_OK);
6381 IntentFilter dumpheapFilter = new IntentFilter();
6382 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6383 mContext.registerReceiver(new BroadcastReceiver() {
6385 public void onReceive(Context context, Intent intent) {
6386 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6387 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6389 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6394 // Let system services know.
6395 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6397 synchronized (this) {
6398 // Ensure that any processes we had put on hold are now started
6400 final int NP = mProcessesOnHold.size();
6402 ArrayList<ProcessRecord> procs =
6403 new ArrayList<ProcessRecord>(mProcessesOnHold);
6404 for (int ip=0; ip<NP; ip++) {
6405 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6407 startProcessLocked(procs.get(ip), "on-hold", null);
6411 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6412 // Start looking for apps that are abusing wake locks.
6413 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6414 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6415 // Tell anyone interested that we are done booting!
6416 SystemProperties.set("sys.boot_completed", "1");
6418 // And trigger dev.bootcomplete if we are not showing encryption progress
6419 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6420 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6421 SystemProperties.set("dev.bootcomplete", "1");
6423 for (int i=0; i<mStartedUsers.size(); i++) {
6424 UserState uss = mStartedUsers.valueAt(i);
6425 if (uss.mState == UserState.STATE_BOOTING) {
6426 uss.mState = UserState.STATE_RUNNING;
6427 final int userId = mStartedUsers.keyAt(i);
6428 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6429 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6430 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6431 broadcastIntentLocked(null, null, intent, null,
6432 new IIntentReceiver.Stub() {
6434 public void performReceive(Intent intent, int resultCode,
6435 String data, Bundle extras, boolean ordered,
6436 boolean sticky, int sendingUser) {
6437 synchronized (ActivityManagerService.this) {
6438 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6444 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6445 AppOpsManager.OP_NONE, null, true, false,
6446 MY_PID, Process.SYSTEM_UID, userId);
6449 scheduleStartProfilesLocked();
6455 public void bootAnimationComplete() {
6456 final boolean callFinishBooting;
6457 synchronized (this) {
6458 callFinishBooting = mCallFinishBooting;
6459 mBootAnimationComplete = true;
6461 if (callFinishBooting) {
6466 final void ensureBootCompleted() {
6468 boolean enableScreen;
6469 synchronized (this) {
6472 enableScreen = !mBooted;
6481 enableScreenAfterBoot();
6486 public final void activityResumed(IBinder token) {
6487 final long origId = Binder.clearCallingIdentity();
6488 synchronized(this) {
6489 ActivityStack stack = ActivityRecord.getStackLocked(token);
6490 if (stack != null) {
6491 ActivityRecord.activityResumedLocked(token);
6494 Binder.restoreCallingIdentity(origId);
6498 public final void activityPaused(IBinder token) {
6499 final long origId = Binder.clearCallingIdentity();
6500 synchronized(this) {
6501 ActivityStack stack = ActivityRecord.getStackLocked(token);
6502 if (stack != null) {
6503 stack.activityPausedLocked(token, false);
6506 Binder.restoreCallingIdentity(origId);
6510 public final void activityStopped(IBinder token, Bundle icicle,
6511 PersistableBundle persistentState, CharSequence description) {
6512 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6514 // Refuse possible leaked file descriptors
6515 if (icicle != null && icicle.hasFileDescriptors()) {
6516 throw new IllegalArgumentException("File descriptors passed in Bundle");
6519 final long origId = Binder.clearCallingIdentity();
6521 synchronized (this) {
6522 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6524 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6530 Binder.restoreCallingIdentity(origId);
6534 public final void activityDestroyed(IBinder token) {
6535 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6536 synchronized (this) {
6537 ActivityStack stack = ActivityRecord.getStackLocked(token);
6538 if (stack != null) {
6539 stack.activityDestroyedLocked(token, "activityDestroyed");
6545 public final void backgroundResourcesReleased(IBinder token) {
6546 final long origId = Binder.clearCallingIdentity();
6548 synchronized (this) {
6549 ActivityStack stack = ActivityRecord.getStackLocked(token);
6550 if (stack != null) {
6551 stack.backgroundResourcesReleased();
6555 Binder.restoreCallingIdentity(origId);
6560 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6561 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6565 public final void notifyEnterAnimationComplete(IBinder token) {
6566 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6570 public String getCallingPackage(IBinder token) {
6571 synchronized (this) {
6572 ActivityRecord r = getCallingRecordLocked(token);
6573 return r != null ? r.info.packageName : null;
6578 public ComponentName getCallingActivity(IBinder token) {
6579 synchronized (this) {
6580 ActivityRecord r = getCallingRecordLocked(token);
6581 return r != null ? r.intent.getComponent() : null;
6585 private ActivityRecord getCallingRecordLocked(IBinder token) {
6586 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6594 public ComponentName getActivityClassForToken(IBinder token) {
6595 synchronized(this) {
6596 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6600 return r.intent.getComponent();
6605 public String getPackageForToken(IBinder token) {
6606 synchronized(this) {
6607 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6611 return r.packageName;
6616 public boolean isRootVoiceInteraction(IBinder token) {
6617 synchronized(this) {
6618 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6622 return r.rootVoiceInteraction;
6627 public IIntentSender getIntentSender(int type,
6628 String packageName, IBinder token, String resultWho,
6629 int requestCode, Intent[] intents, String[] resolvedTypes,
6630 int flags, Bundle options, int userId) {
6631 enforceNotIsolatedCaller("getIntentSender");
6632 // Refuse possible leaked file descriptors
6633 if (intents != null) {
6634 if (intents.length < 1) {
6635 throw new IllegalArgumentException("Intents array length must be >= 1");
6637 for (int i=0; i<intents.length; i++) {
6638 Intent intent = intents[i];
6639 if (intent != null) {
6640 if (intent.hasFileDescriptors()) {
6641 throw new IllegalArgumentException("File descriptors passed in Intent");
6643 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6644 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6645 throw new IllegalArgumentException(
6646 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6648 intents[i] = new Intent(intent);
6651 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6652 throw new IllegalArgumentException(
6653 "Intent array length does not match resolvedTypes length");
6656 if (options != null) {
6657 if (options.hasFileDescriptors()) {
6658 throw new IllegalArgumentException("File descriptors passed in options");
6662 synchronized(this) {
6663 int callingUid = Binder.getCallingUid();
6664 int origUserId = userId;
6665 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6666 type == ActivityManager.INTENT_SENDER_BROADCAST,
6667 ALLOW_NON_FULL, "getIntentSender", null);
6668 if (origUserId == UserHandle.USER_CURRENT) {
6669 // We don't want to evaluate this until the pending intent is
6670 // actually executed. However, we do want to always do the
6671 // security checking for it above.
6672 userId = UserHandle.USER_CURRENT;
6675 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6676 int uid = AppGlobals.getPackageManager()
6677 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6678 if (!UserHandle.isSameApp(callingUid, uid)) {
6679 String msg = "Permission Denial: getIntentSender() from pid="
6680 + Binder.getCallingPid()
6681 + ", uid=" + Binder.getCallingUid()
6682 + ", (need uid=" + uid + ")"
6683 + " is not allowed to send as package " + packageName;
6685 throw new SecurityException(msg);
6689 return getIntentSenderLocked(type, packageName, callingUid, userId,
6690 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6692 } catch (RemoteException e) {
6693 throw new SecurityException(e);
6698 IIntentSender getIntentSenderLocked(int type, String packageName,
6699 int callingUid, int userId, IBinder token, String resultWho,
6700 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6702 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6703 ActivityRecord activity = null;
6704 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6705 activity = ActivityRecord.isInStackLocked(token);
6706 if (activity == null) {
6709 if (activity.finishing) {
6714 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6715 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6716 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6717 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6718 |PendingIntent.FLAG_UPDATE_CURRENT);
6720 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6721 type, packageName, activity, resultWho,
6722 requestCode, intents, resolvedTypes, flags, options, userId);
6723 WeakReference<PendingIntentRecord> ref;
6724 ref = mIntentSenderRecords.get(key);
6725 PendingIntentRecord rec = ref != null ? ref.get() : null;
6727 if (!cancelCurrent) {
6728 if (updateCurrent) {
6729 if (rec.key.requestIntent != null) {
6730 rec.key.requestIntent.replaceExtras(intents != null ?
6731 intents[intents.length - 1] : null);
6733 if (intents != null) {
6734 intents[intents.length-1] = rec.key.requestIntent;
6735 rec.key.allIntents = intents;
6736 rec.key.allResolvedTypes = resolvedTypes;
6738 rec.key.allIntents = null;
6739 rec.key.allResolvedTypes = null;
6744 rec.canceled = true;
6745 mIntentSenderRecords.remove(key);
6750 rec = new PendingIntentRecord(this, key, callingUid);
6751 mIntentSenderRecords.put(key, rec.ref);
6752 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6753 if (activity.pendingResults == null) {
6754 activity.pendingResults
6755 = new HashSet<WeakReference<PendingIntentRecord>>();
6757 activity.pendingResults.add(rec.ref);
6763 public void cancelIntentSender(IIntentSender sender) {
6764 if (!(sender instanceof PendingIntentRecord)) {
6767 synchronized(this) {
6768 PendingIntentRecord rec = (PendingIntentRecord)sender;
6770 int uid = AppGlobals.getPackageManager()
6771 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6772 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6773 String msg = "Permission Denial: cancelIntentSender() from pid="
6774 + Binder.getCallingPid()
6775 + ", uid=" + Binder.getCallingUid()
6776 + " is not allowed to cancel packges "
6777 + rec.key.packageName;
6779 throw new SecurityException(msg);
6781 } catch (RemoteException e) {
6782 throw new SecurityException(e);
6784 cancelIntentSenderLocked(rec, true);
6788 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6789 rec.canceled = true;
6790 mIntentSenderRecords.remove(rec.key);
6791 if (cleanActivity && rec.key.activity != null) {
6792 rec.key.activity.pendingResults.remove(rec.ref);
6797 public String getPackageForIntentSender(IIntentSender pendingResult) {
6798 if (!(pendingResult instanceof PendingIntentRecord)) {
6802 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6803 return res.key.packageName;
6804 } catch (ClassCastException e) {
6810 public int getUidForIntentSender(IIntentSender sender) {
6811 if (sender instanceof PendingIntentRecord) {
6813 PendingIntentRecord res = (PendingIntentRecord)sender;
6815 } catch (ClassCastException e) {
6822 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6823 if (!(pendingResult instanceof PendingIntentRecord)) {
6827 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6828 if (res.key.allIntents == null) {
6831 for (int i=0; i<res.key.allIntents.length; i++) {
6832 Intent intent = res.key.allIntents[i];
6833 if (intent.getPackage() != null && intent.getComponent() != null) {
6838 } catch (ClassCastException e) {
6844 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6845 if (!(pendingResult instanceof PendingIntentRecord)) {
6849 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6850 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6854 } catch (ClassCastException e) {
6860 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6861 if (!(pendingResult instanceof PendingIntentRecord)) {
6865 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6866 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6867 } catch (ClassCastException e) {
6873 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6874 if (!(pendingResult instanceof PendingIntentRecord)) {
6878 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6879 synchronized (this) {
6880 return getTagForIntentSenderLocked(res, prefix);
6882 } catch (ClassCastException e) {
6887 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6888 final Intent intent = res.key.requestIntent;
6889 if (intent != null) {
6890 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6891 || res.lastTagPrefix.equals(prefix))) {
6894 res.lastTagPrefix = prefix;
6895 final StringBuilder sb = new StringBuilder(128);
6896 if (prefix != null) {
6899 if (intent.getAction() != null) {
6900 sb.append(intent.getAction());
6901 } else if (intent.getComponent() != null) {
6902 intent.getComponent().appendShortString(sb);
6906 return res.lastTag = sb.toString();
6912 public void setProcessLimit(int max) {
6913 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6914 "setProcessLimit()");
6915 synchronized (this) {
6916 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6917 mProcessLimitOverride = max;
6923 public int getProcessLimit() {
6924 synchronized (this) {
6925 return mProcessLimitOverride;
6929 void foregroundTokenDied(ForegroundToken token) {
6930 synchronized (ActivityManagerService.this) {
6931 synchronized (mPidsSelfLocked) {
6933 = mForegroundProcesses.get(token.pid);
6937 mForegroundProcesses.remove(token.pid);
6938 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6942 pr.forcingToForeground = null;
6943 updateProcessForegroundLocked(pr, false, false);
6945 updateOomAdjLocked();
6950 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6951 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6952 "setProcessForeground()");
6953 synchronized(this) {
6954 boolean changed = false;
6956 synchronized (mPidsSelfLocked) {
6957 ProcessRecord pr = mPidsSelfLocked.get(pid);
6958 if (pr == null && isForeground) {
6959 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6962 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6963 if (oldToken != null) {
6964 oldToken.token.unlinkToDeath(oldToken, 0);
6965 mForegroundProcesses.remove(pid);
6967 pr.forcingToForeground = null;
6971 if (isForeground && token != null) {
6972 ForegroundToken newToken = new ForegroundToken() {
6974 public void binderDied() {
6975 foregroundTokenDied(this);
6979 newToken.token = token;
6981 token.linkToDeath(newToken, 0);
6982 mForegroundProcesses.put(pid, newToken);
6983 pr.forcingToForeground = token;
6985 } catch (RemoteException e) {
6986 // If the process died while doing this, we will later
6987 // do the cleanup with the process death link.
6993 updateOomAdjLocked();
6998 // =========================================================
7000 // =========================================================
7002 static class ProcessInfoService extends IProcessInfoService.Stub {
7003 final ActivityManagerService mActivityManagerService;
7004 ProcessInfoService(ActivityManagerService activityManagerService) {
7005 mActivityManagerService = activityManagerService;
7009 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7010 mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
7015 * For each PID in the given input array, write the current process state
7016 * for that process into the output array, or -1 to indicate that no
7017 * process with the given PID exists.
7019 public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
7021 throw new NullPointerException("pids");
7022 } else if (states == null) {
7023 throw new NullPointerException("states");
7024 } else if (pids.length != states.length) {
7025 throw new IllegalArgumentException("input and output arrays have different lengths!");
7028 synchronized (mPidsSelfLocked) {
7029 for (int i = 0; i < pids.length; i++) {
7030 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7031 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7037 // =========================================================
7039 // =========================================================
7041 static class PermissionController extends IPermissionController.Stub {
7042 ActivityManagerService mActivityManagerService;
7043 PermissionController(ActivityManagerService activityManagerService) {
7044 mActivityManagerService = activityManagerService;
7048 public boolean checkPermission(String permission, int pid, int uid) {
7049 return mActivityManagerService.checkPermission(permission, pid,
7050 uid) == PackageManager.PERMISSION_GRANTED;
7054 public String[] getPackagesForUid(int uid) {
7055 return mActivityManagerService.mContext.getPackageManager()
7056 .getPackagesForUid(uid);
7060 public boolean isRuntimePermission(String permission) {
7062 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7063 .getPermissionInfo(permission, 0);
7064 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7065 } catch (NameNotFoundException nnfe) {
7066 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7072 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7074 public int checkComponentPermission(String permission, int pid, int uid,
7075 int owningUid, boolean exported) {
7076 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7077 owningUid, exported);
7081 public Object getAMSLock() {
7082 return ActivityManagerService.this;
7087 * This can be called with or without the global lock held.
7089 int checkComponentPermission(String permission, int pid, int uid,
7090 int owningUid, boolean exported) {
7091 if (pid == MY_PID) {
7092 return PackageManager.PERMISSION_GRANTED;
7094 return ActivityManager.checkComponentPermission(permission, uid,
7095 owningUid, exported);
7099 * As the only public entry point for permissions checking, this method
7100 * can enforce the semantic that requesting a check on a null global
7101 * permission is automatically denied. (Internally a null permission
7102 * string is used when calling {@link #checkComponentPermission} in cases
7103 * when only uid-based security is needed.)
7105 * This can be called with or without the global lock held.
7108 public int checkPermission(String permission, int pid, int uid) {
7109 if (permission == null) {
7110 return PackageManager.PERMISSION_DENIED;
7112 return checkComponentPermission(permission, pid, uid, -1, true);
7116 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7117 if (permission == null) {
7118 return PackageManager.PERMISSION_DENIED;
7121 // We might be performing an operation on behalf of an indirect binder
7122 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7123 // client identity accordingly before proceeding.
7124 Identity tlsIdentity = sCallerIdentity.get();
7125 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7126 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7127 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7128 uid = tlsIdentity.uid;
7129 pid = tlsIdentity.pid;
7132 return checkComponentPermission(permission, pid, uid, -1, true);
7136 * Binder IPC calls go through the public entry point.
7137 * This can be called with or without the global lock held.
7139 int checkCallingPermission(String permission) {
7140 return checkPermission(permission,
7141 Binder.getCallingPid(),
7142 UserHandle.getAppId(Binder.getCallingUid()));
7146 * This can be called with or without the global lock held.
7148 void enforceCallingPermission(String permission, String func) {
7149 if (checkCallingPermission(permission)
7150 == PackageManager.PERMISSION_GRANTED) {
7154 String msg = "Permission Denial: " + func + " from pid="
7155 + Binder.getCallingPid()
7156 + ", uid=" + Binder.getCallingUid()
7157 + " requires " + permission;
7159 throw new SecurityException(msg);
7163 * Determine if UID is holding permissions required to access {@link Uri} in
7164 * the given {@link ProviderInfo}. Final permission checking is always done
7165 * in {@link ContentProvider}.
7167 private final boolean checkHoldingPermissionsLocked(
7168 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7169 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7170 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7171 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7172 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7173 != PERMISSION_GRANTED) {
7177 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7180 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7181 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7182 if (pi.applicationInfo.uid == uid) {
7184 } else if (!pi.exported) {
7188 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7189 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7191 // check if target holds top-level <provider> permissions
7192 if (!readMet && pi.readPermission != null && considerUidPermissions
7193 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7196 if (!writeMet && pi.writePermission != null && considerUidPermissions
7197 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7201 // track if unprotected read/write is allowed; any denied
7202 // <path-permission> below removes this ability
7203 boolean allowDefaultRead = pi.readPermission == null;
7204 boolean allowDefaultWrite = pi.writePermission == null;
7206 // check if target holds any <path-permission> that match uri
7207 final PathPermission[] pps = pi.pathPermissions;
7209 final String path = grantUri.uri.getPath();
7211 while (i > 0 && (!readMet || !writeMet)) {
7213 PathPermission pp = pps[i];
7214 if (pp.match(path)) {
7216 final String pprperm = pp.getReadPermission();
7217 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7218 "Checking read perm for " + pprperm + " for " + pp.getPath()
7219 + ": match=" + pp.match(path)
7220 + " check=" + pm.checkUidPermission(pprperm, uid));
7221 if (pprperm != null) {
7222 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7223 == PERMISSION_GRANTED) {
7226 allowDefaultRead = false;
7231 final String ppwperm = pp.getWritePermission();
7232 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7233 "Checking write perm " + ppwperm + " for " + pp.getPath()
7234 + ": match=" + pp.match(path)
7235 + " check=" + pm.checkUidPermission(ppwperm, uid));
7236 if (ppwperm != null) {
7237 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7238 == PERMISSION_GRANTED) {
7241 allowDefaultWrite = false;
7249 // grant unprotected <provider> read/write, if not blocked by
7250 // <path-permission> above
7251 if (allowDefaultRead) readMet = true;
7252 if (allowDefaultWrite) writeMet = true;
7254 } catch (RemoteException e) {
7258 return readMet && writeMet;
7261 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7262 ProviderInfo pi = null;
7263 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7268 pi = AppGlobals.getPackageManager().resolveContentProvider(
7269 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7270 } catch (RemoteException ex) {
7276 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7277 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7278 if (targetUris != null) {
7279 return targetUris.get(grantUri);
7284 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7285 String targetPkg, int targetUid, GrantUri grantUri) {
7286 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7287 if (targetUris == null) {
7288 targetUris = Maps.newArrayMap();
7289 mGrantedUriPermissions.put(targetUid, targetUris);
7292 UriPermission perm = targetUris.get(grantUri);
7294 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7295 targetUris.put(grantUri, perm);
7301 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7302 final int modeFlags) {
7303 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7304 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7305 : UriPermission.STRENGTH_OWNED;
7307 // Root gets to do everything.
7312 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7313 if (perms == null) return false;
7315 // First look for exact match
7316 final UriPermission exactPerm = perms.get(grantUri);
7317 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7321 // No exact match, look for prefixes
7322 final int N = perms.size();
7323 for (int i = 0; i < N; i++) {
7324 final UriPermission perm = perms.valueAt(i);
7325 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7326 && perm.getStrength(modeFlags) >= minStrength) {
7335 * @param uri This uri must NOT contain an embedded userId.
7336 * @param userId The userId in which the uri is to be resolved.
7339 public int checkUriPermission(Uri uri, int pid, int uid,
7340 final int modeFlags, int userId, IBinder callerToken) {
7341 enforceNotIsolatedCaller("checkUriPermission");
7343 // Another redirected-binder-call permissions check as in
7344 // {@link checkPermissionWithToken}.
7345 Identity tlsIdentity = sCallerIdentity.get();
7346 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7347 uid = tlsIdentity.uid;
7348 pid = tlsIdentity.pid;
7351 // Our own process gets to do everything.
7352 if (pid == MY_PID) {
7353 return PackageManager.PERMISSION_GRANTED;
7355 synchronized (this) {
7356 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7357 ? PackageManager.PERMISSION_GRANTED
7358 : PackageManager.PERMISSION_DENIED;
7363 * Check if the targetPkg can be granted permission to access uri by
7364 * the callingUid using the given modeFlags. Throws a security exception
7365 * if callingUid is not allowed to do this. Returns the uid of the target
7366 * if the URI permission grant should be performed; returns -1 if it is not
7367 * needed (for example targetPkg already has permission to access the URI).
7368 * If you already know the uid of the target, you can supply it in
7369 * lastTargetUid else set that to -1.
7371 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7372 final int modeFlags, int lastTargetUid) {
7373 if (!Intent.isAccessUriMode(modeFlags)) {
7377 if (targetPkg != null) {
7378 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7379 "Checking grant " + targetPkg + " permission to " + grantUri);
7382 final IPackageManager pm = AppGlobals.getPackageManager();
7384 // If this is not a content: uri, we can't do anything with it.
7385 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7386 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7387 "Can't grant URI permission for non-content URI: " + grantUri);
7391 final String authority = grantUri.uri.getAuthority();
7392 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7394 Slog.w(TAG, "No content provider found for permission check: " +
7395 grantUri.uri.toSafeString());
7399 int targetUid = lastTargetUid;
7400 if (targetUid < 0 && targetPkg != null) {
7402 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7403 if (targetUid < 0) {
7404 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7405 "Can't grant URI permission no uid for: " + targetPkg);
7408 } catch (RemoteException ex) {
7413 if (targetUid >= 0) {
7414 // First... does the target actually need this permission?
7415 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7416 // No need to grant the target this permission.
7417 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7418 "Target " + targetPkg + " already has full permission to " + grantUri);
7422 // First... there is no target package, so can anyone access it?
7423 boolean allowed = pi.exported;
7424 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7425 if (pi.readPermission != null) {
7429 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7430 if (pi.writePermission != null) {
7439 /* There is a special cross user grant if:
7440 * - The target is on another user.
7441 * - Apps on the current user can access the uri without any uid permissions.
7442 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7443 * grant uri permissions.
7445 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7446 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7447 modeFlags, false /*without considering the uid permissions*/);
7449 // Second... is the provider allowing granting of URI permissions?
7450 if (!specialCrossUserGrant) {
7451 if (!pi.grantUriPermissions) {
7452 throw new SecurityException("Provider " + pi.packageName
7454 + " does not allow granting of Uri permissions (uri "
7457 if (pi.uriPermissionPatterns != null) {
7458 final int N = pi.uriPermissionPatterns.length;
7459 boolean allowed = false;
7460 for (int i=0; i<N; i++) {
7461 if (pi.uriPermissionPatterns[i] != null
7462 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7468 throw new SecurityException("Provider " + pi.packageName
7470 + " does not allow granting of permission to path of Uri "
7476 // Third... does the caller itself have permission to access
7478 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7479 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7480 // Require they hold a strong enough Uri permission
7481 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7482 throw new SecurityException("Uid " + callingUid
7483 + " does not have permission to uri " + grantUri);
7491 * @param uri This uri must NOT contain an embedded userId.
7492 * @param userId The userId in which the uri is to be resolved.
7495 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7496 final int modeFlags, int userId) {
7497 enforceNotIsolatedCaller("checkGrantUriPermission");
7498 synchronized(this) {
7499 return checkGrantUriPermissionLocked(callingUid, targetPkg,
7500 new GrantUri(userId, uri, false), modeFlags, -1);
7504 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7505 final int modeFlags, UriPermissionOwner owner) {
7506 if (!Intent.isAccessUriMode(modeFlags)) {
7510 // So here we are: the caller has the assumed permission
7511 // to the uri, and the target doesn't. Let's now give this to
7514 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7515 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7517 final String authority = grantUri.uri.getAuthority();
7518 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7520 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7524 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7525 grantUri.prefix = true;
7527 final UriPermission perm = findOrCreateUriPermissionLocked(
7528 pi.packageName, targetPkg, targetUid, grantUri);
7529 perm.grantModes(modeFlags, owner);
7532 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7533 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7534 if (targetPkg == null) {
7535 throw new NullPointerException("targetPkg");
7538 final IPackageManager pm = AppGlobals.getPackageManager();
7540 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7541 } catch (RemoteException ex) {
7545 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7547 if (targetUid < 0) {
7551 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7555 static class NeededUriGrants extends ArrayList<GrantUri> {
7556 final String targetPkg;
7557 final int targetUid;
7560 NeededUriGrants(String targetPkg, int targetUid, int flags) {
7561 this.targetPkg = targetPkg;
7562 this.targetUid = targetUid;
7568 * Like checkGrantUriPermissionLocked, but takes an Intent.
7570 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7571 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7572 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7573 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7574 + " clip=" + (intent != null ? intent.getClipData() : null)
7575 + " from " + intent + "; flags=0x"
7576 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7578 if (targetPkg == null) {
7579 throw new NullPointerException("targetPkg");
7582 if (intent == null) {
7585 Uri data = intent.getData();
7586 ClipData clip = intent.getClipData();
7587 if (data == null && clip == null) {
7590 // Default userId for uris in the intent (if they don't specify it themselves)
7591 int contentUserHint = intent.getContentUserHint();
7592 if (contentUserHint == UserHandle.USER_CURRENT) {
7593 contentUserHint = UserHandle.getUserId(callingUid);
7595 final IPackageManager pm = AppGlobals.getPackageManager();
7597 if (needed != null) {
7598 targetUid = needed.targetUid;
7601 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7602 } catch (RemoteException ex) {
7605 if (targetUid < 0) {
7606 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7607 "Can't grant URI permission no uid for: " + targetPkg
7608 + " on user " + targetUserId);
7613 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7614 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7616 if (targetUid > 0) {
7617 if (needed == null) {
7618 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7620 needed.add(grantUri);
7624 for (int i=0; i<clip.getItemCount(); i++) {
7625 Uri uri = clip.getItemAt(i).getUri();
7627 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7628 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7630 if (targetUid > 0) {
7631 if (needed == null) {
7632 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7634 needed.add(grantUri);
7637 Intent clipIntent = clip.getItemAt(i).getIntent();
7638 if (clipIntent != null) {
7639 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7640 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7641 if (newNeeded != null) {
7653 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7655 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7656 UriPermissionOwner owner) {
7657 if (needed != null) {
7658 for (int i=0; i<needed.size(); i++) {
7659 GrantUri grantUri = needed.get(i);
7660 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7661 grantUri, needed.flags, owner);
7666 void grantUriPermissionFromIntentLocked(int callingUid,
7667 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7668 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7669 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7670 if (needed == null) {
7674 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7678 * @param uri This uri must NOT contain an embedded userId.
7679 * @param userId The userId in which the uri is to be resolved.
7682 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7683 final int modeFlags, int userId) {
7684 enforceNotIsolatedCaller("grantUriPermission");
7685 GrantUri grantUri = new GrantUri(userId, uri, false);
7686 synchronized(this) {
7687 final ProcessRecord r = getRecordForAppLocked(caller);
7689 throw new SecurityException("Unable to find app for caller "
7691 + " when granting permission to uri " + grantUri);
7693 if (targetPkg == null) {
7694 throw new IllegalArgumentException("null target");
7696 if (grantUri == null) {
7697 throw new IllegalArgumentException("null uri");
7700 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7701 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7702 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7703 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7705 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7706 UserHandle.getUserId(r.uid));
7710 void removeUriPermissionIfNeededLocked(UriPermission perm) {
7711 if (perm.modeFlags == 0) {
7712 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7714 if (perms != null) {
7715 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7716 "Removing " + perm.targetUid + " permission to " + perm.uri);
7718 perms.remove(perm.uri);
7719 if (perms.isEmpty()) {
7720 mGrantedUriPermissions.remove(perm.targetUid);
7726 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7727 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7728 "Revoking all granted permissions to " + grantUri);
7730 final IPackageManager pm = AppGlobals.getPackageManager();
7731 final String authority = grantUri.uri.getAuthority();
7732 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7734 Slog.w(TAG, "No content provider found for permission revoke: "
7735 + grantUri.toSafeString());
7739 // Does the caller have this permission on the URI?
7740 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7741 // If they don't have direct access to the URI, then revoke any
7742 // ownerless URI permissions that have been granted to them.
7743 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7744 if (perms != null) {
7745 boolean persistChanged = false;
7746 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7747 final UriPermission perm = it.next();
7748 if (perm.uri.sourceUserId == grantUri.sourceUserId
7749 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7750 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7751 "Revoking non-owned " + perm.targetUid
7752 + " permission to " + perm.uri);
7753 persistChanged |= perm.revokeModes(
7754 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7755 if (perm.modeFlags == 0) {
7760 if (perms.isEmpty()) {
7761 mGrantedUriPermissions.remove(callingUid);
7763 if (persistChanged) {
7764 schedulePersistUriGrants();
7770 boolean persistChanged = false;
7772 // Go through all of the permissions and remove any that match.
7773 int N = mGrantedUriPermissions.size();
7774 for (int i = 0; i < N; i++) {
7775 final int targetUid = mGrantedUriPermissions.keyAt(i);
7776 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7778 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7779 final UriPermission perm = it.next();
7780 if (perm.uri.sourceUserId == grantUri.sourceUserId
7781 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7782 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7783 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7784 persistChanged |= perm.revokeModes(
7785 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7786 if (perm.modeFlags == 0) {
7792 if (perms.isEmpty()) {
7793 mGrantedUriPermissions.remove(targetUid);
7799 if (persistChanged) {
7800 schedulePersistUriGrants();
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 revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7811 enforceNotIsolatedCaller("revokeUriPermission");
7812 synchronized(this) {
7813 final ProcessRecord r = getRecordForAppLocked(caller);
7815 throw new SecurityException("Unable to find app for caller "
7817 + " when revoking permission to uri " + uri);
7820 Slog.w(TAG, "revokeUriPermission: null uri");
7824 if (!Intent.isAccessUriMode(modeFlags)) {
7828 final String authority = uri.getAuthority();
7829 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7831 Slog.w(TAG, "No content provider found for permission revoke: "
7832 + uri.toSafeString());
7836 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7841 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7844 * @param packageName Package name to match, or {@code null} to apply to all
7846 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7848 * @param persistable If persistable grants should be removed.
7850 private void removeUriPermissionsForPackageLocked(
7851 String packageName, int userHandle, boolean persistable) {
7852 if (userHandle == UserHandle.USER_ALL && packageName == null) {
7853 throw new IllegalArgumentException("Must narrow by either package or user");
7856 boolean persistChanged = false;
7858 int N = mGrantedUriPermissions.size();
7859 for (int i = 0; i < N; i++) {
7860 final int targetUid = mGrantedUriPermissions.keyAt(i);
7861 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7863 // Only inspect grants matching user
7864 if (userHandle == UserHandle.USER_ALL
7865 || userHandle == UserHandle.getUserId(targetUid)) {
7866 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7867 final UriPermission perm = it.next();
7869 // Only inspect grants matching package
7870 if (packageName == null || perm.sourcePkg.equals(packageName)
7871 || perm.targetPkg.equals(packageName)) {
7872 persistChanged |= perm.revokeModes(persistable
7873 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7875 // Only remove when no modes remain; any persisted grants
7876 // will keep this alive.
7877 if (perm.modeFlags == 0) {
7883 if (perms.isEmpty()) {
7884 mGrantedUriPermissions.remove(targetUid);
7891 if (persistChanged) {
7892 schedulePersistUriGrants();
7897 public IBinder newUriPermissionOwner(String name) {
7898 enforceNotIsolatedCaller("newUriPermissionOwner");
7899 synchronized(this) {
7900 UriPermissionOwner owner = new UriPermissionOwner(this, name);
7901 return owner.getExternalTokenLocked();
7906 * @param uri This uri must NOT contain an embedded userId.
7907 * @param sourceUserId The userId in which the uri is to be resolved.
7908 * @param targetUserId The userId of the app that receives the grant.
7911 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7912 final int modeFlags, int sourceUserId, int targetUserId) {
7913 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7914 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7915 synchronized(this) {
7916 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7917 if (owner == null) {
7918 throw new IllegalArgumentException("Unknown owner: " + token);
7920 if (fromUid != Binder.getCallingUid()) {
7921 if (Binder.getCallingUid() != Process.myUid()) {
7922 // Only system code can grant URI permissions on behalf
7924 throw new SecurityException("nice try");
7927 if (targetPkg == null) {
7928 throw new IllegalArgumentException("null target");
7931 throw new IllegalArgumentException("null uri");
7934 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7935 modeFlags, owner, targetUserId);
7940 * @param uri This uri must NOT contain an embedded userId.
7941 * @param userId The userId in which the uri is to be resolved.
7944 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7945 synchronized(this) {
7946 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7947 if (owner == null) {
7948 throw new IllegalArgumentException("Unknown owner: " + token);
7952 owner.removeUriPermissionsLocked(mode);
7954 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7959 private void schedulePersistUriGrants() {
7960 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7961 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7962 10 * DateUtils.SECOND_IN_MILLIS);
7966 private void writeGrantedUriPermissions() {
7967 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7969 // Snapshot permissions so we can persist without lock
7970 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7971 synchronized (this) {
7972 final int size = mGrantedUriPermissions.size();
7973 for (int i = 0; i < size; i++) {
7974 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7975 for (UriPermission perm : perms.values()) {
7976 if (perm.persistedModeFlags != 0) {
7977 persist.add(perm.snapshot());
7983 FileOutputStream fos = null;
7985 fos = mGrantFile.startWrite();
7987 XmlSerializer out = new FastXmlSerializer();
7988 out.setOutput(fos, StandardCharsets.UTF_8.name());
7989 out.startDocument(null, true);
7990 out.startTag(null, TAG_URI_GRANTS);
7991 for (UriPermission.Snapshot perm : persist) {
7992 out.startTag(null, TAG_URI_GRANT);
7993 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7994 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7995 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7996 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7997 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7998 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7999 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8000 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8001 out.endTag(null, TAG_URI_GRANT);
8003 out.endTag(null, TAG_URI_GRANTS);
8006 mGrantFile.finishWrite(fos);
8007 } catch (IOException e) {
8009 mGrantFile.failWrite(fos);
8014 private void readGrantedUriPermissionsLocked() {
8015 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8017 final long now = System.currentTimeMillis();
8019 FileInputStream fis = null;
8021 fis = mGrantFile.openRead();
8022 final XmlPullParser in = Xml.newPullParser();
8023 in.setInput(fis, StandardCharsets.UTF_8.name());
8026 while ((type = in.next()) != END_DOCUMENT) {
8027 final String tag = in.getName();
8028 if (type == START_TAG) {
8029 if (TAG_URI_GRANT.equals(tag)) {
8030 final int sourceUserId;
8031 final int targetUserId;
8032 final int userHandle = readIntAttribute(in,
8033 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8034 if (userHandle != UserHandle.USER_NULL) {
8035 // For backwards compatibility.
8036 sourceUserId = userHandle;
8037 targetUserId = userHandle;
8039 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8040 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8042 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8043 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8044 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8045 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8046 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8047 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8049 // Sanity check that provider still belongs to source package
8050 final ProviderInfo pi = getProviderInfoLocked(
8051 uri.getAuthority(), sourceUserId);
8052 if (pi != null && sourcePkg.equals(pi.packageName)) {
8055 targetUid = AppGlobals.getPackageManager()
8056 .getPackageUid(targetPkg, targetUserId);
8057 } catch (RemoteException e) {
8059 if (targetUid != -1) {
8060 final UriPermission perm = findOrCreateUriPermissionLocked(
8061 sourcePkg, targetPkg, targetUid,
8062 new GrantUri(sourceUserId, uri, prefix));
8063 perm.initPersistedModes(modeFlags, createdTime);
8066 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8067 + " but instead found " + pi);
8072 } catch (FileNotFoundException e) {
8073 // Missing grants is okay
8074 } catch (IOException e) {
8075 Slog.wtf(TAG, "Failed reading Uri grants", e);
8076 } catch (XmlPullParserException e) {
8077 Slog.wtf(TAG, "Failed reading Uri grants", e);
8079 IoUtils.closeQuietly(fis);
8084 * @param uri This uri must NOT contain an embedded userId.
8085 * @param userId The userId in which the uri is to be resolved.
8088 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8089 enforceNotIsolatedCaller("takePersistableUriPermission");
8091 Preconditions.checkFlagsArgument(modeFlags,
8092 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8094 synchronized (this) {
8095 final int callingUid = Binder.getCallingUid();
8096 boolean persistChanged = false;
8097 GrantUri grantUri = new GrantUri(userId, uri, false);
8099 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8100 new GrantUri(userId, uri, false));
8101 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8102 new GrantUri(userId, uri, true));
8104 final boolean exactValid = (exactPerm != null)
8105 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8106 final boolean prefixValid = (prefixPerm != null)
8107 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8109 if (!(exactValid || prefixValid)) {
8110 throw new SecurityException("No persistable permission grants found for UID "
8111 + callingUid + " and Uri " + grantUri.toSafeString());
8115 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8118 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8121 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8123 if (persistChanged) {
8124 schedulePersistUriGrants();
8130 * @param uri This uri must NOT contain an embedded userId.
8131 * @param userId The userId in which the uri is to be resolved.
8134 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8135 enforceNotIsolatedCaller("releasePersistableUriPermission");
8137 Preconditions.checkFlagsArgument(modeFlags,
8138 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8140 synchronized (this) {
8141 final int callingUid = Binder.getCallingUid();
8142 boolean persistChanged = false;
8144 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8145 new GrantUri(userId, uri, false));
8146 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8147 new GrantUri(userId, uri, true));
8148 if (exactPerm == null && prefixPerm == null) {
8149 throw new SecurityException("No permission grants found for UID " + callingUid
8150 + " and Uri " + uri.toSafeString());
8153 if (exactPerm != null) {
8154 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8155 removeUriPermissionIfNeededLocked(exactPerm);
8157 if (prefixPerm != null) {
8158 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8159 removeUriPermissionIfNeededLocked(prefixPerm);
8162 if (persistChanged) {
8163 schedulePersistUriGrants();
8169 * Prune any older {@link UriPermission} for the given UID until outstanding
8170 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8172 * @return if any mutations occured that require persisting.
8174 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8175 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8176 if (perms == null) return false;
8177 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8179 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8180 for (UriPermission perm : perms.values()) {
8181 if (perm.persistedModeFlags != 0) {
8182 persisted.add(perm);
8186 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8187 if (trimCount <= 0) return false;
8189 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8190 for (int i = 0; i < trimCount; i++) {
8191 final UriPermission perm = persisted.get(i);
8193 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8194 "Trimming grant created at " + perm.persistedCreateTime);
8196 perm.releasePersistableModes(~0);
8197 removeUriPermissionIfNeededLocked(perm);
8204 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8205 String packageName, boolean incoming) {
8206 enforceNotIsolatedCaller("getPersistedUriPermissions");
8207 Preconditions.checkNotNull(packageName, "packageName");
8209 final int callingUid = Binder.getCallingUid();
8210 final IPackageManager pm = AppGlobals.getPackageManager();
8212 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8213 if (packageUid != callingUid) {
8214 throw new SecurityException(
8215 "Package " + packageName + " does not belong to calling UID " + callingUid);
8217 } catch (RemoteException e) {
8218 throw new SecurityException("Failed to verify package name ownership");
8221 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8222 synchronized (this) {
8224 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8226 if (perms == null) {
8227 Slog.w(TAG, "No permission grants found for " + packageName);
8229 for (UriPermission perm : perms.values()) {
8230 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8231 result.add(perm.buildPersistedPublicApiObject());
8236 final int size = mGrantedUriPermissions.size();
8237 for (int i = 0; i < size; i++) {
8238 final ArrayMap<GrantUri, UriPermission> perms =
8239 mGrantedUriPermissions.valueAt(i);
8240 for (UriPermission perm : perms.values()) {
8241 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8242 result.add(perm.buildPersistedPublicApiObject());
8248 return new ParceledListSlice<android.content.UriPermission>(result);
8252 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8253 synchronized (this) {
8255 who != null ? getRecordForAppLocked(who) : null;
8256 if (app == null) return;
8258 Message msg = Message.obtain();
8259 msg.what = WAIT_FOR_DEBUGGER_MSG;
8261 msg.arg1 = waiting ? 1 : 0;
8262 mUiHandler.sendMessage(msg);
8267 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8268 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8269 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8270 outInfo.availMem = Process.getFreeMemory();
8271 outInfo.totalMem = Process.getTotalMemory();
8272 outInfo.threshold = homeAppMem;
8273 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8274 outInfo.hiddenAppThreshold = cachedAppMem;
8275 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8276 ProcessList.SERVICE_ADJ);
8277 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8278 ProcessList.VISIBLE_APP_ADJ);
8279 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8280 ProcessList.FOREGROUND_APP_ADJ);
8283 // =========================================================
8285 // =========================================================
8288 public List<IAppTask> getAppTasks(String callingPackage) {
8289 int callingUid = Binder.getCallingUid();
8290 long ident = Binder.clearCallingIdentity();
8292 synchronized(this) {
8293 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8295 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8297 final int N = mRecentTasks.size();
8298 for (int i = 0; i < N; i++) {
8299 TaskRecord tr = mRecentTasks.get(i);
8300 // Skip tasks that do not match the caller. We don't need to verify
8301 // callingPackage, because we are also limiting to callingUid and know
8302 // that will limit to the correct security sandbox.
8303 if (tr.effectiveUid != callingUid) {
8306 Intent intent = tr.getBaseIntent();
8307 if (intent == null ||
8308 !callingPackage.equals(intent.getComponent().getPackageName())) {
8311 ActivityManager.RecentTaskInfo taskInfo =
8312 createRecentTaskInfoFromTaskRecord(tr);
8313 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8317 Binder.restoreCallingIdentity(ident);
8324 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8325 final int callingUid = Binder.getCallingUid();
8326 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8328 synchronized(this) {
8329 if (DEBUG_ALL) Slog.v(
8330 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8332 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8335 // TODO: Improve with MRU list from all ActivityStacks.
8336 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8343 * Creates a new RecentTaskInfo from a TaskRecord.
8345 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8346 // Update the task description to reflect any changes in the task stack
8347 tr.updateTaskDescription();
8349 // Compose the recent task info
8350 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8351 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8352 rti.persistentId = tr.taskId;
8353 rti.baseIntent = new Intent(tr.getBaseIntent());
8354 rti.origActivity = tr.origActivity;
8355 rti.description = tr.lastDescription;
8356 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8357 rti.userId = tr.userId;
8358 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8359 rti.firstActiveTime = tr.firstActiveTime;
8360 rti.lastActiveTime = tr.lastActiveTime;
8361 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8362 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8363 rti.numActivities = 0;
8365 ActivityRecord base = null;
8366 ActivityRecord top = null;
8369 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8370 tmp = tr.mActivities.get(i);
8371 if (tmp.finishing) {
8375 if (top == null || (top.state == ActivityState.INITIALIZING)) {
8378 rti.numActivities++;
8381 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8382 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8387 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8388 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8389 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8391 if (checkPermission(android.Manifest.permission.GET_TASKS,
8392 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8393 // Temporary compatibility: some existing apps on the system image may
8394 // still be requesting the old permission and not switched to the new
8395 // one; if so, we'll still allow them full access. This means we need
8396 // to see if they are holding the old permission and are a system app.
8398 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8400 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8401 + " is using old GET_TASKS but privileged; allowing");
8403 } catch (RemoteException e) {
8408 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8409 + " does not hold REAL_GET_TASKS; limiting output");
8415 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8416 final int callingUid = Binder.getCallingUid();
8417 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8418 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8420 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8421 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8422 synchronized (this) {
8423 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8425 final boolean detailed = checkCallingPermission(
8426 android.Manifest.permission.GET_DETAILED_TASKS)
8427 == PackageManager.PERMISSION_GRANTED;
8429 final int recentsCount = mRecentTasks.size();
8430 ArrayList<ActivityManager.RecentTaskInfo> res =
8431 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8433 final Set<Integer> includedUsers;
8434 if (includeProfiles) {
8435 includedUsers = getProfileIdsLocked(userId);
8437 includedUsers = new HashSet<>();
8439 includedUsers.add(Integer.valueOf(userId));
8441 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8442 TaskRecord tr = mRecentTasks.get(i);
8443 // Only add calling user or related users recent tasks
8444 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8445 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8449 // Return the entry if desired by the caller. We always return
8450 // the first entry, because callers always expect this to be the
8451 // foreground app. We may filter others if the caller has
8452 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8453 // we should exclude the entry.
8457 || (tr.intent == null)
8458 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8461 // If the caller doesn't have the GET_TASKS permission, then only
8462 // allow them to see a small subset of tasks -- their own and home.
8463 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8464 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8468 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8469 if (tr.stack != null && tr.stack.isHomeStack()) {
8470 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8471 "Skipping, home stack task: " + tr);
8475 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8476 // Don't include auto remove tasks that are finished or finishing.
8477 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8478 "Skipping, auto-remove without activity: " + tr);
8481 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8482 && !tr.isAvailable) {
8483 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8484 "Skipping, unavail real act: " + tr);
8488 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8490 rti.baseIntent.replaceExtras((Bundle)null);
8502 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8503 synchronized (this) {
8504 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8505 "getTaskThumbnail()");
8506 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8508 return tr.getTaskThumbnailLocked();
8515 public int addAppTask(IBinder activityToken, Intent intent,
8516 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8517 final int callingUid = Binder.getCallingUid();
8518 final long callingIdent = Binder.clearCallingIdentity();
8521 synchronized (this) {
8522 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8524 throw new IllegalArgumentException("Activity does not exist; token="
8527 ComponentName comp = intent.getComponent();
8529 throw new IllegalArgumentException("Intent " + intent
8530 + " must specify explicit component");
8532 if (thumbnail.getWidth() != mThumbnailWidth
8533 || thumbnail.getHeight() != mThumbnailHeight) {
8534 throw new IllegalArgumentException("Bad thumbnail size: got "
8535 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8536 + mThumbnailWidth + "x" + mThumbnailHeight);
8538 if (intent.getSelector() != null) {
8539 intent.setSelector(null);
8541 if (intent.getSourceBounds() != null) {
8542 intent.setSourceBounds(null);
8544 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8545 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8546 // The caller has added this as an auto-remove task... that makes no
8547 // sense, so turn off auto-remove.
8548 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8550 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8551 // Must be a new task.
8552 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8554 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8555 mLastAddedTaskActivity = null;
8557 ActivityInfo ainfo = mLastAddedTaskActivity;
8558 if (ainfo == null) {
8559 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8560 comp, 0, UserHandle.getUserId(callingUid));
8561 if (ainfo.applicationInfo.uid != callingUid) {
8562 throw new SecurityException(
8563 "Can't add task for another application: target uid="
8564 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8568 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8569 intent, description);
8571 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8573 // If this would have caused a trim, then we'll abort because that
8574 // means it would be added at the end of the list but then just removed.
8575 return INVALID_TASK_ID;
8578 final int N = mRecentTasks.size();
8579 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8580 final TaskRecord tr = mRecentTasks.remove(N - 1);
8581 tr.removedFromRecents();
8584 task.inRecents = true;
8585 mRecentTasks.add(task);
8586 r.task.stack.addTask(task, false, false);
8588 task.setLastThumbnail(thumbnail);
8589 task.freeLastThumbnail();
8594 Binder.restoreCallingIdentity(callingIdent);
8599 public Point getAppTaskThumbnailSize() {
8600 synchronized (this) {
8601 return new Point(mThumbnailWidth, mThumbnailHeight);
8606 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8607 synchronized (this) {
8608 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8610 r.setTaskDescription(td);
8611 r.task.updateTaskDescription();
8617 public void setTaskResizeable(int taskId, boolean resizeable) {
8618 synchronized (this) {
8619 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8621 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8624 if (task.mResizeable != resizeable) {
8625 task.mResizeable = resizeable;
8626 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8627 mStackSupervisor.resumeTopActivitiesLocked();
8633 public void resizeTask(int taskId, Rect bounds) {
8634 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8636 long ident = Binder.clearCallingIdentity();
8638 synchronized (this) {
8639 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8641 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8644 mStackSupervisor.resizeTaskLocked(task, bounds);
8647 Binder.restoreCallingIdentity(ident);
8652 public Bitmap getTaskDescriptionIcon(String filename) {
8653 if (!FileUtils.isValidExtFilename(filename)
8654 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8655 throw new IllegalArgumentException("Bad filename: " + filename);
8657 return mTaskPersister.getTaskDescriptionIcon(filename);
8661 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8662 throws RemoteException {
8663 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8664 opts.getCustomInPlaceResId() == 0) {
8665 throw new IllegalArgumentException("Expected in-place ActivityOption " +
8666 "with valid animation");
8668 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8669 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8670 opts.getCustomInPlaceResId());
8671 mWindowManager.executeAppTransition();
8674 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8675 mRecentTasks.remove(tr);
8676 tr.removedFromRecents();
8677 ComponentName component = tr.getBaseIntent().getComponent();
8678 if (component == null) {
8679 Slog.w(TAG, "No component for base intent of task: " + tr);
8683 // Find any running services associated with this app and stop if needed.
8684 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8690 // Determine if the process(es) for this task should be killed.
8691 final String pkg = component.getPackageName();
8692 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8693 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8694 for (int i = 0; i < pmap.size(); i++) {
8696 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8697 for (int j = 0; j < uids.size(); j++) {
8698 ProcessRecord proc = uids.valueAt(j);
8699 if (proc.userId != tr.userId) {
8700 // Don't kill process for a different user.
8703 if (proc == mHomeProcess) {
8704 // Don't kill the home process along with tasks from the same package.
8707 if (!proc.pkgList.containsKey(pkg)) {
8708 // Don't kill process that is not associated with this task.
8712 for (int k = 0; k < proc.activities.size(); k++) {
8713 TaskRecord otherTask = proc.activities.get(k).task;
8714 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8715 // Don't kill process(es) that has an activity in a different task that is
8721 if (proc.foregroundServices) {
8722 // Don't kill process(es) with foreground service.
8726 // Add process to kill list.
8727 procsToKill.add(proc);
8731 // Kill the running processes.
8732 for (int i = 0; i < procsToKill.size(); i++) {
8733 ProcessRecord pr = procsToKill.get(i);
8734 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8735 && pr.curReceiver == null) {
8736 pr.kill("remove task", true);
8738 // We delay killing processes that are not in the background or running a receiver.
8739 pr.waitingToKill = "remove task";
8744 private void removeTasksByPackageNameLocked(String packageName, int userId) {
8745 // Remove all tasks with activities in the specified package from the list of recent tasks
8746 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8747 TaskRecord tr = mRecentTasks.get(i);
8748 if (tr.userId != userId) continue;
8750 ComponentName cn = tr.intent.getComponent();
8751 if (cn != null && cn.getPackageName().equals(packageName)) {
8752 // If the package name matches, remove the task.
8753 removeTaskByIdLocked(tr.taskId, true);
8758 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8761 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8762 TaskRecord tr = mRecentTasks.get(i);
8763 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8767 ComponentName cn = tr.intent.getComponent();
8768 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8769 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8770 if (sameComponent) {
8771 removeTaskByIdLocked(tr.taskId, false);
8777 * Removes the task with the specified task id.
8779 * @param taskId Identifier of the task to be removed.
8780 * @param killProcess Kill any process associated with the task if possible.
8781 * @return Returns true if the given task was found and removed.
8783 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8784 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8786 tr.removeTaskActivitiesLocked();
8787 cleanUpRemovedTaskLocked(tr, killProcess);
8788 if (tr.isPersistable) {
8789 notifyTaskPersisterLocked(null, true);
8793 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8798 public boolean removeTask(int taskId) {
8799 synchronized (this) {
8800 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8802 long ident = Binder.clearCallingIdentity();
8804 return removeTaskByIdLocked(taskId, true);
8806 Binder.restoreCallingIdentity(ident);
8812 * TODO: Add mController hook
8815 public void moveTaskToFront(int taskId, int flags, Bundle options) {
8816 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8818 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8819 synchronized(this) {
8820 moveTaskToFrontLocked(taskId, flags, options);
8824 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8825 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8826 Binder.getCallingUid(), -1, -1, "Task to front")) {
8827 ActivityOptions.abort(options);
8830 final long origId = Binder.clearCallingIdentity();
8832 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8834 Slog.d(TAG, "Could not find task for id: "+ taskId);
8837 if (mStackSupervisor.isLockTaskModeViolation(task)) {
8838 mStackSupervisor.showLockTaskToast();
8839 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8842 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8843 if (prev != null && prev.isRecentsActivity()) {
8844 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8846 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8848 Binder.restoreCallingIdentity(origId);
8850 ActivityOptions.abort(options);
8854 * Moves an activity, and all of the other activities within the same task, to the bottom
8855 * of the history stack. The activity's order within the task is unchanged.
8857 * @param token A reference to the activity we wish to move
8858 * @param nonRoot If false then this only works if the activity is the root
8859 * of a task; if true it will work for any activity in a task.
8860 * @return Returns true if the move completed, false if not.
8863 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8864 enforceNotIsolatedCaller("moveActivityTaskToBack");
8865 synchronized(this) {
8866 final long origId = Binder.clearCallingIdentity();
8868 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8869 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8871 if (mStackSupervisor.isLockedTask(task)) {
8872 mStackSupervisor.showLockTaskToast();
8875 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8878 Binder.restoreCallingIdentity(origId);
8885 public void moveTaskBackwards(int task) {
8886 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8887 "moveTaskBackwards()");
8889 synchronized(this) {
8890 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8891 Binder.getCallingUid(), -1, -1, "Task backwards")) {
8894 final long origId = Binder.clearCallingIdentity();
8895 moveTaskBackwardsLocked(task);
8896 Binder.restoreCallingIdentity(origId);
8900 private final void moveTaskBackwardsLocked(int task) {
8901 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8905 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8906 IActivityContainerCallback callback) throws RemoteException {
8907 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8908 "createActivityContainer()");
8909 synchronized (this) {
8910 if (parentActivityToken == null) {
8911 throw new IllegalArgumentException("parent token must not be null");
8913 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8917 if (callback == null) {
8918 throw new IllegalArgumentException("callback must not be null");
8920 return mStackSupervisor.createVirtualActivityContainer(r, callback);
8925 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8926 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8927 "deleteActivityContainer()");
8928 synchronized (this) {
8929 mStackSupervisor.deleteActivityContainer(container);
8934 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8935 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8936 "createStackOnDisplay()");
8937 synchronized (this) {
8938 final int stackId = mStackSupervisor.getNextStackId();
8939 final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8940 if (stack == null) {
8943 return stack.mActivityContainer;
8948 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8949 synchronized (this) {
8950 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8951 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8952 return stack.mActivityContainer.getDisplayId();
8954 return Display.DEFAULT_DISPLAY;
8959 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8960 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8961 "moveTaskToStack()");
8962 if (stackId == HOME_STACK_ID) {
8963 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8964 new RuntimeException("here").fillInStackTrace());
8966 synchronized (this) {
8967 long ident = Binder.clearCallingIdentity();
8969 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8970 + " to stackId=" + stackId + " toTop=" + toTop);
8971 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8973 Binder.restoreCallingIdentity(ident);
8979 public void resizeStack(int stackId, Rect bounds) {
8980 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8982 long ident = Binder.clearCallingIdentity();
8984 synchronized (this) {
8985 mStackSupervisor.resizeStackLocked(stackId, bounds);
8988 Binder.restoreCallingIdentity(ident);
8993 public List<StackInfo> getAllStackInfos() {
8994 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8995 "getAllStackInfos()");
8996 long ident = Binder.clearCallingIdentity();
8998 synchronized (this) {
8999 return mStackSupervisor.getAllStackInfosLocked();
9002 Binder.restoreCallingIdentity(ident);
9007 public StackInfo getStackInfo(int stackId) {
9008 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9010 long ident = Binder.clearCallingIdentity();
9012 synchronized (this) {
9013 return mStackSupervisor.getStackInfoLocked(stackId);
9016 Binder.restoreCallingIdentity(ident);
9021 public boolean isInHomeStack(int taskId) {
9022 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9024 long ident = Binder.clearCallingIdentity();
9026 synchronized (this) {
9027 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
9028 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9031 Binder.restoreCallingIdentity(ident);
9036 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9037 synchronized(this) {
9038 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9043 public void updateDeviceOwner(String packageName) {
9044 final int callingUid = Binder.getCallingUid();
9045 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9046 throw new SecurityException("updateDeviceOwner called from non-system process");
9048 synchronized (this) {
9049 mDeviceOwnerName = packageName;
9054 public void updateLockTaskPackages(int userId, String[] packages) {
9055 final int callingUid = Binder.getCallingUid();
9056 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9057 throw new SecurityException("updateLockTaskPackage called from non-system process");
9059 synchronized (this) {
9060 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9061 Arrays.toString(packages));
9062 mLockTaskPackages.put(userId, packages);
9063 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9068 void startLockTaskModeLocked(TaskRecord task) {
9069 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9070 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9074 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9075 // is initiated by system after the pinning request was shown and locked mode is initiated
9076 // by an authorized app directly
9077 final int callingUid = Binder.getCallingUid();
9078 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9079 long ident = Binder.clearCallingIdentity();
9081 final ActivityStack stack = mStackSupervisor.getFocusedStack();
9082 if (!isSystemInitiated) {
9083 task.mLockTaskUid = callingUid;
9084 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9085 // startLockTask() called by app and task mode is lockTaskModeDefault.
9086 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9087 StatusBarManagerInternal statusBarManager =
9088 LocalServices.getService(StatusBarManagerInternal.class);
9089 if (statusBarManager != null) {
9090 statusBarManager.showScreenPinningRequest();
9095 if (stack == null || task != stack.topTask()) {
9096 throw new IllegalArgumentException("Invalid task, not in foreground");
9099 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9101 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9102 ActivityManager.LOCK_TASK_MODE_PINNED :
9103 ActivityManager.LOCK_TASK_MODE_LOCKED,
9104 "startLockTask", true);
9106 Binder.restoreCallingIdentity(ident);
9111 public void startLockTaskMode(int taskId) {
9112 synchronized (this) {
9113 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9115 startLockTaskModeLocked(task);
9121 public void startLockTaskMode(IBinder token) {
9122 synchronized (this) {
9123 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9127 final TaskRecord task = r.task;
9129 startLockTaskModeLocked(task);
9135 public void startLockTaskModeOnCurrent() throws RemoteException {
9136 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9137 "startLockTaskModeOnCurrent");
9138 long ident = Binder.clearCallingIdentity();
9140 synchronized (this) {
9141 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9143 startLockTaskModeLocked(r.task);
9147 Binder.restoreCallingIdentity(ident);
9152 public void stopLockTaskMode() {
9153 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9154 if (lockTask == null) {
9155 // Our work here is done.
9159 final int callingUid = Binder.getCallingUid();
9160 final int lockTaskUid = lockTask.mLockTaskUid;
9161 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9162 // It is possible lockTaskMode was started by the system process because
9163 // android:lockTaskMode is set to a locking value in the application manifest instead of
9164 // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9165 // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9166 if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9167 callingUid != lockTaskUid
9168 && (lockTaskUid != 0
9169 || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9170 throw new SecurityException("Invalid uid, expected " + lockTaskUid
9171 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9174 long ident = Binder.clearCallingIdentity();
9176 Log.d(TAG, "stopLockTaskMode");
9178 synchronized (this) {
9179 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9180 "stopLockTask", true);
9183 Binder.restoreCallingIdentity(ident);
9188 public void stopLockTaskModeOnCurrent() throws RemoteException {
9189 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9190 "stopLockTaskModeOnCurrent");
9191 long ident = Binder.clearCallingIdentity();
9195 Binder.restoreCallingIdentity(ident);
9200 public boolean isInLockTaskMode() {
9201 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9205 public int getLockTaskModeState() {
9206 synchronized (this) {
9207 return mStackSupervisor.getLockTaskModeState();
9212 public void showLockTaskEscapeMessage(IBinder token) {
9213 synchronized (this) {
9214 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9218 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9222 // =========================================================
9223 // CONTENT PROVIDERS
9224 // =========================================================
9226 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9227 List<ProviderInfo> providers = null;
9229 ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9230 queryContentProviders(app.processName, app.uid,
9231 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9232 providers = slice != null ? slice.getList() : null;
9233 } catch (RemoteException ex) {
9235 if (DEBUG_MU) Slog.v(TAG_MU,
9236 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9237 int userId = app.userId;
9238 if (providers != null) {
9239 int N = providers.size();
9240 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9241 for (int i=0; i<N; i++) {
9243 (ProviderInfo)providers.get(i);
9244 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9245 cpi.name, cpi.flags);
9246 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9247 // This is a singleton provider, but a user besides the
9248 // default user is asking to initialize a process it runs
9249 // in... well, no, it doesn't actually run in this process,
9250 // it runs in the process of the default user. Get rid of it.
9251 providers.remove(i);
9257 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9258 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9260 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9261 mProviderMap.putProviderByClass(comp, cpr);
9263 if (DEBUG_MU) Slog.v(TAG_MU,
9264 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9265 app.pubProviders.put(cpi.name, cpr);
9266 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9267 // Don't add this if it is a platform component that is marked
9268 // to run in multiple processes, because this is actually
9269 // part of the framework so doesn't make sense to track as a
9270 // separate apk in the process.
9271 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9274 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9281 * Check if {@link ProcessRecord} has a possible chance at accessing the
9282 * given {@link ProviderInfo}. Final permission checking is always done
9283 * in {@link ContentProvider}.
9285 private final String checkContentProviderPermissionLocked(
9286 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9287 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9288 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9289 boolean checkedGrants = false;
9291 // Looking for cross-user grants before enforcing the typical cross-users permissions
9292 int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9293 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9294 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9297 checkedGrants = true;
9299 userId = handleIncomingUser(callingPid, callingUid, userId,
9300 false, ALLOW_NON_FULL,
9301 "checkContentProviderPermissionLocked " + cpi.authority, null);
9302 if (userId != tmpTargetUserId) {
9303 // When we actually went to determine the final targer user ID, this ended
9304 // up different than our initial check for the authority. This is because
9305 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9306 // SELF. So we need to re-check the grants again.
9307 checkedGrants = false;
9310 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9311 cpi.applicationInfo.uid, cpi.exported)
9312 == PackageManager.PERMISSION_GRANTED) {
9315 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9316 cpi.applicationInfo.uid, cpi.exported)
9317 == PackageManager.PERMISSION_GRANTED) {
9321 PathPermission[] pps = cpi.pathPermissions;
9326 PathPermission pp = pps[i];
9327 String pprperm = pp.getReadPermission();
9328 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9329 cpi.applicationInfo.uid, cpi.exported)
9330 == PackageManager.PERMISSION_GRANTED) {
9333 String ppwperm = pp.getWritePermission();
9334 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9335 cpi.applicationInfo.uid, cpi.exported)
9336 == PackageManager.PERMISSION_GRANTED) {
9341 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9346 if (!cpi.exported) {
9347 msg = "Permission Denial: opening provider " + cpi.name
9348 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9349 + ", uid=" + callingUid + ") that is not exported from uid "
9350 + cpi.applicationInfo.uid;
9352 msg = "Permission Denial: opening provider " + cpi.name
9353 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9354 + ", uid=" + callingUid + ") requires "
9355 + cpi.readPermission + " or " + cpi.writePermission;
9362 * Returns if the ContentProvider has granted a uri to callingUid
9364 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9365 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9366 if (perms != null) {
9367 for (int i=perms.size()-1; i>=0; i--) {
9368 GrantUri grantUri = perms.keyAt(i);
9369 if (grantUri.sourceUserId == userId || !checkUser) {
9370 if (matchesProvider(grantUri.uri, cpi)) {
9380 * Returns true if the uri authority is one of the authorities specified in the provider.
9382 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9383 String uriAuth = uri.getAuthority();
9384 String cpiAuth = cpi.authority;
9385 if (cpiAuth.indexOf(';') == -1) {
9386 return cpiAuth.equals(uriAuth);
9388 String[] cpiAuths = cpiAuth.split(";");
9389 int length = cpiAuths.length;
9390 for (int i = 0; i < length; i++) {
9391 if (cpiAuths[i].equals(uriAuth)) return true;
9396 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9397 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9399 for (int i=0; i<r.conProviders.size(); i++) {
9400 ContentProviderConnection conn = r.conProviders.get(i);
9401 if (conn.provider == cpr) {
9402 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9403 "Adding provider requested by "
9404 + r.processName + " from process "
9405 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9406 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9409 conn.numStableIncs++;
9411 conn.unstableCount++;
9412 conn.numUnstableIncs++;
9417 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9419 conn.stableCount = 1;
9420 conn.numStableIncs = 1;
9422 conn.unstableCount = 1;
9423 conn.numUnstableIncs = 1;
9425 cpr.connections.add(conn);
9426 r.conProviders.add(conn);
9427 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9430 cpr.addExternalProcessHandleLocked(externalProcessToken);
9434 boolean decProviderCountLocked(ContentProviderConnection conn,
9435 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9437 cpr = conn.provider;
9438 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9439 "Removing provider requested by "
9440 + conn.client.processName + " from process "
9441 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9442 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9446 conn.unstableCount--;
9448 if (conn.stableCount == 0 && conn.unstableCount == 0) {
9449 cpr.connections.remove(conn);
9450 conn.client.conProviders.remove(conn);
9451 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9456 cpr.removeExternalProcessHandleLocked(externalProcessToken);
9460 private void checkTime(long startTime, String where) {
9461 long now = SystemClock.elapsedRealtime();
9462 if ((now-startTime) > 1000) {
9463 // If we are taking more than a second, log about it.
9464 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9468 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9469 String name, IBinder token, boolean stable, int userId) {
9470 ContentProviderRecord cpr;
9471 ContentProviderConnection conn = null;
9472 ProviderInfo cpi = null;
9474 synchronized(this) {
9475 long startTime = SystemClock.elapsedRealtime();
9477 ProcessRecord r = null;
9478 if (caller != null) {
9479 r = getRecordForAppLocked(caller);
9481 throw new SecurityException(
9482 "Unable to find app for caller " + caller
9483 + " (pid=" + Binder.getCallingPid()
9484 + ") when getting content provider " + name);
9488 boolean checkCrossUser = true;
9490 checkTime(startTime, "getContentProviderImpl: getProviderByName");
9492 // First check if this content provider has been published...
9493 cpr = mProviderMap.getProviderByName(name, userId);
9494 // If that didn't work, check if it exists for user 0 and then
9495 // verify that it's a singleton provider before using it.
9496 if (cpr == null && userId != UserHandle.USER_OWNER) {
9497 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9500 if (isSingleton(cpi.processName, cpi.applicationInfo,
9501 cpi.name, cpi.flags)
9502 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9503 userId = UserHandle.USER_OWNER;
9504 checkCrossUser = false;
9512 boolean providerRunning = cpr != null;
9513 if (providerRunning) {
9516 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9517 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9519 throw new SecurityException(msg);
9521 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9523 if (r != null && cpr.canRunHere(r)) {
9524 // This provider has been published or is in the process
9525 // of being published... but it is also allowed to run
9526 // in the caller's process, so don't make a connection
9527 // and just let the caller instantiate its own instance.
9528 ContentProviderHolder holder = cpr.newHolder(null);
9529 // don't give caller the provider object, it needs
9531 holder.provider = null;
9535 final long origId = Binder.clearCallingIdentity();
9537 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9539 // In this case the provider instance already exists, so we can
9540 // return it right away.
9541 conn = incProviderCountLocked(r, cpr, token, stable);
9542 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9543 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9544 // If this is a perceptible app accessing the provider,
9545 // make sure to count it as being accessed and thus
9546 // back up on the LRU list. This is good because
9547 // content providers are often expensive to start.
9548 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9549 updateLruProcessLocked(cpr.proc, false, null);
9550 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9554 if (cpr.proc != null) {
9556 if (cpr.name.flattenToShortString().equals(
9557 "com.android.providers.calendar/.CalendarProvider2")) {
9558 Slog.v(TAG, "****************** KILLING "
9559 + cpr.name.flattenToShortString());
9560 Process.killProcess(cpr.proc.pid);
9563 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9564 boolean success = updateOomAdjLocked(cpr.proc);
9565 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9566 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9567 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9568 // NOTE: there is still a race here where a signal could be
9569 // pending on the process even though we managed to update its
9570 // adj level. Not sure what to do about this, but at least
9571 // the race is now smaller.
9573 // Uh oh... it looks like the provider's process
9574 // has been killed on us. We need to wait for a new
9575 // process to be started, and make sure its death
9576 // doesn't kill our process.
9577 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9578 + " is crashing; detaching " + r);
9579 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9580 checkTime(startTime, "getContentProviderImpl: before appDied");
9581 appDiedLocked(cpr.proc);
9582 checkTime(startTime, "getContentProviderImpl: after appDied");
9584 // This wasn't the last ref our process had on
9585 // the provider... we have now been killed, bail.
9588 providerRunning = false;
9593 Binder.restoreCallingIdentity(origId);
9597 if (!providerRunning) {
9599 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9600 cpi = AppGlobals.getPackageManager().
9601 resolveContentProvider(name,
9602 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9603 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9604 } catch (RemoteException ex) {
9609 // If the provider is a singleton AND
9610 // (it's a call within the same user || the provider is a
9612 // Then allow connecting to the singleton provider
9613 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9614 cpi.name, cpi.flags)
9615 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9617 userId = UserHandle.USER_OWNER;
9619 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9620 checkTime(startTime, "getContentProviderImpl: got app info for user");
9623 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9624 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9626 throw new SecurityException(msg);
9628 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9630 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9631 && !cpi.processName.equals("system")) {
9632 // If this content provider does not run in the system
9633 // process, and the system is not yet ready to run other
9634 // processes, then fail fast instead of hanging.
9635 throw new IllegalArgumentException(
9636 "Attempt to launch content provider before system ready");
9639 // Make sure that the user who owns this provider is running. If not,
9640 // we don't want to allow it to run.
9641 if (!isUserRunningLocked(userId, false)) {
9642 Slog.w(TAG, "Unable to launch app "
9643 + cpi.applicationInfo.packageName + "/"
9644 + cpi.applicationInfo.uid + " for provider "
9645 + name + ": user " + userId + " is stopped");
9649 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9650 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9651 cpr = mProviderMap.getProviderByClass(comp, userId);
9652 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9653 final boolean firstClass = cpr == null;
9655 final long ident = Binder.clearCallingIdentity();
9657 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9658 ApplicationInfo ai =
9659 AppGlobals.getPackageManager().
9661 cpi.applicationInfo.packageName,
9662 STOCK_PM_FLAGS, userId);
9663 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9665 Slog.w(TAG, "No package info for content provider "
9669 ai = getAppInfoForUser(ai, userId);
9670 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9671 } catch (RemoteException ex) {
9672 // pm is in same process, this will never happen.
9674 Binder.restoreCallingIdentity(ident);
9678 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9680 if (r != null && cpr.canRunHere(r)) {
9681 // If this is a multiprocess provider, then just return its
9682 // info and allow the caller to instantiate it. Only do
9683 // this if the provider is the same user as the caller's
9684 // process, or can run as root (so can be in any process).
9685 return cpr.newHolder(null);
9688 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9689 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9690 + cpr.info.name + " callers=" + Debug.getCallers(6));
9692 // This is single process, and our app is now connecting to it.
9693 // See if we are already in the process of launching this
9695 final int N = mLaunchingProviders.size();
9697 for (i = 0; i < N; i++) {
9698 if (mLaunchingProviders.get(i) == cpr) {
9703 // If the provider is not already being launched, then get it
9706 final long origId = Binder.clearCallingIdentity();
9709 // Content provider is now in use, its package can't be stopped.
9711 checkTime(startTime, "getContentProviderImpl: before set stopped state");
9712 AppGlobals.getPackageManager().setPackageStoppedState(
9713 cpr.appInfo.packageName, false, userId);
9714 checkTime(startTime, "getContentProviderImpl: after set stopped state");
9715 } catch (RemoteException e) {
9716 } catch (IllegalArgumentException e) {
9717 Slog.w(TAG, "Failed trying to unstop package "
9718 + cpr.appInfo.packageName + ": " + e);
9721 // Use existing process if already started
9722 checkTime(startTime, "getContentProviderImpl: looking for process record");
9723 ProcessRecord proc = getProcessRecordLocked(
9724 cpi.processName, cpr.appInfo.uid, false);
9725 if (proc != null && proc.thread != null) {
9726 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9727 "Installing in existing process " + proc);
9728 if (!proc.pubProviders.containsKey(cpi.name)) {
9729 checkTime(startTime, "getContentProviderImpl: scheduling install");
9730 proc.pubProviders.put(cpi.name, cpr);
9732 proc.thread.scheduleInstallProvider(cpi);
9733 } catch (RemoteException e) {
9737 checkTime(startTime, "getContentProviderImpl: before start process");
9738 proc = startProcessLocked(cpi.processName,
9739 cpr.appInfo, false, 0, "content provider",
9740 new ComponentName(cpi.applicationInfo.packageName,
9741 cpi.name), false, false, false);
9742 checkTime(startTime, "getContentProviderImpl: after start process");
9744 Slog.w(TAG, "Unable to launch app "
9745 + cpi.applicationInfo.packageName + "/"
9746 + cpi.applicationInfo.uid + " for provider "
9747 + name + ": process is bad");
9751 cpr.launchingApp = proc;
9752 mLaunchingProviders.add(cpr);
9754 Binder.restoreCallingIdentity(origId);
9758 checkTime(startTime, "getContentProviderImpl: updating data structures");
9760 // Make sure the provider is published (the same provider class
9761 // may be published under multiple names).
9763 mProviderMap.putProviderByClass(comp, cpr);
9766 mProviderMap.putProviderByName(name, cpr);
9767 conn = incProviderCountLocked(r, cpr, token, stable);
9769 conn.waiting = true;
9772 checkTime(startTime, "getContentProviderImpl: done!");
9775 // Wait for the provider to be published...
9776 synchronized (cpr) {
9777 while (cpr.provider == null) {
9778 if (cpr.launchingApp == null) {
9779 Slog.w(TAG, "Unable to launch app "
9780 + cpi.applicationInfo.packageName + "/"
9781 + cpi.applicationInfo.uid + " for provider "
9782 + name + ": launching app became null");
9783 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9784 UserHandle.getUserId(cpi.applicationInfo.uid),
9785 cpi.applicationInfo.packageName,
9786 cpi.applicationInfo.uid, name);
9790 if (DEBUG_MU) Slog.v(TAG_MU,
9791 "Waiting to start provider " + cpr
9792 + " launchingApp=" + cpr.launchingApp);
9794 conn.waiting = true;
9797 } catch (InterruptedException ex) {
9800 conn.waiting = false;
9805 return cpr != null ? cpr.newHolder(conn) : null;
9809 public final ContentProviderHolder getContentProvider(
9810 IApplicationThread caller, String name, int userId, boolean stable) {
9811 enforceNotIsolatedCaller("getContentProvider");
9812 if (caller == null) {
9813 String msg = "null IApplicationThread when getting content provider "
9816 throw new SecurityException(msg);
9818 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9819 // with cross-user grant.
9820 return getContentProviderImpl(caller, name, null, stable, userId);
9823 public ContentProviderHolder getContentProviderExternal(
9824 String name, int userId, IBinder token) {
9825 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9826 "Do not have permission in call getContentProviderExternal()");
9827 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9828 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9829 return getContentProviderExternalUnchecked(name, token, userId);
9832 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9833 IBinder token, int userId) {
9834 return getContentProviderImpl(null, name, token, true, userId);
9838 * Drop a content provider from a ProcessRecord's bookkeeping
9840 public void removeContentProvider(IBinder connection, boolean stable) {
9841 enforceNotIsolatedCaller("removeContentProvider");
9842 long ident = Binder.clearCallingIdentity();
9844 synchronized (this) {
9845 ContentProviderConnection conn;
9847 conn = (ContentProviderConnection)connection;
9848 } catch (ClassCastException e) {
9849 String msg ="removeContentProvider: " + connection
9850 + " not a ContentProviderConnection";
9852 throw new IllegalArgumentException(msg);
9855 throw new NullPointerException("connection is null");
9857 if (decProviderCountLocked(conn, null, null, stable)) {
9858 updateOomAdjLocked();
9862 Binder.restoreCallingIdentity(ident);
9866 public void removeContentProviderExternal(String name, IBinder token) {
9867 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9868 "Do not have permission in call removeContentProviderExternal()");
9869 int userId = UserHandle.getCallingUserId();
9870 long ident = Binder.clearCallingIdentity();
9872 removeContentProviderExternalUnchecked(name, token, userId);
9874 Binder.restoreCallingIdentity(ident);
9878 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9879 synchronized (this) {
9880 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9882 //remove from mProvidersByClass
9883 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9887 //update content provider record entry info
9888 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9889 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9890 if (localCpr.hasExternalProcessHandles()) {
9891 if (localCpr.removeExternalProcessHandleLocked(token)) {
9892 updateOomAdjLocked();
9894 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9895 + " with no external reference for token: "
9899 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9900 + " with no external references.");
9905 public final void publishContentProviders(IApplicationThread caller,
9906 List<ContentProviderHolder> providers) {
9907 if (providers == null) {
9911 enforceNotIsolatedCaller("publishContentProviders");
9912 synchronized (this) {
9913 final ProcessRecord r = getRecordForAppLocked(caller);
9914 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9916 throw new SecurityException(
9917 "Unable to find app for caller " + caller
9918 + " (pid=" + Binder.getCallingPid()
9919 + ") when publishing content providers");
9922 final long origId = Binder.clearCallingIdentity();
9924 final int N = providers.size();
9925 for (int i = 0; i < N; i++) {
9926 ContentProviderHolder src = providers.get(i);
9927 if (src == null || src.info == null || src.provider == null) {
9930 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9931 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9933 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9934 mProviderMap.putProviderByClass(comp, dst);
9935 String names[] = dst.info.authority.split(";");
9936 for (int j = 0; j < names.length; j++) {
9937 mProviderMap.putProviderByName(names[j], dst);
9940 int launchingCount = mLaunchingProviders.size();
9942 boolean wasInLaunchingProviders = false;
9943 for (j = 0; j < launchingCount; j++) {
9944 if (mLaunchingProviders.get(j) == dst) {
9945 mLaunchingProviders.remove(j);
9946 wasInLaunchingProviders = true;
9951 if (wasInLaunchingProviders) {
9952 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
9954 synchronized (dst) {
9955 dst.provider = src.provider;
9959 updateOomAdjLocked(r);
9960 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9961 src.info.authority);
9965 Binder.restoreCallingIdentity(origId);
9969 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9970 ContentProviderConnection conn;
9972 conn = (ContentProviderConnection)connection;
9973 } catch (ClassCastException e) {
9974 String msg ="refContentProvider: " + connection
9975 + " not a ContentProviderConnection";
9977 throw new IllegalArgumentException(msg);
9980 throw new NullPointerException("connection is null");
9983 synchronized (this) {
9985 conn.numStableIncs += stable;
9987 stable = conn.stableCount + stable;
9989 throw new IllegalStateException("stableCount < 0: " + stable);
9993 conn.numUnstableIncs += unstable;
9995 unstable = conn.unstableCount + unstable;
9997 throw new IllegalStateException("unstableCount < 0: " + unstable);
10000 if ((stable+unstable) <= 0) {
10001 throw new IllegalStateException("ref counts can't go to zero here: stable="
10002 + stable + " unstable=" + unstable);
10004 conn.stableCount = stable;
10005 conn.unstableCount = unstable;
10010 public void unstableProviderDied(IBinder connection) {
10011 ContentProviderConnection conn;
10013 conn = (ContentProviderConnection)connection;
10014 } catch (ClassCastException e) {
10015 String msg ="refContentProvider: " + connection
10016 + " not a ContentProviderConnection";
10018 throw new IllegalArgumentException(msg);
10020 if (conn == null) {
10021 throw new NullPointerException("connection is null");
10024 // Safely retrieve the content provider associated with the connection.
10025 IContentProvider provider;
10026 synchronized (this) {
10027 provider = conn.provider.provider;
10030 if (provider == null) {
10031 // Um, yeah, we're way ahead of you.
10035 // Make sure the caller is being honest with us.
10036 if (provider.asBinder().pingBinder()) {
10037 // Er, no, still looks good to us.
10038 synchronized (this) {
10039 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10040 + " says " + conn + " died, but we don't agree");
10045 // Well look at that! It's dead!
10046 synchronized (this) {
10047 if (conn.provider.provider != provider) {
10048 // But something changed... good enough.
10052 ProcessRecord proc = conn.provider.proc;
10053 if (proc == null || proc.thread == null) {
10054 // Seems like the process is already cleaned up.
10058 // As far as we're concerned, this is just like receiving a
10059 // death notification... just a bit prematurely.
10060 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10061 + ") early provider death");
10062 final long ident = Binder.clearCallingIdentity();
10064 appDiedLocked(proc);
10066 Binder.restoreCallingIdentity(ident);
10072 public void appNotRespondingViaProvider(IBinder connection) {
10073 enforceCallingPermission(
10074 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10076 final ContentProviderConnection conn = (ContentProviderConnection) connection;
10077 if (conn == null) {
10078 Slog.w(TAG, "ContentProviderConnection is null");
10082 final ProcessRecord host = conn.provider.proc;
10083 if (host == null) {
10084 Slog.w(TAG, "Failed to find hosting ProcessRecord");
10088 final long token = Binder.clearCallingIdentity();
10090 appNotResponding(host, null, null, false, "ContentProvider not responding");
10092 Binder.restoreCallingIdentity(token);
10096 public final void installSystemProviders() {
10097 List<ProviderInfo> providers;
10098 synchronized (this) {
10099 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10100 providers = generateApplicationProvidersLocked(app);
10101 if (providers != null) {
10102 for (int i=providers.size()-1; i>=0; i--) {
10103 ProviderInfo pi = (ProviderInfo)providers.get(i);
10104 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10105 Slog.w(TAG, "Not installing system proc provider " + pi.name
10106 + ": not system .apk");
10107 providers.remove(i);
10112 if (providers != null) {
10113 mSystemThread.installSystemProviders(providers);
10116 mCoreSettingsObserver = new CoreSettingsObserver(this);
10118 //mUsageStatsService.monitorPackages();
10122 * Allows apps to retrieve the MIME type of a URI.
10123 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10124 * users, then it does not need permission to access the ContentProvider.
10125 * Either, it needs cross-user uri grants.
10127 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10129 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10130 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10132 public String getProviderMimeType(Uri uri, int userId) {
10133 enforceNotIsolatedCaller("getProviderMimeType");
10134 final String name = uri.getAuthority();
10135 int callingUid = Binder.getCallingUid();
10136 int callingPid = Binder.getCallingPid();
10138 boolean clearedIdentity = false;
10139 userId = unsafeConvertIncomingUser(userId);
10140 if (canClearIdentity(callingPid, callingUid, userId)) {
10141 clearedIdentity = true;
10142 ident = Binder.clearCallingIdentity();
10144 ContentProviderHolder holder = null;
10146 holder = getContentProviderExternalUnchecked(name, null, userId);
10147 if (holder != null) {
10148 return holder.provider.getType(uri);
10150 } catch (RemoteException e) {
10151 Log.w(TAG, "Content provider dead retrieving " + uri, e);
10154 // We need to clear the identity to call removeContentProviderExternalUnchecked
10155 if (!clearedIdentity) {
10156 ident = Binder.clearCallingIdentity();
10159 if (holder != null) {
10160 removeContentProviderExternalUnchecked(name, null, userId);
10163 Binder.restoreCallingIdentity(ident);
10170 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10171 if (UserHandle.getUserId(callingUid) == userId) {
10174 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10175 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10176 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10177 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10183 // =========================================================
10184 // GLOBAL MANAGEMENT
10185 // =========================================================
10187 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10188 boolean isolated, int isolatedUid) {
10189 String proc = customProcess != null ? customProcess : info.processName;
10190 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10191 final int userId = UserHandle.getUserId(info.uid);
10192 int uid = info.uid;
10194 if (isolatedUid == 0) {
10195 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10197 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10198 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10199 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10201 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10202 mNextIsolatedProcessUid++;
10203 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10204 // No process for this uid, use it.
10208 if (stepsLeft <= 0) {
10213 // Special case for startIsolatedProcess (internal only), where
10214 // the uid of the isolated process is specified by the caller.
10218 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10219 if (!mBooted && !mBooting
10220 && userId == UserHandle.USER_OWNER
10221 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10222 r.persistent = true;
10224 addProcessNameLocked(r);
10228 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10229 String abiOverride) {
10232 app = getProcessRecordLocked(info.processName, info.uid, true);
10238 app = newProcessRecordLocked(info, null, isolated, 0);
10239 updateLruProcessLocked(app, false, null);
10240 updateOomAdjLocked();
10243 // This package really, really can not be stopped.
10245 AppGlobals.getPackageManager().setPackageStoppedState(
10246 info.packageName, false, UserHandle.getUserId(app.uid));
10247 } catch (RemoteException e) {
10248 } catch (IllegalArgumentException e) {
10249 Slog.w(TAG, "Failed trying to unstop package "
10250 + info.packageName + ": " + e);
10253 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10254 app.persistent = true;
10255 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10257 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10258 mPersistentStartingProcesses.add(app);
10259 startProcessLocked(app, "added application", app.processName, abiOverride,
10260 null /* entryPoint */, null /* entryPointArgs */);
10266 public void unhandledBack() {
10267 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10268 "unhandledBack()");
10270 synchronized(this) {
10271 final long origId = Binder.clearCallingIdentity();
10273 getFocusedStack().unhandledBackLocked();
10275 Binder.restoreCallingIdentity(origId);
10280 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10281 enforceNotIsolatedCaller("openContentUri");
10282 final int userId = UserHandle.getCallingUserId();
10283 String name = uri.getAuthority();
10284 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10285 ParcelFileDescriptor pfd = null;
10287 // We record the binder invoker's uid in thread-local storage before
10288 // going to the content provider to open the file. Later, in the code
10289 // that handles all permissions checks, we look for this uid and use
10290 // that rather than the Activity Manager's own uid. The effect is that
10291 // we do the check against the caller's permissions even though it looks
10292 // to the content provider like the Activity Manager itself is making
10294 Binder token = new Binder();
10295 sCallerIdentity.set(new Identity(
10296 token, Binder.getCallingPid(), Binder.getCallingUid()));
10298 pfd = cph.provider.openFile(null, uri, "r", null, token);
10299 } catch (FileNotFoundException e) {
10300 // do nothing; pfd will be returned null
10302 // Ensure that whatever happens, we clean up the identity state
10303 sCallerIdentity.remove();
10304 // Ensure we're done with the provider.
10305 removeContentProviderExternalUnchecked(name, null, userId);
10308 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10313 // Actually is sleeping or shutting down or whatever else in the future
10314 // is an inactive state.
10315 public boolean isSleepingOrShuttingDown() {
10316 return isSleeping() || mShuttingDown;
10319 public boolean isSleeping() {
10323 void onWakefulnessChanged(int wakefulness) {
10324 synchronized(this) {
10325 mWakefulness = wakefulness;
10326 updateSleepIfNeededLocked();
10330 void finishRunningVoiceLocked() {
10331 if (mRunningVoice != null) {
10332 mRunningVoice = null;
10333 mVoiceWakeLock.release();
10334 updateSleepIfNeededLocked();
10338 void startTimeTrackingFocusedActivityLocked() {
10339 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10340 mCurAppTimeTracker.start(mFocusedActivity.packageName);
10344 void updateSleepIfNeededLocked() {
10345 if (mSleeping && !shouldSleepLocked()) {
10347 startTimeTrackingFocusedActivityLocked();
10348 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10349 mStackSupervisor.comeOutOfSleepIfNeededLocked();
10350 updateOomAdjLocked();
10351 } else if (!mSleeping && shouldSleepLocked()) {
10353 if (mCurAppTimeTracker != null) {
10354 mCurAppTimeTracker.stop();
10356 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10357 mStackSupervisor.goingToSleepLocked();
10358 updateOomAdjLocked();
10360 // Initialize the wake times of all processes.
10361 checkExcessivePowerUsageLocked(false);
10362 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10363 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10364 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10368 private boolean shouldSleepLocked() {
10369 // Resume applications while running a voice interactor.
10370 if (mRunningVoice != null) {
10374 // TODO: Transform the lock screen state into a sleep token instead.
10375 switch (mWakefulness) {
10376 case PowerManagerInternal.WAKEFULNESS_AWAKE:
10377 case PowerManagerInternal.WAKEFULNESS_DREAMING:
10378 case PowerManagerInternal.WAKEFULNESS_DOZING:
10379 // Pause applications whenever the lock screen is shown or any sleep
10380 // tokens have been acquired.
10381 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10382 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10384 // If we're asleep then pause applications unconditionally.
10389 /** Pokes the task persister. */
10390 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10391 if (task != null && task.stack != null && task.stack.isHomeStack()) {
10392 // Never persist the home stack.
10395 mTaskPersister.wakeup(task, flush);
10398 /** Notifies all listeners when the task stack has changed. */
10399 void notifyTaskStackChangedLocked() {
10400 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10401 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10402 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10406 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10407 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10411 public boolean shutdown(int timeout) {
10412 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10413 != PackageManager.PERMISSION_GRANTED) {
10414 throw new SecurityException("Requires permission "
10415 + android.Manifest.permission.SHUTDOWN);
10418 boolean timedout = false;
10420 synchronized(this) {
10421 mShuttingDown = true;
10422 updateEventDispatchingLocked();
10423 timedout = mStackSupervisor.shutdownLocked(timeout);
10426 mAppOpsService.shutdown();
10427 if (mUsageStatsService != null) {
10428 mUsageStatsService.prepareShutdown();
10430 mBatteryStatsService.shutdown();
10431 synchronized (this) {
10432 mProcessStats.shutdownLocked();
10433 notifyTaskPersisterLocked(null, true);
10439 public final void activitySlept(IBinder token) {
10440 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10442 final long origId = Binder.clearCallingIdentity();
10444 synchronized (this) {
10445 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10447 mStackSupervisor.activitySleptLocked(r);
10451 Binder.restoreCallingIdentity(origId);
10454 private String lockScreenShownToString() {
10455 switch (mLockScreenShown) {
10456 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10457 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10458 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10459 default: return "Unknown=" + mLockScreenShown;
10463 void logLockScreen(String msg) {
10464 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10465 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10466 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10467 + " mSleeping=" + mSleeping);
10470 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10471 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10472 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10473 boolean wasRunningVoice = mRunningVoice != null;
10474 mRunningVoice = session;
10475 if (!wasRunningVoice) {
10476 mVoiceWakeLock.acquire();
10477 updateSleepIfNeededLocked();
10482 private void updateEventDispatchingLocked() {
10483 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10486 public void setLockScreenShown(boolean shown) {
10487 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10488 != PackageManager.PERMISSION_GRANTED) {
10489 throw new SecurityException("Requires permission "
10490 + android.Manifest.permission.DEVICE_POWER);
10493 synchronized(this) {
10494 long ident = Binder.clearCallingIdentity();
10496 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10497 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10498 updateSleepIfNeededLocked();
10500 Binder.restoreCallingIdentity(ident);
10506 public void stopAppSwitches() {
10507 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10508 != PackageManager.PERMISSION_GRANTED) {
10509 throw new SecurityException("Requires permission "
10510 + android.Manifest.permission.STOP_APP_SWITCHES);
10513 synchronized(this) {
10514 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10515 + APP_SWITCH_DELAY_TIME;
10516 mDidAppSwitch = false;
10517 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10518 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10519 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10523 public void resumeAppSwitches() {
10524 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10525 != PackageManager.PERMISSION_GRANTED) {
10526 throw new SecurityException("Requires permission "
10527 + android.Manifest.permission.STOP_APP_SWITCHES);
10530 synchronized(this) {
10531 // Note that we don't execute any pending app switches... we will
10532 // let those wait until either the timeout, or the next start
10533 // activity request.
10534 mAppSwitchesAllowedTime = 0;
10538 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10539 int callingPid, int callingUid, String name) {
10540 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10544 int perm = checkComponentPermission(
10545 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10546 sourceUid, -1, true);
10547 if (perm == PackageManager.PERMISSION_GRANTED) {
10551 // If the actual IPC caller is different from the logical source, then
10552 // also see if they are allowed to control app switches.
10553 if (callingUid != -1 && callingUid != sourceUid) {
10554 perm = checkComponentPermission(
10555 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10556 callingUid, -1, true);
10557 if (perm == PackageManager.PERMISSION_GRANTED) {
10562 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10566 public void setDebugApp(String packageName, boolean waitForDebugger,
10567 boolean persistent) {
10568 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10571 long ident = Binder.clearCallingIdentity();
10573 // Note that this is not really thread safe if there are multiple
10574 // callers into it at the same time, but that's not a situation we
10577 final ContentResolver resolver = mContext.getContentResolver();
10578 Settings.Global.putString(
10579 resolver, Settings.Global.DEBUG_APP,
10581 Settings.Global.putInt(
10582 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10583 waitForDebugger ? 1 : 0);
10586 synchronized (this) {
10588 mOrigDebugApp = mDebugApp;
10589 mOrigWaitForDebugger = mWaitForDebugger;
10591 mDebugApp = packageName;
10592 mWaitForDebugger = waitForDebugger;
10593 mDebugTransient = !persistent;
10594 if (packageName != null) {
10595 forceStopPackageLocked(packageName, -1, false, false, true, true,
10596 false, UserHandle.USER_ALL, "set debug app");
10600 Binder.restoreCallingIdentity(ident);
10604 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10605 synchronized (this) {
10606 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10607 if (!isDebuggable) {
10608 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10609 throw new SecurityException("Process not debuggable: " + app.packageName);
10613 mOpenGlTraceApp = processName;
10617 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10618 synchronized (this) {
10619 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10620 if (!isDebuggable) {
10621 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10622 throw new SecurityException("Process not debuggable: " + app.packageName);
10625 mProfileApp = processName;
10626 mProfileFile = profilerInfo.profileFile;
10627 if (mProfileFd != null) {
10629 mProfileFd.close();
10630 } catch (IOException e) {
10634 mProfileFd = profilerInfo.profileFd;
10635 mSamplingInterval = profilerInfo.samplingInterval;
10636 mAutoStopProfiler = profilerInfo.autoStopProfiler;
10642 public void setAlwaysFinish(boolean enabled) {
10643 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10644 "setAlwaysFinish()");
10646 Settings.Global.putInt(
10647 mContext.getContentResolver(),
10648 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10650 synchronized (this) {
10651 mAlwaysFinishActivities = enabled;
10656 public void setActivityController(IActivityController controller) {
10657 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10658 "setActivityController()");
10659 synchronized (this) {
10660 mController = controller;
10661 Watchdog.getInstance().setActivityController(controller);
10666 public void setUserIsMonkey(boolean userIsMonkey) {
10667 synchronized (this) {
10668 synchronized (mPidsSelfLocked) {
10669 final int callingPid = Binder.getCallingPid();
10670 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10671 if (precessRecord == null) {
10672 throw new SecurityException("Unknown process: " + callingPid);
10674 if (precessRecord.instrumentationUiAutomationConnection == null) {
10675 throw new SecurityException("Only an instrumentation process "
10676 + "with a UiAutomation can call setUserIsMonkey");
10679 mUserIsMonkey = userIsMonkey;
10684 public boolean isUserAMonkey() {
10685 synchronized (this) {
10686 // If there is a controller also implies the user is a monkey.
10687 return (mUserIsMonkey || mController != null);
10691 public void requestBugReport() {
10692 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10693 SystemProperties.set("ctl.start", "bugreport");
10696 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10697 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10700 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10701 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10702 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10704 return KEY_DISPATCHING_TIMEOUT;
10708 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10709 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10710 != PackageManager.PERMISSION_GRANTED) {
10711 throw new SecurityException("Requires permission "
10712 + android.Manifest.permission.FILTER_EVENTS);
10714 ProcessRecord proc;
10716 synchronized (this) {
10717 synchronized (mPidsSelfLocked) {
10718 proc = mPidsSelfLocked.get(pid);
10720 timeout = getInputDispatchingTimeoutLocked(proc);
10723 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10731 * Handle input dispatching timeouts.
10732 * Returns whether input dispatching should be aborted or not.
10734 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10735 final ActivityRecord activity, final ActivityRecord parent,
10736 final boolean aboveSystem, String reason) {
10737 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10738 != PackageManager.PERMISSION_GRANTED) {
10739 throw new SecurityException("Requires permission "
10740 + android.Manifest.permission.FILTER_EVENTS);
10743 final String annotation;
10744 if (reason == null) {
10745 annotation = "Input dispatching timed out";
10747 annotation = "Input dispatching timed out (" + reason + ")";
10750 if (proc != null) {
10751 synchronized (this) {
10752 if (proc.debugging) {
10757 // Give more time since we were dexopting.
10758 mDidDexOpt = false;
10762 if (proc.instrumentationClass != null) {
10763 Bundle info = new Bundle();
10764 info.putString("shortMsg", "keyDispatchingTimedOut");
10765 info.putString("longMsg", annotation);
10766 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10770 mHandler.post(new Runnable() {
10772 public void run() {
10773 appNotResponding(proc, activity, parent, aboveSystem, annotation);
10782 public Bundle getAssistContextExtras(int requestType) {
10783 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10784 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10788 synchronized (pae) {
10789 while (!pae.haveResult) {
10792 } catch (InterruptedException e) {
10796 synchronized (this) {
10797 buildAssistBundleLocked(pae, pae.result);
10798 mPendingAssistExtras.remove(pae);
10799 mUiHandler.removeCallbacks(pae);
10805 public boolean isAssistDataAllowedOnCurrentActivity() {
10806 int userId = mCurrentUserId;
10807 synchronized (this) {
10808 ActivityRecord activity = getFocusedStack().topActivity();
10809 if (activity == null) {
10812 userId = activity.userId;
10814 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10815 Context.DEVICE_POLICY_SERVICE);
10816 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10820 public boolean showAssistFromActivity(IBinder token, Bundle args) {
10821 long ident = Binder.clearCallingIdentity();
10823 synchronized (this) {
10824 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10825 ActivityRecord top = getFocusedStack().topActivity();
10826 if (top != caller) {
10827 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10828 + " is not current top " + top);
10831 if (!top.nowVisible) {
10832 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10833 + " is not visible");
10837 AssistUtils utils = new AssistUtils(mContext);
10838 return utils.showSessionForActiveService(args,
10839 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10841 Binder.restoreCallingIdentity(ident);
10846 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10847 IBinder activityToken) {
10848 return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10849 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10852 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10853 IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10855 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10856 "enqueueAssistContext()");
10857 synchronized (this) {
10858 ActivityRecord activity = getFocusedStack().topActivity();
10859 if (activity == null) {
10860 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10863 if (activity.app == null || activity.app.thread == null) {
10864 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10867 if (activityToken != null) {
10868 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10869 if (activity != caller) {
10870 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10871 + " is not current top " + activity);
10875 PendingAssistExtras pae;
10876 Bundle extras = new Bundle();
10877 if (args != null) {
10878 extras.putAll(args);
10880 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10881 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10882 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10884 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10886 mPendingAssistExtras.add(pae);
10887 mUiHandler.postDelayed(pae, timeout);
10888 } catch (RemoteException e) {
10889 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10896 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10897 IResultReceiver receiver;
10898 synchronized (this) {
10899 mPendingAssistExtras.remove(pae);
10900 receiver = pae.receiver;
10902 if (receiver != null) {
10903 // Caller wants result sent back to them.
10905 pae.receiver.send(0, null);
10906 } catch (RemoteException e) {
10911 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10912 if (result != null) {
10913 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10915 if (pae.hint != null) {
10916 pae.extras.putBoolean(pae.hint, true);
10920 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10921 AssistContent content, Uri referrer) {
10922 PendingAssistExtras pae = (PendingAssistExtras)token;
10923 synchronized (pae) {
10924 pae.result = extras;
10925 pae.structure = structure;
10926 pae.content = content;
10927 if (referrer != null) {
10928 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10930 pae.haveResult = true;
10932 if (pae.intent == null && pae.receiver == null) {
10933 // Caller is just waiting for the result.
10938 // We are now ready to launch the assist activity.
10939 IResultReceiver sendReceiver = null;
10940 Bundle sendBundle = null;
10941 synchronized (this) {
10942 buildAssistBundleLocked(pae, extras);
10943 boolean exists = mPendingAssistExtras.remove(pae);
10944 mUiHandler.removeCallbacks(pae);
10949 if ((sendReceiver=pae.receiver) != null) {
10950 // Caller wants result sent back to them.
10951 sendBundle = new Bundle();
10952 sendBundle.putBundle("data", pae.extras);
10953 sendBundle.putParcelable("structure", pae.structure);
10954 sendBundle.putParcelable("content", pae.content);
10957 if (sendReceiver != null) {
10959 sendReceiver.send(0, sendBundle);
10960 } catch (RemoteException e) {
10965 long ident = Binder.clearCallingIdentity();
10967 pae.intent.replaceExtras(pae.extras);
10968 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10969 | Intent.FLAG_ACTIVITY_SINGLE_TOP
10970 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10971 closeSystemDialogs("assist");
10973 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10974 } catch (ActivityNotFoundException e) {
10975 Slog.w(TAG, "No activity to handle assist action.", e);
10978 Binder.restoreCallingIdentity(ident);
10982 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10984 return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10985 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10988 public void registerProcessObserver(IProcessObserver observer) {
10989 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10990 "registerProcessObserver()");
10991 synchronized (this) {
10992 mProcessObservers.register(observer);
10997 public void unregisterProcessObserver(IProcessObserver observer) {
10998 synchronized (this) {
10999 mProcessObservers.unregister(observer);
11003 public void registerUidObserver(IUidObserver observer) {
11004 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11005 "registerUidObserver()");
11006 synchronized (this) {
11007 mUidObservers.register(observer);
11012 public void unregisterUidObserver(IUidObserver observer) {
11013 synchronized (this) {
11014 mUidObservers.unregister(observer);
11019 public boolean convertFromTranslucent(IBinder token) {
11020 final long origId = Binder.clearCallingIdentity();
11022 synchronized (this) {
11023 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11027 final boolean translucentChanged = r.changeWindowTranslucency(true);
11028 if (translucentChanged) {
11029 r.task.stack.releaseBackgroundResources(r);
11030 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11032 mWindowManager.setAppFullscreen(token, true);
11033 return translucentChanged;
11036 Binder.restoreCallingIdentity(origId);
11041 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11042 final long origId = Binder.clearCallingIdentity();
11044 synchronized (this) {
11045 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11049 int index = r.task.mActivities.lastIndexOf(r);
11051 ActivityRecord under = r.task.mActivities.get(index - 1);
11052 under.returningOptions = options;
11054 final boolean translucentChanged = r.changeWindowTranslucency(false);
11055 if (translucentChanged) {
11056 r.task.stack.convertActivityToTranslucent(r);
11058 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11059 mWindowManager.setAppFullscreen(token, false);
11060 return translucentChanged;
11063 Binder.restoreCallingIdentity(origId);
11068 public boolean requestVisibleBehind(IBinder token, boolean visible) {
11069 final long origId = Binder.clearCallingIdentity();
11071 synchronized (this) {
11072 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11074 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11079 Binder.restoreCallingIdentity(origId);
11084 public boolean isBackgroundVisibleBehind(IBinder token) {
11085 final long origId = Binder.clearCallingIdentity();
11087 synchronized (this) {
11088 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11089 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11090 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11091 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11095 Binder.restoreCallingIdentity(origId);
11100 public ActivityOptions getActivityOptions(IBinder token) {
11101 final long origId = Binder.clearCallingIdentity();
11103 synchronized (this) {
11104 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11106 final ActivityOptions activityOptions = r.pendingOptions;
11107 r.pendingOptions = null;
11108 return activityOptions;
11113 Binder.restoreCallingIdentity(origId);
11118 public void setImmersive(IBinder token, boolean immersive) {
11119 synchronized(this) {
11120 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11122 throw new IllegalArgumentException();
11124 r.immersive = immersive;
11126 // update associated state if we're frontmost
11127 if (r == mFocusedActivity) {
11128 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11129 applyUpdateLockStateLocked(r);
11135 public boolean isImmersive(IBinder token) {
11136 synchronized (this) {
11137 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11139 throw new IllegalArgumentException();
11141 return r.immersive;
11145 public boolean isTopActivityImmersive() {
11146 enforceNotIsolatedCaller("startActivity");
11147 synchronized (this) {
11148 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11149 return (r != null) ? r.immersive : false;
11154 public boolean isTopOfTask(IBinder token) {
11155 synchronized (this) {
11156 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11158 throw new IllegalArgumentException();
11160 return r.task.getTopActivity() == r;
11164 public final void enterSafeMode() {
11165 synchronized(this) {
11166 // It only makes sense to do this before the system is ready
11167 // and started launching other packages.
11168 if (!mSystemReady) {
11170 AppGlobals.getPackageManager().enterSafeMode();
11171 } catch (RemoteException e) {
11179 public final void showSafeModeOverlay() {
11180 View v = LayoutInflater.from(mContext).inflate(
11181 com.android.internal.R.layout.safe_mode, null);
11182 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11183 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11184 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11185 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11186 lp.gravity = Gravity.BOTTOM | Gravity.START;
11187 lp.format = v.getBackground().getOpacity();
11188 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11189 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11190 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11191 ((WindowManager)mContext.getSystemService(
11192 Context.WINDOW_SERVICE)).addView(v, lp);
11195 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11196 if (!(sender instanceof PendingIntentRecord)) {
11199 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11200 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11201 synchronized (stats) {
11202 if (mBatteryStatsService.isOnBattery()) {
11203 mBatteryStatsService.enforceCallingPermission();
11204 int MY_UID = Binder.getCallingUid();
11205 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11206 BatteryStatsImpl.Uid.Pkg pkg =
11207 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11208 sourcePkg != null ? sourcePkg : rec.key.packageName);
11209 pkg.noteWakeupAlarmLocked(tag);
11214 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11215 if (!(sender instanceof PendingIntentRecord)) {
11218 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11219 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11220 synchronized (stats) {
11221 mBatteryStatsService.enforceCallingPermission();
11222 int MY_UID = Binder.getCallingUid();
11223 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11224 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11228 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11229 if (!(sender instanceof PendingIntentRecord)) {
11232 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11233 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11234 synchronized (stats) {
11235 mBatteryStatsService.enforceCallingPermission();
11236 int MY_UID = Binder.getCallingUid();
11237 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11238 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11242 public boolean killPids(int[] pids, String pReason, boolean secure) {
11243 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11244 throw new SecurityException("killPids only available to the system");
11246 String reason = (pReason == null) ? "Unknown" : pReason;
11247 // XXX Note: don't acquire main activity lock here, because the window
11248 // manager calls in with its locks held.
11250 boolean killed = false;
11251 synchronized (mPidsSelfLocked) {
11252 int[] types = new int[pids.length];
11254 for (int i=0; i<pids.length; i++) {
11255 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11256 if (proc != null) {
11257 int type = proc.setAdj;
11259 if (type > worstType) {
11265 // If the worst oom_adj is somewhere in the cached proc LRU range,
11266 // then constrain it so we will kill all cached procs.
11267 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11268 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11269 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11272 // If this is not a secure call, don't let it kill processes that
11274 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11275 worstType = ProcessList.SERVICE_ADJ;
11278 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11279 for (int i=0; i<pids.length; i++) {
11280 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11281 if (proc == null) {
11284 int adj = proc.setAdj;
11285 if (adj >= worstType && !proc.killedByAm) {
11286 proc.kill(reason, true);
11295 public void killUid(int appId, int userId, String reason) {
11296 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11297 synchronized (this) {
11298 final long identity = Binder.clearCallingIdentity();
11300 killPackageProcessesLocked(null, appId, userId,
11301 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11302 reason != null ? reason : "kill uid");
11304 Binder.restoreCallingIdentity(identity);
11310 public boolean killProcessesBelowForeground(String reason) {
11311 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11312 throw new SecurityException("killProcessesBelowForeground() only available to system");
11315 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11318 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11319 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11320 throw new SecurityException("killProcessesBelowAdj() only available to system");
11323 boolean killed = false;
11324 synchronized (mPidsSelfLocked) {
11325 final int size = mPidsSelfLocked.size();
11326 for (int i = 0; i < size; i++) {
11327 final int pid = mPidsSelfLocked.keyAt(i);
11328 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11329 if (proc == null) continue;
11331 final int adj = proc.setAdj;
11332 if (adj > belowAdj && !proc.killedByAm) {
11333 proc.kill(reason, true);
11342 public void hang(final IBinder who, boolean allowRestart) {
11343 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11344 != PackageManager.PERMISSION_GRANTED) {
11345 throw new SecurityException("Requires permission "
11346 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11349 final IBinder.DeathRecipient death = new DeathRecipient() {
11351 public void binderDied() {
11352 synchronized (this) {
11359 who.linkToDeath(death, 0);
11360 } catch (RemoteException e) {
11361 Slog.w(TAG, "hang: given caller IBinder is already dead.");
11365 synchronized (this) {
11366 Watchdog.getInstance().setAllowRestart(allowRestart);
11367 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11368 synchronized (death) {
11369 while (who.isBinderAlive()) {
11372 } catch (InterruptedException e) {
11376 Watchdog.getInstance().setAllowRestart(true);
11381 public void restart() {
11382 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11383 != PackageManager.PERMISSION_GRANTED) {
11384 throw new SecurityException("Requires permission "
11385 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11388 Log.i(TAG, "Sending shutdown broadcast...");
11390 BroadcastReceiver br = new BroadcastReceiver() {
11391 @Override public void onReceive(Context context, Intent intent) {
11392 // Now the broadcast is done, finish up the low-level shutdown.
11393 Log.i(TAG, "Shutting down activity manager...");
11395 Log.i(TAG, "Shutdown complete, restarting!");
11396 Process.killProcess(Process.myPid());
11401 // First send the high-level shut down broadcast.
11402 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11403 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11404 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11405 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11406 mContext.sendOrderedBroadcastAsUser(intent,
11407 UserHandle.ALL, null, br, mHandler, 0, null, null);
11409 br.onReceive(mContext, intent);
11412 private long getLowRamTimeSinceIdle(long now) {
11413 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11417 public void performIdleMaintenance() {
11418 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11419 != PackageManager.PERMISSION_GRANTED) {
11420 throw new SecurityException("Requires permission "
11421 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11424 synchronized (this) {
11425 final long now = SystemClock.uptimeMillis();
11426 final long timeSinceLastIdle = now - mLastIdleTime;
11427 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11428 mLastIdleTime = now;
11429 mLowRamTimeSinceLastIdle = 0;
11430 if (mLowRamStartTime != 0) {
11431 mLowRamStartTime = now;
11434 StringBuilder sb = new StringBuilder(128);
11435 sb.append("Idle maintenance over ");
11436 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11437 sb.append(" low RAM for ");
11438 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11439 Slog.i(TAG, sb.toString());
11441 // If at least 1/3 of our time since the last idle period has been spent
11442 // with RAM low, then we want to kill processes.
11443 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11445 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11446 ProcessRecord proc = mLruProcesses.get(i);
11447 if (proc.notCachedSinceIdle) {
11448 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11449 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11450 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11451 if (doKilling && proc.initialIdlePss != 0
11452 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11453 sb = new StringBuilder(128);
11455 sb.append(proc.processName);
11456 sb.append(" in idle maint: pss=");
11457 sb.append(proc.lastPss);
11458 sb.append(", initialPss=");
11459 sb.append(proc.initialIdlePss);
11460 sb.append(", period=");
11461 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11462 sb.append(", lowRamPeriod=");
11463 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11464 Slog.wtfQuiet(TAG, sb.toString());
11465 proc.kill("idle maint (pss " + proc.lastPss
11466 + " from " + proc.initialIdlePss + ")", true);
11469 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11470 proc.notCachedSinceIdle = true;
11471 proc.initialIdlePss = 0;
11472 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11473 mTestPssMode, isSleeping(), now);
11477 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11478 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11482 private void retrieveSettings() {
11483 final ContentResolver resolver = mContext.getContentResolver();
11484 String debugApp = Settings.Global.getString(
11485 resolver, Settings.Global.DEBUG_APP);
11486 boolean waitForDebugger = Settings.Global.getInt(
11487 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11488 boolean alwaysFinishActivities = Settings.Global.getInt(
11489 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11490 boolean forceRtl = Settings.Global.getInt(
11491 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11492 // Transfer any global setting for forcing RTL layout, into a System Property
11493 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11495 Configuration configuration = new Configuration();
11496 Settings.System.getConfiguration(resolver, configuration);
11498 // This will take care of setting the correct layout direction flags
11499 configuration.setLayoutDirection(configuration.locale);
11502 synchronized (this) {
11503 mDebugApp = mOrigDebugApp = debugApp;
11504 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11505 mAlwaysFinishActivities = alwaysFinishActivities;
11506 // This happens before any activities are started, so we can
11507 // change mConfiguration in-place.
11508 updateConfigurationLocked(configuration, null, false, true);
11509 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11510 "Initial config: " + mConfiguration);
11514 /** Loads resources after the current configuration has been set. */
11515 private void loadResourcesOnSystemReady() {
11516 final Resources res = mContext.getResources();
11517 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11518 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11519 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11522 public boolean testIsSystemReady() {
11523 // no need to synchronize(this) just to read & return the value
11524 return mSystemReady;
11527 private static File getCalledPreBootReceiversFile() {
11528 File dataDir = Environment.getDataDirectory();
11529 File systemDir = new File(dataDir, "system");
11530 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11534 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11535 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11536 File file = getCalledPreBootReceiversFile();
11537 FileInputStream fis = null;
11539 fis = new FileInputStream(file);
11540 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11541 int fvers = dis.readInt();
11542 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11543 String vers = dis.readUTF();
11544 String codename = dis.readUTF();
11545 String build = dis.readUTF();
11546 if (android.os.Build.VERSION.RELEASE.equals(vers)
11547 && android.os.Build.VERSION.CODENAME.equals(codename)
11548 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11549 int num = dis.readInt();
11552 String pkg = dis.readUTF();
11553 String cls = dis.readUTF();
11554 lastDoneReceivers.add(new ComponentName(pkg, cls));
11558 } catch (FileNotFoundException e) {
11559 } catch (IOException e) {
11560 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11565 } catch (IOException e) {
11569 return lastDoneReceivers;
11572 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11573 File file = getCalledPreBootReceiversFile();
11574 FileOutputStream fos = null;
11575 DataOutputStream dos = null;
11577 fos = new FileOutputStream(file);
11578 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11579 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11580 dos.writeUTF(android.os.Build.VERSION.RELEASE);
11581 dos.writeUTF(android.os.Build.VERSION.CODENAME);
11582 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11583 dos.writeInt(list.size());
11584 for (int i=0; i<list.size(); i++) {
11585 dos.writeUTF(list.get(i).getPackageName());
11586 dos.writeUTF(list.get(i).getClassName());
11588 } catch (IOException e) {
11589 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11592 FileUtils.sync(fos);
11596 } catch (IOException e) {
11597 // TODO Auto-generated catch block
11598 e.printStackTrace();
11604 final class PreBootContinuation extends IIntentReceiver.Stub {
11605 final Intent intent;
11606 final Runnable onFinishCallback;
11607 final ArrayList<ComponentName> doneReceivers;
11608 final List<ResolveInfo> ris;
11614 PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11615 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11617 onFinishCallback = _onFinishCallback;
11618 doneReceivers = _doneReceivers;
11624 if (lastRi != curRi) {
11625 ActivityInfo ai = ris.get(curRi).activityInfo;
11626 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11627 intent.setComponent(comp);
11628 doneReceivers.add(comp);
11630 CharSequence label = ai.loadLabel(mContext.getPackageManager());
11631 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11633 Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11634 + " for user " + users[curUser]);
11635 EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11636 broadcastIntentLocked(null, null, intent, null, this,
11637 0, null, null, null, AppOpsManager.OP_NONE,
11638 null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11641 public void performReceive(Intent intent, int resultCode,
11642 String data, Bundle extras, boolean ordered,
11643 boolean sticky, int sendingUser) {
11645 if (curUser >= users.length) {
11648 if (curRi >= ris.size()) {
11649 // All done sending broadcasts!
11650 if (onFinishCallback != null) {
11651 // The raw IIntentReceiver interface is called
11652 // with the AM lock held, so redispatch to
11653 // execute our code without the lock.
11654 mHandler.post(onFinishCallback);
11663 private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11664 ArrayList<ComponentName> doneReceivers, int userId) {
11665 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11666 List<ResolveInfo> ris = null;
11668 ris = AppGlobals.getPackageManager().queryIntentReceivers(
11669 intent, null, 0, userId);
11670 } catch (RemoteException e) {
11675 for (int i=ris.size()-1; i>=0; i--) {
11676 if ((ris.get(i).activityInfo.applicationInfo.flags
11677 &ApplicationInfo.FLAG_SYSTEM) == 0) {
11681 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11683 // For User 0, load the version number. When delivering to a new user, deliver
11684 // to all receivers.
11685 if (userId == UserHandle.USER_OWNER) {
11686 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11687 for (int i=0; i<ris.size(); i++) {
11688 ActivityInfo ai = ris.get(i).activityInfo;
11689 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11690 if (lastDoneReceivers.contains(comp)) {
11691 // We already did the pre boot receiver for this app with the current
11692 // platform version, so don't do it again...
11695 // ...however, do keep it as one that has been done, so we don't
11696 // forget about it when rewriting the file of last done receivers.
11697 doneReceivers.add(comp);
11702 if (ris.size() <= 0) {
11706 // If primary user, send broadcast to all available users, else just to userId
11707 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11708 : new int[] { userId };
11709 if (users.length <= 0) {
11713 PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11719 public void systemReady(final Runnable goingCallback) {
11720 synchronized(this) {
11721 if (mSystemReady) {
11722 // If we're done calling all the receivers, run the next "boot phase" passed in
11723 // by the SystemServer
11724 if (goingCallback != null) {
11725 goingCallback.run();
11730 mLocalDeviceIdleController
11731 = LocalServices.getService(DeviceIdleController.LocalService.class);
11733 // Make sure we have the current profile info, since it is needed for
11734 // security checks.
11735 updateCurrentProfileIdsLocked();
11737 mRecentTasks.clear();
11738 mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11739 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11740 mTaskPersister.startPersisting();
11742 // Check to see if there are any update receivers to run.
11744 if (mWaitingUpdate) {
11747 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11748 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11749 public void run() {
11750 synchronized (ActivityManagerService.this) {
11753 showBootMessage(mContext.getText(
11754 R.string.android_upgrading_complete),
11756 writeLastDonePreBootReceivers(doneReceivers);
11757 systemReady(goingCallback);
11759 }, doneReceivers, UserHandle.USER_OWNER);
11761 if (mWaitingUpdate) {
11767 mAppOpsService.systemReady();
11768 mSystemReady = true;
11771 ArrayList<ProcessRecord> procsToKill = null;
11772 synchronized(mPidsSelfLocked) {
11773 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11774 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11775 if (!isAllowedWhileBooting(proc.info)){
11776 if (procsToKill == null) {
11777 procsToKill = new ArrayList<ProcessRecord>();
11779 procsToKill.add(proc);
11784 synchronized(this) {
11785 if (procsToKill != null) {
11786 for (int i=procsToKill.size()-1; i>=0; i--) {
11787 ProcessRecord proc = procsToKill.get(i);
11788 Slog.i(TAG, "Removing system update proc: " + proc);
11789 removeProcessLocked(proc, true, false, "system update done");
11793 // Now that we have cleaned up any update processes, we
11794 // are ready to start launching real processes and know that
11795 // we won't trample on them any more.
11796 mProcessesReady = true;
11799 Slog.i(TAG, "System now ready");
11800 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11801 SystemClock.uptimeMillis());
11803 synchronized(this) {
11804 // Make sure we have no pre-ready processes sitting around.
11806 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11807 ResolveInfo ri = mContext.getPackageManager()
11808 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11810 CharSequence errorMsg = null;
11812 ActivityInfo ai = ri.activityInfo;
11813 ApplicationInfo app = ai.applicationInfo;
11814 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11815 mTopAction = Intent.ACTION_FACTORY_TEST;
11817 mTopComponent = new ComponentName(app.packageName,
11820 errorMsg = mContext.getResources().getText(
11821 com.android.internal.R.string.factorytest_not_system);
11824 errorMsg = mContext.getResources().getText(
11825 com.android.internal.R.string.factorytest_no_action);
11827 if (errorMsg != null) {
11830 mTopComponent = null;
11831 Message msg = Message.obtain();
11832 msg.what = SHOW_FACTORY_ERROR_MSG;
11833 msg.getData().putCharSequence("msg", errorMsg);
11834 mUiHandler.sendMessage(msg);
11839 retrieveSettings();
11840 loadResourcesOnSystemReady();
11842 synchronized (this) {
11843 readGrantedUriPermissionsLocked();
11846 if (goingCallback != null) goingCallback.run();
11848 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11849 Integer.toString(mCurrentUserId), mCurrentUserId);
11850 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11851 Integer.toString(mCurrentUserId), mCurrentUserId);
11852 mSystemServiceManager.startUser(mCurrentUserId);
11854 synchronized (this) {
11855 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11857 List apps = AppGlobals.getPackageManager().
11858 getPersistentApplications(STOCK_PM_FLAGS);
11859 if (apps != null) {
11860 int N = apps.size();
11862 for (i=0; i<N; i++) {
11863 ApplicationInfo info
11864 = (ApplicationInfo)apps.get(i);
11865 if (info != null &&
11866 !info.packageName.equals("android")) {
11867 addAppLocked(info, false, null /* ABI override */);
11871 } catch (RemoteException ex) {
11872 // pm is in same process, this will never happen.
11876 // Start up initial activity.
11878 startHomeActivityLocked(mCurrentUserId, "systemReady");
11881 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11882 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11883 + " data partition or your device will be unstable.");
11884 mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11886 } catch (RemoteException e) {
11889 if (!Build.isBuildConsistent()) {
11890 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11891 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11894 long ident = Binder.clearCallingIdentity();
11896 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11897 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11898 | Intent.FLAG_RECEIVER_FOREGROUND);
11899 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11900 broadcastIntentLocked(null, null, intent,
11901 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11902 null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11903 intent = new Intent(Intent.ACTION_USER_STARTING);
11904 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11905 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11906 broadcastIntentLocked(null, null, intent,
11907 null, new IIntentReceiver.Stub() {
11909 public void performReceive(Intent intent, int resultCode, String data,
11910 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11911 throws RemoteException {
11914 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11915 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11916 } catch (Throwable t) {
11917 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11919 Binder.restoreCallingIdentity(ident);
11921 mStackSupervisor.resumeTopActivitiesLocked();
11922 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11926 private boolean makeAppCrashingLocked(ProcessRecord app,
11927 String shortMsg, String longMsg, String stackTrace) {
11928 app.crashing = true;
11929 app.crashingReport = generateProcessError(app,
11930 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11931 startAppProblemLocked(app);
11932 app.stopFreezingAllLocked();
11933 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11936 private void makeAppNotRespondingLocked(ProcessRecord app,
11937 String activity, String shortMsg, String longMsg) {
11938 app.notResponding = true;
11939 app.notRespondingReport = generateProcessError(app,
11940 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11941 activity, shortMsg, longMsg, null);
11942 startAppProblemLocked(app);
11943 app.stopFreezingAllLocked();
11947 * Generate a process error record, suitable for attachment to a ProcessRecord.
11949 * @param app The ProcessRecord in which the error occurred.
11950 * @param condition Crashing, Application Not Responding, etc. Values are defined in
11951 * ActivityManager.AppErrorStateInfo
11952 * @param activity The activity associated with the crash, if known.
11953 * @param shortMsg Short message describing the crash.
11954 * @param longMsg Long message describing the crash.
11955 * @param stackTrace Full crash stack trace, may be null.
11957 * @return Returns a fully-formed AppErrorStateInfo record.
11959 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11960 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11961 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11963 report.condition = condition;
11964 report.processName = app.processName;
11965 report.pid = app.pid;
11966 report.uid = app.info.uid;
11967 report.tag = activity;
11968 report.shortMsg = shortMsg;
11969 report.longMsg = longMsg;
11970 report.stackTrace = stackTrace;
11975 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11976 synchronized (this) {
11977 app.crashing = false;
11978 app.crashingReport = null;
11979 app.notResponding = false;
11980 app.notRespondingReport = null;
11981 if (app.anrDialog == fromDialog) {
11982 app.anrDialog = null;
11984 if (app.waitDialog == fromDialog) {
11985 app.waitDialog = null;
11987 if (app.pid > 0 && app.pid != MY_PID) {
11988 handleAppCrashLocked(app, "user-terminated" /*reason*/,
11989 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11990 app.kill("user request after error", true);
11995 private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11996 String shortMsg, String longMsg, String stackTrace) {
11997 long now = SystemClock.uptimeMillis();
12000 if (!app.isolated) {
12001 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12005 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12006 // This process loses!
12007 Slog.w(TAG, "Process " + app.info.processName
12008 + " has crashed too many times: killing!");
12009 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12010 app.userId, app.info.processName, app.uid);
12011 mStackSupervisor.handleAppCrashLocked(app);
12012 if (!app.persistent) {
12013 // We don't want to start this process again until the user
12014 // explicitly does so... but for persistent process, we really
12015 // need to keep it running. If a persistent process is actually
12016 // repeatedly crashing, then badness for everyone.
12017 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12018 app.info.processName);
12019 if (!app.isolated) {
12020 // XXX We don't have a way to mark isolated processes
12021 // as bad, since they don't have a peristent identity.
12022 mBadProcesses.put(app.info.processName, app.uid,
12023 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12024 mProcessCrashTimes.remove(app.info.processName, app.uid);
12027 app.removed = true;
12028 // Don't let services in this process be restarted and potentially
12029 // annoy the user repeatedly. Unless it is persistent, since those
12030 // processes run critical code.
12031 removeProcessLocked(app, false, false, "crash");
12032 mStackSupervisor.resumeTopActivitiesLocked();
12035 mStackSupervisor.resumeTopActivitiesLocked();
12037 mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12040 // Bump up the crash count of any services currently running in the proc.
12041 for (int i=app.services.size()-1; i>=0; i--) {
12042 // Any services running in the application need to be placed
12043 // back in the pending list.
12044 ServiceRecord sr = app.services.valueAt(i);
12048 // If the crashing process is what we consider to be the "home process" and it has been
12049 // replaced by a third-party app, clear the package preferred activities from packages
12050 // with a home activity running in the process to prevent a repeatedly crashing app
12051 // from blocking the user to manually clear the list.
12052 final ArrayList<ActivityRecord> activities = app.activities;
12053 if (app == mHomeProcess && activities.size() > 0
12054 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12055 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12056 final ActivityRecord r = activities.get(activityNdx);
12057 if (r.isHomeActivity()) {
12058 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12060 ActivityThread.getPackageManager()
12061 .clearPackagePreferredActivities(r.packageName);
12062 } catch (RemoteException c) {
12063 // pm is in same process, this will never happen.
12069 if (!app.isolated) {
12070 // XXX Can't keep track of crash times for isolated processes,
12071 // because they don't have a perisistent identity.
12072 mProcessCrashTimes.put(app.info.processName, app.uid, now);
12075 if (app.crashHandler != null) mHandler.post(app.crashHandler);
12079 void startAppProblemLocked(ProcessRecord app) {
12080 // If this app is not running under the current user, then we
12081 // can't give it a report button because that would require
12082 // launching the report UI under a different user.
12083 app.errorReportReceiver = null;
12085 for (int userId : mCurrentProfileIds) {
12086 if (app.userId == userId) {
12087 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12088 mContext, app.info.packageName, app.info.flags);
12091 skipCurrentReceiverLocked(app);
12094 void skipCurrentReceiverLocked(ProcessRecord app) {
12095 for (BroadcastQueue queue : mBroadcastQueues) {
12096 queue.skipCurrentReceiverLocked(app);
12101 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12102 * The application process will exit immediately after this call returns.
12103 * @param app object of the crashing app, null for the system server
12104 * @param crashInfo describing the exception
12106 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12107 ProcessRecord r = findAppProcess(app, "Crash");
12108 final String processName = app == null ? "system_server"
12109 : (r == null ? "unknown" : r.processName);
12111 handleApplicationCrashInner("crash", r, processName, crashInfo);
12114 /* Native crash reporting uses this inner version because it needs to be somewhat
12115 * decoupled from the AM-managed cleanup lifecycle
12117 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12118 ApplicationErrorReport.CrashInfo crashInfo) {
12119 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12120 UserHandle.getUserId(Binder.getCallingUid()), processName,
12121 r == null ? -1 : r.info.flags,
12122 crashInfo.exceptionClassName,
12123 crashInfo.exceptionMessage,
12124 crashInfo.throwFileName,
12125 crashInfo.throwLineNumber);
12127 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12129 crashApplication(r, crashInfo);
12132 public void handleApplicationStrictModeViolation(
12135 StrictMode.ViolationInfo info) {
12136 ProcessRecord r = findAppProcess(app, "StrictMode");
12141 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12142 Integer stackFingerprint = info.hashCode();
12143 boolean logIt = true;
12144 synchronized (mAlreadyLoggedViolatedStacks) {
12145 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12147 // TODO: sub-sample into EventLog for these, with
12148 // the info.durationMillis? Then we'd get
12149 // the relative pain numbers, without logging all
12150 // the stack traces repeatedly. We'd want to do
12151 // likewise in the client code, which also does
12152 // dup suppression, before the Binder call.
12154 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12155 mAlreadyLoggedViolatedStacks.clear();
12157 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12161 logStrictModeViolationToDropBox(r, info);
12165 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12166 AppErrorResult result = new AppErrorResult();
12167 synchronized (this) {
12168 final long origId = Binder.clearCallingIdentity();
12170 Message msg = Message.obtain();
12171 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12172 HashMap<String, Object> data = new HashMap<String, Object>();
12173 data.put("result", result);
12174 data.put("app", r);
12175 data.put("violationMask", violationMask);
12176 data.put("info", info);
12178 mUiHandler.sendMessage(msg);
12180 Binder.restoreCallingIdentity(origId);
12182 int res = result.get();
12183 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12187 // Depending on the policy in effect, there could be a bunch of
12188 // these in quick succession so we try to batch these together to
12189 // minimize disk writes, number of dropbox entries, and maximize
12190 // compression, by having more fewer, larger records.
12191 private void logStrictModeViolationToDropBox(
12192 ProcessRecord process,
12193 StrictMode.ViolationInfo info) {
12194 if (info == null) {
12197 final boolean isSystemApp = process == null ||
12198 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12199 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12200 final String processName = process == null ? "unknown" : process.processName;
12201 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12202 final DropBoxManager dbox = (DropBoxManager)
12203 mContext.getSystemService(Context.DROPBOX_SERVICE);
12205 // Exit early if the dropbox isn't configured to accept this report type.
12206 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12208 boolean bufferWasEmpty;
12209 boolean needsFlush;
12210 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12211 synchronized (sb) {
12212 bufferWasEmpty = sb.length() == 0;
12213 appendDropBoxProcessHeaders(process, processName, sb);
12214 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12215 sb.append("System-App: ").append(isSystemApp).append("\n");
12216 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12217 if (info.violationNumThisLoop != 0) {
12218 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12220 if (info.numAnimationsRunning != 0) {
12221 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12223 if (info.broadcastIntentAction != null) {
12224 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12226 if (info.durationMillis != -1) {
12227 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12229 if (info.numInstances != -1) {
12230 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12232 if (info.tags != null) {
12233 for (String tag : info.tags) {
12234 sb.append("Span-Tag: ").append(tag).append("\n");
12238 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12239 sb.append(info.crashInfo.stackTrace);
12242 if (info.message != null) {
12243 sb.append(info.message);
12247 // Only buffer up to ~64k. Various logging bits truncate
12249 needsFlush = (sb.length() > 64 * 1024);
12252 // Flush immediately if the buffer's grown too large, or this
12253 // is a non-system app. Non-system apps are isolated with a
12254 // different tag & policy and not batched.
12256 // Batching is useful during internal testing with
12257 // StrictMode settings turned up high. Without batching,
12258 // thousands of separate files could be created on boot.
12259 if (!isSystemApp || needsFlush) {
12260 new Thread("Error dump: " + dropboxTag) {
12262 public void run() {
12264 synchronized (sb) {
12265 report = sb.toString();
12266 sb.delete(0, sb.length());
12269 if (report.length() != 0) {
12270 dbox.addText(dropboxTag, report);
12277 // System app batching:
12278 if (!bufferWasEmpty) {
12279 // An existing dropbox-writing thread is outstanding, so
12280 // we don't need to start it up. The existing thread will
12281 // catch the buffer appends we just did.
12285 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12286 // (After this point, we shouldn't access AMS internal data structures.)
12287 new Thread("Error dump: " + dropboxTag) {
12289 public void run() {
12290 // 5 second sleep to let stacks arrive and be batched together
12292 Thread.sleep(5000); // 5 seconds
12293 } catch (InterruptedException e) {}
12295 String errorReport;
12296 synchronized (mStrictModeBuffer) {
12297 errorReport = mStrictModeBuffer.toString();
12298 if (errorReport.length() == 0) {
12301 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12302 mStrictModeBuffer.trimToSize();
12304 dbox.addText(dropboxTag, errorReport);
12310 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12311 * @param app object of the crashing app, null for the system server
12312 * @param tag reported by the caller
12313 * @param system whether this wtf is coming from the system
12314 * @param crashInfo describing the context of the error
12315 * @return true if the process should exit immediately (WTF is fatal)
12317 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12318 final ApplicationErrorReport.CrashInfo crashInfo) {
12319 final int callingUid = Binder.getCallingUid();
12320 final int callingPid = Binder.getCallingPid();
12323 // If this is coming from the system, we could very well have low-level
12324 // system locks held, so we want to do this all asynchronously. And we
12325 // never want this to become fatal, so there is that too.
12326 mHandler.post(new Runnable() {
12327 @Override public void run() {
12328 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12334 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12337 if (r != null && r.pid != Process.myPid() &&
12338 Settings.Global.getInt(mContext.getContentResolver(),
12339 Settings.Global.WTF_IS_FATAL, 0) != 0) {
12340 crashApplication(r, crashInfo);
12347 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12348 final ApplicationErrorReport.CrashInfo crashInfo) {
12349 final ProcessRecord r = findAppProcess(app, "WTF");
12350 final String processName = app == null ? "system_server"
12351 : (r == null ? "unknown" : r.processName);
12353 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12354 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12356 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12362 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12363 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12365 private ProcessRecord findAppProcess(IBinder app, String reason) {
12370 synchronized (this) {
12371 final int NP = mProcessNames.getMap().size();
12372 for (int ip=0; ip<NP; ip++) {
12373 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12374 final int NA = apps.size();
12375 for (int ia=0; ia<NA; ia++) {
12376 ProcessRecord p = apps.valueAt(ia);
12377 if (p.thread != null && p.thread.asBinder() == app) {
12383 Slog.w(TAG, "Can't find mystery application for " + reason
12384 + " from pid=" + Binder.getCallingPid()
12385 + " uid=" + Binder.getCallingUid() + ": " + app);
12391 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12392 * to append various headers to the dropbox log text.
12394 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12395 StringBuilder sb) {
12396 // Watchdog thread ends up invoking this function (with
12397 // a null ProcessRecord) to add the stack file to dropbox.
12398 // Do not acquire a lock on this (am) in such cases, as it
12399 // could cause a potential deadlock, if and when watchdog
12400 // is invoked due to unavailability of lock on am and it
12401 // would prevent watchdog from killing system_server.
12402 if (process == null) {
12403 sb.append("Process: ").append(processName).append("\n");
12406 // Note: ProcessRecord 'process' is guarded by the service
12407 // instance. (notably process.pkgList, which could otherwise change
12408 // concurrently during execution of this method)
12409 synchronized (this) {
12410 sb.append("Process: ").append(processName).append("\n");
12411 int flags = process.info.flags;
12412 IPackageManager pm = AppGlobals.getPackageManager();
12413 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12414 for (int ip=0; ip<process.pkgList.size(); ip++) {
12415 String pkg = process.pkgList.keyAt(ip);
12416 sb.append("Package: ").append(pkg);
12418 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12420 sb.append(" v").append(pi.versionCode);
12421 if (pi.versionName != null) {
12422 sb.append(" (").append(pi.versionName).append(")");
12425 } catch (RemoteException e) {
12426 Slog.e(TAG, "Error getting package info: " + pkg, e);
12433 private static String processClass(ProcessRecord process) {
12434 if (process == null || process.pid == MY_PID) {
12435 return "system_server";
12436 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12437 return "system_app";
12444 * Write a description of an error (crash, WTF, ANR) to the drop box.
12445 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12446 * @param process which caused the error, null means the system server
12447 * @param activity which triggered the error, null if unknown
12448 * @param parent activity related to the error, null if unknown
12449 * @param subject line related to the error, null if absent
12450 * @param report in long form describing the error, null if absent
12451 * @param logFile to include in the report, null if none
12452 * @param crashInfo giving an application stack trace, null if absent
12454 public void addErrorToDropBox(String eventType,
12455 ProcessRecord process, String processName, ActivityRecord activity,
12456 ActivityRecord parent, String subject,
12457 final String report, final File logFile,
12458 final ApplicationErrorReport.CrashInfo crashInfo) {
12459 // NOTE -- this must never acquire the ActivityManagerService lock,
12460 // otherwise the watchdog may be prevented from resetting the system.
12462 final String dropboxTag = processClass(process) + "_" + eventType;
12463 final DropBoxManager dbox = (DropBoxManager)
12464 mContext.getSystemService(Context.DROPBOX_SERVICE);
12466 // Exit early if the dropbox isn't configured to accept this report type.
12467 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12469 final StringBuilder sb = new StringBuilder(1024);
12470 appendDropBoxProcessHeaders(process, processName, sb);
12471 if (activity != null) {
12472 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12474 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12475 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12477 if (parent != null && parent != activity) {
12478 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12480 if (subject != null) {
12481 sb.append("Subject: ").append(subject).append("\n");
12483 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12484 if (Debug.isDebuggerConnected()) {
12485 sb.append("Debugger: Connected\n");
12489 // Do the rest in a worker thread to avoid blocking the caller on I/O
12490 // (After this point, we shouldn't access AMS internal data structures.)
12491 Thread worker = new Thread("Error dump: " + dropboxTag) {
12493 public void run() {
12494 if (report != null) {
12497 if (logFile != null) {
12499 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12500 "\n\n[[TRUNCATED]]"));
12501 } catch (IOException e) {
12502 Slog.e(TAG, "Error reading " + logFile, e);
12505 if (crashInfo != null && crashInfo.stackTrace != null) {
12506 sb.append(crashInfo.stackTrace);
12509 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12510 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12514 // Merge several logcat streams, and take the last N lines
12515 InputStreamReader input = null;
12517 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12518 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12520 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12522 try { logcat.getOutputStream().close(); } catch (IOException e) {}
12523 try { logcat.getErrorStream().close(); } catch (IOException e) {}
12524 input = new InputStreamReader(logcat.getInputStream());
12527 char[] buf = new char[8192];
12528 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12529 } catch (IOException e) {
12530 Slog.e(TAG, "Error running logcat", e);
12532 if (input != null) try { input.close(); } catch (IOException e) {}
12536 dbox.addText(dropboxTag, sb.toString());
12540 if (process == null) {
12541 // If process is null, we are being called from some internal code
12542 // and may be about to die -- run this synchronously.
12550 * Bring up the "unexpected error" dialog box for a crashing app.
12551 * Deal with edge cases (intercepts from instrumented applications,
12552 * ActivityController, error intent receivers, that sort of thing).
12553 * @param r the application crashing
12554 * @param crashInfo describing the failure
12556 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12557 long timeMillis = System.currentTimeMillis();
12558 String shortMsg = crashInfo.exceptionClassName;
12559 String longMsg = crashInfo.exceptionMessage;
12560 String stackTrace = crashInfo.stackTrace;
12561 if (shortMsg != null && longMsg != null) {
12562 longMsg = shortMsg + ": " + longMsg;
12563 } else if (shortMsg != null) {
12564 longMsg = shortMsg;
12567 AppErrorResult result = new AppErrorResult();
12568 synchronized (this) {
12569 if (mController != null) {
12571 String name = r != null ? r.processName : null;
12572 int pid = r != null ? r.pid : Binder.getCallingPid();
12573 int uid = r != null ? r.info.uid : Binder.getCallingUid();
12574 if (!mController.appCrashed(name, pid,
12575 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12576 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12577 && "Native crash".equals(crashInfo.exceptionClassName)) {
12578 Slog.w(TAG, "Skip killing native crashed app " + name
12579 + "(" + pid + ") during testing");
12581 Slog.w(TAG, "Force-killing crashed app " + name
12582 + " at watcher's request");
12584 r.kill("crash", true);
12587 Process.killProcess(pid);
12588 killProcessGroup(uid, pid);
12593 } catch (RemoteException e) {
12594 mController = null;
12595 Watchdog.getInstance().setActivityController(null);
12599 final long origId = Binder.clearCallingIdentity();
12601 // If this process is running instrumentation, finish it.
12602 if (r != null && r.instrumentationClass != null) {
12603 Slog.w(TAG, "Error in app " + r.processName
12604 + " running instrumentation " + r.instrumentationClass + ":");
12605 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
12606 if (longMsg != null) Slog.w(TAG, " " + longMsg);
12607 Bundle info = new Bundle();
12608 info.putString("shortMsg", shortMsg);
12609 info.putString("longMsg", longMsg);
12610 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12611 Binder.restoreCallingIdentity(origId);
12615 // Log crash in battery stats.
12617 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12620 // If we can't identify the process or it's already exceeded its crash quota,
12621 // quit right away without showing a crash dialog.
12622 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12623 Binder.restoreCallingIdentity(origId);
12627 Message msg = Message.obtain();
12628 msg.what = SHOW_ERROR_MSG;
12629 HashMap data = new HashMap();
12630 data.put("result", result);
12631 data.put("app", r);
12633 mUiHandler.sendMessage(msg);
12635 Binder.restoreCallingIdentity(origId);
12638 int res = result.get();
12640 Intent appErrorIntent = null;
12641 synchronized (this) {
12642 if (r != null && !r.isolated) {
12643 // XXX Can't keep track of crash time for isolated processes,
12644 // since they don't have a persistent identity.
12645 mProcessCrashTimes.put(r.info.processName, r.uid,
12646 SystemClock.uptimeMillis());
12648 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12649 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12653 if (appErrorIntent != null) {
12655 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12656 } catch (ActivityNotFoundException e) {
12657 Slog.w(TAG, "bug report receiver dissappeared", e);
12662 Intent createAppErrorIntentLocked(ProcessRecord r,
12663 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12664 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12665 if (report == null) {
12668 Intent result = new Intent(Intent.ACTION_APP_ERROR);
12669 result.setComponent(r.errorReportReceiver);
12670 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12671 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12675 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12676 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12677 if (r.errorReportReceiver == null) {
12681 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12685 ApplicationErrorReport report = new ApplicationErrorReport();
12686 report.packageName = r.info.packageName;
12687 report.installerPackageName = r.errorReportReceiver.getPackageName();
12688 report.processName = r.processName;
12689 report.time = timeMillis;
12690 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12692 if (r.crashing || r.forceCrashReport) {
12693 report.type = ApplicationErrorReport.TYPE_CRASH;
12694 report.crashInfo = crashInfo;
12695 } else if (r.notResponding) {
12696 report.type = ApplicationErrorReport.TYPE_ANR;
12697 report.anrInfo = new ApplicationErrorReport.AnrInfo();
12699 report.anrInfo.activity = r.notRespondingReport.tag;
12700 report.anrInfo.cause = r.notRespondingReport.shortMsg;
12701 report.anrInfo.info = r.notRespondingReport.longMsg;
12707 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12708 enforceNotIsolatedCaller("getProcessesInErrorState");
12709 // assume our apps are happy - lazy create the list
12710 List<ActivityManager.ProcessErrorStateInfo> errList = null;
12712 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12713 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12714 int userId = UserHandle.getUserId(Binder.getCallingUid());
12716 synchronized (this) {
12718 // iterate across all processes
12719 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12720 ProcessRecord app = mLruProcesses.get(i);
12721 if (!allUsers && app.userId != userId) {
12724 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12725 // This one's in trouble, so we'll generate a report for it
12726 // crashes are higher priority (in case there's a crash *and* an anr)
12727 ActivityManager.ProcessErrorStateInfo report = null;
12728 if (app.crashing) {
12729 report = app.crashingReport;
12730 } else if (app.notResponding) {
12731 report = app.notRespondingReport;
12734 if (report != null) {
12735 if (errList == null) {
12736 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12738 errList.add(report);
12740 Slog.w(TAG, "Missing app error report, app = " + app.processName +
12741 " crashing = " + app.crashing +
12742 " notResponding = " + app.notResponding);
12751 static int procStateToImportance(int procState, int memAdj,
12752 ActivityManager.RunningAppProcessInfo currApp) {
12753 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12754 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12755 currApp.lru = memAdj;
12762 private void fillInProcMemInfo(ProcessRecord app,
12763 ActivityManager.RunningAppProcessInfo outInfo) {
12764 outInfo.pid = app.pid;
12765 outInfo.uid = app.info.uid;
12766 if (mHeavyWeightProcess == app) {
12767 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12769 if (app.persistent) {
12770 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12772 if (app.activities.size() > 0) {
12773 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12775 outInfo.lastTrimLevel = app.trimMemoryLevel;
12776 int adj = app.curAdj;
12777 int procState = app.curProcState;
12778 outInfo.importance = procStateToImportance(procState, adj, outInfo);
12779 outInfo.importanceReasonCode = app.adjTypeCode;
12780 outInfo.processState = app.curProcState;
12783 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12784 enforceNotIsolatedCaller("getRunningAppProcesses");
12786 final int callingUid = Binder.getCallingUid();
12788 // Lazy instantiation of list
12789 List<ActivityManager.RunningAppProcessInfo> runList = null;
12790 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12791 callingUid) == PackageManager.PERMISSION_GRANTED;
12792 final int userId = UserHandle.getUserId(callingUid);
12793 final boolean allUids = isGetTasksAllowed(
12794 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12796 synchronized (this) {
12797 // Iterate across all processes
12798 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12799 ProcessRecord app = mLruProcesses.get(i);
12800 if ((!allUsers && app.userId != userId)
12801 || (!allUids && app.uid != callingUid)) {
12804 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12805 // Generate process state info for running application
12806 ActivityManager.RunningAppProcessInfo currApp =
12807 new ActivityManager.RunningAppProcessInfo(app.processName,
12808 app.pid, app.getPackageList());
12809 fillInProcMemInfo(app, currApp);
12810 if (app.adjSource instanceof ProcessRecord) {
12811 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12812 currApp.importanceReasonImportance =
12813 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12814 app.adjSourceProcState);
12815 } else if (app.adjSource instanceof ActivityRecord) {
12816 ActivityRecord r = (ActivityRecord)app.adjSource;
12817 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12819 if (app.adjTarget instanceof ComponentName) {
12820 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12822 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12823 // + " lru=" + currApp.lru);
12824 if (runList == null) {
12825 runList = new ArrayList<>();
12827 runList.add(currApp);
12834 public List<ApplicationInfo> getRunningExternalApplications() {
12835 enforceNotIsolatedCaller("getRunningExternalApplications");
12836 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12837 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12838 if (runningApps != null && runningApps.size() > 0) {
12839 Set<String> extList = new HashSet<String>();
12840 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12841 if (app.pkgList != null) {
12842 for (String pkg : app.pkgList) {
12847 IPackageManager pm = AppGlobals.getPackageManager();
12848 for (String pkg : extList) {
12850 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12851 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12854 } catch (RemoteException e) {
12862 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12863 enforceNotIsolatedCaller("getMyMemoryState");
12864 synchronized (this) {
12865 ProcessRecord proc;
12866 synchronized (mPidsSelfLocked) {
12867 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12869 fillInProcMemInfo(proc, outInfo);
12874 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12875 if (checkCallingPermission(android.Manifest.permission.DUMP)
12876 != PackageManager.PERMISSION_GRANTED) {
12877 pw.println("Permission Denial: can't dump ActivityManager from from pid="
12878 + Binder.getCallingPid()
12879 + ", uid=" + Binder.getCallingUid()
12880 + " without permission "
12881 + android.Manifest.permission.DUMP);
12885 boolean dumpAll = false;
12886 boolean dumpClient = false;
12887 String dumpPackage = null;
12890 while (opti < args.length) {
12891 String opt = args[opti];
12892 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12896 if ("-a".equals(opt)) {
12898 } else if ("-c".equals(opt)) {
12900 } else if ("-p".equals(opt)) {
12901 if (opti < args.length) {
12902 dumpPackage = args[opti];
12905 pw.println("Error: -p option requires package argument");
12909 } else if ("-h".equals(opt)) {
12910 pw.println("Activity manager dump options:");
12911 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ...");
12912 pw.println(" cmd may be one of:");
12913 pw.println(" a[ctivities]: activity stack state");
12914 pw.println(" r[recents]: recent activities state");
12915 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12916 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
12917 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
12918 pw.println(" o[om]: out of memory management");
12919 pw.println(" perm[issions]: URI permission grant state");
12920 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
12921 pw.println(" provider [COMP_SPEC]: provider client-side state");
12922 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
12923 pw.println(" as[sociations]: tracked app associations");
12924 pw.println(" service [COMP_SPEC]: service client-side state");
12925 pw.println(" package [PACKAGE_NAME]: all state related to given package");
12926 pw.println(" all: dump all activities");
12927 pw.println(" top: dump the top activity");
12928 pw.println(" write: write all pending state to storage");
12929 pw.println(" track-associations: enable association tracking");
12930 pw.println(" untrack-associations: disable and clear association tracking");
12931 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
12932 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
12933 pw.println(" a partial substring in a component name, a");
12934 pw.println(" hex object identifier.");
12935 pw.println(" -a: include all available server state.");
12936 pw.println(" -c: include client state.");
12937 pw.println(" -p: limit output to given package.");
12940 pw.println("Unknown argument: " + opt + "; use -h for help");
12944 long origId = Binder.clearCallingIdentity();
12945 boolean more = false;
12946 // Is the caller requesting to dump a particular piece of data?
12947 if (opti < args.length) {
12948 String cmd = args[opti];
12950 if ("activities".equals(cmd) || "a".equals(cmd)) {
12951 synchronized (this) {
12952 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12954 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12955 synchronized (this) {
12956 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12958 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12961 if (opti >= args.length) {
12963 newArgs = EMPTY_STRING_ARRAY;
12965 dumpPackage = args[opti];
12967 newArgs = new String[args.length - opti];
12968 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12969 args.length - opti);
12971 synchronized (this) {
12972 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12974 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12977 if (opti >= args.length) {
12979 newArgs = EMPTY_STRING_ARRAY;
12981 dumpPackage = args[opti];
12983 newArgs = new String[args.length - opti];
12984 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12985 args.length - opti);
12987 synchronized (this) {
12988 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12990 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12993 if (opti >= args.length) {
12995 newArgs = EMPTY_STRING_ARRAY;
12997 dumpPackage = args[opti];
12999 newArgs = new String[args.length - opti];
13000 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13001 args.length - opti);
13003 synchronized (this) {
13004 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13006 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13007 synchronized (this) {
13008 dumpOomLocked(fd, pw, args, opti, true);
13010 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13011 synchronized (this) {
13012 dumpPermissionsLocked(fd, pw, args, opti, true, null);
13014 } else if ("provider".equals(cmd)) {
13017 if (opti >= args.length) {
13019 newArgs = EMPTY_STRING_ARRAY;
13023 newArgs = new String[args.length - opti];
13024 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13026 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13027 pw.println("No providers match: " + name);
13028 pw.println("Use -h for help.");
13030 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13031 synchronized (this) {
13032 dumpProvidersLocked(fd, pw, args, opti, true, null);
13034 } else if ("service".equals(cmd)) {
13037 if (opti >= args.length) {
13039 newArgs = EMPTY_STRING_ARRAY;
13043 newArgs = new String[args.length - opti];
13044 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13045 args.length - opti);
13047 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13048 pw.println("No services match: " + name);
13049 pw.println("Use -h for help.");
13051 } else if ("package".equals(cmd)) {
13053 if (opti >= args.length) {
13054 pw.println("package: no package name specified");
13055 pw.println("Use -h for help.");
13057 dumpPackage = args[opti];
13059 newArgs = new String[args.length - opti];
13060 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13061 args.length - opti);
13066 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13067 synchronized (this) {
13068 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13070 } else if ("services".equals(cmd) || "s".equals(cmd)) {
13071 synchronized (this) {
13072 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13074 } else if ("write".equals(cmd)) {
13075 mTaskPersister.flush();
13076 pw.println("All tasks persisted.");
13078 } else if ("track-associations".equals(cmd)) {
13079 synchronized (this) {
13080 if (!mTrackingAssociations) {
13081 mTrackingAssociations = true;
13082 pw.println("Association tracking started.");
13084 pw.println("Association tracking already enabled.");
13088 } else if ("untrack-associations".equals(cmd)) {
13089 synchronized (this) {
13090 if (mTrackingAssociations) {
13091 mTrackingAssociations = false;
13092 mAssociations.clear();
13093 pw.println("Association tracking stopped.");
13095 pw.println("Association tracking not running.");
13100 // Dumping a single activity?
13101 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13102 pw.println("Bad activity command, or no activities match: " + cmd);
13103 pw.println("Use -h for help.");
13107 Binder.restoreCallingIdentity(origId);
13112 // No piece of data specified, dump everything.
13113 synchronized (this) {
13114 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13117 pw.println("-------------------------------------------------------------------------------");
13119 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13122 pw.println("-------------------------------------------------------------------------------");
13124 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13127 pw.println("-------------------------------------------------------------------------------");
13129 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13132 pw.println("-------------------------------------------------------------------------------");
13134 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13137 pw.println("-------------------------------------------------------------------------------");
13139 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13142 pw.println("-------------------------------------------------------------------------------");
13144 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13145 if (mAssociations.size() > 0) {
13148 pw.println("-------------------------------------------------------------------------------");
13150 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13154 pw.println("-------------------------------------------------------------------------------");
13156 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13158 Binder.restoreCallingIdentity(origId);
13161 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13162 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13163 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13165 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13167 boolean needSep = printedAnything;
13169 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13170 dumpPackage, needSep, " mFocusedActivity: ");
13172 printedAnything = true;
13176 if (dumpPackage == null) {
13181 printedAnything = true;
13182 mStackSupervisor.dump(pw, " ");
13185 if (!printedAnything) {
13186 pw.println(" (nothing)");
13190 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13191 int opti, boolean dumpAll, String dumpPackage) {
13192 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13194 boolean printedAnything = false;
13196 if (mRecentTasks != null && mRecentTasks.size() > 0) {
13197 boolean printedHeader = false;
13199 final int N = mRecentTasks.size();
13200 for (int i=0; i<N; i++) {
13201 TaskRecord tr = mRecentTasks.get(i);
13202 if (dumpPackage != null) {
13203 if (tr.realActivity == null ||
13204 !dumpPackage.equals(tr.realActivity)) {
13208 if (!printedHeader) {
13209 pw.println(" Recent tasks:");
13210 printedHeader = true;
13211 printedAnything = true;
13213 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
13216 mRecentTasks.get(i).dump(pw, " ");
13221 if (!printedAnything) {
13222 pw.println(" (nothing)");
13226 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13227 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13228 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13231 if (dumpPackage != null) {
13232 IPackageManager pm = AppGlobals.getPackageManager();
13234 dumpUid = pm.getPackageUid(dumpPackage, 0);
13235 } catch (RemoteException e) {
13239 boolean printedAnything = false;
13241 final long now = SystemClock.uptimeMillis();
13243 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13244 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13245 = mAssociations.valueAt(i1);
13246 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13247 SparseArray<ArrayMap<String, Association>> sourceUids
13248 = targetComponents.valueAt(i2);
13249 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13250 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13251 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13252 Association ass = sourceProcesses.valueAt(i4);
13253 if (dumpPackage != null) {
13254 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13255 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13259 printedAnything = true;
13261 pw.print(ass.mTargetProcess);
13263 UserHandle.formatUid(pw, ass.mTargetUid);
13265 pw.print(ass.mSourceProcess);
13267 UserHandle.formatUid(pw, ass.mSourceUid);
13270 pw.print(ass.mTargetComponent.flattenToShortString());
13273 long dur = ass.mTime;
13274 if (ass.mNesting > 0) {
13275 dur += now - ass.mStartTime;
13277 TimeUtils.formatDuration(dur, pw);
13279 pw.print(ass.mCount);
13280 pw.println(" times)");
13281 if (ass.mNesting > 0) {
13283 pw.print(" Currently active: ");
13284 TimeUtils.formatDuration(now - ass.mStartTime, pw);
13293 if (!printedAnything) {
13294 pw.println(" (nothing)");
13298 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13299 int opti, boolean dumpAll, String dumpPackage) {
13300 boolean needSep = false;
13301 boolean printedAnything = false;
13304 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13307 final int NP = mProcessNames.getMap().size();
13308 for (int ip=0; ip<NP; ip++) {
13309 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13310 final int NA = procs.size();
13311 for (int ia=0; ia<NA; ia++) {
13312 ProcessRecord r = procs.valueAt(ia);
13313 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13317 pw.println(" All known processes:");
13319 printedAnything = true;
13321 pw.print(r.persistent ? " *PERS*" : " *APP*");
13322 pw.print(" UID "); pw.print(procs.keyAt(ia));
13323 pw.print(" "); pw.println(r);
13325 if (r.persistent) {
13332 if (mIsolatedProcesses.size() > 0) {
13333 boolean printed = false;
13334 for (int i=0; i<mIsolatedProcesses.size(); i++) {
13335 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13336 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13343 pw.println(" Isolated process list (sorted by uid):");
13344 printedAnything = true;
13348 pw.println(String.format("%sIsolated #%2d: %s",
13349 " ", i, r.toString()));
13353 if (mActiveUids.size() > 0) {
13357 pw.println(" UID states:");
13358 for (int i=0; i<mActiveUids.size(); i++) {
13359 UidRecord uidRec = mActiveUids.valueAt(i);
13360 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
13361 pw.print(": "); pw.println(uidRec);
13364 printedAnything = true;
13367 if (mLruProcesses.size() > 0) {
13371 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13372 pw.print(" total, non-act at ");
13373 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13374 pw.print(", non-svc at ");
13375 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13377 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
13379 printedAnything = true;
13382 if (dumpAll || dumpPackage != null) {
13383 synchronized (mPidsSelfLocked) {
13384 boolean printed = false;
13385 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13386 ProcessRecord r = mPidsSelfLocked.valueAt(i);
13387 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13391 if (needSep) pw.println();
13393 pw.println(" PID mappings:");
13395 printedAnything = true;
13397 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13398 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13403 if (mForegroundProcesses.size() > 0) {
13404 synchronized (mPidsSelfLocked) {
13405 boolean printed = false;
13406 for (int i=0; i<mForegroundProcesses.size(); i++) {
13407 ProcessRecord r = mPidsSelfLocked.get(
13408 mForegroundProcesses.valueAt(i).pid);
13409 if (dumpPackage != null && (r == null
13410 || !r.pkgList.containsKey(dumpPackage))) {
13414 if (needSep) pw.println();
13416 pw.println(" Foreground Processes:");
13418 printedAnything = true;
13420 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
13421 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13426 if (mPersistentStartingProcesses.size() > 0) {
13427 if (needSep) pw.println();
13429 printedAnything = true;
13430 pw.println(" Persisent processes that are starting:");
13431 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
13432 "Starting Norm", "Restarting PERS", dumpPackage);
13435 if (mRemovedProcesses.size() > 0) {
13436 if (needSep) pw.println();
13438 printedAnything = true;
13439 pw.println(" Processes that are being removed:");
13440 dumpProcessList(pw, this, mRemovedProcesses, " ",
13441 "Removed Norm", "Removed PERS", dumpPackage);
13444 if (mProcessesOnHold.size() > 0) {
13445 if (needSep) pw.println();
13447 printedAnything = true;
13448 pw.println(" Processes that are on old until the system is ready:");
13449 dumpProcessList(pw, this, mProcessesOnHold, " ",
13450 "OnHold Norm", "OnHold PERS", dumpPackage);
13453 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13455 if (mProcessCrashTimes.getMap().size() > 0) {
13456 boolean printed = false;
13457 long now = SystemClock.uptimeMillis();
13458 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13459 final int NP = pmap.size();
13460 for (int ip=0; ip<NP; ip++) {
13461 String pname = pmap.keyAt(ip);
13462 SparseArray<Long> uids = pmap.valueAt(ip);
13463 final int N = uids.size();
13464 for (int i=0; i<N; i++) {
13465 int puid = uids.keyAt(i);
13466 ProcessRecord r = mProcessNames.get(pname, puid);
13467 if (dumpPackage != null && (r == null
13468 || !r.pkgList.containsKey(dumpPackage))) {
13472 if (needSep) pw.println();
13474 pw.println(" Time since processes crashed:");
13476 printedAnything = true;
13478 pw.print(" Process "); pw.print(pname);
13479 pw.print(" uid "); pw.print(puid);
13480 pw.print(": last crashed ");
13481 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13482 pw.println(" ago");
13487 if (mBadProcesses.getMap().size() > 0) {
13488 boolean printed = false;
13489 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13490 final int NP = pmap.size();
13491 for (int ip=0; ip<NP; ip++) {
13492 String pname = pmap.keyAt(ip);
13493 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13494 final int N = uids.size();
13495 for (int i=0; i<N; i++) {
13496 int puid = uids.keyAt(i);
13497 ProcessRecord r = mProcessNames.get(pname, puid);
13498 if (dumpPackage != null && (r == null
13499 || !r.pkgList.containsKey(dumpPackage))) {
13503 if (needSep) pw.println();
13505 pw.println(" Bad processes:");
13506 printedAnything = true;
13508 BadProcessInfo info = uids.valueAt(i);
13509 pw.print(" Bad process "); pw.print(pname);
13510 pw.print(" uid "); pw.print(puid);
13511 pw.print(": crashed at time "); pw.println(info.time);
13512 if (info.shortMsg != null) {
13513 pw.print(" Short msg: "); pw.println(info.shortMsg);
13515 if (info.longMsg != null) {
13516 pw.print(" Long msg: "); pw.println(info.longMsg);
13518 if (info.stack != null) {
13519 pw.println(" Stack:");
13521 for (int pos=0; pos<info.stack.length(); pos++) {
13522 if (info.stack.charAt(pos) == '\n') {
13524 pw.write(info.stack, lastPos, pos-lastPos);
13529 if (lastPos < info.stack.length()) {
13531 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13539 if (dumpPackage == null) {
13542 pw.println(" mStartedUsers:");
13543 for (int i=0; i<mStartedUsers.size(); i++) {
13544 UserState uss = mStartedUsers.valueAt(i);
13545 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
13546 pw.print(": "); uss.dump("", pw);
13548 pw.print(" mStartedUserArray: [");
13549 for (int i=0; i<mStartedUserArray.length; i++) {
13550 if (i > 0) pw.print(", ");
13551 pw.print(mStartedUserArray[i]);
13554 pw.print(" mUserLru: [");
13555 for (int i=0; i<mUserLru.size(); i++) {
13556 if (i > 0) pw.print(", ");
13557 pw.print(mUserLru.get(i));
13561 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13563 synchronized (mUserProfileGroupIdsSelfLocked) {
13564 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13565 pw.println(" mUserProfileGroupIds:");
13566 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13567 pw.print(" User #");
13568 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13569 pw.print(" -> profile #");
13570 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13575 if (mHomeProcess != null && (dumpPackage == null
13576 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13581 pw.println(" mHomeProcess: " + mHomeProcess);
13583 if (mPreviousProcess != null && (dumpPackage == null
13584 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13589 pw.println(" mPreviousProcess: " + mPreviousProcess);
13592 StringBuilder sb = new StringBuilder(128);
13593 sb.append(" mPreviousProcessVisibleTime: ");
13594 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13597 if (mHeavyWeightProcess != null && (dumpPackage == null
13598 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13603 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13605 if (dumpPackage == null) {
13606 pw.println(" mConfiguration: " + mConfiguration);
13609 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13610 if (mCompatModePackages.getPackages().size() > 0) {
13611 boolean printed = false;
13612 for (Map.Entry<String, Integer> entry
13613 : mCompatModePackages.getPackages().entrySet()) {
13614 String pkg = entry.getKey();
13615 int mode = entry.getValue();
13616 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13620 pw.println(" mScreenCompatPackages:");
13623 pw.print(" "); pw.print(pkg); pw.print(": ");
13624 pw.print(mode); pw.println();
13628 if (dumpPackage == null) {
13629 pw.println(" mWakefulness="
13630 + PowerManagerInternal.wakefulnessToString(mWakefulness));
13631 pw.println(" mSleepTokens=" + mSleepTokens);
13632 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
13633 + lockScreenShownToString());
13634 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13635 if (mRunningVoice != null) {
13636 pw.println(" mRunningVoice=" + mRunningVoice);
13637 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
13640 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13641 || mOrigWaitForDebugger) {
13642 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13643 || dumpPackage.equals(mOrigDebugApp)) {
13648 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13649 + " mDebugTransient=" + mDebugTransient
13650 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13653 if (mCurAppTimeTracker != null) {
13654 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
13656 if (mMemWatchProcesses.getMap().size() > 0) {
13657 pw.println(" Mem watch processes:");
13658 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13659 = mMemWatchProcesses.getMap();
13660 for (int i=0; i<procs.size(); i++) {
13661 final String proc = procs.keyAt(i);
13662 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13663 for (int j=0; j<uids.size(); j++) {
13668 StringBuilder sb = new StringBuilder();
13669 sb.append(" ").append(proc).append('/');
13670 UserHandle.formatUid(sb, uids.keyAt(j));
13671 Pair<Long, String> val = uids.valueAt(j);
13672 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13673 if (val.second != null) {
13674 sb.append(", report to ").append(val.second);
13676 pw.println(sb.toString());
13679 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13680 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13681 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13682 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13684 if (mOpenGlTraceApp != null) {
13685 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13690 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
13693 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13694 || mProfileFd != null) {
13695 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13700 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13701 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13702 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13703 + mAutoStopProfiler);
13704 pw.println(" mProfileType=" + mProfileType);
13707 if (dumpPackage == null) {
13708 if (mAlwaysFinishActivities || mController != null) {
13709 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
13710 + " mController=" + mController);
13713 pw.println(" Total persistent processes: " + numPers);
13714 pw.println(" mProcessesReady=" + mProcessesReady
13715 + " mSystemReady=" + mSystemReady
13716 + " mBooted=" + mBooted
13717 + " mFactoryTest=" + mFactoryTest);
13718 pw.println(" mBooting=" + mBooting
13719 + " mCallFinishBooting=" + mCallFinishBooting
13720 + " mBootAnimationComplete=" + mBootAnimationComplete);
13721 pw.print(" mLastPowerCheckRealtime=");
13722 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13724 pw.print(" mLastPowerCheckUptime=");
13725 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13727 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13728 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13729 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13730 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
13731 + " (" + mLruProcesses.size() + " total)"
13732 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13733 + " mNumServiceProcs=" + mNumServiceProcs
13734 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13735 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
13736 + " mLastMemoryLevel" + mLastMemoryLevel
13737 + " mLastNumProcesses" + mLastNumProcesses);
13738 long now = SystemClock.uptimeMillis();
13739 pw.print(" mLastIdleTime=");
13740 TimeUtils.formatDuration(now, mLastIdleTime, pw);
13741 pw.print(" mLowRamSinceLastIdle=");
13742 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13747 if (!printedAnything) {
13748 pw.println(" (nothing)");
13752 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13753 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13754 if (mProcessesToGc.size() > 0) {
13755 boolean printed = false;
13756 long now = SystemClock.uptimeMillis();
13757 for (int i=0; i<mProcessesToGc.size(); i++) {
13758 ProcessRecord proc = mProcessesToGc.get(i);
13759 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13763 if (needSep) pw.println();
13765 pw.println(" Processes that are waiting to GC:");
13768 pw.print(" Process "); pw.println(proc);
13769 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
13770 pw.print(", last gced=");
13771 pw.print(now-proc.lastRequestedGc);
13772 pw.print(" ms ago, last lowMem=");
13773 pw.print(now-proc.lastLowMemory);
13774 pw.println(" ms ago");
13781 void printOomLevel(PrintWriter pw, String name, int adj) {
13785 if (adj < 10) pw.print(' ');
13787 if (adj > -10) pw.print(' ');
13793 pw.print(mProcessList.getMemLevel(adj)/1024);
13794 pw.println(" kB)");
13797 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13798 int opti, boolean dumpAll) {
13799 boolean needSep = false;
13801 if (mLruProcesses.size() > 0) {
13802 if (needSep) pw.println();
13804 pw.println(" OOM levels:");
13805 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13806 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13807 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13808 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13809 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13810 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13811 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13812 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13813 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13814 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13815 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13816 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13817 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13818 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13820 if (needSep) pw.println();
13821 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
13822 pw.print(" total, non-act at ");
13823 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13824 pw.print(", non-svc at ");
13825 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13827 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
13831 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13834 pw.println(" mHomeProcess: " + mHomeProcess);
13835 pw.println(" mPreviousProcess: " + mPreviousProcess);
13836 if (mHeavyWeightProcess != null) {
13837 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13844 * There are three ways to call this:
13845 * - no provider specified: dump all the providers
13846 * - a flattened component name that matched an existing provider was specified as the
13847 * first arg: dump that one provider
13848 * - the first arg isn't the flattened component name of an existing provider:
13849 * dump all providers whose component contains the first arg as a substring
13851 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13852 int opti, boolean dumpAll) {
13853 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13856 static class ItemMatcher {
13857 ArrayList<ComponentName> components;
13858 ArrayList<String> strings;
13859 ArrayList<Integer> objects;
13866 void build(String name) {
13867 ComponentName componentName = ComponentName.unflattenFromString(name);
13868 if (componentName != null) {
13869 if (components == null) {
13870 components = new ArrayList<ComponentName>();
13872 components.add(componentName);
13876 // Not a '/' separated full component name; maybe an object ID?
13878 objectId = Integer.parseInt(name, 16);
13879 if (objects == null) {
13880 objects = new ArrayList<Integer>();
13882 objects.add(objectId);
13884 } catch (RuntimeException e) {
13885 // Not an integer; just do string match.
13886 if (strings == null) {
13887 strings = new ArrayList<String>();
13895 int build(String[] args, int opti) {
13896 for (; opti<args.length; opti++) {
13897 String name = args[opti];
13898 if ("--".equals(name)) {
13906 boolean match(Object object, ComponentName comp) {
13910 if (components != null) {
13911 for (int i=0; i<components.size(); i++) {
13912 if (components.get(i).equals(comp)) {
13917 if (objects != null) {
13918 for (int i=0; i<objects.size(); i++) {
13919 if (System.identityHashCode(object) == objects.get(i)) {
13924 if (strings != null) {
13925 String flat = comp.flattenToString();
13926 for (int i=0; i<strings.size(); i++) {
13927 if (flat.contains(strings.get(i))) {
13937 * There are three things that cmd can be:
13938 * - a flattened component name that matches an existing activity
13939 * - the cmd arg isn't the flattened component name of an existing activity:
13940 * dump all activity whose component contains the cmd as a substring
13941 * - A hex number of the ActivityRecord object instance.
13943 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13944 int opti, boolean dumpAll) {
13945 ArrayList<ActivityRecord> activities;
13947 synchronized (this) {
13948 activities = mStackSupervisor.getDumpActivitiesLocked(name);
13951 if (activities.size() <= 0) {
13955 String[] newArgs = new String[args.length - opti];
13956 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13958 TaskRecord lastTask = null;
13959 boolean needSep = false;
13960 for (int i=activities.size()-1; i>=0; i--) {
13961 ActivityRecord r = activities.get(i);
13966 synchronized (this) {
13967 if (lastTask != r.task) {
13969 pw.print("TASK "); pw.print(lastTask.affinity);
13970 pw.print(" id="); pw.println(lastTask.taskId);
13972 lastTask.dump(pw, " ");
13976 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
13982 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13983 * there is a thread associated with the activity.
13985 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13986 final ActivityRecord r, String[] args, boolean dumpAll) {
13987 String innerPrefix = prefix + " ";
13988 synchronized (this) {
13989 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13990 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13992 if (r.app != null) pw.println(r.app.pid);
13993 else pw.println("(not running)");
13995 r.dump(pw, innerPrefix);
13998 if (r.app != null && r.app.thread != null) {
13999 // flush anything that is already in the PrintWriter since the thread is going
14000 // to write to the file descriptor directly
14003 TransferPipe tp = new TransferPipe();
14005 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14006 r.appToken, innerPrefix, args);
14011 } catch (IOException e) {
14012 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14013 } catch (RemoteException e) {
14014 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14019 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14020 int opti, boolean dumpAll, String dumpPackage) {
14021 boolean needSep = false;
14022 boolean onlyHistory = false;
14023 boolean printedAnything = false;
14025 if ("history".equals(dumpPackage)) {
14026 if (opti < args.length && "-s".equals(args[opti])) {
14029 onlyHistory = true;
14030 dumpPackage = null;
14033 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14034 if (!onlyHistory && dumpAll) {
14035 if (mRegisteredReceivers.size() > 0) {
14036 boolean printed = false;
14037 Iterator it = mRegisteredReceivers.values().iterator();
14038 while (it.hasNext()) {
14039 ReceiverList r = (ReceiverList)it.next();
14040 if (dumpPackage != null && (r.app == null ||
14041 !dumpPackage.equals(r.app.info.packageName))) {
14045 pw.println(" Registered Receivers:");
14048 printedAnything = true;
14050 pw.print(" * "); pw.println(r);
14055 if (mReceiverResolver.dump(pw, needSep ?
14056 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
14057 " ", dumpPackage, false, false)) {
14059 printedAnything = true;
14063 for (BroadcastQueue q : mBroadcastQueues) {
14064 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14065 printedAnything |= needSep;
14070 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14071 for (int user=0; user<mStickyBroadcasts.size(); user++) {
14076 printedAnything = true;
14077 pw.print(" Sticky broadcasts for user ");
14078 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14079 StringBuilder sb = new StringBuilder(128);
14080 for (Map.Entry<String, ArrayList<Intent>> ent
14081 : mStickyBroadcasts.valueAt(user).entrySet()) {
14082 pw.print(" * Sticky action "); pw.print(ent.getKey());
14085 ArrayList<Intent> intents = ent.getValue();
14086 final int N = intents.size();
14087 for (int i=0; i<N; i++) {
14089 sb.append(" Intent: ");
14090 intents.get(i).toShortString(sb, false, true, false, false);
14091 pw.println(sb.toString());
14092 Bundle bundle = intents.get(i).getExtras();
14093 if (bundle != null) {
14095 pw.println(bundle.toString());
14105 if (!onlyHistory && dumpAll) {
14107 for (BroadcastQueue queue : mBroadcastQueues) {
14108 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
14109 + queue.mBroadcastsScheduled);
14111 pw.println(" mHandler:");
14112 mHandler.dump(new PrintWriterPrinter(pw), " ");
14114 printedAnything = true;
14117 if (!printedAnything) {
14118 pw.println(" (nothing)");
14122 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14123 int opti, boolean dumpAll, String dumpPackage) {
14125 boolean printedAnything = false;
14127 ItemMatcher matcher = new ItemMatcher();
14128 matcher.build(args, opti);
14130 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14132 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14133 printedAnything |= needSep;
14135 if (mLaunchingProviders.size() > 0) {
14136 boolean printed = false;
14137 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14138 ContentProviderRecord r = mLaunchingProviders.get(i);
14139 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14143 if (needSep) pw.println();
14145 pw.println(" Launching content providers:");
14147 printedAnything = true;
14149 pw.print(" Launching #"); pw.print(i); pw.print(": ");
14154 if (!printedAnything) {
14155 pw.println(" (nothing)");
14159 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14160 int opti, boolean dumpAll, String dumpPackage) {
14161 boolean needSep = false;
14162 boolean printedAnything = false;
14164 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14166 if (mGrantedUriPermissions.size() > 0) {
14167 boolean printed = false;
14169 if (dumpPackage != null) {
14171 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14172 } catch (NameNotFoundException e) {
14176 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14177 int uid = mGrantedUriPermissions.keyAt(i);
14178 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14181 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14183 if (needSep) pw.println();
14185 pw.println(" Granted Uri Permissions:");
14187 printedAnything = true;
14189 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
14190 for (UriPermission perm : perms.values()) {
14191 pw.print(" "); pw.println(perm);
14193 perm.dump(pw, " ");
14199 if (!printedAnything) {
14200 pw.println(" (nothing)");
14204 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14205 int opti, boolean dumpAll, String dumpPackage) {
14206 boolean printed = false;
14208 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14210 if (mIntentSenderRecords.size() > 0) {
14211 Iterator<WeakReference<PendingIntentRecord>> it
14212 = mIntentSenderRecords.values().iterator();
14213 while (it.hasNext()) {
14214 WeakReference<PendingIntentRecord> ref = it.next();
14215 PendingIntentRecord rec = ref != null ? ref.get(): null;
14216 if (dumpPackage != null && (rec == null
14217 || !dumpPackage.equals(rec.key.packageName))) {
14222 pw.print(" * "); pw.println(rec);
14227 pw.print(" * "); pw.println(ref);
14233 pw.println(" (nothing)");
14237 private static final int dumpProcessList(PrintWriter pw,
14238 ActivityManagerService service, List list,
14239 String prefix, String normalLabel, String persistentLabel,
14240 String dumpPackage) {
14242 final int N = list.size()-1;
14243 for (int i=N; i>=0; i--) {
14244 ProcessRecord r = (ProcessRecord)list.get(i);
14245 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14248 pw.println(String.format("%s%s #%2d: %s",
14249 prefix, (r.persistent ? persistentLabel : normalLabel),
14251 if (r.persistent) {
14258 private static final boolean dumpProcessOomList(PrintWriter pw,
14259 ActivityManagerService service, List<ProcessRecord> origList,
14260 String prefix, String normalLabel, String persistentLabel,
14261 boolean inclDetails, String dumpPackage) {
14263 ArrayList<Pair<ProcessRecord, Integer>> list
14264 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14265 for (int i=0; i<origList.size(); i++) {
14266 ProcessRecord r = origList.get(i);
14267 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14270 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14273 if (list.size() <= 0) {
14277 Comparator<Pair<ProcessRecord, Integer>> comparator
14278 = new Comparator<Pair<ProcessRecord, Integer>>() {
14280 public int compare(Pair<ProcessRecord, Integer> object1,
14281 Pair<ProcessRecord, Integer> object2) {
14282 if (object1.first.setAdj != object2.first.setAdj) {
14283 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14285 if (object1.second.intValue() != object2.second.intValue()) {
14286 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14292 Collections.sort(list, comparator);
14294 final long curRealtime = SystemClock.elapsedRealtime();
14295 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14296 final long curUptime = SystemClock.uptimeMillis();
14297 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14299 for (int i=list.size()-1; i>=0; i--) {
14300 ProcessRecord r = list.get(i).first;
14301 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14303 switch (r.setSchedGroup) {
14304 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14307 case Process.THREAD_GROUP_DEFAULT:
14315 if (r.foregroundActivities) {
14317 } else if (r.foregroundServices) {
14322 String procState = ProcessList.makeProcStateString(r.curProcState);
14324 pw.print(r.persistent ? persistentLabel : normalLabel);
14326 int num = (origList.size()-1)-list.get(i).second;
14327 if (num < 10) pw.print(' ');
14332 pw.print(schedGroup);
14334 pw.print(foreground);
14336 pw.print(procState);
14338 if (r.trimMemoryLevel < 10) pw.print(' ');
14339 pw.print(r.trimMemoryLevel);
14341 pw.print(r.toShortString());
14343 pw.print(r.adjType);
14345 if (r.adjSource != null || r.adjTarget != null) {
14348 if (r.adjTarget instanceof ComponentName) {
14349 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14350 } else if (r.adjTarget != null) {
14351 pw.print(r.adjTarget.toString());
14353 pw.print("{null}");
14356 if (r.adjSource instanceof ProcessRecord) {
14358 pw.print(((ProcessRecord)r.adjSource).toShortString());
14360 } else if (r.adjSource != null) {
14361 pw.println(r.adjSource.toString());
14363 pw.println("{null}");
14369 pw.print("oom: max="); pw.print(r.maxAdj);
14370 pw.print(" curRaw="); pw.print(r.curRawAdj);
14371 pw.print(" setRaw="); pw.print(r.setRawAdj);
14372 pw.print(" cur="); pw.print(r.curAdj);
14373 pw.print(" set="); pw.println(r.setAdj);
14376 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14377 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14378 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14379 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14383 pw.print("cached="); pw.print(r.cached);
14384 pw.print(" empty="); pw.print(r.empty);
14385 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14387 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14388 if (r.lastWakeTime != 0) {
14390 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14391 synchronized (stats) {
14392 wtime = stats.getProcessWakeTime(r.info.uid,
14393 r.pid, curRealtime);
14395 long timeUsed = wtime - r.lastWakeTime;
14398 pw.print("keep awake over ");
14399 TimeUtils.formatDuration(realtimeSince, pw);
14400 pw.print(" used ");
14401 TimeUtils.formatDuration(timeUsed, pw);
14403 pw.print((timeUsed*100)/realtimeSince);
14406 if (r.lastCpuTime != 0) {
14407 long timeUsed = r.curCpuTime - r.lastCpuTime;
14410 pw.print("run cpu over ");
14411 TimeUtils.formatDuration(uptimeSince, pw);
14412 pw.print(" used ");
14413 TimeUtils.formatDuration(timeUsed, pw);
14415 pw.print((timeUsed*100)/uptimeSince);
14424 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14426 ArrayList<ProcessRecord> procs;
14427 synchronized (this) {
14428 if (args != null && args.length > start
14429 && args[start].charAt(0) != '-') {
14430 procs = new ArrayList<ProcessRecord>();
14433 pid = Integer.parseInt(args[start]);
14434 } catch (NumberFormatException e) {
14436 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14437 ProcessRecord proc = mLruProcesses.get(i);
14438 if (proc.pid == pid) {
14440 } else if (allPkgs && proc.pkgList != null
14441 && proc.pkgList.containsKey(args[start])) {
14443 } else if (proc.processName.equals(args[start])) {
14447 if (procs.size() <= 0) {
14451 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14457 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14458 PrintWriter pw, String[] args) {
14459 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14460 if (procs == null) {
14461 pw.println("No process found for: " + args[0]);
14465 long uptime = SystemClock.uptimeMillis();
14466 long realtime = SystemClock.elapsedRealtime();
14467 pw.println("Applications Graphics Acceleration Info:");
14468 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14470 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14471 ProcessRecord r = procs.get(i);
14472 if (r.thread != null) {
14473 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14476 TransferPipe tp = new TransferPipe();
14478 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14483 } catch (IOException e) {
14484 pw.println("Failure while dumping the app: " + r);
14486 } catch (RemoteException e) {
14487 pw.println("Got a RemoteException while dumping the app " + r);
14494 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14495 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14496 if (procs == null) {
14497 pw.println("No process found for: " + args[0]);
14501 pw.println("Applications Database Info:");
14503 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14504 ProcessRecord r = procs.get(i);
14505 if (r.thread != null) {
14506 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14509 TransferPipe tp = new TransferPipe();
14511 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14516 } catch (IOException e) {
14517 pw.println("Failure while dumping the app: " + r);
14519 } catch (RemoteException e) {
14520 pw.println("Got a RemoteException while dumping the app " + r);
14527 final static class MemItem {
14528 final boolean isProc;
14529 final String label;
14530 final String shortLabel;
14533 final boolean hasActivities;
14534 ArrayList<MemItem> subitems;
14536 public MemItem(String _label, String _shortLabel, long _pss, int _id,
14537 boolean _hasActivities) {
14540 shortLabel = _shortLabel;
14543 hasActivities = _hasActivities;
14546 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14549 shortLabel = _shortLabel;
14552 hasActivities = false;
14556 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14557 ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14558 if (sort && !isCompact) {
14559 Collections.sort(items, new Comparator<MemItem>() {
14561 public int compare(MemItem lhs, MemItem rhs) {
14562 if (lhs.pss < rhs.pss) {
14564 } else if (lhs.pss > rhs.pss) {
14572 for (int i=0; i<items.size(); i++) {
14573 MemItem mi = items.get(i);
14575 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14576 } else if (mi.isProc) {
14577 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14578 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14579 pw.println(mi.hasActivities ? ",a" : ",e");
14581 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14582 pw.println(mi.pss);
14584 if (mi.subitems != null) {
14585 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
14591 // These are in KB.
14592 static final long[] DUMP_MEM_BUCKETS = new long[] {
14593 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14594 120*1024, 160*1024, 200*1024,
14595 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14596 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14599 static final void appendMemBucket(StringBuilder out, long memKB, String label,
14600 boolean stackLike) {
14601 int start = label.lastIndexOf('.');
14602 if (start >= 0) start++;
14604 int end = label.length();
14605 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14606 if (DUMP_MEM_BUCKETS[i] >= memKB) {
14607 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14608 out.append(bucket);
14609 out.append(stackLike ? "MB." : "MB ");
14610 out.append(label, start, end);
14614 out.append(memKB/1024);
14615 out.append(stackLike ? "MB." : "MB ");
14616 out.append(label, start, end);
14619 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14620 ProcessList.NATIVE_ADJ,
14621 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14622 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14623 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14624 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14625 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14626 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14628 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14630 "System", "Persistent", "Persistent Service", "Foreground",
14631 "Visible", "Perceptible",
14632 "Heavy Weight", "Backup",
14633 "A Services", "Home",
14634 "Previous", "B Services", "Cached"
14636 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14638 "sys", "pers", "persvc", "fore",
14641 "servicea", "home",
14642 "prev", "serviceb", "cached"
14645 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14646 long realtime, boolean isCheckinRequest, boolean isCompact) {
14647 if (isCheckinRequest || isCompact) {
14648 // short checkin version
14649 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14651 pw.println("Applications Memory Usage (kB):");
14652 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14656 private static final int KSM_SHARED = 0;
14657 private static final int KSM_SHARING = 1;
14658 private static final int KSM_UNSHARED = 2;
14659 private static final int KSM_VOLATILE = 3;
14661 private final long[] getKsmInfo() {
14662 long[] longOut = new long[4];
14663 final int[] SINGLE_LONG_FORMAT = new int[] {
14664 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14666 long[] longTmp = new long[1];
14667 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14668 SINGLE_LONG_FORMAT, null, longTmp, null);
14669 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14671 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14672 SINGLE_LONG_FORMAT, null, longTmp, null);
14673 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14675 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14676 SINGLE_LONG_FORMAT, null, longTmp, null);
14677 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14679 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14680 SINGLE_LONG_FORMAT, null, longTmp, null);
14681 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14685 final void dumpApplicationMemoryUsage(FileDescriptor fd,
14686 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14687 boolean dumpDetails = false;
14688 boolean dumpFullDetails = false;
14689 boolean dumpDalvik = false;
14690 boolean dumpSummaryOnly = false;
14691 boolean oomOnly = false;
14692 boolean isCompact = false;
14693 boolean localOnly = false;
14694 boolean packages = false;
14697 while (opti < args.length) {
14698 String opt = args[opti];
14699 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14703 if ("-a".equals(opt)) {
14704 dumpDetails = true;
14705 dumpFullDetails = true;
14707 } else if ("-d".equals(opt)) {
14709 } else if ("-c".equals(opt)) {
14711 } else if ("-s".equals(opt)) {
14712 dumpDetails = true;
14713 dumpSummaryOnly = true;
14714 } else if ("--oom".equals(opt)) {
14716 } else if ("--local".equals(opt)) {
14718 } else if ("--package".equals(opt)) {
14720 } else if ("-h".equals(opt)) {
14721 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14722 pw.println(" -a: include all available information for each process.");
14723 pw.println(" -d: include dalvik details.");
14724 pw.println(" -c: dump in a compact machine-parseable representation.");
14725 pw.println(" -s: dump only summary of application memory usage.");
14726 pw.println(" --oom: only show processes organized by oom adj.");
14727 pw.println(" --local: only collect details locally, don't call process.");
14728 pw.println(" --package: interpret process arg as package, dumping all");
14729 pw.println(" processes that have loaded that package.");
14730 pw.println("If [process] is specified it can be the name or ");
14731 pw.println("pid of a specific process to dump.");
14734 pw.println("Unknown argument: " + opt + "; use -h for help");
14738 final boolean isCheckinRequest = scanArgs(args, "--checkin");
14739 long uptime = SystemClock.uptimeMillis();
14740 long realtime = SystemClock.elapsedRealtime();
14741 final long[] tmpLong = new long[1];
14743 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14744 if (procs == null) {
14745 // No Java processes. Maybe they want to print a native process.
14746 if (args != null && args.length > opti
14747 && args[opti].charAt(0) != '-') {
14748 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14749 = new ArrayList<ProcessCpuTracker.Stats>();
14750 updateCpuStatsNow();
14753 findPid = Integer.parseInt(args[opti]);
14754 } catch (NumberFormatException e) {
14756 synchronized (mProcessCpuTracker) {
14757 final int N = mProcessCpuTracker.countStats();
14758 for (int i=0; i<N; i++) {
14759 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14760 if (st.pid == findPid || (st.baseName != null
14761 && st.baseName.equals(args[opti]))) {
14762 nativeProcs.add(st);
14766 if (nativeProcs.size() > 0) {
14767 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14769 Debug.MemoryInfo mi = null;
14770 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14771 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14772 final int pid = r.pid;
14773 if (!isCheckinRequest && dumpDetails) {
14774 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14777 mi = new Debug.MemoryInfo();
14779 if (dumpDetails || (!brief && !oomOnly)) {
14780 Debug.getMemoryInfo(pid, mi);
14782 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14783 mi.dalvikPrivateDirty = (int)tmpLong[0];
14785 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14786 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14787 if (isCheckinRequest) {
14794 pw.println("No process found for: " + args[opti]);
14798 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14799 dumpDetails = true;
14802 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14804 String[] innerArgs = new String[args.length-opti];
14805 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14807 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14808 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14809 long nativePss = 0;
14810 long dalvikPss = 0;
14811 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14814 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14816 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14817 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14818 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14821 long cachedPss = 0;
14823 Debug.MemoryInfo mi = null;
14824 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14825 final ProcessRecord r = procs.get(i);
14826 final IApplicationThread thread;
14829 final boolean hasActivities;
14830 synchronized (this) {
14833 oomAdj = r.getSetAdjWithServices();
14834 hasActivities = r.activities.size() > 0;
14836 if (thread != null) {
14837 if (!isCheckinRequest && dumpDetails) {
14838 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14841 mi = new Debug.MemoryInfo();
14843 if (dumpDetails || (!brief && !oomOnly)) {
14844 Debug.getMemoryInfo(pid, mi);
14846 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14847 mi.dalvikPrivateDirty = (int)tmpLong[0];
14851 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14852 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14853 if (isCheckinRequest) {
14859 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14860 dumpDalvik, dumpSummaryOnly, innerArgs);
14861 } catch (RemoteException e) {
14862 if (!isCheckinRequest) {
14863 pw.println("Got RemoteException!");
14870 final long myTotalPss = mi.getTotalPss();
14871 final long myTotalUss = mi.getTotalUss();
14873 synchronized (this) {
14874 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14875 // Record this for posterity if the process has been stable.
14876 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14880 if (!isCheckinRequest && mi != null) {
14881 totalPss += myTotalPss;
14882 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14883 (hasActivities ? " / activities)" : ")"),
14884 r.processName, myTotalPss, pid, hasActivities);
14885 procMems.add(pssItem);
14886 procMemsMap.put(pid, pssItem);
14888 nativePss += mi.nativePss;
14889 dalvikPss += mi.dalvikPss;
14890 for (int j=0; j<dalvikSubitemPss.length; j++) {
14891 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14893 otherPss += mi.otherPss;
14894 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14895 long mem = mi.getOtherPss(j);
14900 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14901 cachedPss += myTotalPss;
14904 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14905 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14906 || oomIndex == (oomPss.length-1)) {
14907 oomPss[oomIndex] += myTotalPss;
14908 if (oomProcs[oomIndex] == null) {
14909 oomProcs[oomIndex] = new ArrayList<MemItem>();
14911 oomProcs[oomIndex].add(pssItem);
14919 long nativeProcTotalPss = 0;
14921 if (!isCheckinRequest && procs.size() > 1 && !packages) {
14922 // If we are showing aggregations, also look for native processes to
14923 // include so that our aggregations are more accurate.
14924 updateCpuStatsNow();
14926 synchronized (mProcessCpuTracker) {
14927 final int N = mProcessCpuTracker.countStats();
14928 for (int i=0; i<N; i++) {
14929 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14930 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14932 mi = new Debug.MemoryInfo();
14934 if (!brief && !oomOnly) {
14935 Debug.getMemoryInfo(st.pid, mi);
14937 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14938 mi.nativePrivateDirty = (int)tmpLong[0];
14941 final long myTotalPss = mi.getTotalPss();
14942 totalPss += myTotalPss;
14943 nativeProcTotalPss += myTotalPss;
14945 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14946 st.name, myTotalPss, st.pid, false);
14947 procMems.add(pssItem);
14949 nativePss += mi.nativePss;
14950 dalvikPss += mi.dalvikPss;
14951 for (int j=0; j<dalvikSubitemPss.length; j++) {
14952 dalvikSubitemPss[j] += mi.getOtherPss(
14953 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14955 otherPss += mi.otherPss;
14956 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14957 long mem = mi.getOtherPss(j);
14961 oomPss[0] += myTotalPss;
14962 if (oomProcs[0] == null) {
14963 oomProcs[0] = new ArrayList<MemItem>();
14965 oomProcs[0].add(pssItem);
14970 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14972 catMems.add(new MemItem("Native", "Native", nativePss, -1));
14973 final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14974 if (dalvikSubitemPss.length > 0) {
14975 dalvikItem.subitems = new ArrayList<MemItem>();
14976 for (int j=0; j<dalvikSubitemPss.length; j++) {
14977 final String name = Debug.MemoryInfo.getOtherLabel(
14978 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14979 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14982 catMems.add(dalvikItem);
14983 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14984 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14985 String label = Debug.MemoryInfo.getOtherLabel(j);
14986 catMems.add(new MemItem(label, label, miscPss[j], j));
14989 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14990 for (int j=0; j<oomPss.length; j++) {
14991 if (oomPss[j] != 0) {
14992 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14993 : DUMP_MEM_OOM_LABEL[j];
14994 MemItem item = new MemItem(label, label, oomPss[j],
14995 DUMP_MEM_OOM_ADJ[j]);
14996 item.subitems = oomProcs[j];
15001 if (!brief && !oomOnly && !isCompact) {
15003 pw.println("Total PSS by process:");
15004 dumpMemItems(pw, " ", "proc", procMems, true, isCompact);
15008 pw.println("Total PSS by OOM adjustment:");
15010 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact);
15011 if (!brief && !oomOnly) {
15012 PrintWriter out = categoryPw != null ? categoryPw : pw;
15015 out.println("Total PSS by category:");
15017 dumpMemItems(out, " ", "cat", catMems, true, isCompact);
15022 MemInfoReader memInfo = new MemInfoReader();
15023 memInfo.readMemInfo();
15024 if (nativeProcTotalPss > 0) {
15025 synchronized (this) {
15026 final long cachedKb = memInfo.getCachedSizeKb();
15027 final long freeKb = memInfo.getFreeSizeKb();
15028 final long zramKb = memInfo.getZramTotalSizeKb();
15029 final long kernelKb = memInfo.getKernelUsedSizeKb();
15030 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15031 kernelKb*1024, nativeProcTotalPss*1024);
15032 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15033 nativeProcTotalPss);
15038 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
15039 pw.print(" kB (status ");
15040 switch (mLastMemoryLevel) {
15041 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15042 pw.println("normal)");
15044 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15045 pw.println("moderate)");
15047 case ProcessStats.ADJ_MEM_FACTOR_LOW:
15048 pw.println("low)");
15050 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15051 pw.println("critical)");
15054 pw.print(mLastMemoryLevel);
15058 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
15059 + memInfo.getFreeSizeKb()); pw.print(" kB (");
15060 pw.print(cachedPss); pw.print(" cached pss + ");
15061 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
15062 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
15064 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15065 pw.print(cachedPss + memInfo.getCachedSizeKb()
15066 + memInfo.getFreeSizeKb()); pw.print(",");
15067 pw.println(totalPss - cachedPss);
15071 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15072 + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15073 pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15074 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15075 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15076 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15077 - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15080 if (memInfo.getZramTotalSizeKb() != 0) {
15082 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15083 pw.print(" kB physical used for ");
15084 pw.print(memInfo.getSwapTotalSizeKb()
15085 - memInfo.getSwapFreeSizeKb());
15086 pw.print(" kB in swap (");
15087 pw.print(memInfo.getSwapTotalSizeKb());
15088 pw.println(" kB total swap)");
15090 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15091 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15092 pw.println(memInfo.getSwapFreeSizeKb());
15095 final long[] ksm = getKsmInfo();
15097 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15098 || ksm[KSM_VOLATILE] != 0) {
15099 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]);
15100 pw.print(" kB saved from shared ");
15101 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15102 pw.print(" "); pw.print(ksm[KSM_UNSHARED]);
15103 pw.print(" kB unshared; ");
15104 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15106 pw.print(" Tuning: ");
15107 pw.print(ActivityManager.staticGetMemoryClass());
15108 pw.print(" (large ");
15109 pw.print(ActivityManager.staticGetLargeMemoryClass());
15110 pw.print("), oom ");
15111 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15113 pw.print(", restore limit ");
15114 pw.print(mProcessList.getCachedRestoreThresholdKb());
15116 if (ActivityManager.isLowRamDeviceStatic()) {
15117 pw.print(" (low-ram)");
15119 if (ActivityManager.isHighEndGfx()) {
15120 pw.print(" (high-end-gfx)");
15124 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15125 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15126 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15127 pw.print("tuning,");
15128 pw.print(ActivityManager.staticGetMemoryClass());
15130 pw.print(ActivityManager.staticGetLargeMemoryClass());
15132 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15133 if (ActivityManager.isLowRamDeviceStatic()) {
15134 pw.print(",low-ram");
15136 if (ActivityManager.isHighEndGfx()) {
15137 pw.print(",high-end-gfx");
15145 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15146 long memtrack, String name) {
15148 sb.append(ProcessList.makeOomAdjString(oomAdj));
15150 sb.append(ProcessList.makeProcStateString(procState));
15152 ProcessList.appendRamKb(sb, pss);
15153 sb.append(" kB: ");
15155 if (memtrack > 0) {
15157 sb.append(memtrack);
15158 sb.append(" kB memtrack)");
15162 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15163 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15164 sb.append(" (pid ");
15167 sb.append(mi.adjType);
15169 if (mi.adjReason != null) {
15171 sb.append(mi.adjReason);
15176 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15177 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15178 for (int i=0, N=memInfos.size(); i<N; i++) {
15179 ProcessMemInfo mi = memInfos.get(i);
15180 infoMap.put(mi.pid, mi);
15182 updateCpuStatsNow();
15183 long[] memtrackTmp = new long[1];
15184 synchronized (mProcessCpuTracker) {
15185 final int N = mProcessCpuTracker.countStats();
15186 for (int i=0; i<N; i++) {
15187 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15188 if (st.vsize > 0) {
15189 long pss = Debug.getPss(st.pid, null, memtrackTmp);
15191 if (infoMap.indexOfKey(st.pid) < 0) {
15192 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15193 ProcessList.NATIVE_ADJ, -1, "native", null);
15195 mi.memtrack = memtrackTmp[0];
15204 long totalMemtrack = 0;
15205 for (int i=0, N=memInfos.size(); i<N; i++) {
15206 ProcessMemInfo mi = memInfos.get(i);
15208 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15209 mi.memtrack = memtrackTmp[0];
15211 totalPss += mi.pss;
15212 totalMemtrack += mi.memtrack;
15214 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15215 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15216 if (lhs.oomAdj != rhs.oomAdj) {
15217 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15219 if (lhs.pss != rhs.pss) {
15220 return lhs.pss < rhs.pss ? 1 : -1;
15226 StringBuilder tag = new StringBuilder(128);
15227 StringBuilder stack = new StringBuilder(128);
15228 tag.append("Low on memory -- ");
15229 appendMemBucket(tag, totalPss, "total", false);
15230 appendMemBucket(stack, totalPss, "total", true);
15232 StringBuilder fullNativeBuilder = new StringBuilder(1024);
15233 StringBuilder shortNativeBuilder = new StringBuilder(1024);
15234 StringBuilder fullJavaBuilder = new StringBuilder(1024);
15236 boolean firstLine = true;
15237 int lastOomAdj = Integer.MIN_VALUE;
15238 long extraNativeRam = 0;
15239 long extraNativeMemtrack = 0;
15240 long cachedPss = 0;
15241 for (int i=0, N=memInfos.size(); i<N; i++) {
15242 ProcessMemInfo mi = memInfos.get(i);
15244 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15245 cachedPss += mi.pss;
15248 if (mi.oomAdj != ProcessList.NATIVE_ADJ
15249 && (mi.oomAdj < ProcessList.SERVICE_ADJ
15250 || mi.oomAdj == ProcessList.HOME_APP_ADJ
15251 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15252 if (lastOomAdj != mi.oomAdj) {
15253 lastOomAdj = mi.oomAdj;
15254 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15257 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15262 stack.append("\n\t at ");
15270 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15271 appendMemBucket(tag, mi.pss, mi.name, false);
15273 appendMemBucket(stack, mi.pss, mi.name, true);
15274 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15275 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15277 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15278 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15279 stack.append(DUMP_MEM_OOM_LABEL[k]);
15281 stack.append(DUMP_MEM_OOM_ADJ[k]);
15288 appendMemInfo(fullNativeBuilder, mi);
15289 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15290 // The short form only has native processes that are >= 512K.
15291 if (mi.pss >= 512) {
15292 appendMemInfo(shortNativeBuilder, mi);
15294 extraNativeRam += mi.pss;
15295 extraNativeMemtrack += mi.memtrack;
15298 // Short form has all other details, but if we have collected RAM
15299 // from smaller native processes let's dump a summary of that.
15300 if (extraNativeRam > 0) {
15301 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15302 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15303 shortNativeBuilder.append('\n');
15304 extraNativeRam = 0;
15306 appendMemInfo(fullJavaBuilder, mi);
15310 fullJavaBuilder.append(" ");
15311 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15312 fullJavaBuilder.append(" kB: TOTAL");
15313 if (totalMemtrack > 0) {
15314 fullJavaBuilder.append(" (");
15315 fullJavaBuilder.append(totalMemtrack);
15316 fullJavaBuilder.append(" kB memtrack)");
15319 fullJavaBuilder.append("\n");
15321 MemInfoReader memInfo = new MemInfoReader();
15322 memInfo.readMemInfo();
15323 final long[] infos = memInfo.getRawInfo();
15325 StringBuilder memInfoBuilder = new StringBuilder(1024);
15326 Debug.getMemInfo(infos);
15327 memInfoBuilder.append(" MemInfo: ");
15328 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15329 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15330 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15331 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15332 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15333 memInfoBuilder.append(" ");
15334 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15335 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15336 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15337 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15338 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15339 memInfoBuilder.append(" ZRAM: ");
15340 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15341 memInfoBuilder.append(" kB RAM, ");
15342 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15343 memInfoBuilder.append(" kB swap total, ");
15344 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15345 memInfoBuilder.append(" kB swap free\n");
15347 final long[] ksm = getKsmInfo();
15348 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15349 || ksm[KSM_VOLATILE] != 0) {
15350 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15351 memInfoBuilder.append(" kB saved from shared ");
15352 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15353 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15354 memInfoBuilder.append(" kB unshared; ");
15355 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15357 memInfoBuilder.append(" Free RAM: ");
15358 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15359 + memInfo.getFreeSizeKb());
15360 memInfoBuilder.append(" kB\n");
15361 memInfoBuilder.append(" Used RAM: ");
15362 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15363 memInfoBuilder.append(" kB\n");
15364 memInfoBuilder.append(" Lost RAM: ");
15365 memInfoBuilder.append(memInfo.getTotalSizeKb()
15366 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15367 - memInfo.getKernelUsedSizeKb());
15368 memInfoBuilder.append(" kB\n");
15369 Slog.i(TAG, "Low on memory:");
15370 Slog.i(TAG, shortNativeBuilder.toString());
15371 Slog.i(TAG, fullJavaBuilder.toString());
15372 Slog.i(TAG, memInfoBuilder.toString());
15374 StringBuilder dropBuilder = new StringBuilder(1024);
15376 StringWriter oomSw = new StringWriter();
15377 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15378 StringWriter catSw = new StringWriter();
15379 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15380 String[] emptyArgs = new String[] { };
15381 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
15383 String oomString = oomSw.toString();
15385 dropBuilder.append("Low on memory:");
15386 dropBuilder.append(stack);
15387 dropBuilder.append('\n');
15388 dropBuilder.append(fullNativeBuilder);
15389 dropBuilder.append(fullJavaBuilder);
15390 dropBuilder.append('\n');
15391 dropBuilder.append(memInfoBuilder);
15392 dropBuilder.append('\n');
15394 dropBuilder.append(oomString);
15395 dropBuilder.append('\n');
15397 StringWriter catSw = new StringWriter();
15398 synchronized (ActivityManagerService.this) {
15399 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15400 String[] emptyArgs = new String[] { };
15402 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15404 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15405 false, false, null);
15407 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15410 dropBuilder.append(catSw.toString());
15411 addErrorToDropBox("lowmem", null, "system_server", null,
15412 null, tag.toString(), dropBuilder.toString(), null, null);
15413 //Slog.i(TAG, "Sent to dropbox:");
15414 //Slog.i(TAG, dropBuilder.toString());
15415 synchronized (ActivityManagerService.this) {
15416 long now = SystemClock.uptimeMillis();
15417 if (mLastMemUsageReportTime < now) {
15418 mLastMemUsageReportTime = now;
15424 * Searches array of arguments for the specified string
15425 * @param args array of argument strings
15426 * @param value value to search for
15427 * @return true if the value is contained in the array
15429 private static boolean scanArgs(String[] args, String value) {
15430 if (args != null) {
15431 for (String arg : args) {
15432 if (value.equals(arg)) {
15440 private final boolean removeDyingProviderLocked(ProcessRecord proc,
15441 ContentProviderRecord cpr, boolean always) {
15442 final boolean inLaunching = mLaunchingProviders.contains(cpr);
15444 if (!inLaunching || always) {
15445 synchronized (cpr) {
15446 cpr.launchingApp = null;
15449 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15450 String names[] = cpr.info.authority.split(";");
15451 for (int j = 0; j < names.length; j++) {
15452 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15456 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15457 ContentProviderConnection conn = cpr.connections.get(i);
15458 if (conn.waiting) {
15459 // If this connection is waiting for the provider, then we don't
15460 // need to mess with its process unless we are always removing
15461 // or for some reason the provider is not currently launching.
15462 if (inLaunching && !always) {
15466 ProcessRecord capp = conn.client;
15468 if (conn.stableCount > 0) {
15469 if (!capp.persistent && capp.thread != null
15471 && capp.pid != MY_PID) {
15472 capp.kill("depends on provider "
15473 + cpr.name.flattenToShortString()
15474 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15476 } else if (capp.thread != null && conn.provider.provider != null) {
15478 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15479 } catch (RemoteException e) {
15481 // In the protocol here, we don't expect the client to correctly
15482 // clean up this connection, we'll just remove it.
15483 cpr.connections.remove(i);
15484 if (conn.client.conProviders.remove(conn)) {
15485 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15490 if (inLaunching && always) {
15491 mLaunchingProviders.remove(cpr);
15493 return inLaunching;
15497 * Main code for cleaning up a process when it has gone away. This is
15498 * called both as a result of the process dying, or directly when stopping
15499 * a process when running in single process mode.
15501 * @return Returns true if the given process has been restarted, so the
15502 * app that was passed in must remain on the process lists.
15504 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15505 boolean restarting, boolean allowRestart, int index) {
15507 removeLruProcessLocked(app);
15508 ProcessList.remove(app.pid);
15511 mProcessesToGc.remove(app);
15512 mPendingPssProcesses.remove(app);
15514 // Dismiss any open dialogs.
15515 if (app.crashDialog != null && !app.forceCrashReport) {
15516 app.crashDialog.dismiss();
15517 app.crashDialog = null;
15519 if (app.anrDialog != null) {
15520 app.anrDialog.dismiss();
15521 app.anrDialog = null;
15523 if (app.waitDialog != null) {
15524 app.waitDialog.dismiss();
15525 app.waitDialog = null;
15528 app.crashing = false;
15529 app.notResponding = false;
15531 app.resetPackageList(mProcessStats);
15532 app.unlinkDeathRecipient();
15533 app.makeInactive(mProcessStats);
15534 app.waitingToKill = null;
15535 app.forcingToForeground = null;
15536 updateProcessForegroundLocked(app, false, false);
15537 app.foregroundActivities = false;
15538 app.hasShownUi = false;
15539 app.treatLikeActivity = false;
15540 app.hasAboveClient = false;
15541 app.hasClientActivities = false;
15543 mServices.killServicesLocked(app, allowRestart);
15545 boolean restart = false;
15547 // Remove published content providers.
15548 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15549 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15550 final boolean always = app.bad || !allowRestart;
15551 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15552 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15553 // We left the provider in the launching list, need to
15558 cpr.provider = null;
15561 app.pubProviders.clear();
15563 // Take care of any launching providers waiting for this process.
15564 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15568 // Unregister from connected content providers.
15569 if (!app.conProviders.isEmpty()) {
15570 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15571 ContentProviderConnection conn = app.conProviders.get(i);
15572 conn.provider.connections.remove(conn);
15573 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15574 conn.provider.name);
15576 app.conProviders.clear();
15579 // At this point there may be remaining entries in mLaunchingProviders
15580 // where we were the only one waiting, so they are no longer of use.
15581 // Look for these and clean up if found.
15582 // XXX Commented out for now. Trying to figure out a way to reproduce
15583 // the actual situation to identify what is actually going on.
15585 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15586 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15587 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15588 synchronized (cpr) {
15589 cpr.launchingApp = null;
15596 skipCurrentReceiverLocked(app);
15598 // Unregister any receivers.
15599 for (int i = app.receivers.size() - 1; i >= 0; i--) {
15600 removeReceiverLocked(app.receivers.valueAt(i));
15602 app.receivers.clear();
15604 // If the app is undergoing backup, tell the backup manager about it
15605 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15606 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15607 + mBackupTarget.appInfo + " died during backup");
15609 IBackupManager bm = IBackupManager.Stub.asInterface(
15610 ServiceManager.getService(Context.BACKUP_SERVICE));
15611 bm.agentDisconnected(app.info.packageName);
15612 } catch (RemoteException e) {
15613 // can't happen; backup manager is local
15617 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15618 ProcessChangeItem item = mPendingProcessChanges.get(i);
15619 if (item.pid == app.pid) {
15620 mPendingProcessChanges.remove(i);
15621 mAvailProcessChanges.add(item);
15624 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15626 // If the caller is restarting this app, then leave it in its
15627 // current lists and let the caller take care of it.
15632 if (!app.persistent || app.isolated) {
15633 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15634 "Removing non-persistent process during cleanup: " + app);
15635 removeProcessNameLocked(app.processName, app.uid);
15636 if (mHeavyWeightProcess == app) {
15637 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15638 mHeavyWeightProcess.userId, 0));
15639 mHeavyWeightProcess = null;
15641 } else if (!app.removed) {
15642 // This app is persistent, so we need to keep its record around.
15643 // If it is not already on the pending app list, add it there
15644 // and start a new process for it.
15645 if (mPersistentStartingProcesses.indexOf(app) < 0) {
15646 mPersistentStartingProcesses.add(app);
15650 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15651 TAG_CLEANUP, "Clean-up removing on hold: " + app);
15652 mProcessesOnHold.remove(app);
15654 if (app == mHomeProcess) {
15655 mHomeProcess = null;
15657 if (app == mPreviousProcess) {
15658 mPreviousProcess = null;
15661 if (restart && !app.isolated) {
15662 // We have components that still need to be running in the
15663 // process, so re-launch it.
15665 ProcessList.remove(app.pid);
15667 addProcessNameLocked(app);
15668 startProcessLocked(app, "restart", app.processName);
15670 } else if (app.pid > 0 && app.pid != MY_PID) {
15673 synchronized (mPidsSelfLocked) {
15674 mPidsSelfLocked.remove(app.pid);
15675 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15677 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15678 if (app.isolated) {
15679 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15686 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
15687 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15688 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15689 if (cpr.launchingApp == app) {
15696 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15697 // Look through the content providers we are waiting to have launched,
15698 // and if any run in this process then either schedule a restart of
15699 // the process or kill the client waiting for it if this process has
15701 boolean restart = false;
15702 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15703 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15704 if (cpr.launchingApp == app) {
15705 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15708 removeDyingProviderLocked(app, cpr, true);
15715 // =========================================================
15717 // =========================================================
15720 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15722 enforceNotIsolatedCaller("getServices");
15723 synchronized (this) {
15724 return mServices.getRunningServiceInfoLocked(maxNum, flags);
15729 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15730 enforceNotIsolatedCaller("getRunningServiceControlPanel");
15731 synchronized (this) {
15732 return mServices.getRunningServiceControlPanelLocked(name);
15737 public ComponentName startService(IApplicationThread caller, Intent service,
15738 String resolvedType, String callingPackage, int userId)
15739 throws TransactionTooLargeException {
15740 enforceNotIsolatedCaller("startService");
15741 // Refuse possible leaked file descriptors
15742 if (service != null && service.hasFileDescriptors() == true) {
15743 throw new IllegalArgumentException("File descriptors passed in Intent");
15746 if (callingPackage == null) {
15747 throw new IllegalArgumentException("callingPackage cannot be null");
15750 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15751 "startService: " + service + " type=" + resolvedType);
15752 synchronized(this) {
15753 final int callingPid = Binder.getCallingPid();
15754 final int callingUid = Binder.getCallingUid();
15755 final long origId = Binder.clearCallingIdentity();
15756 ComponentName res = mServices.startServiceLocked(caller, service,
15757 resolvedType, callingPid, callingUid, callingPackage, userId);
15758 Binder.restoreCallingIdentity(origId);
15763 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15764 String callingPackage, int userId)
15765 throws TransactionTooLargeException {
15766 synchronized(this) {
15767 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15768 "startServiceInPackage: " + service + " type=" + resolvedType);
15769 final long origId = Binder.clearCallingIdentity();
15770 ComponentName res = mServices.startServiceLocked(null, service,
15771 resolvedType, -1, uid, callingPackage, userId);
15772 Binder.restoreCallingIdentity(origId);
15778 public int stopService(IApplicationThread caller, Intent service,
15779 String resolvedType, int userId) {
15780 enforceNotIsolatedCaller("stopService");
15781 // Refuse possible leaked file descriptors
15782 if (service != null && service.hasFileDescriptors() == true) {
15783 throw new IllegalArgumentException("File descriptors passed in Intent");
15786 synchronized(this) {
15787 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15792 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15793 enforceNotIsolatedCaller("peekService");
15794 // Refuse possible leaked file descriptors
15795 if (service != null && service.hasFileDescriptors() == true) {
15796 throw new IllegalArgumentException("File descriptors passed in Intent");
15799 if (callingPackage == null) {
15800 throw new IllegalArgumentException("callingPackage cannot be null");
15803 synchronized(this) {
15804 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15809 public boolean stopServiceToken(ComponentName className, IBinder token,
15811 synchronized(this) {
15812 return mServices.stopServiceTokenLocked(className, token, startId);
15817 public void setServiceForeground(ComponentName className, IBinder token,
15818 int id, Notification notification, boolean removeNotification) {
15819 synchronized(this) {
15820 mServices.setServiceForegroundLocked(className, token, id, notification,
15821 removeNotification);
15826 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15827 boolean requireFull, String name, String callerPackage) {
15828 return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15829 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15832 int unsafeConvertIncomingUser(int userId) {
15833 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15834 ? mCurrentUserId : userId;
15837 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15838 int allowMode, String name, String callerPackage) {
15839 final int callingUserId = UserHandle.getUserId(callingUid);
15840 if (callingUserId == userId) {
15844 // Note that we may be accessing mCurrentUserId outside of a lock...
15845 // shouldn't be a big deal, if this is being called outside
15846 // of a locked context there is intrinsically a race with
15847 // the value the caller will receive and someone else changing it.
15848 // We assume that USER_CURRENT_OR_SELF will use the current user; later
15849 // we will switch to the calling user if access to the current user fails.
15850 int targetUserId = unsafeConvertIncomingUser(userId);
15852 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15853 final boolean allow;
15854 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15855 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15856 // If the caller has this permission, they always pass go. And collect $200.
15858 } else if (allowMode == ALLOW_FULL_ONLY) {
15859 // We require full access, sucks to be you.
15861 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15862 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15863 // If the caller does not have either permission, they are always doomed.
15865 } else if (allowMode == ALLOW_NON_FULL) {
15866 // We are blanket allowing non-full access, you lucky caller!
15868 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15869 // We may or may not allow this depending on whether the two users are
15870 // in the same profile.
15871 synchronized (mUserProfileGroupIdsSelfLocked) {
15872 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15873 UserInfo.NO_PROFILE_GROUP_ID);
15874 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15875 UserInfo.NO_PROFILE_GROUP_ID);
15876 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15877 && callingProfile == targetProfile;
15880 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15883 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15884 // In this case, they would like to just execute as their
15885 // owner user instead of failing.
15886 targetUserId = callingUserId;
15888 StringBuilder builder = new StringBuilder(128);
15889 builder.append("Permission Denial: ");
15890 builder.append(name);
15891 if (callerPackage != null) {
15892 builder.append(" from ");
15893 builder.append(callerPackage);
15895 builder.append(" asks to run as user ");
15896 builder.append(userId);
15897 builder.append(" but is calling from user ");
15898 builder.append(UserHandle.getUserId(callingUid));
15899 builder.append("; this requires ");
15900 builder.append(INTERACT_ACROSS_USERS_FULL);
15901 if (allowMode != ALLOW_FULL_ONLY) {
15902 builder.append(" or ");
15903 builder.append(INTERACT_ACROSS_USERS);
15905 String msg = builder.toString();
15907 throw new SecurityException(msg);
15911 if (!allowAll && targetUserId < 0) {
15912 throw new IllegalArgumentException(
15913 "Call does not support special user #" + targetUserId);
15915 // Check shell permission
15916 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15917 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15919 throw new SecurityException("Shell does not have permission to access user "
15920 + targetUserId + "\n " + Debug.getCallers(3));
15923 return targetUserId;
15926 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15927 String className, int flags) {
15928 boolean result = false;
15929 // For apps that don't have pre-defined UIDs, check for permission
15930 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15931 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15932 if (ActivityManager.checkUidPermission(
15933 INTERACT_ACROSS_USERS,
15934 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15935 ComponentName comp = new ComponentName(aInfo.packageName, className);
15936 String msg = "Permission Denial: Component " + comp.flattenToShortString()
15937 + " requests FLAG_SINGLE_USER, but app does not hold "
15938 + INTERACT_ACROSS_USERS;
15940 throw new SecurityException(msg);
15942 // Permission passed
15945 } else if ("system".equals(componentProcessName)) {
15947 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15948 // Phone app and persistent apps are allowed to export singleuser providers.
15949 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15950 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15952 if (DEBUG_MU) Slog.v(TAG_MU,
15953 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15954 + Integer.toHexString(flags) + ") = " + result);
15959 * Checks to see if the caller is in the same app as the singleton
15960 * component, or the component is in a special app. It allows special apps
15961 * to export singleton components but prevents exporting singleton
15962 * components for regular apps.
15964 boolean isValidSingletonCall(int callingUid, int componentUid) {
15965 int componentAppId = UserHandle.getAppId(componentUid);
15966 return UserHandle.isSameApp(callingUid, componentUid)
15967 || componentAppId == Process.SYSTEM_UID
15968 || componentAppId == Process.PHONE_UID
15969 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15970 == PackageManager.PERMISSION_GRANTED;
15973 public int bindService(IApplicationThread caller, IBinder token, Intent service,
15974 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15975 int userId) throws TransactionTooLargeException {
15976 enforceNotIsolatedCaller("bindService");
15978 // Refuse possible leaked file descriptors
15979 if (service != null && service.hasFileDescriptors() == true) {
15980 throw new IllegalArgumentException("File descriptors passed in Intent");
15983 if (callingPackage == null) {
15984 throw new IllegalArgumentException("callingPackage cannot be null");
15987 synchronized(this) {
15988 return mServices.bindServiceLocked(caller, token, service,
15989 resolvedType, connection, flags, callingPackage, userId);
15993 public boolean unbindService(IServiceConnection connection) {
15994 synchronized (this) {
15995 return mServices.unbindServiceLocked(connection);
15999 public void publishService(IBinder token, Intent intent, IBinder service) {
16000 // Refuse possible leaked file descriptors
16001 if (intent != null && intent.hasFileDescriptors() == true) {
16002 throw new IllegalArgumentException("File descriptors passed in Intent");
16005 synchronized(this) {
16006 if (!(token instanceof ServiceRecord)) {
16007 throw new IllegalArgumentException("Invalid service token");
16009 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16013 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16014 // Refuse possible leaked file descriptors
16015 if (intent != null && intent.hasFileDescriptors() == true) {
16016 throw new IllegalArgumentException("File descriptors passed in Intent");
16019 synchronized(this) {
16020 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16024 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16025 synchronized(this) {
16026 if (!(token instanceof ServiceRecord)) {
16027 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16028 throw new IllegalArgumentException("Invalid service token");
16030 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16034 // =========================================================
16035 // BACKUP AND RESTORE
16036 // =========================================================
16038 // Cause the target app to be launched if necessary and its backup agent
16039 // instantiated. The backup agent will invoke backupAgentCreated() on the
16040 // activity manager to announce its creation.
16041 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16042 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16043 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16044 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16046 synchronized(this) {
16047 // !!! TODO: currently no check here that we're already bound
16048 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16049 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16050 synchronized (stats) {
16051 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16054 // Backup agent is now in use, its package can't be stopped.
16056 AppGlobals.getPackageManager().setPackageStoppedState(
16057 app.packageName, false, UserHandle.getUserId(app.uid));
16058 } catch (RemoteException e) {
16059 } catch (IllegalArgumentException e) {
16060 Slog.w(TAG, "Failed trying to unstop package "
16061 + app.packageName + ": " + e);
16064 BackupRecord r = new BackupRecord(ss, app, backupMode);
16065 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16066 ? new ComponentName(app.packageName, app.backupAgentName)
16067 : new ComponentName("android", "FullBackupAgent");
16068 // startProcessLocked() returns existing proc's record if it's already running
16069 ProcessRecord proc = startProcessLocked(app.processName, app,
16070 false, 0, "backup", hostingName, false, false, false);
16071 if (proc == null) {
16072 Slog.e(TAG, "Unable to start backup agent process " + r);
16078 mBackupAppName = app.packageName;
16080 // Try not to kill the process during backup
16081 updateOomAdjLocked(proc);
16083 // If the process is already attached, schedule the creation of the backup agent now.
16084 // If it is not yet live, this will be done when it attaches to the framework.
16085 if (proc.thread != null) {
16086 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16088 proc.thread.scheduleCreateBackupAgent(app,
16089 compatibilityInfoForPackageLocked(app), backupMode);
16090 } catch (RemoteException e) {
16091 // Will time out on the backup manager side
16094 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16096 // Invariants: at this point, the target app process exists and the application
16097 // is either already running or in the process of coming up. mBackupTarget and
16098 // mBackupAppName describe the app, so that when it binds back to the AM we
16099 // know that it's scheduled for a backup-agent operation.
16106 public void clearPendingBackup() {
16107 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16108 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16110 synchronized (this) {
16111 mBackupTarget = null;
16112 mBackupAppName = null;
16116 // A backup agent has just come up
16117 public void backupAgentCreated(String agentPackageName, IBinder agent) {
16118 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16121 synchronized(this) {
16122 if (!agentPackageName.equals(mBackupAppName)) {
16123 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16128 long oldIdent = Binder.clearCallingIdentity();
16130 IBackupManager bm = IBackupManager.Stub.asInterface(
16131 ServiceManager.getService(Context.BACKUP_SERVICE));
16132 bm.agentConnected(agentPackageName, agent);
16133 } catch (RemoteException e) {
16134 // can't happen; the backup manager service is local
16135 } catch (Exception e) {
16136 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16137 e.printStackTrace();
16139 Binder.restoreCallingIdentity(oldIdent);
16143 // done with this agent
16144 public void unbindBackupAgent(ApplicationInfo appInfo) {
16145 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16146 if (appInfo == null) {
16147 Slog.w(TAG, "unbind backup agent for null app");
16151 synchronized(this) {
16153 if (mBackupAppName == null) {
16154 Slog.w(TAG, "Unbinding backup agent with no active backup");
16158 if (!mBackupAppName.equals(appInfo.packageName)) {
16159 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16163 // Not backing this app up any more; reset its OOM adjustment
16164 final ProcessRecord proc = mBackupTarget.app;
16165 updateOomAdjLocked(proc);
16167 // If the app crashed during backup, 'thread' will be null here
16168 if (proc.thread != null) {
16170 proc.thread.scheduleDestroyBackupAgent(appInfo,
16171 compatibilityInfoForPackageLocked(appInfo));
16172 } catch (Exception e) {
16173 Slog.e(TAG, "Exception when unbinding backup agent:");
16174 e.printStackTrace();
16178 mBackupTarget = null;
16179 mBackupAppName = null;
16183 // =========================================================
16185 // =========================================================
16187 boolean isPendingBroadcastProcessLocked(int pid) {
16188 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16189 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16192 void skipPendingBroadcastLocked(int pid) {
16193 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16194 for (BroadcastQueue queue : mBroadcastQueues) {
16195 queue.skipPendingBroadcastLocked(pid);
16199 // The app just attached; send any pending broadcasts that it should receive
16200 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16201 boolean didSomething = false;
16202 for (BroadcastQueue queue : mBroadcastQueues) {
16203 didSomething |= queue.sendPendingBroadcastsLocked(app);
16205 return didSomething;
16208 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16209 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16210 enforceNotIsolatedCaller("registerReceiver");
16211 ArrayList<Intent> stickyIntents = null;
16212 ProcessRecord callerApp = null;
16215 synchronized(this) {
16216 if (caller != null) {
16217 callerApp = getRecordForAppLocked(caller);
16218 if (callerApp == null) {
16219 throw new SecurityException(
16220 "Unable to find app for caller " + caller
16221 + " (pid=" + Binder.getCallingPid()
16222 + ") when registering receiver " + receiver);
16224 if (callerApp.info.uid != Process.SYSTEM_UID &&
16225 !callerApp.pkgList.containsKey(callerPackage) &&
16226 !"android".equals(callerPackage)) {
16227 throw new SecurityException("Given caller package " + callerPackage
16228 + " is not running in process " + callerApp);
16230 callingUid = callerApp.info.uid;
16231 callingPid = callerApp.pid;
16233 callerPackage = null;
16234 callingUid = Binder.getCallingUid();
16235 callingPid = Binder.getCallingPid();
16238 userId = handleIncomingUser(callingPid, callingUid, userId,
16239 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16241 Iterator<String> actions = filter.actionsIterator();
16242 if (actions == null) {
16243 ArrayList<String> noAction = new ArrayList<String>(1);
16244 noAction.add(null);
16245 actions = noAction.iterator();
16248 // Collect stickies of users
16249 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16250 while (actions.hasNext()) {
16251 String action = actions.next();
16252 for (int id : userIds) {
16253 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16254 if (stickies != null) {
16255 ArrayList<Intent> intents = stickies.get(action);
16256 if (intents != null) {
16257 if (stickyIntents == null) {
16258 stickyIntents = new ArrayList<Intent>();
16260 stickyIntents.addAll(intents);
16267 ArrayList<Intent> allSticky = null;
16268 if (stickyIntents != null) {
16269 final ContentResolver resolver = mContext.getContentResolver();
16270 // Look for any matching sticky broadcasts...
16271 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16272 Intent intent = stickyIntents.get(i);
16273 // If intent has scheme "content", it will need to acccess
16274 // provider that needs to lock mProviderMap in ActivityThread
16275 // and also it may need to wait application response, so we
16276 // cannot lock ActivityManagerService here.
16277 if (filter.match(resolver, intent, true, TAG) >= 0) {
16278 if (allSticky == null) {
16279 allSticky = new ArrayList<Intent>();
16281 allSticky.add(intent);
16286 // The first sticky in the list is returned directly back to the client.
16287 Intent sticky = allSticky != null ? allSticky.get(0) : null;
16288 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16289 if (receiver == null) {
16293 synchronized (this) {
16294 if (callerApp != null && (callerApp.thread == null
16295 || callerApp.thread.asBinder() != caller.asBinder())) {
16296 // Original caller already died
16299 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16301 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16303 if (rl.app != null) {
16304 rl.app.receivers.add(rl);
16307 receiver.asBinder().linkToDeath(rl, 0);
16308 } catch (RemoteException e) {
16311 rl.linkedToDeath = true;
16313 mRegisteredReceivers.put(receiver.asBinder(), rl);
16314 } else if (rl.uid != callingUid) {
16315 throw new IllegalArgumentException(
16316 "Receiver requested to register for uid " + callingUid
16317 + " was previously registered for uid " + rl.uid);
16318 } else if (rl.pid != callingPid) {
16319 throw new IllegalArgumentException(
16320 "Receiver requested to register for pid " + callingPid
16321 + " was previously registered for pid " + rl.pid);
16322 } else if (rl.userId != userId) {
16323 throw new IllegalArgumentException(
16324 "Receiver requested to register for user " + userId
16325 + " was previously registered for user " + rl.userId);
16327 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16328 permission, callingUid, userId);
16330 if (!bf.debugCheck()) {
16331 Slog.w(TAG, "==> For Dynamic broadcast");
16333 mReceiverResolver.addFilter(bf);
16335 // Enqueue broadcasts for all existing stickies that match
16337 if (allSticky != null) {
16338 ArrayList receivers = new ArrayList();
16341 final int stickyCount = allSticky.size();
16342 for (int i = 0; i < stickyCount; i++) {
16343 Intent intent = allSticky.get(i);
16344 BroadcastQueue queue = broadcastQueueForIntent(intent);
16345 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16346 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16347 null, 0, null, null, false, true, true, -1);
16348 queue.enqueueParallelBroadcastLocked(r);
16349 queue.scheduleBroadcastsLocked();
16357 public void unregisterReceiver(IIntentReceiver receiver) {
16358 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16360 final long origId = Binder.clearCallingIdentity();
16362 boolean doTrim = false;
16364 synchronized(this) {
16365 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16367 final BroadcastRecord r = rl.curBroadcast;
16368 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16369 final boolean doNext = r.queue.finishReceiverLocked(
16370 r, r.resultCode, r.resultData, r.resultExtras,
16371 r.resultAbort, false);
16374 r.queue.processNextBroadcast(false);
16378 if (rl.app != null) {
16379 rl.app.receivers.remove(rl);
16381 removeReceiverLocked(rl);
16382 if (rl.linkedToDeath) {
16383 rl.linkedToDeath = false;
16384 rl.receiver.asBinder().unlinkToDeath(rl, 0);
16389 // If we actually concluded any broadcasts, we might now be able
16390 // to trim the recipients' apps from our working set
16392 trimApplications();
16397 Binder.restoreCallingIdentity(origId);
16401 void removeReceiverLocked(ReceiverList rl) {
16402 mRegisteredReceivers.remove(rl.receiver.asBinder());
16403 for (int i = rl.size() - 1; i >= 0; i--) {
16404 mReceiverResolver.removeFilter(rl.get(i));
16408 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16409 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16410 ProcessRecord r = mLruProcesses.get(i);
16411 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16413 r.thread.dispatchPackageBroadcast(cmd, packages);
16414 } catch (RemoteException ex) {
16420 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16421 int callingUid, int[] users) {
16422 List<ResolveInfo> receivers = null;
16424 HashSet<ComponentName> singleUserReceivers = null;
16425 boolean scannedFirstReceivers = false;
16426 for (int user : users) {
16427 // Skip users that have Shell restrictions
16428 if (callingUid == Process.SHELL_UID
16429 && getUserManagerLocked().hasUserRestriction(
16430 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16433 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16434 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16435 if (user != UserHandle.USER_OWNER && newReceivers != null) {
16436 // If this is not the primary user, we need to check for
16437 // any receivers that should be filtered out.
16438 for (int i=0; i<newReceivers.size(); i++) {
16439 ResolveInfo ri = newReceivers.get(i);
16440 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16441 newReceivers.remove(i);
16446 if (newReceivers != null && newReceivers.size() == 0) {
16447 newReceivers = null;
16449 if (receivers == null) {
16450 receivers = newReceivers;
16451 } else if (newReceivers != null) {
16452 // We need to concatenate the additional receivers
16453 // found with what we have do far. This would be easy,
16454 // but we also need to de-dup any receivers that are
16456 if (!scannedFirstReceivers) {
16457 // Collect any single user receivers we had already retrieved.
16458 scannedFirstReceivers = true;
16459 for (int i=0; i<receivers.size(); i++) {
16460 ResolveInfo ri = receivers.get(i);
16461 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16462 ComponentName cn = new ComponentName(
16463 ri.activityInfo.packageName, ri.activityInfo.name);
16464 if (singleUserReceivers == null) {
16465 singleUserReceivers = new HashSet<ComponentName>();
16467 singleUserReceivers.add(cn);
16471 // Add the new results to the existing results, tracking
16472 // and de-dupping single user receivers.
16473 for (int i=0; i<newReceivers.size(); i++) {
16474 ResolveInfo ri = newReceivers.get(i);
16475 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16476 ComponentName cn = new ComponentName(
16477 ri.activityInfo.packageName, ri.activityInfo.name);
16478 if (singleUserReceivers == null) {
16479 singleUserReceivers = new HashSet<ComponentName>();
16481 if (!singleUserReceivers.contains(cn)) {
16482 singleUserReceivers.add(cn);
16491 } catch (RemoteException ex) {
16492 // pm is in same process, this will never happen.
16497 private final int broadcastIntentLocked(ProcessRecord callerApp,
16498 String callerPackage, Intent intent, String resolvedType,
16499 IIntentReceiver resultTo, int resultCode, String resultData,
16500 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16501 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16502 intent = new Intent(intent);
16504 // By default broadcasts do not go to stopped apps.
16505 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16507 // If we have not finished booting, don't allow this to launch new processes.
16508 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16509 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16512 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16513 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16514 + " ordered=" + ordered + " userid=" + userId);
16515 if ((resultTo != null) && !ordered) {
16516 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16519 userId = handleIncomingUser(callingPid, callingUid, userId,
16520 true, ALLOW_NON_FULL, "broadcast", callerPackage);
16522 // Make sure that the user who is receiving this broadcast is running.
16523 // If not, we will just skip it. Make an exception for shutdown broadcasts
16524 // and upgrade steps.
16526 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16527 if ((callingUid != Process.SYSTEM_UID
16528 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16529 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16530 Slog.w(TAG, "Skipping broadcast of " + intent
16531 + ": user " + userId + " is stopped");
16532 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16536 BroadcastOptions brOptions = null;
16537 if (options != null) {
16538 brOptions = new BroadcastOptions(options);
16539 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16540 // See if the caller is allowed to do this. Note we are checking against
16541 // the actual real caller (not whoever provided the operation as say a
16542 // PendingIntent), because that who is actually supplied the arguments.
16543 if (checkComponentPermission(
16544 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16545 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16546 != PackageManager.PERMISSION_GRANTED) {
16547 String msg = "Permission Denial: " + intent.getAction()
16548 + " broadcast from " + callerPackage + " (pid=" + callingPid
16549 + ", uid=" + callingUid + ")"
16551 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16553 throw new SecurityException(msg);
16559 * Prevent non-system code (defined here to be non-persistent
16560 * processes) from sending protected broadcasts.
16562 int callingAppId = UserHandle.getAppId(callingUid);
16563 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16564 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16565 || callingAppId == Process.NFC_UID || callingUid == 0) {
16567 } else if (callerApp == null || !callerApp.persistent) {
16569 if (AppGlobals.getPackageManager().isProtectedBroadcast(
16570 intent.getAction())) {
16571 String msg = "Permission Denial: not allowed to send broadcast "
16572 + intent.getAction() + " from pid="
16573 + callingPid + ", uid=" + callingUid;
16575 throw new SecurityException(msg);
16576 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16577 // Special case for compatibility: we don't want apps to send this,
16578 // but historically it has not been protected and apps may be using it
16579 // to poke their own app widget. So, instead of making it protected,
16580 // just limit it to the caller.
16581 if (callerApp == null) {
16582 String msg = "Permission Denial: not allowed to send broadcast "
16583 + intent.getAction() + " from unknown caller.";
16585 throw new SecurityException(msg);
16586 } else if (intent.getComponent() != null) {
16587 // They are good enough to send to an explicit component... verify
16588 // it is being sent to the calling app.
16589 if (!intent.getComponent().getPackageName().equals(
16590 callerApp.info.packageName)) {
16591 String msg = "Permission Denial: not allowed to send broadcast "
16592 + intent.getAction() + " to "
16593 + intent.getComponent().getPackageName() + " from "
16594 + callerApp.info.packageName;
16596 throw new SecurityException(msg);
16599 // Limit broadcast to their own package.
16600 intent.setPackage(callerApp.info.packageName);
16603 } catch (RemoteException e) {
16604 Slog.w(TAG, "Remote exception", e);
16605 return ActivityManager.BROADCAST_SUCCESS;
16609 final String action = intent.getAction();
16610 if (action != null) {
16612 case Intent.ACTION_UID_REMOVED:
16613 case Intent.ACTION_PACKAGE_REMOVED:
16614 case Intent.ACTION_PACKAGE_CHANGED:
16615 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16616 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16617 // Handle special intents: if this broadcast is from the package
16618 // manager about a package being removed, we need to remove all of
16619 // its activities from the history stack.
16620 if (checkComponentPermission(
16621 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16622 callingPid, callingUid, -1, true)
16623 != PackageManager.PERMISSION_GRANTED) {
16624 String msg = "Permission Denial: " + intent.getAction()
16625 + " broadcast from " + callerPackage + " (pid=" + callingPid
16626 + ", uid=" + callingUid + ")"
16628 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16630 throw new SecurityException(msg);
16633 case Intent.ACTION_UID_REMOVED:
16634 final Bundle intentExtras = intent.getExtras();
16635 final int uid = intentExtras != null
16636 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16638 mBatteryStatsService.removeUid(uid);
16639 mAppOpsService.uidRemoved(uid);
16642 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16643 // If resources are unavailable just force stop all those packages
16644 // and flush the attribute cache as well.
16646 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16647 if (list != null && list.length > 0) {
16648 for (int i = 0; i < list.length; i++) {
16649 forceStopPackageLocked(list[i], -1, false, true, true,
16650 false, false, userId, "storage unmount");
16652 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16653 sendPackageBroadcastLocked(
16654 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16658 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16659 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16661 case Intent.ACTION_PACKAGE_REMOVED:
16662 case Intent.ACTION_PACKAGE_CHANGED:
16663 Uri data = intent.getData();
16665 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16666 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16667 boolean fullUninstall = removed &&
16668 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16669 final boolean killProcess =
16670 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16672 forceStopPackageLocked(ssp, UserHandle.getAppId(
16673 intent.getIntExtra(Intent.EXTRA_UID, -1)),
16674 false, true, true, false, fullUninstall, userId,
16675 removed ? "pkg removed" : "pkg changed");
16678 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16679 new String[] {ssp}, userId);
16680 if (fullUninstall) {
16681 mAppOpsService.packageRemoved(
16682 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16684 // Remove all permissions granted from/to this package
16685 removeUriPermissionsForPackageLocked(ssp, userId, true);
16687 removeTasksByPackageNameLocked(ssp, userId);
16688 mBatteryStatsService.notePackageUninstalled(ssp);
16691 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16692 intent.getStringArrayExtra(
16693 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16699 case Intent.ACTION_PACKAGE_ADDED:
16700 // Special case for adding a package: by default turn on compatibility mode.
16701 Uri data = intent.getData();
16703 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16704 final boolean replacing =
16705 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16706 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16709 ApplicationInfo ai = AppGlobals.getPackageManager().
16710 getApplicationInfo(ssp, 0, 0);
16711 mBatteryStatsService.notePackageInstalled(ssp,
16712 ai != null ? ai.versionCode : 0);
16713 } catch (RemoteException e) {
16717 case Intent.ACTION_TIMEZONE_CHANGED:
16718 // If this is the time zone changed action, queue up a message that will reset
16719 // the timezone of all currently running processes. This message will get
16720 // queued up before the broadcast happens.
16721 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16723 case Intent.ACTION_TIME_CHANGED:
16724 // If the user set the time, let all running processes know.
16725 final int is24Hour =
16726 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16728 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16729 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16730 synchronized (stats) {
16731 stats.noteCurrentTimeChangedLocked();
16734 case Intent.ACTION_CLEAR_DNS_CACHE:
16735 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16737 case Proxy.PROXY_CHANGE_ACTION:
16738 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16739 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16744 // Add to the sticky list if requested.
16746 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16747 callingPid, callingUid)
16748 != PackageManager.PERMISSION_GRANTED) {
16749 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16750 + callingPid + ", uid=" + callingUid
16751 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16753 throw new SecurityException(msg);
16755 if (requiredPermissions != null && requiredPermissions.length > 0) {
16756 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16757 + " and enforce permissions " + Arrays.toString(requiredPermissions));
16758 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16760 if (intent.getComponent() != null) {
16761 throw new SecurityException(
16762 "Sticky broadcasts can't target a specific component");
16764 // We use userId directly here, since the "all" target is maintained
16765 // as a separate set of sticky broadcasts.
16766 if (userId != UserHandle.USER_ALL) {
16767 // But first, if this is not a broadcast to all users, then
16768 // make sure it doesn't conflict with an existing broadcast to
16770 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16771 UserHandle.USER_ALL);
16772 if (stickies != null) {
16773 ArrayList<Intent> list = stickies.get(intent.getAction());
16774 if (list != null) {
16775 int N = list.size();
16777 for (i=0; i<N; i++) {
16778 if (intent.filterEquals(list.get(i))) {
16779 throw new IllegalArgumentException(
16780 "Sticky broadcast " + intent + " for user "
16781 + userId + " conflicts with existing global broadcast");
16787 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16788 if (stickies == null) {
16789 stickies = new ArrayMap<>();
16790 mStickyBroadcasts.put(userId, stickies);
16792 ArrayList<Intent> list = stickies.get(intent.getAction());
16793 if (list == null) {
16794 list = new ArrayList<>();
16795 stickies.put(intent.getAction(), list);
16797 final int stickiesCount = list.size();
16799 for (i = 0; i < stickiesCount; i++) {
16800 if (intent.filterEquals(list.get(i))) {
16801 // This sticky already exists, replace it.
16802 list.set(i, new Intent(intent));
16806 if (i >= stickiesCount) {
16807 list.add(new Intent(intent));
16812 if (userId == UserHandle.USER_ALL) {
16813 // Caller wants broadcast to go to all started users.
16814 users = mStartedUserArray;
16816 // Caller wants broadcast to go to one specific user.
16817 users = new int[] {userId};
16820 // Figure out who all will receive this broadcast.
16821 List receivers = null;
16822 List<BroadcastFilter> registeredReceivers = null;
16823 // Need to resolve the intent to interested receivers...
16824 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16826 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16828 if (intent.getComponent() == null) {
16829 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16830 // Query one target user at a time, excluding shell-restricted users
16831 UserManagerService ums = getUserManagerLocked();
16832 for (int i = 0; i < users.length; i++) {
16833 if (ums.hasUserRestriction(
16834 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16837 List<BroadcastFilter> registeredReceiversForUser =
16838 mReceiverResolver.queryIntent(intent,
16839 resolvedType, false, users[i]);
16840 if (registeredReceivers == null) {
16841 registeredReceivers = registeredReceiversForUser;
16842 } else if (registeredReceiversForUser != null) {
16843 registeredReceivers.addAll(registeredReceiversForUser);
16847 registeredReceivers = mReceiverResolver.queryIntent(intent,
16848 resolvedType, false, userId);
16852 final boolean replacePending =
16853 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16855 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16856 + " replacePending=" + replacePending);
16858 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16859 if (!ordered && NR > 0) {
16860 // If we are not serializing this broadcast, then send the
16861 // registered receivers separately so they don't wait for the
16862 // components to be launched.
16863 final BroadcastQueue queue = broadcastQueueForIntent(intent);
16864 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16865 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16866 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16867 resultExtras, ordered, sticky, false, userId);
16868 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16869 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16871 queue.enqueueParallelBroadcastLocked(r);
16872 queue.scheduleBroadcastsLocked();
16874 registeredReceivers = null;
16878 // Merge into one list.
16880 if (receivers != null) {
16881 // A special case for PACKAGE_ADDED: do not allow the package
16882 // being added to see this broadcast. This prevents them from
16883 // using this as a back door to get run as soon as they are
16884 // installed. Maybe in the future we want to have a special install
16885 // broadcast or such for apps, but we'd like to deliberately make
16887 String skipPackages[] = null;
16888 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16889 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16890 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16891 Uri data = intent.getData();
16892 if (data != null) {
16893 String pkgName = data.getSchemeSpecificPart();
16894 if (pkgName != null) {
16895 skipPackages = new String[] { pkgName };
16898 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16899 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16901 if (skipPackages != null && (skipPackages.length > 0)) {
16902 for (String skipPackage : skipPackages) {
16903 if (skipPackage != null) {
16904 int NT = receivers.size();
16905 for (int it=0; it<NT; it++) {
16906 ResolveInfo curt = (ResolveInfo)receivers.get(it);
16907 if (curt.activityInfo.packageName.equals(skipPackage)) {
16908 receivers.remove(it);
16917 int NT = receivers != null ? receivers.size() : 0;
16919 ResolveInfo curt = null;
16920 BroadcastFilter curr = null;
16921 while (it < NT && ir < NR) {
16922 if (curt == null) {
16923 curt = (ResolveInfo)receivers.get(it);
16925 if (curr == null) {
16926 curr = registeredReceivers.get(ir);
16928 if (curr.getPriority() >= curt.priority) {
16929 // Insert this broadcast record into the final list.
16930 receivers.add(it, curr);
16936 // Skip to the next ResolveInfo in the final list.
16943 if (receivers == null) {
16944 receivers = new ArrayList();
16946 receivers.add(registeredReceivers.get(ir));
16950 if ((receivers != null && receivers.size() > 0)
16951 || resultTo != null) {
16952 BroadcastQueue queue = broadcastQueueForIntent(intent);
16953 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16954 callerPackage, callingPid, callingUid, resolvedType,
16955 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16956 resultData, resultExtras, ordered, sticky, false, userId);
16958 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16959 + ": prev had " + queue.mOrderedBroadcasts.size());
16960 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16961 "Enqueueing broadcast " + r.intent.getAction());
16963 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16965 queue.enqueueOrderedBroadcastLocked(r);
16966 queue.scheduleBroadcastsLocked();
16970 return ActivityManager.BROADCAST_SUCCESS;
16973 final Intent verifyBroadcastLocked(Intent intent) {
16974 // Refuse possible leaked file descriptors
16975 if (intent != null && intent.hasFileDescriptors() == true) {
16976 throw new IllegalArgumentException("File descriptors passed in Intent");
16979 int flags = intent.getFlags();
16981 if (!mProcessesReady) {
16982 // if the caller really truly claims to know what they're doing, go
16983 // ahead and allow the broadcast without launching any receivers
16984 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16985 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16986 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16987 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16988 + " before boot completion");
16989 throw new IllegalStateException("Cannot broadcast before boot completed");
16993 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16994 throw new IllegalArgumentException(
16995 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17001 public final int broadcastIntent(IApplicationThread caller,
17002 Intent intent, String resolvedType, IIntentReceiver resultTo,
17003 int resultCode, String resultData, Bundle resultExtras,
17004 String[] requiredPermissions, int appOp, Bundle options,
17005 boolean serialized, boolean sticky, int userId) {
17006 enforceNotIsolatedCaller("broadcastIntent");
17007 synchronized(this) {
17008 intent = verifyBroadcastLocked(intent);
17010 final ProcessRecord callerApp = getRecordForAppLocked(caller);
17011 final int callingPid = Binder.getCallingPid();
17012 final int callingUid = Binder.getCallingUid();
17013 final long origId = Binder.clearCallingIdentity();
17014 int res = broadcastIntentLocked(callerApp,
17015 callerApp != null ? callerApp.info.packageName : null,
17016 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17017 requiredPermissions, appOp, null, serialized, sticky,
17018 callingPid, callingUid, userId);
17019 Binder.restoreCallingIdentity(origId);
17025 int broadcastIntentInPackage(String packageName, int uid,
17026 Intent intent, String resolvedType, IIntentReceiver resultTo,
17027 int resultCode, String resultData, Bundle resultExtras,
17028 String requiredPermission, Bundle options, boolean serialized, boolean sticky,
17030 synchronized(this) {
17031 intent = verifyBroadcastLocked(intent);
17033 final long origId = Binder.clearCallingIdentity();
17034 String[] requiredPermissions = requiredPermission == null ? null
17035 : new String[] {requiredPermission};
17036 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17037 resultTo, resultCode, resultData, resultExtras,
17038 requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
17039 sticky, -1, uid, userId);
17040 Binder.restoreCallingIdentity(origId);
17045 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17046 // Refuse possible leaked file descriptors
17047 if (intent != null && intent.hasFileDescriptors() == true) {
17048 throw new IllegalArgumentException("File descriptors passed in Intent");
17051 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17052 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17054 synchronized(this) {
17055 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17056 != PackageManager.PERMISSION_GRANTED) {
17057 String msg = "Permission Denial: unbroadcastIntent() from pid="
17058 + Binder.getCallingPid()
17059 + ", uid=" + Binder.getCallingUid()
17060 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17062 throw new SecurityException(msg);
17064 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17065 if (stickies != null) {
17066 ArrayList<Intent> list = stickies.get(intent.getAction());
17067 if (list != null) {
17068 int N = list.size();
17070 for (i=0; i<N; i++) {
17071 if (intent.filterEquals(list.get(i))) {
17076 if (list.size() <= 0) {
17077 stickies.remove(intent.getAction());
17080 if (stickies.size() <= 0) {
17081 mStickyBroadcasts.remove(userId);
17087 void backgroundServicesFinishedLocked(int userId) {
17088 for (BroadcastQueue queue : mBroadcastQueues) {
17089 queue.backgroundServicesFinishedLocked(userId);
17093 public void finishReceiver(IBinder who, int resultCode, String resultData,
17094 Bundle resultExtras, boolean resultAbort, int flags) {
17095 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17097 // Refuse possible leaked file descriptors
17098 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17099 throw new IllegalArgumentException("File descriptors passed in Bundle");
17102 final long origId = Binder.clearCallingIdentity();
17104 boolean doNext = false;
17107 synchronized(this) {
17108 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17109 ? mFgBroadcastQueue : mBgBroadcastQueue;
17110 r = queue.getMatchingOrderedReceiver(who);
17112 doNext = r.queue.finishReceiverLocked(r, resultCode,
17113 resultData, resultExtras, resultAbort, true);
17118 r.queue.processNextBroadcast(false);
17120 trimApplications();
17122 Binder.restoreCallingIdentity(origId);
17126 // =========================================================
17128 // =========================================================
17130 public boolean startInstrumentation(ComponentName className,
17131 String profileFile, int flags, Bundle arguments,
17132 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17133 int userId, String abiOverride) {
17134 enforceNotIsolatedCaller("startInstrumentation");
17135 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17136 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17137 // Refuse possible leaked file descriptors
17138 if (arguments != null && arguments.hasFileDescriptors()) {
17139 throw new IllegalArgumentException("File descriptors passed in Bundle");
17142 synchronized(this) {
17143 InstrumentationInfo ii = null;
17144 ApplicationInfo ai = null;
17146 ii = mContext.getPackageManager().getInstrumentationInfo(
17147 className, STOCK_PM_FLAGS);
17148 ai = AppGlobals.getPackageManager().getApplicationInfo(
17149 ii.targetPackage, STOCK_PM_FLAGS, userId);
17150 } catch (PackageManager.NameNotFoundException e) {
17151 } catch (RemoteException e) {
17154 reportStartInstrumentationFailure(watcher, className,
17155 "Unable to find instrumentation info for: " + className);
17159 reportStartInstrumentationFailure(watcher, className,
17160 "Unable to find instrumentation target package: " + ii.targetPackage);
17164 int match = mContext.getPackageManager().checkSignatures(
17165 ii.targetPackage, ii.packageName);
17166 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17167 String msg = "Permission Denial: starting instrumentation "
17168 + className + " from pid="
17169 + Binder.getCallingPid()
17170 + ", uid=" + Binder.getCallingPid()
17171 + " not allowed because package " + ii.packageName
17172 + " does not have a signature matching the target "
17173 + ii.targetPackage;
17174 reportStartInstrumentationFailure(watcher, className, msg);
17175 throw new SecurityException(msg);
17178 final long origId = Binder.clearCallingIdentity();
17179 // Instrumentation can kill and relaunch even persistent processes
17180 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17182 ProcessRecord app = addAppLocked(ai, false, abiOverride);
17183 app.instrumentationClass = className;
17184 app.instrumentationInfo = ai;
17185 app.instrumentationProfileFile = profileFile;
17186 app.instrumentationArguments = arguments;
17187 app.instrumentationWatcher = watcher;
17188 app.instrumentationUiAutomationConnection = uiAutomationConnection;
17189 app.instrumentationResultClass = className;
17190 Binder.restoreCallingIdentity(origId);
17197 * Report errors that occur while attempting to start Instrumentation. Always writes the
17198 * error to the logs, but if somebody is watching, send the report there too. This enables
17199 * the "am" command to report errors with more information.
17201 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
17202 * @param cn The component name of the instrumentation.
17203 * @param report The error report.
17205 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17206 ComponentName cn, String report) {
17207 Slog.w(TAG, report);
17209 if (watcher != null) {
17210 Bundle results = new Bundle();
17211 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17212 results.putString("Error", report);
17213 watcher.instrumentationStatus(cn, -1, results);
17215 } catch (RemoteException e) {
17220 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17221 if (app.instrumentationWatcher != null) {
17223 // NOTE: IInstrumentationWatcher *must* be oneway here
17224 app.instrumentationWatcher.instrumentationFinished(
17225 app.instrumentationClass,
17228 } catch (RemoteException e) {
17232 // Can't call out of the system process with a lock held, so post a message.
17233 if (app.instrumentationUiAutomationConnection != null) {
17234 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17235 app.instrumentationUiAutomationConnection).sendToTarget();
17238 app.instrumentationWatcher = null;
17239 app.instrumentationUiAutomationConnection = null;
17240 app.instrumentationClass = null;
17241 app.instrumentationInfo = null;
17242 app.instrumentationProfileFile = null;
17243 app.instrumentationArguments = null;
17245 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17249 public void finishInstrumentation(IApplicationThread target,
17250 int resultCode, Bundle results) {
17251 int userId = UserHandle.getCallingUserId();
17252 // Refuse possible leaked file descriptors
17253 if (results != null && results.hasFileDescriptors()) {
17254 throw new IllegalArgumentException("File descriptors passed in Intent");
17257 synchronized(this) {
17258 ProcessRecord app = getRecordForAppLocked(target);
17260 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17263 final long origId = Binder.clearCallingIdentity();
17264 finishInstrumentationLocked(app, resultCode, results);
17265 Binder.restoreCallingIdentity(origId);
17269 // =========================================================
17271 // =========================================================
17273 public ConfigurationInfo getDeviceConfigurationInfo() {
17274 ConfigurationInfo config = new ConfigurationInfo();
17275 synchronized (this) {
17276 config.reqTouchScreen = mConfiguration.touchscreen;
17277 config.reqKeyboardType = mConfiguration.keyboard;
17278 config.reqNavigation = mConfiguration.navigation;
17279 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17280 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17281 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17283 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17284 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17285 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17287 config.reqGlEsVersion = GL_ES_VERSION;
17292 ActivityStack getFocusedStack() {
17293 return mStackSupervisor.getFocusedStack();
17297 public int getFocusedStackId() throws RemoteException {
17298 ActivityStack focusedStack = getFocusedStack();
17299 if (focusedStack != null) {
17300 return focusedStack.getStackId();
17305 public Configuration getConfiguration() {
17307 synchronized(this) {
17308 ci = new Configuration(mConfiguration);
17309 ci.userSetLocale = false;
17314 public void updatePersistentConfiguration(Configuration values) {
17315 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17316 "updateConfiguration()");
17317 enforceWriteSettingsPermission("updateConfiguration()");
17318 if (values == null) {
17319 throw new NullPointerException("Configuration must not be null");
17322 synchronized(this) {
17323 final long origId = Binder.clearCallingIdentity();
17324 updateConfigurationLocked(values, null, true, false);
17325 Binder.restoreCallingIdentity(origId);
17329 private void enforceWriteSettingsPermission(String func) {
17330 int uid = Binder.getCallingUid();
17331 if (uid == Process.ROOT_UID) {
17335 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17336 Settings.getPackageNameForUid(mContext, uid), false)) {
17340 String msg = "Permission Denial: " + func + " from pid="
17341 + Binder.getCallingPid()
17343 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17345 throw new SecurityException(msg);
17348 public void updateConfiguration(Configuration values) {
17349 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17350 "updateConfiguration()");
17352 synchronized(this) {
17353 if (values == null && mWindowManager != null) {
17354 // sentinel: fetch the current configuration from the window manager
17355 values = mWindowManager.computeNewConfiguration();
17358 if (mWindowManager != null) {
17359 mProcessList.applyDisplaySize(mWindowManager);
17362 final long origId = Binder.clearCallingIdentity();
17363 if (values != null) {
17364 Settings.System.clearConfiguration(values);
17366 updateConfigurationLocked(values, null, false, false);
17367 Binder.restoreCallingIdentity(origId);
17372 * Do either or both things: (1) change the current configuration, and (2)
17373 * make sure the given activity is running with the (now) current
17374 * configuration. Returns true if the activity has been left running, or
17375 * false if <var>starting</var> is being destroyed to match the new
17377 * @param persistent TODO
17379 boolean updateConfigurationLocked(Configuration values,
17380 ActivityRecord starting, boolean persistent, boolean initLocale) {
17383 if (values != null) {
17384 Configuration newConfig = new Configuration(mConfiguration);
17385 changes = newConfig.updateFrom(values);
17386 if (changes != 0) {
17387 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17388 "Updating configuration to: " + values);
17390 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17392 if (!initLocale && values.locale != null && values.userSetLocale) {
17393 final String languageTag = values.locale.toLanguageTag();
17394 SystemProperties.set("persist.sys.locale", languageTag);
17395 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17399 mConfigurationSeq++;
17400 if (mConfigurationSeq <= 0) {
17401 mConfigurationSeq = 1;
17403 newConfig.seq = mConfigurationSeq;
17404 mConfiguration = newConfig;
17405 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17406 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17407 //mUsageStatsService.noteStartConfig(newConfig);
17409 final Configuration configCopy = new Configuration(mConfiguration);
17411 // TODO: If our config changes, should we auto dismiss any currently
17412 // showing dialogs?
17413 mShowDialogs = shouldShowDialogs(newConfig);
17415 AttributeCache ac = AttributeCache.instance();
17417 ac.updateConfiguration(configCopy);
17420 // Make sure all resources in our process are updated
17421 // right now, so that anyone who is going to retrieve
17422 // resource values after we return will be sure to get
17423 // the new ones. This is especially important during
17424 // boot, where the first config change needs to guarantee
17425 // all resources have that config before following boot
17426 // code is executed.
17427 mSystemThread.applyConfigurationToResources(configCopy);
17429 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17430 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17431 msg.obj = new Configuration(configCopy);
17432 mHandler.sendMessage(msg);
17435 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17436 ProcessRecord app = mLruProcesses.get(i);
17438 if (app.thread != null) {
17439 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17440 + app.processName + " new config " + mConfiguration);
17441 app.thread.scheduleConfigurationChanged(configCopy);
17443 } catch (Exception e) {
17446 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17447 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17448 | Intent.FLAG_RECEIVER_REPLACE_PENDING
17449 | Intent.FLAG_RECEIVER_FOREGROUND);
17450 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17451 null, AppOpsManager.OP_NONE, null, false, false,
17452 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17453 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17454 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17455 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17456 if (!mProcessesReady) {
17457 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17459 broadcastIntentLocked(null, null, intent,
17460 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17461 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17466 boolean kept = true;
17467 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17468 // mainStack is null during startup.
17469 if (mainStack != null) {
17470 if (changes != 0 && starting == null) {
17471 // If the configuration changed, and the caller is not already
17472 // in the process of starting an activity, then find the top
17473 // activity to check if its configuration needs to change.
17474 starting = mainStack.topRunningActivityLocked(null);
17477 if (starting != null) {
17478 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17479 // And we need to make sure at this point that all other activities
17480 // are made visible with the correct configuration.
17481 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17485 if (values != null && mWindowManager != null) {
17486 mWindowManager.setNewConfiguration(mConfiguration);
17493 * Decide based on the configuration whether we should shouw the ANR,
17494 * crash, etc dialogs. The idea is that if there is no affordnace to
17495 * press the on-screen buttons, we shouldn't show the dialog.
17497 * A thought: SystemUI might also want to get told about this, the Power
17498 * dialog / global actions also might want different behaviors.
17500 private static final boolean shouldShowDialogs(Configuration config) {
17501 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17502 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17503 && config.navigation == Configuration.NAVIGATION_NONAV);
17507 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17508 synchronized (this) {
17509 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17510 if (srec != null) {
17511 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17517 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17518 Intent resultData) {
17520 synchronized (this) {
17521 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17523 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17529 public int getLaunchedFromUid(IBinder activityToken) {
17530 ActivityRecord srec;
17531 synchronized (this) {
17532 srec = ActivityRecord.forTokenLocked(activityToken);
17534 if (srec == null) {
17537 return srec.launchedFromUid;
17540 public String getLaunchedFromPackage(IBinder activityToken) {
17541 ActivityRecord srec;
17542 synchronized (this) {
17543 srec = ActivityRecord.forTokenLocked(activityToken);
17545 if (srec == null) {
17548 return srec.launchedFromPackage;
17551 // =========================================================
17552 // LIFETIME MANAGEMENT
17553 // =========================================================
17555 // Returns which broadcast queue the app is the current [or imminent] receiver
17556 // on, or 'null' if the app is not an active broadcast recipient.
17557 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17558 BroadcastRecord r = app.curReceiver;
17563 // It's not the current receiver, but it might be starting up to become one
17564 synchronized (this) {
17565 for (BroadcastQueue queue : mBroadcastQueues) {
17566 r = queue.mPendingBroadcast;
17567 if (r != null && r.curApp == app) {
17568 // found it; report which queue it's in
17577 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17578 ComponentName targetComponent, String targetProcess) {
17579 if (!mTrackingAssociations) {
17582 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17583 = mAssociations.get(targetUid);
17584 if (components == null) {
17585 components = new ArrayMap<>();
17586 mAssociations.put(targetUid, components);
17588 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17589 if (sourceUids == null) {
17590 sourceUids = new SparseArray<>();
17591 components.put(targetComponent, sourceUids);
17593 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17594 if (sourceProcesses == null) {
17595 sourceProcesses = new ArrayMap<>();
17596 sourceUids.put(sourceUid, sourceProcesses);
17598 Association ass = sourceProcesses.get(sourceProcess);
17600 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17602 sourceProcesses.put(sourceProcess, ass);
17606 if (ass.mNesting == 1) {
17607 ass.mStartTime = SystemClock.uptimeMillis();
17612 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17613 ComponentName targetComponent) {
17614 if (!mTrackingAssociations) {
17617 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17618 = mAssociations.get(targetUid);
17619 if (components == null) {
17622 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17623 if (sourceUids == null) {
17626 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17627 if (sourceProcesses == null) {
17630 Association ass = sourceProcesses.get(sourceProcess);
17631 if (ass == null || ass.mNesting <= 0) {
17635 if (ass.mNesting == 0) {
17636 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17640 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17641 boolean doingAll, long now) {
17642 if (mAdjSeq == app.adjSeq) {
17643 // This adjustment has already been computed.
17644 return app.curRawAdj;
17647 if (app.thread == null) {
17648 app.adjSeq = mAdjSeq;
17649 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17650 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17651 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17654 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17655 app.adjSource = null;
17656 app.adjTarget = null;
17658 app.cached = false;
17660 final int activitiesSize = app.activities.size();
17662 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17663 // The max adjustment doesn't allow this app to be anything
17664 // below foreground, so it is not worth doing work for it.
17665 app.adjType = "fixed";
17666 app.adjSeq = mAdjSeq;
17667 app.curRawAdj = app.maxAdj;
17668 app.foregroundActivities = false;
17669 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17670 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17671 // System processes can do UI, and when they do we want to have
17672 // them trim their memory after the user leaves the UI. To
17673 // facilitate this, here we need to determine whether or not it
17674 // is currently showing UI.
17675 app.systemNoUi = true;
17676 if (app == TOP_APP) {
17677 app.systemNoUi = false;
17678 } else if (activitiesSize > 0) {
17679 for (int j = 0; j < activitiesSize; j++) {
17680 final ActivityRecord r = app.activities.get(j);
17682 app.systemNoUi = false;
17686 if (!app.systemNoUi) {
17687 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17689 return (app.curAdj=app.maxAdj);
17692 app.systemNoUi = false;
17694 final int PROCESS_STATE_TOP = mTopProcessState;
17696 // Determine the importance of the process, starting with most
17697 // important to least, and assign an appropriate OOM adjustment.
17701 boolean foregroundActivities = false;
17702 BroadcastQueue queue;
17703 if (app == TOP_APP) {
17704 // The last app on the list is the foreground app.
17705 adj = ProcessList.FOREGROUND_APP_ADJ;
17706 schedGroup = Process.THREAD_GROUP_DEFAULT;
17707 app.adjType = "top-activity";
17708 foregroundActivities = true;
17709 procState = PROCESS_STATE_TOP;
17710 } else if (app.instrumentationClass != null) {
17711 // Don't want to kill running instrumentation.
17712 adj = ProcessList.FOREGROUND_APP_ADJ;
17713 schedGroup = Process.THREAD_GROUP_DEFAULT;
17714 app.adjType = "instrumentation";
17715 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17716 } else if ((queue = isReceivingBroadcast(app)) != null) {
17717 // An app that is currently receiving a broadcast also
17718 // counts as being in the foreground for OOM killer purposes.
17719 // It's placed in a sched group based on the nature of the
17720 // broadcast as reflected by which queue it's active in.
17721 adj = ProcessList.FOREGROUND_APP_ADJ;
17722 schedGroup = (queue == mFgBroadcastQueue)
17723 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17724 app.adjType = "broadcast";
17725 procState = ActivityManager.PROCESS_STATE_RECEIVER;
17726 } else if (app.executingServices.size() > 0) {
17727 // An app that is currently executing a service callback also
17728 // counts as being in the foreground.
17729 adj = ProcessList.FOREGROUND_APP_ADJ;
17730 schedGroup = app.execServicesFg ?
17731 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17732 app.adjType = "exec-service";
17733 procState = ActivityManager.PROCESS_STATE_SERVICE;
17734 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17736 // As far as we know the process is empty. We may change our mind later.
17737 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17738 // At this point we don't actually know the adjustment. Use the cached adj
17739 // value that the caller wants us to.
17741 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17744 app.adjType = "cch-empty";
17747 // Examine all activities if not already foreground.
17748 if (!foregroundActivities && activitiesSize > 0) {
17749 for (int j = 0; j < activitiesSize; j++) {
17750 final ActivityRecord r = app.activities.get(j);
17751 if (r.app != app) {
17752 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17753 + app + "?!? Using " + r.app + " instead.");
17757 // App has a visible activity; only upgrade adjustment.
17758 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17759 adj = ProcessList.VISIBLE_APP_ADJ;
17760 app.adjType = "visible";
17762 if (procState > PROCESS_STATE_TOP) {
17763 procState = PROCESS_STATE_TOP;
17765 schedGroup = Process.THREAD_GROUP_DEFAULT;
17766 app.cached = false;
17768 foregroundActivities = true;
17770 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17771 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17772 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17773 app.adjType = "pausing";
17775 if (procState > PROCESS_STATE_TOP) {
17776 procState = PROCESS_STATE_TOP;
17778 schedGroup = Process.THREAD_GROUP_DEFAULT;
17779 app.cached = false;
17781 foregroundActivities = true;
17782 } else if (r.state == ActivityState.STOPPING) {
17783 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17784 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17785 app.adjType = "stopping";
17787 // For the process state, we will at this point consider the
17788 // process to be cached. It will be cached either as an activity
17789 // or empty depending on whether the activity is finishing. We do
17790 // this so that we can treat the process as cached for purposes of
17791 // memory trimming (determing current memory level, trim command to
17792 // send to process) since there can be an arbitrary number of stopping
17793 // processes and they should soon all go into the cached state.
17794 if (!r.finishing) {
17795 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17796 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17799 app.cached = false;
17801 foregroundActivities = true;
17803 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17804 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17805 app.adjType = "cch-act";
17811 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17812 if (app.foregroundServices) {
17813 // The user is aware of this app, so make it visible.
17814 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17815 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17816 app.cached = false;
17817 app.adjType = "fg-service";
17818 schedGroup = Process.THREAD_GROUP_DEFAULT;
17819 } else if (app.forcingToForeground != null) {
17820 // The user is aware of this app, so make it visible.
17821 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17822 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17823 app.cached = false;
17824 app.adjType = "force-fg";
17825 app.adjSource = app.forcingToForeground;
17826 schedGroup = Process.THREAD_GROUP_DEFAULT;
17830 if (app == mHeavyWeightProcess) {
17831 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17832 // We don't want to kill the current heavy-weight process.
17833 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17834 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17835 app.cached = false;
17836 app.adjType = "heavy";
17838 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17839 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17843 if (app == mHomeProcess) {
17844 if (adj > ProcessList.HOME_APP_ADJ) {
17845 // This process is hosting what we currently consider to be the
17846 // home app, so we don't want to let it go into the background.
17847 adj = ProcessList.HOME_APP_ADJ;
17848 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17849 app.cached = false;
17850 app.adjType = "home";
17852 if (procState > ActivityManager.PROCESS_STATE_HOME) {
17853 procState = ActivityManager.PROCESS_STATE_HOME;
17857 if (app == mPreviousProcess && app.activities.size() > 0) {
17858 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17859 // This was the previous process that showed UI to the user.
17860 // We want to try to keep it around more aggressively, to give
17861 // a good experience around switching between two apps.
17862 adj = ProcessList.PREVIOUS_APP_ADJ;
17863 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17864 app.cached = false;
17865 app.adjType = "previous";
17867 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17868 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17872 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17873 + " reason=" + app.adjType);
17875 // By default, we use the computed adjustment. It may be changed if
17876 // there are applications dependent on our services or providers, but
17877 // this gives us a baseline and makes sure we don't get into an
17878 // infinite recursion.
17879 app.adjSeq = mAdjSeq;
17880 app.curRawAdj = adj;
17881 app.hasStartedServices = false;
17883 if (mBackupTarget != null && app == mBackupTarget.app) {
17884 // If possible we want to avoid killing apps while they're being backed up
17885 if (adj > ProcessList.BACKUP_APP_ADJ) {
17886 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17887 adj = ProcessList.BACKUP_APP_ADJ;
17888 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17889 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17891 app.adjType = "backup";
17892 app.cached = false;
17894 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17895 procState = ActivityManager.PROCESS_STATE_BACKUP;
17899 boolean mayBeTop = false;
17901 for (int is = app.services.size()-1;
17902 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17903 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17904 || procState > ActivityManager.PROCESS_STATE_TOP);
17906 ServiceRecord s = app.services.valueAt(is);
17907 if (s.startRequested) {
17908 app.hasStartedServices = true;
17909 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17910 procState = ActivityManager.PROCESS_STATE_SERVICE;
17912 if (app.hasShownUi && app != mHomeProcess) {
17913 // If this process has shown some UI, let it immediately
17914 // go to the LRU list because it may be pretty heavy with
17915 // UI stuff. We'll tag it with a label just to help
17916 // debug and understand what is going on.
17917 if (adj > ProcessList.SERVICE_ADJ) {
17918 app.adjType = "cch-started-ui-services";
17921 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17922 // This service has seen some activity within
17923 // recent memory, so we will keep its process ahead
17924 // of the background processes.
17925 if (adj > ProcessList.SERVICE_ADJ) {
17926 adj = ProcessList.SERVICE_ADJ;
17927 app.adjType = "started-services";
17928 app.cached = false;
17931 // If we have let the service slide into the background
17932 // state, still have some text describing what it is doing
17933 // even though the service no longer has an impact.
17934 if (adj > ProcessList.SERVICE_ADJ) {
17935 app.adjType = "cch-started-services";
17939 for (int conni = s.connections.size()-1;
17940 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17941 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17942 || procState > ActivityManager.PROCESS_STATE_TOP);
17944 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17946 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17947 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17948 || procState > ActivityManager.PROCESS_STATE_TOP);
17950 // XXX should compute this based on the max of
17951 // all connected clients.
17952 ConnectionRecord cr = clist.get(i);
17953 if (cr.binding.client == app) {
17954 // Binding to ourself is not interesting.
17957 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17958 ProcessRecord client = cr.binding.client;
17959 int clientAdj = computeOomAdjLocked(client, cachedAdj,
17960 TOP_APP, doingAll, now);
17961 int clientProcState = client.curProcState;
17962 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17963 // If the other app is cached for any reason, for purposes here
17964 // we are going to consider it empty. The specific cached state
17965 // doesn't propagate except under certain conditions.
17966 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17968 String adjType = null;
17969 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17970 // Not doing bind OOM management, so treat
17971 // this guy more like a started service.
17972 if (app.hasShownUi && app != mHomeProcess) {
17973 // If this process has shown some UI, let it immediately
17974 // go to the LRU list because it may be pretty heavy with
17975 // UI stuff. We'll tag it with a label just to help
17976 // debug and understand what is going on.
17977 if (adj > clientAdj) {
17978 adjType = "cch-bound-ui-services";
17980 app.cached = false;
17982 clientProcState = procState;
17984 if (now >= (s.lastActivity
17985 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17986 // This service has not seen activity within
17987 // recent memory, so allow it to drop to the
17988 // LRU list if there is no other reason to keep
17989 // it around. We'll also tag it with a label just
17990 // to help debug and undertand what is going on.
17991 if (adj > clientAdj) {
17992 adjType = "cch-bound-services";
17998 if (adj > clientAdj) {
17999 // If this process has recently shown UI, and
18000 // the process that is binding to it is less
18001 // important than being visible, then we don't
18002 // care about the binding as much as we care
18003 // about letting this process get into the LRU
18004 // list to be killed and restarted if needed for
18006 if (app.hasShownUi && app != mHomeProcess
18007 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18008 adjType = "cch-bound-ui-services";
18010 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18011 |Context.BIND_IMPORTANT)) != 0) {
18012 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18013 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18014 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18015 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18016 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18017 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18018 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
18021 if (adj > ProcessList.VISIBLE_APP_ADJ) {
18022 adj = ProcessList.VISIBLE_APP_ADJ;
18025 if (!client.cached) {
18026 app.cached = false;
18028 adjType = "service";
18031 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18032 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18033 schedGroup = Process.THREAD_GROUP_DEFAULT;
18035 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18036 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18037 // Special handling of clients who are in the top state.
18038 // We *may* want to consider this process to be in the
18039 // top state as well, but only if there is not another
18040 // reason for it to be running. Being on the top is a
18041 // special state, meaning you are specifically running
18042 // for the current top app. If the process is already
18043 // running in the background for some other reason, it
18044 // is more important to continue considering it to be
18045 // in the background state.
18047 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18049 // Special handling for above-top states (persistent
18050 // processes). These should not bring the current process
18051 // into the top state, since they are not on top. Instead
18052 // give them the best state after that.
18053 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18055 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18056 } else if (mWakefulness
18057 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18058 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18061 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18064 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18069 if (clientProcState <
18070 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18072 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18075 if (procState > clientProcState) {
18076 procState = clientProcState;
18078 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18079 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18080 app.pendingUiClean = true;
18082 if (adjType != null) {
18083 app.adjType = adjType;
18084 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18085 .REASON_SERVICE_IN_USE;
18086 app.adjSource = cr.binding.client;
18087 app.adjSourceProcState = clientProcState;
18088 app.adjTarget = s.name;
18091 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18092 app.treatLikeActivity = true;
18094 final ActivityRecord a = cr.activity;
18095 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18096 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18097 (a.visible || a.state == ActivityState.RESUMED
18098 || a.state == ActivityState.PAUSING)) {
18099 adj = ProcessList.FOREGROUND_APP_ADJ;
18100 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18101 schedGroup = Process.THREAD_GROUP_DEFAULT;
18103 app.cached = false;
18104 app.adjType = "service";
18105 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18106 .REASON_SERVICE_IN_USE;
18108 app.adjSourceProcState = procState;
18109 app.adjTarget = s.name;
18116 for (int provi = app.pubProviders.size()-1;
18117 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18118 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18119 || procState > ActivityManager.PROCESS_STATE_TOP);
18121 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18122 for (int i = cpr.connections.size()-1;
18123 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18124 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18125 || procState > ActivityManager.PROCESS_STATE_TOP);
18127 ContentProviderConnection conn = cpr.connections.get(i);
18128 ProcessRecord client = conn.client;
18129 if (client == app) {
18130 // Being our own client is not interesting.
18133 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18134 int clientProcState = client.curProcState;
18135 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18136 // If the other app is cached for any reason, for purposes here
18137 // we are going to consider it empty.
18138 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18140 if (adj > clientAdj) {
18141 if (app.hasShownUi && app != mHomeProcess
18142 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18143 app.adjType = "cch-ui-provider";
18145 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18146 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18147 app.adjType = "provider";
18149 app.cached &= client.cached;
18150 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18151 .REASON_PROVIDER_IN_USE;
18152 app.adjSource = client;
18153 app.adjSourceProcState = clientProcState;
18154 app.adjTarget = cpr.name;
18156 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18157 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18158 // Special handling of clients who are in the top state.
18159 // We *may* want to consider this process to be in the
18160 // top state as well, but only if there is not another
18161 // reason for it to be running. Being on the top is a
18162 // special state, meaning you are specifically running
18163 // for the current top app. If the process is already
18164 // running in the background for some other reason, it
18165 // is more important to continue considering it to be
18166 // in the background state.
18168 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18170 // Special handling for above-top states (persistent
18171 // processes). These should not bring the current process
18172 // into the top state, since they are not on top. Instead
18173 // give them the best state after that.
18175 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18178 if (procState > clientProcState) {
18179 procState = clientProcState;
18181 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18182 schedGroup = Process.THREAD_GROUP_DEFAULT;
18185 // If the provider has external (non-framework) process
18186 // dependencies, ensure that its adjustment is at least
18187 // FOREGROUND_APP_ADJ.
18188 if (cpr.hasExternalProcessHandles()) {
18189 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18190 adj = ProcessList.FOREGROUND_APP_ADJ;
18191 schedGroup = Process.THREAD_GROUP_DEFAULT;
18192 app.cached = false;
18193 app.adjType = "provider";
18194 app.adjTarget = cpr.name;
18196 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18197 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18202 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18203 // A client of one of our services or providers is in the top state. We
18204 // *may* want to be in the top state, but not if we are already running in
18205 // the background for some other reason. For the decision here, we are going
18206 // to pick out a few specific states that we want to remain in when a client
18207 // is top (states that tend to be longer-term) and otherwise allow it to go
18208 // to the top state.
18209 switch (procState) {
18210 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18211 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18212 case ActivityManager.PROCESS_STATE_SERVICE:
18213 // These all are longer-term states, so pull them up to the top
18214 // of the background states, but not all the way to the top state.
18215 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18218 // Otherwise, top is a better choice, so take it.
18219 procState = ActivityManager.PROCESS_STATE_TOP;
18224 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18225 if (app.hasClientActivities) {
18226 // This is a cached process, but with client activities. Mark it so.
18227 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18228 app.adjType = "cch-client-act";
18229 } else if (app.treatLikeActivity) {
18230 // This is a cached process, but somebody wants us to treat it like it has
18231 // an activity, okay!
18232 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18233 app.adjType = "cch-as-act";
18237 if (adj == ProcessList.SERVICE_ADJ) {
18239 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18240 mNewNumServiceProcs++;
18241 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18242 if (!app.serviceb) {
18243 // This service isn't far enough down on the LRU list to
18244 // normally be a B service, but if we are low on RAM and it
18245 // is large we want to force it down since we would prefer to
18246 // keep launcher over it.
18247 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18248 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18249 app.serviceHighRam = true;
18250 app.serviceb = true;
18251 //Slog.i(TAG, "ADJ " + app + " high ram!");
18253 mNewNumAServiceProcs++;
18254 //Slog.i(TAG, "ADJ " + app + " not high ram!");
18257 app.serviceHighRam = false;
18260 if (app.serviceb) {
18261 adj = ProcessList.SERVICE_B_ADJ;
18265 app.curRawAdj = adj;
18267 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18268 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18269 if (adj > app.maxAdj) {
18271 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18272 schedGroup = Process.THREAD_GROUP_DEFAULT;
18276 // Do final modification to adj. Everything we do between here and applying
18277 // the final setAdj must be done in this function, because we will also use
18278 // it when computing the final cached adj later. Note that we don't need to
18279 // worry about this for max adj above, since max adj will always be used to
18280 // keep it out of the cached vaues.
18281 app.curAdj = app.modifyRawOomAdj(adj);
18282 app.curSchedGroup = schedGroup;
18283 app.curProcState = procState;
18284 app.foregroundActivities = foregroundActivities;
18286 return app.curRawAdj;
18290 * Record new PSS sample for a process.
18292 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18293 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18294 proc.lastPssTime = now;
18295 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18296 if (DEBUG_PSS) Slog.d(TAG_PSS,
18297 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18298 + " state=" + ProcessList.makeProcStateString(procState));
18299 if (proc.initialIdlePss == 0) {
18300 proc.initialIdlePss = pss;
18302 proc.lastPss = pss;
18303 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18304 proc.lastCachedPss = pss;
18307 final SparseArray<Pair<Long, String>> watchUids
18308 = mMemWatchProcesses.getMap().get(proc.processName);
18310 if (watchUids != null) {
18311 Pair<Long, String> val = watchUids.get(proc.uid);
18313 val = watchUids.get(0);
18319 if (check != null) {
18320 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18321 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18322 if (!isDebuggable) {
18323 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18324 isDebuggable = true;
18327 if (isDebuggable) {
18328 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18329 final ProcessRecord myProc = proc;
18330 final File heapdumpFile = DumpHeapProvider.getJavaFile();
18331 mMemWatchDumpProcName = proc.processName;
18332 mMemWatchDumpFile = heapdumpFile.toString();
18333 mMemWatchDumpPid = proc.pid;
18334 mMemWatchDumpUid = proc.uid;
18335 BackgroundThread.getHandler().post(new Runnable() {
18337 public void run() {
18338 revokeUriPermission(ActivityThread.currentActivityThread()
18339 .getApplicationThread(),
18340 DumpHeapActivity.JAVA_URI,
18341 Intent.FLAG_GRANT_READ_URI_PERMISSION
18342 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18343 UserHandle.myUserId());
18344 ParcelFileDescriptor fd = null;
18346 heapdumpFile.delete();
18347 fd = ParcelFileDescriptor.open(heapdumpFile,
18348 ParcelFileDescriptor.MODE_CREATE |
18349 ParcelFileDescriptor.MODE_TRUNCATE |
18350 ParcelFileDescriptor.MODE_WRITE_ONLY |
18351 ParcelFileDescriptor.MODE_APPEND);
18352 IApplicationThread thread = myProc.thread;
18353 if (thread != null) {
18355 if (DEBUG_PSS) Slog.d(TAG_PSS,
18356 "Requesting dump heap from "
18357 + myProc + " to " + heapdumpFile);
18358 thread.dumpHeap(true, heapdumpFile.toString(), fd);
18359 } catch (RemoteException e) {
18362 } catch (FileNotFoundException e) {
18363 e.printStackTrace();
18368 } catch (IOException e) {
18375 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18376 + ", but debugging not enabled");
18383 * Schedule PSS collection of a process.
18385 void requestPssLocked(ProcessRecord proc, int procState) {
18386 if (mPendingPssProcesses.contains(proc)) {
18389 if (mPendingPssProcesses.size() == 0) {
18390 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18392 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18393 proc.pssProcState = procState;
18394 mPendingPssProcesses.add(proc);
18398 * Schedule PSS collection of all processes.
18400 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18402 if (now < (mLastFullPssTime +
18403 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18407 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
18408 mLastFullPssTime = now;
18409 mFullPssPending = true;
18410 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18411 mPendingPssProcesses.clear();
18412 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18413 ProcessRecord app = mLruProcesses.get(i);
18414 if (app.thread == null
18415 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18418 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18419 app.pssProcState = app.setProcState;
18420 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18421 mTestPssMode, isSleeping(), now);
18422 mPendingPssProcesses.add(app);
18425 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18428 public void setTestPssMode(boolean enabled) {
18429 synchronized (this) {
18430 mTestPssMode = enabled;
18432 // Whenever we enable the mode, we want to take a snapshot all of current
18433 // process mem use.
18434 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18440 * Ask a given process to GC right now.
18442 final void performAppGcLocked(ProcessRecord app) {
18444 app.lastRequestedGc = SystemClock.uptimeMillis();
18445 if (app.thread != null) {
18446 if (app.reportLowMemory) {
18447 app.reportLowMemory = false;
18448 app.thread.scheduleLowMemory();
18450 app.thread.processInBackground();
18453 } catch (Exception e) {
18459 * Returns true if things are idle enough to perform GCs.
18461 private final boolean canGcNowLocked() {
18462 boolean processingBroadcasts = false;
18463 for (BroadcastQueue q : mBroadcastQueues) {
18464 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18465 processingBroadcasts = true;
18468 return !processingBroadcasts
18469 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18473 * Perform GCs on all processes that are waiting for it, but only
18474 * if things are idle.
18476 final void performAppGcsLocked() {
18477 final int N = mProcessesToGc.size();
18481 if (canGcNowLocked()) {
18482 while (mProcessesToGc.size() > 0) {
18483 ProcessRecord proc = mProcessesToGc.remove(0);
18484 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18485 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18486 <= SystemClock.uptimeMillis()) {
18487 // To avoid spamming the system, we will GC processes one
18488 // at a time, waiting a few seconds between each.
18489 performAppGcLocked(proc);
18490 scheduleAppGcsLocked();
18493 // It hasn't been long enough since we last GCed this
18494 // process... put it in the list to wait for its time.
18495 addProcessToGcListLocked(proc);
18501 scheduleAppGcsLocked();
18506 * If all looks good, perform GCs on all processes waiting for them.
18508 final void performAppGcsIfAppropriateLocked() {
18509 if (canGcNowLocked()) {
18510 performAppGcsLocked();
18513 // Still not idle, wait some more.
18514 scheduleAppGcsLocked();
18518 * Schedule the execution of all pending app GCs.
18520 final void scheduleAppGcsLocked() {
18521 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18523 if (mProcessesToGc.size() > 0) {
18524 // Schedule a GC for the time to the next process.
18525 ProcessRecord proc = mProcessesToGc.get(0);
18526 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18528 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18529 long now = SystemClock.uptimeMillis();
18530 if (when < (now+GC_TIMEOUT)) {
18531 when = now + GC_TIMEOUT;
18533 mHandler.sendMessageAtTime(msg, when);
18538 * Add a process to the array of processes waiting to be GCed. Keeps the
18539 * list in sorted order by the last GC time. The process can't already be
18542 final void addProcessToGcListLocked(ProcessRecord proc) {
18543 boolean added = false;
18544 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18545 if (mProcessesToGc.get(i).lastRequestedGc <
18546 proc.lastRequestedGc) {
18548 mProcessesToGc.add(i+1, proc);
18553 mProcessesToGc.add(0, proc);
18558 * Set up to ask a process to GC itself. This will either do it
18559 * immediately, or put it on the list of processes to gc the next
18560 * time things are idle.
18562 final void scheduleAppGcLocked(ProcessRecord app) {
18563 long now = SystemClock.uptimeMillis();
18564 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18567 if (!mProcessesToGc.contains(app)) {
18568 addProcessToGcListLocked(app);
18569 scheduleAppGcsLocked();
18573 final void checkExcessivePowerUsageLocked(boolean doKills) {
18574 updateCpuStatsNow();
18576 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18577 boolean doWakeKills = doKills;
18578 boolean doCpuKills = doKills;
18579 if (mLastPowerCheckRealtime == 0) {
18580 doWakeKills = false;
18582 if (mLastPowerCheckUptime == 0) {
18583 doCpuKills = false;
18585 if (stats.isScreenOn()) {
18586 doWakeKills = false;
18588 final long curRealtime = SystemClock.elapsedRealtime();
18589 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18590 final long curUptime = SystemClock.uptimeMillis();
18591 final long uptimeSince = curUptime - mLastPowerCheckUptime;
18592 mLastPowerCheckRealtime = curRealtime;
18593 mLastPowerCheckUptime = curUptime;
18594 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18595 doWakeKills = false;
18597 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18598 doCpuKills = false;
18600 int i = mLruProcesses.size();
18603 ProcessRecord app = mLruProcesses.get(i);
18604 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18606 synchronized (stats) {
18607 wtime = stats.getProcessWakeTime(app.info.uid,
18608 app.pid, curRealtime);
18610 long wtimeUsed = wtime - app.lastWakeTime;
18611 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18613 StringBuilder sb = new StringBuilder(128);
18614 sb.append("Wake for ");
18615 app.toShortString(sb);
18616 sb.append(": over ");
18617 TimeUtils.formatDuration(realtimeSince, sb);
18618 sb.append(" used ");
18619 TimeUtils.formatDuration(wtimeUsed, sb);
18621 sb.append((wtimeUsed*100)/realtimeSince);
18623 Slog.i(TAG_POWER, sb.toString());
18625 sb.append("CPU for ");
18626 app.toShortString(sb);
18627 sb.append(": over ");
18628 TimeUtils.formatDuration(uptimeSince, sb);
18629 sb.append(" used ");
18630 TimeUtils.formatDuration(cputimeUsed, sb);
18632 sb.append((cputimeUsed*100)/uptimeSince);
18634 Slog.i(TAG_POWER, sb.toString());
18636 // If a process has held a wake lock for more
18637 // than 50% of the time during this period,
18638 // that sounds bad. Kill!
18639 if (doWakeKills && realtimeSince > 0
18640 && ((wtimeUsed*100)/realtimeSince) >= 50) {
18641 synchronized (stats) {
18642 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18643 realtimeSince, wtimeUsed);
18645 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18646 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18647 } else if (doCpuKills && uptimeSince > 0
18648 && ((cputimeUsed*100)/uptimeSince) >= 25) {
18649 synchronized (stats) {
18650 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18651 uptimeSince, cputimeUsed);
18653 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18654 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18656 app.lastWakeTime = wtime;
18657 app.lastCpuTime = app.curCpuTime;
18663 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
18665 boolean success = true;
18667 if (app.curRawAdj != app.setRawAdj) {
18668 app.setRawAdj = app.curRawAdj;
18673 if (app.curAdj != app.setAdj) {
18674 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18675 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18676 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18678 app.setAdj = app.curAdj;
18681 if (app.setSchedGroup != app.curSchedGroup) {
18682 app.setSchedGroup = app.curSchedGroup;
18683 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18684 "Setting process group of " + app.processName
18685 + " to " + app.curSchedGroup);
18686 if (app.waitingToKill != null && app.curReceiver == null
18687 && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18688 app.kill(app.waitingToKill, true);
18692 long oldId = Binder.clearCallingIdentity();
18694 Process.setProcessGroup(app.pid, app.curSchedGroup);
18695 } catch (Exception e) {
18696 Slog.w(TAG, "Failed setting process group of " + app.pid
18697 + " to " + app.curSchedGroup);
18698 e.printStackTrace();
18700 Binder.restoreCallingIdentity(oldId);
18703 if (app.thread != null) {
18705 app.thread.setSchedulingGroup(app.curSchedGroup);
18706 } catch (RemoteException e) {
18710 Process.setSwappiness(app.pid,
18711 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18714 if (app.repForegroundActivities != app.foregroundActivities) {
18715 app.repForegroundActivities = app.foregroundActivities;
18716 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18718 if (app.repProcState != app.curProcState) {
18719 app.repProcState = app.curProcState;
18720 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18721 if (app.thread != null) {
18724 //RuntimeException h = new RuntimeException("here");
18725 Slog.i(TAG, "Sending new process state " + app.repProcState
18726 + " to " + app /*, h*/);
18728 app.thread.setProcessState(app.repProcState);
18729 } catch (RemoteException e) {
18733 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18734 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18735 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18736 // Experimental code to more aggressively collect pss while
18737 // running test... the problem is that this tends to collect
18738 // the data right when a process is transitioning between process
18739 // states, which well tend to give noisy data.
18740 long start = SystemClock.uptimeMillis();
18741 long pss = Debug.getPss(app.pid, mTmpLong, null);
18742 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18743 mPendingPssProcesses.remove(app);
18744 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18745 + " to " + app.curProcState + ": "
18746 + (SystemClock.uptimeMillis()-start) + "ms");
18748 app.lastStateTime = now;
18749 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18750 mTestPssMode, isSleeping(), now);
18751 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18752 + ProcessList.makeProcStateString(app.setProcState) + " to "
18753 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18754 + (app.nextPssTime-now) + ": " + app);
18756 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18757 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18759 requestPssLocked(app, app.setProcState);
18760 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18761 mTestPssMode, isSleeping(), now);
18762 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18763 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18765 if (app.setProcState != app.curProcState) {
18766 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18767 "Proc state change of " + app.processName
18768 + " to " + app.curProcState);
18769 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18770 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18771 if (setImportant && !curImportant) {
18772 // This app is no longer something we consider important enough to allow to
18773 // use arbitrary amounts of battery power. Note
18774 // its current wake lock time to later know to kill it if
18775 // it is not behaving well.
18776 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18777 synchronized (stats) {
18778 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18779 app.pid, nowElapsed);
18781 app.lastCpuTime = app.curCpuTime;
18784 // Inform UsageStats of important process state change
18785 // Must be called before updating setProcState
18786 maybeUpdateUsageStatsLocked(app, nowElapsed);
18788 app.setProcState = app.curProcState;
18789 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18790 app.notCachedSinceIdle = false;
18793 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18795 app.procStateChanged = true;
18797 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
18798 > USAGE_STATS_INTERACTION_INTERVAL) {
18799 // For apps that sit around for a long time in the interactive state, we need
18800 // to report this at least once a day so they don't go idle.
18801 maybeUpdateUsageStatsLocked(app, nowElapsed);
18804 if (changes != 0) {
18805 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18806 "Changes in " + app + ": " + changes);
18807 int i = mPendingProcessChanges.size()-1;
18808 ProcessChangeItem item = null;
18810 item = mPendingProcessChanges.get(i);
18811 if (item.pid == app.pid) {
18812 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18813 "Re-using existing item: " + item);
18819 // No existing item in pending changes; need a new one.
18820 final int NA = mAvailProcessChanges.size();
18822 item = mAvailProcessChanges.remove(NA-1);
18823 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18824 "Retrieving available item: " + item);
18826 item = new ProcessChangeItem();
18827 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18828 "Allocating new item: " + item);
18831 item.pid = app.pid;
18832 item.uid = app.info.uid;
18833 if (mPendingProcessChanges.size() == 0) {
18834 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18835 "*** Enqueueing dispatch processes changed!");
18836 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18838 mPendingProcessChanges.add(item);
18840 item.changes |= changes;
18841 item.processState = app.repProcState;
18842 item.foregroundActivities = app.repForegroundActivities;
18843 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18844 "Item " + Integer.toHexString(System.identityHashCode(item))
18845 + " " + app.toShortString() + ": changes=" + item.changes
18846 + " procState=" + item.processState
18847 + " foreground=" + item.foregroundActivities
18848 + " type=" + app.adjType + " source=" + app.adjSource
18849 + " target=" + app.adjTarget);
18855 private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18856 if (uidRec.pendingChange == null) {
18857 if (mPendingUidChanges.size() == 0) {
18858 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18859 "*** Enqueueing dispatch uid changed!");
18860 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18862 final int NA = mAvailUidChanges.size();
18864 uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18865 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18866 "Retrieving available item: " + uidRec.pendingChange);
18868 uidRec.pendingChange = new UidRecord.ChangeItem();
18869 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18870 "Allocating new item: " + uidRec.pendingChange);
18872 uidRec.pendingChange.uidRecord = uidRec;
18873 uidRec.pendingChange.uid = uidRec.uid;
18874 mPendingUidChanges.add(uidRec.pendingChange);
18876 uidRec.pendingChange.gone = gone;
18877 uidRec.pendingChange.processState = uidRec.setProcState;
18880 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18881 String authority) {
18882 if (app == null) return;
18883 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18884 UserState userState = mStartedUsers.get(app.userId);
18885 if (userState == null) return;
18886 final long now = SystemClock.elapsedRealtime();
18887 Long lastReported = userState.mProviderLastReportedFg.get(authority);
18888 if (lastReported == null || lastReported < now - 60 * 1000L) {
18889 mUsageStatsService.reportContentProviderUsage(
18890 authority, providerPkgName, app.userId);
18891 userState.mProviderLastReportedFg.put(authority, now);
18896 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
18897 if (DEBUG_USAGE_STATS) {
18898 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18899 + "] state changes: old = " + app.setProcState + ", new = "
18900 + app.curProcState);
18902 if (mUsageStatsService == null) {
18905 boolean isInteraction;
18906 // To avoid some abuse patterns, we are going to be careful about what we consider
18907 // to be an app interaction. Being the top activity doesn't count while the display
18908 // is sleeping, nor do short foreground services.
18909 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18910 isInteraction = true;
18911 app.fgInteractionTime = 0;
18912 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18913 if (app.fgInteractionTime == 0) {
18914 app.fgInteractionTime = nowElapsed;
18915 isInteraction = false;
18917 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18920 isInteraction = app.curProcState
18921 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18922 app.fgInteractionTime = 0;
18924 if (isInteraction && (!app.reportedInteraction
18925 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
18926 app.interactionEventTime = nowElapsed;
18927 String[] packages = app.getPackageList();
18928 if (packages != null) {
18929 for (int i = 0; i < packages.length; i++) {
18930 mUsageStatsService.reportEvent(packages[i], app.userId,
18931 UsageEvents.Event.SYSTEM_INTERACTION);
18935 app.reportedInteraction = isInteraction;
18936 if (!isInteraction) {
18937 app.interactionEventTime = 0;
18941 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18942 if (proc.thread != null) {
18943 if (proc.baseProcessTracker != null) {
18944 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18946 if (proc.repProcState >= 0) {
18947 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18948 proc.repProcState);
18953 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18954 ProcessRecord TOP_APP, boolean doingAll, long now) {
18955 if (app.thread == null) {
18959 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18961 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
18964 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18966 if (isForeground != proc.foregroundServices) {
18967 proc.foregroundServices = isForeground;
18968 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18970 if (isForeground) {
18971 if (curProcs == null) {
18972 curProcs = new ArrayList<ProcessRecord>();
18973 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18975 if (!curProcs.contains(proc)) {
18976 curProcs.add(proc);
18977 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18978 proc.info.packageName, proc.info.uid);
18981 if (curProcs != null) {
18982 if (curProcs.remove(proc)) {
18983 mBatteryStatsService.noteEvent(
18984 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18985 proc.info.packageName, proc.info.uid);
18986 if (curProcs.size() <= 0) {
18987 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18993 updateOomAdjLocked();
18998 private final ActivityRecord resumedAppLocked() {
18999 ActivityRecord act = mStackSupervisor.resumedAppLocked();
19003 pkg = act.packageName;
19004 uid = act.info.applicationInfo.uid;
19009 // Has the UID or resumed package name changed?
19010 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19011 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19012 if (mCurResumedPackage != null) {
19013 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19014 mCurResumedPackage, mCurResumedUid);
19016 mCurResumedPackage = pkg;
19017 mCurResumedUid = uid;
19018 if (mCurResumedPackage != null) {
19019 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19020 mCurResumedPackage, mCurResumedUid);
19026 final boolean updateOomAdjLocked(ProcessRecord app) {
19027 final ActivityRecord TOP_ACT = resumedAppLocked();
19028 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19029 final boolean wasCached = app.cached;
19033 // This is the desired cached adjusment we want to tell it to use.
19034 // If our app is currently cached, we know it, and that is it. Otherwise,
19035 // we don't know it yet, and it needs to now be cached we will then
19036 // need to do a complete oom adj.
19037 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19038 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19039 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19040 SystemClock.uptimeMillis());
19041 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19042 // Changed to/from cached state, so apps after it in the LRU
19043 // list may also be changed.
19044 updateOomAdjLocked();
19049 final void updateOomAdjLocked() {
19050 final ActivityRecord TOP_ACT = resumedAppLocked();
19051 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19052 final long now = SystemClock.uptimeMillis();
19053 final long nowElapsed = SystemClock.elapsedRealtime();
19054 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19055 final int N = mLruProcesses.size();
19058 RuntimeException e = new RuntimeException();
19059 e.fillInStackTrace();
19060 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19063 // Reset state in all uid records.
19064 for (int i=mActiveUids.size()-1; i>=0; i--) {
19065 final UidRecord uidRec = mActiveUids.valueAt(i);
19066 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19067 "Starting update of " + uidRec);
19072 mNewNumServiceProcs = 0;
19073 mNewNumAServiceProcs = 0;
19075 final int emptyProcessLimit;
19076 final int cachedProcessLimit;
19077 if (mProcessLimit <= 0) {
19078 emptyProcessLimit = cachedProcessLimit = 0;
19079 } else if (mProcessLimit == 1) {
19080 emptyProcessLimit = 1;
19081 cachedProcessLimit = 0;
19083 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19084 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19087 // Let's determine how many processes we have running vs.
19088 // how many slots we have for background processes; we may want
19089 // to put multiple processes in a slot of there are enough of
19091 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19092 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19093 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19094 if (numEmptyProcs > cachedProcessLimit) {
19095 // If there are more empty processes than our limit on cached
19096 // processes, then use the cached process limit for the factor.
19097 // This ensures that the really old empty processes get pushed
19098 // down to the bottom, so if we are running low on memory we will
19099 // have a better chance at keeping around more cached processes
19100 // instead of a gazillion empty processes.
19101 numEmptyProcs = cachedProcessLimit;
19103 int emptyFactor = numEmptyProcs/numSlots;
19104 if (emptyFactor < 1) emptyFactor = 1;
19105 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19106 if (cachedFactor < 1) cachedFactor = 1;
19107 int stepCached = 0;
19111 int numTrimming = 0;
19113 mNumNonCachedProcs = 0;
19114 mNumCachedHiddenProcs = 0;
19116 // First update the OOM adjustment for each of the
19117 // application processes based on their current state.
19118 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19119 int nextCachedAdj = curCachedAdj+1;
19120 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19121 int nextEmptyAdj = curEmptyAdj+2;
19122 for (int i=N-1; i>=0; i--) {
19123 ProcessRecord app = mLruProcesses.get(i);
19124 if (!app.killedByAm && app.thread != null) {
19125 app.procStateChanged = false;
19126 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19128 // If we haven't yet assigned the final cached adj
19129 // to the process, do that now.
19130 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19131 switch (app.curProcState) {
19132 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19133 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19134 // This process is a cached process holding activities...
19135 // assign it the next cached value for that type, and then
19136 // step that cached level.
19137 app.curRawAdj = curCachedAdj;
19138 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19139 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19140 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19142 if (curCachedAdj != nextCachedAdj) {
19144 if (stepCached >= cachedFactor) {
19146 curCachedAdj = nextCachedAdj;
19147 nextCachedAdj += 2;
19148 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19149 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19155 // For everything else, assign next empty cached process
19156 // level and bump that up. Note that this means that
19157 // long-running services that have dropped down to the
19158 // cached level will be treated as empty (since their process
19159 // state is still as a service), which is what we want.
19160 app.curRawAdj = curEmptyAdj;
19161 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19162 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19163 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19165 if (curEmptyAdj != nextEmptyAdj) {
19167 if (stepEmpty >= emptyFactor) {
19169 curEmptyAdj = nextEmptyAdj;
19171 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19172 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19180 applyOomAdjLocked(app, true, now, nowElapsed);
19182 // Count the number of process types.
19183 switch (app.curProcState) {
19184 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19185 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19186 mNumCachedHiddenProcs++;
19188 if (numCached > cachedProcessLimit) {
19189 app.kill("cached #" + numCached, true);
19192 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19193 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19194 && app.lastActivityTime < oldTime) {
19195 app.kill("empty for "
19196 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19197 / 1000) + "s", true);
19200 if (numEmpty > emptyProcessLimit) {
19201 app.kill("empty #" + numEmpty, true);
19206 mNumNonCachedProcs++;
19210 if (app.isolated && app.services.size() <= 0) {
19211 // If this is an isolated process, and there are no
19212 // services running in it, then the process is no longer
19213 // needed. We agressively kill these because we can by
19214 // definition not re-use the same process again, and it is
19215 // good to avoid having whatever code was running in them
19216 // left sitting around after no longer needed.
19217 app.kill("isolated not needed", true);
19219 // Keeping this process, update its uid.
19220 final UidRecord uidRec = app.uidRecord;
19221 if (uidRec != null && uidRec.curProcState > app.curProcState) {
19222 uidRec.curProcState = app.curProcState;
19226 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19227 && !app.killedByAm) {
19233 mNumServiceProcs = mNewNumServiceProcs;
19235 // Now determine the memory trimming level of background processes.
19236 // Unfortunately we need to start at the back of the list to do this
19237 // properly. We only do this if the number of background apps we
19238 // are managing to keep around is less than half the maximum we desire;
19239 // if we are keeping a good number around, we'll let them use whatever
19240 // memory they want.
19241 final int numCachedAndEmpty = numCached + numEmpty;
19243 if (numCached <= ProcessList.TRIM_CACHED_APPS
19244 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19245 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19246 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19247 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19248 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19250 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19253 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19255 // We always allow the memory level to go up (better). We only allow it to go
19256 // down if we are in a state where that is allowed, *and* the total number of processes
19257 // has gone down since last time.
19258 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19259 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19260 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19261 if (memFactor > mLastMemoryLevel) {
19262 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19263 memFactor = mLastMemoryLevel;
19264 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19267 mLastMemoryLevel = memFactor;
19268 mLastNumProcesses = mLruProcesses.size();
19269 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19270 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19271 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19272 if (mLowRamStartTime == 0) {
19273 mLowRamStartTime = now;
19277 switch (memFactor) {
19278 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19279 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19281 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19282 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19285 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19288 int factor = numTrimming/3;
19290 if (mHomeProcess != null) minFactor++;
19291 if (mPreviousProcess != null) minFactor++;
19292 if (factor < minFactor) factor = minFactor;
19293 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19294 for (int i=N-1; i>=0; i--) {
19295 ProcessRecord app = mLruProcesses.get(i);
19296 if (allChanged || app.procStateChanged) {
19297 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19298 app.procStateChanged = false;
19300 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19301 && !app.killedByAm) {
19302 if (app.trimMemoryLevel < curLevel && app.thread != null) {
19304 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19305 "Trimming memory of " + app.processName + " to " + curLevel);
19306 app.thread.scheduleTrimMemory(curLevel);
19307 } catch (RemoteException e) {
19310 // For now we won't do this; our memory trimming seems
19311 // to be good enough at this point that destroying
19312 // activities causes more harm than good.
19313 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19314 && app != mHomeProcess && app != mPreviousProcess) {
19315 // Need to do this on its own message because the stack may not
19316 // be in a consistent state at this point.
19317 // For these apps we will also finish their activities
19318 // to help them free memory.
19319 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19323 app.trimMemoryLevel = curLevel;
19325 if (step >= factor) {
19327 switch (curLevel) {
19328 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19329 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19331 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19332 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19336 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19337 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19338 && app.thread != null) {
19340 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19341 "Trimming memory of heavy-weight " + app.processName
19342 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19343 app.thread.scheduleTrimMemory(
19344 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19345 } catch (RemoteException e) {
19348 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19350 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19351 || app.systemNoUi) && app.pendingUiClean) {
19352 // If this application is now in the background and it
19353 // had done UI, then give it the special trim level to
19354 // have it free UI resources.
19355 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19356 if (app.trimMemoryLevel < level && app.thread != null) {
19358 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19359 "Trimming memory of bg-ui " + app.processName
19361 app.thread.scheduleTrimMemory(level);
19362 } catch (RemoteException e) {
19365 app.pendingUiClean = false;
19367 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19369 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19370 "Trimming memory of fg " + app.processName
19371 + " to " + fgTrimLevel);
19372 app.thread.scheduleTrimMemory(fgTrimLevel);
19373 } catch (RemoteException e) {
19376 app.trimMemoryLevel = fgTrimLevel;
19380 if (mLowRamStartTime != 0) {
19381 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19382 mLowRamStartTime = 0;
19384 for (int i=N-1; i>=0; i--) {
19385 ProcessRecord app = mLruProcesses.get(i);
19386 if (allChanged || app.procStateChanged) {
19387 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19388 app.procStateChanged = false;
19390 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19391 || app.systemNoUi) && app.pendingUiClean) {
19392 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19393 && app.thread != null) {
19395 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19396 "Trimming memory of ui hidden " + app.processName
19397 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19398 app.thread.scheduleTrimMemory(
19399 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19400 } catch (RemoteException e) {
19403 app.pendingUiClean = false;
19405 app.trimMemoryLevel = 0;
19409 if (mAlwaysFinishActivities) {
19410 // Need to do this on its own message because the stack may not
19411 // be in a consistent state at this point.
19412 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19416 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19419 // Update from any uid changes.
19420 for (int i=mActiveUids.size()-1; i>=0; i--) {
19421 final UidRecord uidRec = mActiveUids.valueAt(i);
19422 if (uidRec.setProcState != uidRec.curProcState) {
19423 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19424 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19425 + " to " + uidRec.curProcState);
19426 uidRec.setProcState = uidRec.curProcState;
19427 enqueueUidChangeLocked(uidRec, false);
19431 if (mProcessStats.shouldWriteNowLocked(now)) {
19432 mHandler.post(new Runnable() {
19433 @Override public void run() {
19434 synchronized (ActivityManagerService.this) {
19435 mProcessStats.writeStateAsyncLocked();
19441 if (DEBUG_OOM_ADJ) {
19442 final long duration = SystemClock.uptimeMillis() - now;
19444 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19445 new RuntimeException("here").fillInStackTrace());
19447 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19452 final void trimApplications() {
19453 synchronized (this) {
19456 // First remove any unused application processes whose package
19457 // has been removed.
19458 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19459 final ProcessRecord app = mRemovedProcesses.get(i);
19460 if (app.activities.size() == 0
19461 && app.curReceiver == null && app.services.size() == 0) {
19463 TAG, "Exiting empty application process "
19464 + app.processName + " ("
19465 + (app.thread != null ? app.thread.asBinder() : null)
19467 if (app.pid > 0 && app.pid != MY_PID) {
19468 app.kill("empty", false);
19471 app.thread.scheduleExit();
19472 } catch (Exception e) {
19473 // Ignore exceptions.
19476 cleanUpApplicationRecordLocked(app, false, true, -1);
19477 mRemovedProcesses.remove(i);
19479 if (app.persistent) {
19480 addAppLocked(app.info, false, null /* ABI override */);
19485 // Now update the oom adj for all processes.
19486 updateOomAdjLocked();
19490 /** This method sends the specified signal to each of the persistent apps */
19491 public void signalPersistentProcesses(int sig) throws RemoteException {
19492 if (sig != Process.SIGNAL_USR1) {
19493 throw new SecurityException("Only SIGNAL_USR1 is allowed");
19496 synchronized (this) {
19497 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19498 != PackageManager.PERMISSION_GRANTED) {
19499 throw new SecurityException("Requires permission "
19500 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19503 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19504 ProcessRecord r = mLruProcesses.get(i);
19505 if (r.thread != null && r.persistent) {
19506 Process.sendSignal(r.pid, sig);
19512 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19513 if (proc == null || proc == mProfileProc) {
19514 proc = mProfileProc;
19515 profileType = mProfileType;
19516 clearProfilerLocked();
19518 if (proc == null) {
19522 proc.thread.profilerControl(false, null, profileType);
19523 } catch (RemoteException e) {
19524 throw new IllegalStateException("Process disappeared");
19528 private void clearProfilerLocked() {
19529 if (mProfileFd != null) {
19531 mProfileFd.close();
19532 } catch (IOException e) {
19535 mProfileApp = null;
19536 mProfileProc = null;
19537 mProfileFile = null;
19539 mAutoStopProfiler = false;
19540 mSamplingInterval = 0;
19543 public boolean profileControl(String process, int userId, boolean start,
19544 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19547 synchronized (this) {
19548 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19549 // its own permission.
19550 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19551 != PackageManager.PERMISSION_GRANTED) {
19552 throw new SecurityException("Requires permission "
19553 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19556 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19557 throw new IllegalArgumentException("null profile info or fd");
19560 ProcessRecord proc = null;
19561 if (process != null) {
19562 proc = findProcessLocked(process, userId, "profileControl");
19565 if (start && (proc == null || proc.thread == null)) {
19566 throw new IllegalArgumentException("Unknown process: " + process);
19570 stopProfilerLocked(null, 0);
19571 setProfileApp(proc.info, proc.processName, profilerInfo);
19572 mProfileProc = proc;
19573 mProfileType = profileType;
19574 ParcelFileDescriptor fd = profilerInfo.profileFd;
19577 } catch (IOException e) {
19580 profilerInfo.profileFd = fd;
19581 proc.thread.profilerControl(start, profilerInfo, profileType);
19585 stopProfilerLocked(proc, profileType);
19586 if (profilerInfo != null && profilerInfo.profileFd != null) {
19588 profilerInfo.profileFd.close();
19589 } catch (IOException e) {
19596 } catch (RemoteException e) {
19597 throw new IllegalStateException("Process disappeared");
19599 if (profilerInfo != null && profilerInfo.profileFd != null) {
19601 profilerInfo.profileFd.close();
19602 } catch (IOException e) {
19608 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19609 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19610 userId, true, ALLOW_FULL_ONLY, callName, null);
19611 ProcessRecord proc = null;
19613 int pid = Integer.parseInt(process);
19614 synchronized (mPidsSelfLocked) {
19615 proc = mPidsSelfLocked.get(pid);
19617 } catch (NumberFormatException e) {
19620 if (proc == null) {
19621 ArrayMap<String, SparseArray<ProcessRecord>> all
19622 = mProcessNames.getMap();
19623 SparseArray<ProcessRecord> procs = all.get(process);
19624 if (procs != null && procs.size() > 0) {
19625 proc = procs.valueAt(0);
19626 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19627 for (int i=1; i<procs.size(); i++) {
19628 ProcessRecord thisProc = procs.valueAt(i);
19629 if (thisProc.userId == userId) {
19641 public boolean dumpHeap(String process, int userId, boolean managed,
19642 String path, ParcelFileDescriptor fd) throws RemoteException {
19645 synchronized (this) {
19646 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19647 // its own permission (same as profileControl).
19648 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19649 != PackageManager.PERMISSION_GRANTED) {
19650 throw new SecurityException("Requires permission "
19651 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19655 throw new IllegalArgumentException("null fd");
19658 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19659 if (proc == null || proc.thread == null) {
19660 throw new IllegalArgumentException("Unknown process: " + process);
19663 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19664 if (!isDebuggable) {
19665 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19666 throw new SecurityException("Process not debuggable: " + proc);
19670 proc.thread.dumpHeap(managed, path, fd);
19674 } catch (RemoteException e) {
19675 throw new IllegalStateException("Process disappeared");
19680 } catch (IOException e) {
19687 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19688 String reportPackage) {
19689 if (processName != null) {
19690 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19691 "setDumpHeapDebugLimit()");
19693 synchronized (mPidsSelfLocked) {
19694 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19695 if (proc == null) {
19696 throw new SecurityException("No process found for calling pid "
19697 + Binder.getCallingPid());
19699 if (!Build.IS_DEBUGGABLE
19700 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19701 throw new SecurityException("Not running a debuggable build");
19703 processName = proc.processName;
19705 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19706 throw new SecurityException("Package " + reportPackage + " is not running in "
19711 synchronized (this) {
19712 if (maxMemSize > 0) {
19713 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19716 mMemWatchProcesses.remove(processName, uid);
19718 mMemWatchProcesses.getMap().remove(processName);
19725 public void dumpHeapFinished(String path) {
19726 synchronized (this) {
19727 if (Binder.getCallingPid() != mMemWatchDumpPid) {
19728 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19729 + " does not match last pid " + mMemWatchDumpPid);
19732 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19733 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19734 + " does not match last path " + mMemWatchDumpFile);
19737 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19738 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19742 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19743 public void monitor() {
19744 synchronized (this) { }
19747 void onCoreSettingsChange(Bundle settings) {
19748 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19749 ProcessRecord processRecord = mLruProcesses.get(i);
19751 if (processRecord.thread != null) {
19752 processRecord.thread.setCoreSettings(settings);
19754 } catch (RemoteException re) {
19760 // Multi-user methods
19763 * Start user, if its not already running, but don't bring it to foreground.
19766 public boolean startUserInBackground(final int userId) {
19767 return startUser(userId, /* foreground */ false);
19771 * Start user, if its not already running, and bring it to foreground.
19773 boolean startUserInForeground(final int userId, Dialog dlg) {
19774 boolean result = startUser(userId, /* foreground */ true);
19780 * Refreshes the list of users related to the current user when either a
19781 * user switch happens or when a new related user is started in the
19784 private void updateCurrentProfileIdsLocked() {
19785 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19786 mCurrentUserId, false /* enabledOnly */);
19787 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19788 for (int i = 0; i < currentProfileIds.length; i++) {
19789 currentProfileIds[i] = profiles.get(i).id;
19791 mCurrentProfileIds = currentProfileIds;
19793 synchronized (mUserProfileGroupIdsSelfLocked) {
19794 mUserProfileGroupIdsSelfLocked.clear();
19795 final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19796 for (int i = 0; i < users.size(); i++) {
19797 UserInfo user = users.get(i);
19798 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19799 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19805 private Set<Integer> getProfileIdsLocked(int userId) {
19806 Set<Integer> userIds = new HashSet<Integer>();
19807 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19808 userId, false /* enabledOnly */);
19809 for (UserInfo user : profiles) {
19810 userIds.add(Integer.valueOf(user.id));
19816 public boolean switchUser(final int userId) {
19817 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19819 synchronized (this) {
19820 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19821 if (userInfo == null) {
19822 Slog.w(TAG, "No user info for user #" + userId);
19825 if (userInfo.isManagedProfile()) {
19826 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19829 userName = userInfo.name;
19830 mTargetUserId = userId;
19832 mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19833 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19837 private void showUserSwitchDialog(int userId, String userName) {
19838 // The dialog will show and then initiate the user switch by calling startUserInForeground
19839 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19840 true /* above system */);
19844 private boolean startUser(final int userId, final boolean foreground) {
19845 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19846 != PackageManager.PERMISSION_GRANTED) {
19847 String msg = "Permission Denial: switchUser() from pid="
19848 + Binder.getCallingPid()
19849 + ", uid=" + Binder.getCallingUid()
19850 + " requires " + INTERACT_ACROSS_USERS_FULL;
19852 throw new SecurityException(msg);
19855 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19857 final long ident = Binder.clearCallingIdentity();
19859 synchronized (this) {
19860 final int oldUserId = mCurrentUserId;
19861 if (oldUserId == userId) {
19865 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19866 "startUser", false);
19868 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19869 if (userInfo == null) {
19870 Slog.w(TAG, "No user info for user #" + userId);
19873 if (foreground && userInfo.isManagedProfile()) {
19874 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19879 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19880 R.anim.screen_user_enter);
19883 boolean needStart = false;
19885 // If the user we are switching to is not currently started, then
19886 // we need to start it now.
19887 if (mStartedUsers.get(userId) == null) {
19888 mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19889 updateStartedUserArrayLocked();
19893 final Integer userIdInt = Integer.valueOf(userId);
19894 mUserLru.remove(userIdInt);
19895 mUserLru.add(userIdInt);
19898 mCurrentUserId = userId;
19899 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19900 updateCurrentProfileIdsLocked();
19901 mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19902 // Once the internal notion of the active user has switched, we lock the device
19903 // with the option to show the user switcher on the keyguard.
19904 mWindowManager.lockNow(null);
19906 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19907 updateCurrentProfileIdsLocked();
19908 mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19909 mUserLru.remove(currentUserIdInt);
19910 mUserLru.add(currentUserIdInt);
19913 final UserState uss = mStartedUsers.get(userId);
19915 // Make sure user is in the started state. If it is currently
19916 // stopping, we need to knock that off.
19917 if (uss.mState == UserState.STATE_STOPPING) {
19918 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19919 // so we can just fairly silently bring the user back from
19920 // the almost-dead.
19921 uss.mState = UserState.STATE_RUNNING;
19922 updateStartedUserArrayLocked();
19924 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19925 // This means ACTION_SHUTDOWN has been sent, so we will
19926 // need to treat this as a new boot of the user.
19927 uss.mState = UserState.STATE_BOOTING;
19928 updateStartedUserArrayLocked();
19932 if (uss.mState == UserState.STATE_BOOTING) {
19933 // Booting up a new user, need to tell system services about it.
19934 // Note that this is on the same handler as scheduling of broadcasts,
19935 // which is important because it needs to go first.
19936 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19940 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19942 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19943 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19944 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19945 oldUserId, userId, uss));
19946 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19947 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19951 // Send USER_STARTED broadcast
19952 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19953 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19954 | Intent.FLAG_RECEIVER_FOREGROUND);
19955 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19956 broadcastIntentLocked(null, null, intent,
19957 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19958 null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19961 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19962 if (userId != UserHandle.USER_OWNER) {
19963 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19964 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19965 broadcastIntentLocked(null, null, intent, null,
19966 new IIntentReceiver.Stub() {
19967 public void performReceive(Intent intent, int resultCode,
19968 String data, Bundle extras, boolean ordered,
19969 boolean sticky, int sendingUser) {
19970 onUserInitialized(uss, foreground, oldUserId, userId);
19972 }, 0, null, null, null, AppOpsManager.OP_NONE,
19973 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19974 uss.initializing = true;
19976 getUserManagerLocked().makeInitialized(userInfo.id);
19981 if (!uss.initializing) {
19982 moveUserToForeground(uss, oldUserId, userId);
19985 mStackSupervisor.startBackgroundUserLocked(userId, uss);
19989 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19990 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19991 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19992 broadcastIntentLocked(null, null, intent,
19993 null, new IIntentReceiver.Stub() {
19995 public void performReceive(Intent intent, int resultCode,
19996 String data, Bundle extras, boolean ordered, boolean sticky,
19997 int sendingUser) throws RemoteException {
20000 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20001 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20005 Binder.restoreCallingIdentity(ident);
20011 void dispatchForegroundProfileChanged(int userId) {
20012 final int N = mUserSwitchObservers.beginBroadcast();
20013 for (int i = 0; i < N; i++) {
20015 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
20016 } catch (RemoteException e) {
20020 mUserSwitchObservers.finishBroadcast();
20023 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
20024 long ident = Binder.clearCallingIdentity();
20027 if (oldUserId >= 0) {
20028 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
20029 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
20030 int count = profiles.size();
20031 for (int i = 0; i < count; i++) {
20032 int profileUserId = profiles.get(i).id;
20033 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
20034 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20035 | Intent.FLAG_RECEIVER_FOREGROUND);
20036 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20037 broadcastIntentLocked(null, null, intent,
20038 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20039 null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20042 if (newUserId >= 0) {
20043 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
20044 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
20045 int count = profiles.size();
20046 for (int i = 0; i < count; i++) {
20047 int profileUserId = profiles.get(i).id;
20048 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
20049 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20050 | Intent.FLAG_RECEIVER_FOREGROUND);
20051 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20052 broadcastIntentLocked(null, null, intent,
20053 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20054 null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20056 intent = new Intent(Intent.ACTION_USER_SWITCHED);
20057 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20058 | Intent.FLAG_RECEIVER_FOREGROUND);
20059 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
20060 broadcastIntentLocked(null, null, intent,
20061 null, null, 0, null, null,
20062 new String[] {android.Manifest.permission.MANAGE_USERS},
20063 AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20064 UserHandle.USER_ALL);
20067 Binder.restoreCallingIdentity(ident);
20071 void dispatchUserSwitch(final UserState uss, final int oldUserId,
20072 final int newUserId) {
20073 final int N = mUserSwitchObservers.beginBroadcast();
20075 final IRemoteCallback callback = new IRemoteCallback.Stub() {
20078 public void sendResult(Bundle data) throws RemoteException {
20079 synchronized (ActivityManagerService.this) {
20080 if (mCurUserSwitchCallback == this) {
20083 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20089 synchronized (this) {
20090 uss.switching = true;
20091 mCurUserSwitchCallback = callback;
20093 for (int i=0; i<N; i++) {
20095 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20096 newUserId, callback);
20097 } catch (RemoteException e) {
20101 synchronized (this) {
20102 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20105 mUserSwitchObservers.finishBroadcast();
20108 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20109 synchronized (this) {
20110 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20111 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20115 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20116 mCurUserSwitchCallback = null;
20117 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20118 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20119 oldUserId, newUserId, uss));
20122 void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20123 synchronized (this) {
20125 moveUserToForeground(uss, oldUserId, newUserId);
20129 completeSwitchAndInitialize(uss, newUserId, true, false);
20132 void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20133 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20135 startHomeActivityLocked(newUserId, "moveUserToFroreground");
20137 mStackSupervisor.resumeTopActivitiesLocked();
20139 EventLogTags.writeAmSwitchUser(newUserId);
20140 getUserManagerLocked().onUserForeground(newUserId);
20141 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20144 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20145 completeSwitchAndInitialize(uss, newUserId, false, true);
20148 void completeSwitchAndInitialize(UserState uss, int newUserId,
20149 boolean clearInitializing, boolean clearSwitching) {
20150 boolean unfrozen = false;
20151 synchronized (this) {
20152 if (clearInitializing) {
20153 uss.initializing = false;
20154 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20156 if (clearSwitching) {
20157 uss.switching = false;
20159 if (!uss.switching && !uss.initializing) {
20160 mWindowManager.stopFreezingScreen();
20165 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20166 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20169 stopGuestUserIfBackground();
20172 /** Called on handler thread */
20173 void dispatchUserSwitchComplete(int userId) {
20174 final int observerCount = mUserSwitchObservers.beginBroadcast();
20175 for (int i = 0; i < observerCount; i++) {
20177 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20178 } catch (RemoteException e) {
20181 mUserSwitchObservers.finishBroadcast();
20185 * Stops the guest user if it has gone to the background.
20187 private void stopGuestUserIfBackground() {
20188 synchronized (this) {
20189 final int num = mUserLru.size();
20190 for (int i = 0; i < num; i++) {
20191 Integer oldUserId = mUserLru.get(i);
20192 UserState oldUss = mStartedUsers.get(oldUserId);
20193 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20194 || oldUss.mState == UserState.STATE_STOPPING
20195 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20198 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20199 if (userInfo.isGuest()) {
20200 // This is a user to be stopped.
20201 stopUserLocked(oldUserId, null);
20208 void scheduleStartProfilesLocked() {
20209 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20210 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20211 DateUtils.SECOND_IN_MILLIS);
20215 void startProfilesLocked() {
20216 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20217 List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20218 mCurrentUserId, false /* enabledOnly */);
20219 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20220 for (UserInfo user : profiles) {
20221 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20222 && user.id != mCurrentUserId) {
20226 final int n = toStart.size();
20228 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20229 startUserInBackground(toStart.get(i).id);
20232 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20236 void finishUserBoot(UserState uss) {
20237 synchronized (this) {
20238 if (uss.mState == UserState.STATE_BOOTING
20239 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20240 uss.mState = UserState.STATE_RUNNING;
20241 final int userId = uss.mHandle.getIdentifier();
20242 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20243 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20244 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20245 broadcastIntentLocked(null, null, intent,
20246 null, null, 0, null, null,
20247 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20248 AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20254 void finishUserSwitch(UserState uss) {
20255 synchronized (this) {
20256 finishUserBoot(uss);
20258 startProfilesLocked();
20260 int num = mUserLru.size();
20262 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20263 Integer oldUserId = mUserLru.get(i);
20264 UserState oldUss = mStartedUsers.get(oldUserId);
20265 if (oldUss == null) {
20266 // Shouldn't happen, but be sane if it does.
20267 mUserLru.remove(i);
20271 if (oldUss.mState == UserState.STATE_STOPPING
20272 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20273 // This user is already stopping, doesn't count.
20278 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20279 // Owner and current can't be stopped, but count as running.
20283 // This is a user to be stopped.
20284 stopUserLocked(oldUserId, null);
20292 public int stopUser(final int userId, final IStopUserCallback callback) {
20293 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20294 != PackageManager.PERMISSION_GRANTED) {
20295 String msg = "Permission Denial: switchUser() from pid="
20296 + Binder.getCallingPid()
20297 + ", uid=" + Binder.getCallingUid()
20298 + " requires " + INTERACT_ACROSS_USERS_FULL;
20300 throw new SecurityException(msg);
20302 if (userId < 0 || userId == UserHandle.USER_OWNER) {
20303 throw new IllegalArgumentException("Can't stop primary user " + userId);
20305 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20306 synchronized (this) {
20307 return stopUserLocked(userId, callback);
20311 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20312 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20313 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20314 return ActivityManager.USER_OP_IS_CURRENT;
20317 final UserState uss = mStartedUsers.get(userId);
20319 // User is not started, nothing to do... but we do need to
20320 // callback if requested.
20321 if (callback != null) {
20322 mHandler.post(new Runnable() {
20324 public void run() {
20326 callback.userStopped(userId);
20327 } catch (RemoteException e) {
20332 return ActivityManager.USER_OP_SUCCESS;
20335 if (callback != null) {
20336 uss.mStopCallbacks.add(callback);
20339 if (uss.mState != UserState.STATE_STOPPING
20340 && uss.mState != UserState.STATE_SHUTDOWN) {
20341 uss.mState = UserState.STATE_STOPPING;
20342 updateStartedUserArrayLocked();
20344 long ident = Binder.clearCallingIdentity();
20346 // We are going to broadcast ACTION_USER_STOPPING and then
20347 // once that is done send a final ACTION_SHUTDOWN and then
20349 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20350 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20351 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20352 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20353 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20354 // This is the result receiver for the final shutdown broadcast.
20355 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20357 public void performReceive(Intent intent, int resultCode, String data,
20358 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20359 finishUserStop(uss);
20362 // This is the result receiver for the initial stopping broadcast.
20363 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20365 public void performReceive(Intent intent, int resultCode, String data,
20366 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20368 synchronized (ActivityManagerService.this) {
20369 if (uss.mState != UserState.STATE_STOPPING) {
20370 // Whoops, we are being started back up. Abort, abort!
20373 uss.mState = UserState.STATE_SHUTDOWN;
20375 mBatteryStatsService.noteEvent(
20376 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20377 Integer.toString(userId), userId);
20378 mSystemServiceManager.stopUser(userId);
20379 broadcastIntentLocked(null, null, shutdownIntent,
20380 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20381 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20384 // Kick things off.
20385 broadcastIntentLocked(null, null, stoppingIntent,
20386 null, stoppingReceiver, 0, null, null,
20387 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20388 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20390 Binder.restoreCallingIdentity(ident);
20394 return ActivityManager.USER_OP_SUCCESS;
20397 void finishUserStop(UserState uss) {
20398 final int userId = uss.mHandle.getIdentifier();
20400 ArrayList<IStopUserCallback> callbacks;
20401 synchronized (this) {
20402 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20403 if (mStartedUsers.get(userId) != uss) {
20405 } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20409 // User can no longer run.
20410 mStartedUsers.remove(userId);
20411 mUserLru.remove(Integer.valueOf(userId));
20412 updateStartedUserArrayLocked();
20414 // Clean up all state and processes associated with the user.
20415 // Kill all the processes for the user.
20416 forceStopUserLocked(userId, "finish user");
20419 // Explicitly remove the old information in mRecentTasks.
20420 mRecentTasks.removeTasksForUserLocked(userId);
20423 for (int i=0; i<callbacks.size(); i++) {
20425 if (stopped) callbacks.get(i).userStopped(userId);
20426 else callbacks.get(i).userStopAborted(userId);
20427 } catch (RemoteException e) {
20432 mSystemServiceManager.cleanupUser(userId);
20433 synchronized (this) {
20434 mStackSupervisor.removeUserLocked(userId);
20440 public UserInfo getCurrentUser() {
20441 if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20442 != PackageManager.PERMISSION_GRANTED) && (
20443 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20444 != PackageManager.PERMISSION_GRANTED)) {
20445 String msg = "Permission Denial: getCurrentUser() from pid="
20446 + Binder.getCallingPid()
20447 + ", uid=" + Binder.getCallingUid()
20448 + " requires " + INTERACT_ACROSS_USERS;
20450 throw new SecurityException(msg);
20452 synchronized (this) {
20453 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20454 return getUserManagerLocked().getUserInfo(userId);
20458 int getCurrentUserIdLocked() {
20459 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20463 public boolean isUserRunning(int userId, boolean orStopped) {
20464 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20465 != PackageManager.PERMISSION_GRANTED) {
20466 String msg = "Permission Denial: isUserRunning() from pid="
20467 + Binder.getCallingPid()
20468 + ", uid=" + Binder.getCallingUid()
20469 + " requires " + INTERACT_ACROSS_USERS;
20471 throw new SecurityException(msg);
20473 synchronized (this) {
20474 return isUserRunningLocked(userId, orStopped);
20478 boolean isUserRunningLocked(int userId, boolean orStopped) {
20479 UserState state = mStartedUsers.get(userId);
20480 if (state == null) {
20486 return state.mState != UserState.STATE_STOPPING
20487 && state.mState != UserState.STATE_SHUTDOWN;
20491 public int[] getRunningUserIds() {
20492 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20493 != PackageManager.PERMISSION_GRANTED) {
20494 String msg = "Permission Denial: isUserRunning() from pid="
20495 + Binder.getCallingPid()
20496 + ", uid=" + Binder.getCallingUid()
20497 + " requires " + INTERACT_ACROSS_USERS;
20499 throw new SecurityException(msg);
20501 synchronized (this) {
20502 return mStartedUserArray;
20506 private void updateStartedUserArrayLocked() {
20508 for (int i=0; i<mStartedUsers.size(); i++) {
20509 UserState uss = mStartedUsers.valueAt(i);
20510 // This list does not include stopping users.
20511 if (uss.mState != UserState.STATE_STOPPING
20512 && uss.mState != UserState.STATE_SHUTDOWN) {
20516 mStartedUserArray = new int[num];
20518 for (int i=0; i<mStartedUsers.size(); i++) {
20519 UserState uss = mStartedUsers.valueAt(i);
20520 if (uss.mState != UserState.STATE_STOPPING
20521 && uss.mState != UserState.STATE_SHUTDOWN) {
20522 mStartedUserArray[num] = mStartedUsers.keyAt(i);
20529 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20530 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20531 != PackageManager.PERMISSION_GRANTED) {
20532 String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20533 + Binder.getCallingPid()
20534 + ", uid=" + Binder.getCallingUid()
20535 + " requires " + INTERACT_ACROSS_USERS_FULL;
20537 throw new SecurityException(msg);
20540 mUserSwitchObservers.register(observer);
20544 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20545 mUserSwitchObservers.unregister(observer);
20548 int[] getUsersLocked() {
20549 UserManagerService ums = getUserManagerLocked();
20550 return ums != null ? ums.getUserIds() : new int[] { 0 };
20553 UserManagerService getUserManagerLocked() {
20554 if (mUserManager == null) {
20555 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20556 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20558 return mUserManager;
20561 private int applyUserId(int uid, int userId) {
20562 return UserHandle.getUid(userId, uid);
20565 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20566 if (info == null) return null;
20567 ApplicationInfo newInfo = new ApplicationInfo(info);
20568 newInfo.uid = applyUserId(info.uid, userId);
20569 newInfo.dataDir = Environment
20570 .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20571 .getAbsolutePath();
20575 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20577 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20581 ActivityInfo info = new ActivityInfo(aInfo);
20582 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20586 private final class LocalService extends ActivityManagerInternal {
20588 public void onWakefulnessChanged(int wakefulness) {
20589 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20593 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20594 String processName, String abiOverride, int uid, Runnable crashHandler) {
20595 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20596 processName, abiOverride, uid, crashHandler);
20600 public SleepToken acquireSleepToken(String tag) {
20601 Preconditions.checkNotNull(tag);
20603 synchronized (ActivityManagerService.this) {
20604 SleepTokenImpl token = new SleepTokenImpl(tag);
20605 mSleepTokens.add(token);
20606 updateSleepIfNeededLocked();
20612 public ComponentName getHomeActivityForUser(int userId) {
20613 synchronized (ActivityManagerService.this) {
20614 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20615 return homeActivity == null ? null : homeActivity.realActivity;
20620 private final class SleepTokenImpl extends SleepToken {
20621 private final String mTag;
20622 private final long mAcquireTime;
20624 public SleepTokenImpl(String tag) {
20626 mAcquireTime = SystemClock.uptimeMillis();
20630 public void release() {
20631 synchronized (ActivityManagerService.this) {
20632 if (mSleepTokens.remove(this)) {
20633 updateSleepIfNeededLocked();
20639 public String toString() {
20640 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20645 * An implementation of IAppTask, that allows an app to manage its own tasks via
20646 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
20647 * only the process that calls getAppTasks() can call the AppTask methods.
20649 class AppTaskImpl extends IAppTask.Stub {
20650 private int mTaskId;
20651 private int mCallingUid;
20653 public AppTaskImpl(int taskId, int callingUid) {
20655 mCallingUid = callingUid;
20658 private void checkCaller() {
20659 if (mCallingUid != Binder.getCallingUid()) {
20660 throw new SecurityException("Caller " + mCallingUid
20661 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20666 public void finishAndRemoveTask() {
20669 synchronized (ActivityManagerService.this) {
20670 long origId = Binder.clearCallingIdentity();
20672 if (!removeTaskByIdLocked(mTaskId, false)) {
20673 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20676 Binder.restoreCallingIdentity(origId);
20682 public ActivityManager.RecentTaskInfo getTaskInfo() {
20685 synchronized (ActivityManagerService.this) {
20686 long origId = Binder.clearCallingIdentity();
20688 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20690 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20692 return createRecentTaskInfoFromTaskRecord(tr);
20694 Binder.restoreCallingIdentity(origId);
20700 public void moveToFront() {
20702 // Will bring task to front if it already has a root activity.
20703 startActivityFromRecentsInner(mTaskId, null);
20707 public int startActivity(IBinder whoThread, String callingPackage,
20708 Intent intent, String resolvedType, Bundle options) {
20711 int callingUser = UserHandle.getCallingUserId();
20713 IApplicationThread appThread;
20714 synchronized (ActivityManagerService.this) {
20715 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20717 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20719 appThread = ApplicationThreadNative.asInterface(whoThread);
20720 if (appThread == null) {
20721 throw new IllegalArgumentException("Bad app thread " + appThread);
20724 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20725 resolvedType, null, null, null, null, 0, 0, null, null,
20726 null, options, false, callingUser, null, tr);
20730 public void setExcludeFromRecents(boolean exclude) {
20733 synchronized (ActivityManagerService.this) {
20734 long origId = Binder.clearCallingIdentity();
20736 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20738 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20740 Intent intent = tr.getBaseIntent();
20742 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20744 intent.setFlags(intent.getFlags()
20745 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20748 Binder.restoreCallingIdentity(origId);