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 number of users we allow to be running at a time.
372 static final int MAX_RUNNING_USERS = 3;
374 // How long to wait in getAssistContextExtras for the activity and foreground services
375 // to respond with the result.
376 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
378 // How long top wait when going through the modern assist (which doesn't need to block
379 // on getting this result before starting to launch its UI).
380 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
382 // Maximum number of persisted Uri grants a package is allowed
383 static final int MAX_PERSISTED_URI_GRANTS = 128;
385 static final int MY_PID = Process.myPid();
387 static final String[] EMPTY_STRING_ARRAY = new String[0];
389 // How many bytes to write into the dropbox log before truncating
390 static final int DROPBOX_MAX_SIZE = 256 * 1024;
392 // Access modes for handleIncomingUser.
393 static final int ALLOW_NON_FULL = 0;
394 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
395 static final int ALLOW_FULL_ONLY = 2;
397 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
399 // Delay in notifying task stack change listeners (in millis)
400 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
402 // Necessary ApplicationInfo flags to mark an app as persistent
403 private static final int PERSISTENT_MASK =
404 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
407 // Delay to disable app launch boost
408 static final int APP_BOOST_MESSAGE_DELAY = 3000;
409 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
410 static final int APP_BOOST_TIMEOUT = 2500;
412 private static native int nativeMigrateToBoost();
413 private static native int nativeMigrateFromBoost();
414 private boolean mIsBoosted = false;
415 private long mBoostStartTime = 0;
417 /** All system services */
418 SystemServiceManager mSystemServiceManager;
420 private Installer mInstaller;
422 /** Run all ActivityStacks through this */
423 ActivityStackSupervisor mStackSupervisor;
425 /** Task stack change listeners. */
426 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
427 new RemoteCallbackList<ITaskStackListener>();
429 public IntentFirewall mIntentFirewall;
431 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
432 // default actuion automatically. Important for devices without direct input
434 private boolean mShowDialogs = true;
436 BroadcastQueue mFgBroadcastQueue;
437 BroadcastQueue mBgBroadcastQueue;
438 // Convenient for easy iteration over the queues. Foreground is first
439 // so that dispatch of foreground broadcasts gets precedence.
440 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
442 BroadcastQueue broadcastQueueForIntent(Intent intent) {
443 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
444 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
445 "Broadcast intent " + intent + " on "
446 + (isFg ? "foreground" : "background") + " queue");
447 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
451 * Activity we have told the window manager to have key focus.
453 ActivityRecord mFocusedActivity = null;
456 * User id of the last activity mFocusedActivity was set to.
458 private int mLastFocusedUserId;
461 * If non-null, we are tracking the time the user spends in the currently focused app.
463 private AppTimeTracker mCurAppTimeTracker;
466 * List of intents that were used to start the most recent tasks.
468 private final RecentTasks mRecentTasks;
471 * For addAppTask: cached of the last activity component that was added.
473 ComponentName mLastAddedTaskComponent;
476 * For addAppTask: cached of the last activity uid that was added.
478 int mLastAddedTaskUid;
481 * For addAppTask: cached of the last ActivityInfo that was added.
483 ActivityInfo mLastAddedTaskActivity;
486 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
488 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
491 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
493 String mDeviceOwnerName;
495 public class PendingAssistExtras extends Binder implements Runnable {
496 public final ActivityRecord activity;
497 public final Bundle extras;
498 public final Intent intent;
499 public final String hint;
500 public final IResultReceiver receiver;
501 public final int userHandle;
502 public boolean haveResult = false;
503 public Bundle result = null;
504 public AssistStructure structure = null;
505 public AssistContent content = null;
506 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
507 String _hint, IResultReceiver _receiver, int _userHandle) {
508 activity = _activity;
512 receiver = _receiver;
513 userHandle = _userHandle;
517 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
518 synchronized (this) {
522 pendingAssistExtrasTimedOut(this);
526 final ArrayList<PendingAssistExtras> mPendingAssistExtras
527 = new ArrayList<PendingAssistExtras>();
530 * Process management.
532 final ProcessList mProcessList = new ProcessList();
535 * All of the applications we currently have running organized by name.
536 * The keys are strings of the application package name (as
537 * returned by the package manager), and the keys are ApplicationRecord
540 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
543 * Tracking long-term execution of processes to look for abuse and other
546 final ProcessStatsService mProcessStats;
549 * The currently running isolated processes.
551 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
554 * Counter for assigning isolated process uids, to avoid frequently reusing the
557 int mNextIsolatedProcessUid = 0;
560 * The currently running heavy-weight process, if any.
562 ProcessRecord mHeavyWeightProcess = null;
565 * The last time that various processes have crashed.
567 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
570 * Information about a process that is currently marked as bad.
572 static final class BadProcessInfo {
573 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
575 this.shortMsg = shortMsg;
576 this.longMsg = longMsg;
581 final String shortMsg;
582 final String longMsg;
587 * Set of applications that we consider to be bad, and will reject
588 * incoming broadcasts from (which the user has no control over).
589 * Processes are added to this set when they have crashed twice within
590 * a minimum amount of time; they are removed from it when they are
591 * later restarted (hopefully due to some user action). The value is the
592 * time it was added to the list.
594 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
597 * All of the processes we currently have running organized by pid.
598 * The keys are the pid running the application.
600 * <p>NOTE: This object is protected by its own lock, NOT the global
601 * activity manager lock!
603 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
606 * All of the processes that have been forced to be foreground. The key
607 * is the pid of the caller who requested it (we hold a death
610 abstract class ForegroundToken implements IBinder.DeathRecipient {
614 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
617 * List of records for processes that someone had tried to start before the
618 * system was ready. We don't start them at that point, but ensure they
619 * are started by the time booting is complete.
621 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
624 * List of persistent applications that are in the process
627 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
630 * Processes that are being forcibly torn down.
632 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
635 * List of running applications, sorted by recent usage.
636 * The first entry in the list is the least recently used.
638 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
641 * Where in mLruProcesses that the processes hosting activities start.
643 int mLruProcessActivityStart = 0;
646 * Where in mLruProcesses that the processes hosting services start.
647 * This is after (lower index) than mLruProcessesActivityStart.
649 int mLruProcessServiceStart = 0;
652 * List of processes that should gc as soon as things are idle.
654 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
657 * Processes we want to collect PSS data from.
659 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
662 * Last time we requested PSS data of all processes.
664 long mLastFullPssTime = SystemClock.uptimeMillis();
667 * If set, the next time we collect PSS data we should do a full collection
668 * with data from native processes and the kernel.
670 boolean mFullPssPending = false;
673 * This is the process holding what we currently consider to be
674 * the "home" activity.
676 ProcessRecord mHomeProcess;
679 * This is the process holding the activity the user last visited that
680 * is in a different process from the one they are currently in.
682 ProcessRecord mPreviousProcess;
685 * The time at which the previous process was last visible.
687 long mPreviousProcessVisibleTime;
690 * Track all uids that have actively running processes.
692 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
695 * Which users have been started, so are allowed to run code.
697 final SparseArray<UserState> mStartedUsers = new SparseArray<>();
700 * LRU list of history of current users. Most recently current is at the end.
702 final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
705 * Constant array of the users that are currently started.
707 int[] mStartedUserArray = new int[] { 0 };
710 * Registered observers of the user switching mechanics.
712 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
713 = new RemoteCallbackList<IUserSwitchObserver>();
716 * Currently active user switch.
718 Object mCurUserSwitchCallback;
721 * Packages that the user has asked to have run in screen size
722 * compatibility mode instead of filling the screen.
724 final CompatModePackages mCompatModePackages;
727 * Set of IntentSenderRecord objects that are currently active.
729 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
730 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
733 * Fingerprints (hashCode()) of stack traces that we've
734 * already logged DropBox entries for. Guarded by itself. If
735 * something (rogue user app) forces this over
736 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
738 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
739 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
742 * Strict Mode background batched logging state.
744 * The string buffer is guarded by itself, and its lock is also
745 * used to determine if another batched write is already
748 private final StringBuilder mStrictModeBuffer = new StringBuilder();
751 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
752 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
754 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
757 * Resolver for broadcast intents to registered receivers.
758 * Holds BroadcastFilter (subclass of IntentFilter).
760 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
761 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
763 protected boolean allowFilterResult(
764 BroadcastFilter filter, List<BroadcastFilter> dest) {
765 IBinder target = filter.receiverList.receiver.asBinder();
766 for (int i = dest.size() - 1; i >= 0; i--) {
767 if (dest.get(i).receiverList.receiver.asBinder() == target) {
775 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
776 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
777 || userId == filter.owningUserId) {
778 return super.newResult(filter, match, userId);
784 protected BroadcastFilter[] newArray(int size) {
785 return new BroadcastFilter[size];
789 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
790 return packageName.equals(filter.packageName);
795 * State of all active sticky broadcasts per user. Keys are the action of the
796 * sticky Intent, values are an ArrayList of all broadcasted intents with
797 * that action (which should usually be one). The SparseArray is keyed
798 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
799 * for stickies that are sent to all users.
801 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
802 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
804 final ActiveServices mServices;
806 final static class Association {
807 final int mSourceUid;
808 final String mSourceProcess;
809 final int mTargetUid;
810 final ComponentName mTargetComponent;
811 final String mTargetProcess;
819 Association(int sourceUid, String sourceProcess, int targetUid,
820 ComponentName targetComponent, String targetProcess) {
821 mSourceUid = sourceUid;
822 mSourceProcess = sourceProcess;
823 mTargetUid = targetUid;
824 mTargetComponent = targetComponent;
825 mTargetProcess = targetProcess;
830 * When service association tracking is enabled, this is all of the associations we
831 * have seen. Mapping is target uid -> target component -> source uid -> source process name
832 * -> association data.
834 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
835 mAssociations = new SparseArray<>();
836 boolean mTrackingAssociations;
839 * Backup/restore process management
841 String mBackupAppName = null;
842 BackupRecord mBackupTarget = null;
844 final ProviderMap mProviderMap;
847 * List of content providers who have clients waiting for them. The
848 * application is currently being launched and the provider will be
849 * removed from this list once it is published.
851 final ArrayList<ContentProviderRecord> mLaunchingProviders
852 = new ArrayList<ContentProviderRecord>();
855 * File storing persisted {@link #mGrantedUriPermissions}.
857 private final AtomicFile mGrantFile;
859 /** XML constants used in {@link #mGrantFile} */
860 private static final String TAG_URI_GRANTS = "uri-grants";
861 private static final String TAG_URI_GRANT = "uri-grant";
862 private static final String ATTR_USER_HANDLE = "userHandle";
863 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
864 private static final String ATTR_TARGET_USER_ID = "targetUserId";
865 private static final String ATTR_SOURCE_PKG = "sourcePkg";
866 private static final String ATTR_TARGET_PKG = "targetPkg";
867 private static final String ATTR_URI = "uri";
868 private static final String ATTR_MODE_FLAGS = "modeFlags";
869 private static final String ATTR_CREATED_TIME = "createdTime";
870 private static final String ATTR_PREFIX = "prefix";
873 * Global set of specific {@link Uri} permissions that have been granted.
874 * This optimized lookup structure maps from {@link UriPermission#targetUid}
875 * to {@link UriPermission#uri} to {@link UriPermission}.
878 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
879 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
881 public static class GrantUri {
882 public final int sourceUserId;
883 public final Uri uri;
884 public boolean prefix;
886 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
887 this.sourceUserId = sourceUserId;
889 this.prefix = prefix;
893 public int hashCode() {
895 hashCode = 31 * hashCode + sourceUserId;
896 hashCode = 31 * hashCode + uri.hashCode();
897 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
902 public boolean equals(Object o) {
903 if (o instanceof GrantUri) {
904 GrantUri other = (GrantUri) o;
905 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
906 && prefix == other.prefix;
912 public String toString() {
913 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
914 if (prefix) result += " [prefix]";
918 public String toSafeString() {
919 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
920 if (prefix) result += " [prefix]";
924 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
925 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
926 ContentProvider.getUriWithoutUserId(uri), false);
930 CoreSettingsObserver mCoreSettingsObserver;
933 * Thread-local storage used to carry caller permissions over through
934 * indirect content-provider access.
936 private class Identity {
937 public final IBinder token;
938 public final int pid;
939 public final int uid;
941 Identity(IBinder _token, int _pid, int _uid) {
948 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
951 * All information we have collected about the runtime performance of
952 * any user id that can impact battery performance.
954 final BatteryStatsService mBatteryStatsService;
957 * Information about component usage
959 UsageStatsManagerInternal mUsageStatsService;
962 * Access to DeviceIdleController service.
964 DeviceIdleController.LocalService mLocalDeviceIdleController;
967 * Information about and control over application operations
969 final AppOpsService mAppOpsService;
972 * Save recent tasks information across reboots.
974 final TaskPersister mTaskPersister;
977 * Current configuration information. HistoryRecord objects are given
978 * a reference to this object to indicate which configuration they are
979 * currently running in, so this object must be kept immutable.
981 Configuration mConfiguration = new Configuration();
984 * Current sequencing integer of the configuration, for skipping old
987 int mConfigurationSeq = 0;
990 * Hardware-reported OpenGLES version.
992 final int GL_ES_VERSION;
995 * List of initialization arguments to pass to all processes when binding applications to them.
996 * For example, references to the commonly used services.
998 HashMap<String, IBinder> mAppBindArgs;
1001 * Temporary to avoid allocations. Protected by main lock.
1003 final StringBuilder mStringBuilder = new StringBuilder(256);
1006 * Used to control how we initialize the service.
1008 ComponentName mTopComponent;
1009 String mTopAction = Intent.ACTION_MAIN;
1011 boolean mProcessesReady = false;
1012 boolean mSystemReady = false;
1013 boolean mBooting = false;
1014 boolean mCallFinishBooting = false;
1015 boolean mBootAnimationComplete = false;
1016 boolean mWaitingUpdate = false;
1017 boolean mDidUpdate = false;
1018 boolean mOnBattery = false;
1019 boolean mLaunchWarningShown = false;
1025 boolean mCheckedForSetup;
1028 * The time at which we will allow normal application switches again,
1029 * after a call to {@link #stopAppSwitches()}.
1031 long mAppSwitchesAllowedTime;
1034 * This is set to true after the first switch after mAppSwitchesAllowedTime
1035 * is set; any switches after that will clear the time.
1037 boolean mDidAppSwitch;
1040 * Last time (in realtime) at which we checked for power usage.
1042 long mLastPowerCheckRealtime;
1045 * Last time (in uptime) at which we checked for power usage.
1047 long mLastPowerCheckUptime;
1050 * Set while we are wanting to sleep, to prevent any
1051 * activities from being started/resumed.
1053 private boolean mSleeping = false;
1056 * The process state used for processes that are running the top activities.
1057 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1059 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1062 * Set while we are running a voice interaction. This overrides
1063 * sleeping while it is active.
1065 private IVoiceInteractionSession mRunningVoice;
1068 * For some direct access we need to power manager.
1070 PowerManagerInternal mLocalPowerManager;
1073 * We want to hold a wake lock while running a voice interaction session, since
1074 * this may happen with the screen off and we need to keep the CPU running to
1075 * be able to continue to interact with the user.
1077 PowerManager.WakeLock mVoiceWakeLock;
1080 * State of external calls telling us if the device is awake or asleep.
1082 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1085 * A list of tokens that cause the top activity to be put to sleep.
1086 * They are used by components that may hide and block interaction with underlying
1089 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1091 static final int LOCK_SCREEN_HIDDEN = 0;
1092 static final int LOCK_SCREEN_LEAVING = 1;
1093 static final int LOCK_SCREEN_SHOWN = 2;
1095 * State of external call telling us if the lock screen is shown.
1097 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1100 * Set if we are shutting down the system, similar to sleeping.
1102 boolean mShuttingDown = false;
1105 * Current sequence id for oom_adj computation traversal.
1110 * Current sequence id for process LRU updating.
1115 * Keep track of the non-cached/empty process we last found, to help
1116 * determine how to distribute cached/empty processes next time.
1118 int mNumNonCachedProcs = 0;
1121 * Keep track of the number of cached hidden procs, to balance oom adj
1122 * distribution between those and empty procs.
1124 int mNumCachedHiddenProcs = 0;
1127 * Keep track of the number of service processes we last found, to
1128 * determine on the next iteration which should be B services.
1130 int mNumServiceProcs = 0;
1131 int mNewNumAServiceProcs = 0;
1132 int mNewNumServiceProcs = 0;
1135 * Allow the current computed overall memory level of the system to go down?
1136 * This is set to false when we are killing processes for reasons other than
1137 * memory management, so that the now smaller process list will not be taken as
1138 * an indication that memory is tighter.
1140 boolean mAllowLowerMemLevel = false;
1143 * The last computed memory level, for holding when we are in a state that
1144 * processes are going away for other reasons.
1146 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1149 * The last total number of process we have, to determine if changes actually look
1150 * like a shrinking number of process due to lower RAM.
1152 int mLastNumProcesses;
1155 * The uptime of the last time we performed idle maintenance.
1157 long mLastIdleTime = SystemClock.uptimeMillis();
1160 * Total time spent with RAM that has been added in the past since the last idle time.
1162 long mLowRamTimeSinceLastIdle = 0;
1165 * If RAM is currently low, when that horrible situation started.
1167 long mLowRamStartTime = 0;
1170 * For reporting to battery stats the current top application.
1172 private String mCurResumedPackage = null;
1173 private int mCurResumedUid = -1;
1176 * For reporting to battery stats the apps currently running foreground
1177 * service. The ProcessMap is package/uid tuples; each of these contain
1178 * an array of the currently foreground processes.
1180 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1181 = new ProcessMap<ArrayList<ProcessRecord>>();
1184 * This is set if we had to do a delayed dexopt of an app before launching
1185 * it, to increase the ANR timeouts in that case.
1190 * Set if the systemServer made a call to enterSafeMode.
1195 * If true, we are running under a test environment so will sample PSS from processes
1196 * much more rapidly to try to collect better data when the tests are rapidly
1197 * running through apps.
1199 boolean mTestPssMode = false;
1201 String mDebugApp = null;
1202 boolean mWaitForDebugger = false;
1203 boolean mDebugTransient = false;
1204 String mOrigDebugApp = null;
1205 boolean mOrigWaitForDebugger = false;
1206 boolean mAlwaysFinishActivities = false;
1207 IActivityController mController = null;
1208 String mProfileApp = null;
1209 ProcessRecord mProfileProc = null;
1210 String mProfileFile;
1211 ParcelFileDescriptor mProfileFd;
1212 int mSamplingInterval = 0;
1213 boolean mAutoStopProfiler = false;
1214 int mProfileType = 0;
1215 String mOpenGlTraceApp = null;
1216 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1217 String mMemWatchDumpProcName;
1218 String mMemWatchDumpFile;
1219 int mMemWatchDumpPid;
1220 int mMemWatchDumpUid;
1222 final long[] mTmpLong = new long[1];
1224 static final class ProcessChangeItem {
1225 static final int CHANGE_ACTIVITIES = 1<<0;
1226 static final int CHANGE_PROCESS_STATE = 1<<1;
1231 boolean foregroundActivities;
1234 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1235 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1237 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1238 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1240 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1241 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1243 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1244 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1247 * Runtime CPU use collection thread. This object's lock is used to
1248 * perform synchronization with the thread (notifying it to run).
1250 final Thread mProcessCpuThread;
1253 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1254 * Must acquire this object's lock when accessing it.
1255 * NOTE: this lock will be held while doing long operations (trawling
1256 * through all processes in /proc), so it should never be acquired by
1257 * any critical paths such as when holding the main activity manager lock.
1259 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1260 MONITOR_THREAD_CPU_USAGE);
1261 final AtomicLong mLastCpuTime = new AtomicLong(0);
1262 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1264 long mLastWriteTime = 0;
1267 * Used to retain an update lock when the foreground activity is in
1270 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1273 * Set to true after the system has finished booting.
1275 boolean mBooted = false;
1277 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1278 int mProcessLimitOverride = -1;
1280 WindowManagerService mWindowManager;
1282 final ActivityThread mSystemThread;
1284 // Holds the current foreground user's id
1285 int mCurrentUserId = 0;
1286 // Holds the target user's id during a user switch
1287 int mTargetUserId = UserHandle.USER_NULL;
1288 // If there are multiple profiles for the current user, their ids are here
1289 // Currently only the primary user can have managed profiles
1290 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1293 * Mapping from each known user ID to the profile group ID it is associated with.
1295 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1297 private UserManagerService mUserManager;
1299 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1300 final ProcessRecord mApp;
1302 final IApplicationThread mAppThread;
1304 AppDeathRecipient(ProcessRecord app, int pid,
1305 IApplicationThread thread) {
1306 if (DEBUG_ALL) Slog.v(
1307 TAG, "New death recipient " + this
1308 + " for thread " + thread.asBinder());
1311 mAppThread = thread;
1315 public void binderDied() {
1316 if (DEBUG_ALL) Slog.v(
1317 TAG, "Death received in " + this
1318 + " for thread " + mAppThread.asBinder());
1319 synchronized(ActivityManagerService.this) {
1320 appDiedLocked(mApp, mPid, mAppThread, true);
1325 static final int SHOW_ERROR_MSG = 1;
1326 static final int SHOW_NOT_RESPONDING_MSG = 2;
1327 static final int SHOW_FACTORY_ERROR_MSG = 3;
1328 static final int UPDATE_CONFIGURATION_MSG = 4;
1329 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1330 static final int WAIT_FOR_DEBUGGER_MSG = 6;
1331 static final int SERVICE_TIMEOUT_MSG = 12;
1332 static final int UPDATE_TIME_ZONE = 13;
1333 static final int SHOW_UID_ERROR_MSG = 14;
1334 static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1335 static final int PROC_START_TIMEOUT_MSG = 20;
1336 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1337 static final int KILL_APPLICATION_MSG = 22;
1338 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1339 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1340 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1341 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1342 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1343 static final int CLEAR_DNS_CACHE_MSG = 28;
1344 static final int UPDATE_HTTP_PROXY_MSG = 29;
1345 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1346 static final int DISPATCH_PROCESSES_CHANGED = 31;
1347 static final int DISPATCH_PROCESS_DIED = 32;
1348 static final int REPORT_MEM_USAGE_MSG = 33;
1349 static final int REPORT_USER_SWITCH_MSG = 34;
1350 static final int CONTINUE_USER_SWITCH_MSG = 35;
1351 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1352 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1353 static final int PERSIST_URI_GRANTS_MSG = 38;
1354 static final int REQUEST_ALL_PSS_MSG = 39;
1355 static final int START_PROFILES_MSG = 40;
1356 static final int UPDATE_TIME = 41;
1357 static final int SYSTEM_USER_START_MSG = 42;
1358 static final int SYSTEM_USER_CURRENT_MSG = 43;
1359 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1360 static final int FINISH_BOOTING_MSG = 45;
1361 static final int START_USER_SWITCH_MSG = 46;
1362 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1363 static final int DISMISS_DIALOG_MSG = 48;
1364 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1365 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1366 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1367 static final int DELETE_DUMPHEAP_MSG = 52;
1368 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1369 static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1370 static final int REPORT_TIME_TRACKER_MSG = 55;
1371 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1372 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1373 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1374 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1376 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1377 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1378 static final int FIRST_COMPAT_MODE_MSG = 300;
1379 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1381 CompatModeDialog mCompatModeDialog;
1382 long mLastMemUsageReportTime = 0;
1385 * Flag whether the current user is a "monkey", i.e. whether
1386 * the UI is driven by a UI automation tool.
1388 private boolean mUserIsMonkey;
1390 /** Flag whether the device has a Recents UI */
1391 boolean mHasRecents;
1393 /** The dimensions of the thumbnails in the Recents UI. */
1394 int mThumbnailWidth;
1395 int mThumbnailHeight;
1397 final ServiceThread mHandlerThread;
1398 final MainHandler mHandler;
1399 final UiHandler mUiHandler;
1401 final class UiHandler extends Handler {
1402 public UiHandler() {
1403 super(com.android.server.UiThread.get().getLooper(), null, true);
1407 public void handleMessage(Message msg) {
1409 case SHOW_ERROR_MSG: {
1410 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1411 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1412 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1413 synchronized (ActivityManagerService.this) {
1414 ProcessRecord proc = (ProcessRecord)data.get("app");
1415 AppErrorResult res = (AppErrorResult) data.get("result");
1416 if (proc != null && proc.crashDialog != null) {
1417 Slog.e(TAG, "App already has crash dialog: " + proc);
1423 boolean isBackground = (UserHandle.getAppId(proc.uid)
1424 >= Process.FIRST_APPLICATION_UID
1425 && proc.pid != MY_PID);
1426 for (int userId : mCurrentProfileIds) {
1427 isBackground &= (proc.userId != userId);
1429 if (isBackground && !showBackground) {
1430 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1436 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1437 Dialog d = new AppErrorDialog(mContext,
1438 ActivityManagerService.this, res, proc);
1440 proc.crashDialog = d;
1442 // The device is asleep, so just pretend that the user
1443 // saw a crash dialog and hit "force quit".
1450 ensureBootCompleted();
1452 case SHOW_NOT_RESPONDING_MSG: {
1453 synchronized (ActivityManagerService.this) {
1454 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1455 ProcessRecord proc = (ProcessRecord)data.get("app");
1456 if (proc != null && proc.anrDialog != null) {
1457 Slog.e(TAG, "App already has anr dialog: " + proc);
1461 Intent intent = new Intent("android.intent.action.ANR");
1462 if (!mProcessesReady) {
1463 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1464 | Intent.FLAG_RECEIVER_FOREGROUND);
1466 broadcastIntentLocked(null, null, intent,
1467 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1468 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1471 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1472 mContext, proc, (ActivityRecord)data.get("activity"),
1477 // Just kill the app if there is no dialog to be shown.
1478 killAppAtUsersRequest(proc, null);
1482 ensureBootCompleted();
1484 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1485 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1486 synchronized (ActivityManagerService.this) {
1487 ProcessRecord proc = (ProcessRecord) data.get("app");
1489 Slog.e(TAG, "App not found when showing strict mode dialog.");
1492 if (proc.crashDialog != null) {
1493 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1496 AppErrorResult res = (AppErrorResult) data.get("result");
1497 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1498 Dialog d = new StrictModeViolationDialog(mContext,
1499 ActivityManagerService.this, res, proc);
1501 proc.crashDialog = d;
1503 // The device is asleep, so just pretend that the user
1504 // saw a crash dialog and hit "force quit".
1508 ensureBootCompleted();
1510 case SHOW_FACTORY_ERROR_MSG: {
1511 Dialog d = new FactoryErrorDialog(
1512 mContext, msg.getData().getCharSequence("msg"));
1514 ensureBootCompleted();
1516 case WAIT_FOR_DEBUGGER_MSG: {
1517 synchronized (ActivityManagerService.this) {
1518 ProcessRecord app = (ProcessRecord)msg.obj;
1519 if (msg.arg1 != 0) {
1520 if (!app.waitedForDebugger) {
1521 Dialog d = new AppWaitingForDebuggerDialog(
1522 ActivityManagerService.this,
1525 app.waitedForDebugger = true;
1529 if (app.waitDialog != null) {
1530 app.waitDialog.dismiss();
1531 app.waitDialog = null;
1536 case SHOW_UID_ERROR_MSG: {
1538 AlertDialog d = new BaseErrorDialog(mContext);
1539 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1540 d.setCancelable(false);
1541 d.setTitle(mContext.getText(R.string.android_system_label));
1542 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1543 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1544 obtainMessage(DISMISS_DIALOG_MSG, d));
1548 case SHOW_FINGERPRINT_ERROR_MSG: {
1550 AlertDialog d = new BaseErrorDialog(mContext);
1551 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1552 d.setCancelable(false);
1553 d.setTitle(mContext.getText(R.string.android_system_label));
1554 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1555 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1556 obtainMessage(DISMISS_DIALOG_MSG, d));
1560 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1561 synchronized (ActivityManagerService.this) {
1562 ActivityRecord ar = (ActivityRecord) msg.obj;
1563 if (mCompatModeDialog != null) {
1564 if (mCompatModeDialog.mAppInfo.packageName.equals(
1565 ar.info.applicationInfo.packageName)) {
1568 mCompatModeDialog.dismiss();
1569 mCompatModeDialog = null;
1571 if (ar != null && false) {
1572 if (mCompatModePackages.getPackageAskCompatModeLocked(
1574 int mode = mCompatModePackages.computeCompatModeLocked(
1575 ar.info.applicationInfo);
1576 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1577 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1578 mCompatModeDialog = new CompatModeDialog(
1579 ActivityManagerService.this, mContext,
1580 ar.info.applicationInfo);
1581 mCompatModeDialog.show();
1588 case START_USER_SWITCH_MSG: {
1589 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1592 case DISMISS_DIALOG_MSG: {
1593 final Dialog d = (Dialog) msg.obj;
1597 case DISPATCH_PROCESSES_CHANGED: {
1598 dispatchProcessesChanged();
1601 case DISPATCH_PROCESS_DIED: {
1602 final int pid = msg.arg1;
1603 final int uid = msg.arg2;
1604 dispatchProcessDied(pid, uid);
1607 case DISPATCH_UIDS_CHANGED_MSG: {
1608 dispatchUidsChanged();
1614 final class MainHandler extends Handler {
1615 public MainHandler(Looper looper) {
1616 super(looper, null, true);
1620 public void handleMessage(Message msg) {
1622 case UPDATE_CONFIGURATION_MSG: {
1623 final ContentResolver resolver = mContext.getContentResolver();
1624 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1626 case GC_BACKGROUND_PROCESSES_MSG: {
1627 synchronized (ActivityManagerService.this) {
1628 performAppGcsIfAppropriateLocked();
1631 case SERVICE_TIMEOUT_MSG: {
1634 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1636 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1639 mServices.serviceTimeout((ProcessRecord)msg.obj);
1641 case UPDATE_TIME_ZONE: {
1642 synchronized (ActivityManagerService.this) {
1643 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1644 ProcessRecord r = mLruProcesses.get(i);
1645 if (r.thread != null) {
1647 r.thread.updateTimeZone();
1648 } catch (RemoteException ex) {
1649 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1655 case CLEAR_DNS_CACHE_MSG: {
1656 synchronized (ActivityManagerService.this) {
1657 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1658 ProcessRecord r = mLruProcesses.get(i);
1659 if (r.thread != null) {
1661 r.thread.clearDnsCache();
1662 } catch (RemoteException ex) {
1663 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1669 case UPDATE_HTTP_PROXY_MSG: {
1670 ProxyInfo proxy = (ProxyInfo)msg.obj;
1673 String exclList = "";
1674 Uri pacFileUrl = Uri.EMPTY;
1675 if (proxy != null) {
1676 host = proxy.getHost();
1677 port = Integer.toString(proxy.getPort());
1678 exclList = proxy.getExclusionListAsString();
1679 pacFileUrl = proxy.getPacFileUrl();
1681 synchronized (ActivityManagerService.this) {
1682 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1683 ProcessRecord r = mLruProcesses.get(i);
1684 if (r.thread != null) {
1686 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1687 } catch (RemoteException ex) {
1688 Slog.w(TAG, "Failed to update http proxy for: " +
1689 r.info.processName);
1695 case PROC_START_TIMEOUT_MSG: {
1698 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1700 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1703 ProcessRecord app = (ProcessRecord)msg.obj;
1704 synchronized (ActivityManagerService.this) {
1705 processStartTimedOutLocked(app);
1708 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1709 ProcessRecord app = (ProcessRecord)msg.obj;
1710 synchronized (ActivityManagerService.this) {
1711 processContentProviderPublishTimedOutLocked(app);
1714 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1715 synchronized (ActivityManagerService.this) {
1716 mStackSupervisor.doPendingActivityLaunchesLocked(true);
1719 case KILL_APPLICATION_MSG: {
1720 synchronized (ActivityManagerService.this) {
1721 int appid = msg.arg1;
1722 boolean restart = (msg.arg2 == 1);
1723 Bundle bundle = (Bundle)msg.obj;
1724 String pkg = bundle.getString("pkg");
1725 String reason = bundle.getString("reason");
1726 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1727 false, UserHandle.USER_ALL, reason);
1730 case FINALIZE_PENDING_INTENT_MSG: {
1731 ((PendingIntentRecord)msg.obj).completeFinalize();
1733 case POST_HEAVY_NOTIFICATION_MSG: {
1734 INotificationManager inm = NotificationManager.getService();
1739 ActivityRecord root = (ActivityRecord)msg.obj;
1740 ProcessRecord process = root.app;
1741 if (process == null) {
1746 Context context = mContext.createPackageContext(process.info.packageName, 0);
1747 String text = mContext.getString(R.string.heavy_weight_notification,
1748 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1749 Notification notification = new Notification.Builder(context)
1750 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1754 .setColor(mContext.getColor(
1755 com.android.internal.R.color.system_notification_accent_color))
1756 .setContentTitle(text)
1758 mContext.getText(R.string.heavy_weight_notification_detail))
1759 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1760 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1761 new UserHandle(root.userId)))
1764 int[] outId = new int[1];
1765 inm.enqueueNotificationWithTag("android", "android", null,
1766 R.string.heavy_weight_notification,
1767 notification, outId, root.userId);
1768 } catch (RuntimeException e) {
1769 Slog.w(ActivityManagerService.TAG,
1770 "Error showing notification for heavy-weight app", e);
1771 } catch (RemoteException e) {
1773 } catch (NameNotFoundException e) {
1774 Slog.w(TAG, "Unable to create context for heavy notification", e);
1777 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1778 INotificationManager inm = NotificationManager.getService();
1783 inm.cancelNotificationWithTag("android", null,
1784 R.string.heavy_weight_notification, msg.arg1);
1785 } catch (RuntimeException e) {
1786 Slog.w(ActivityManagerService.TAG,
1787 "Error canceling notification for service", e);
1788 } catch (RemoteException e) {
1791 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1792 synchronized (ActivityManagerService.this) {
1793 checkExcessivePowerUsageLocked(true);
1794 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1795 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1796 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1799 case REPORT_MEM_USAGE_MSG: {
1800 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1801 Thread thread = new Thread() {
1802 @Override public void run() {
1803 reportMemUsage(memInfos);
1809 case REPORT_USER_SWITCH_MSG: {
1810 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1813 case CONTINUE_USER_SWITCH_MSG: {
1814 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1817 case USER_SWITCH_TIMEOUT_MSG: {
1818 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1821 case IMMERSIVE_MODE_LOCK_MSG: {
1822 final boolean nextState = (msg.arg1 != 0);
1823 if (mUpdateLock.isHeld() != nextState) {
1824 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1825 "Applying new update lock state '" + nextState
1826 + "' for " + (ActivityRecord)msg.obj);
1828 mUpdateLock.acquire();
1830 mUpdateLock.release();
1835 case PERSIST_URI_GRANTS_MSG: {
1836 writeGrantedUriPermissions();
1839 case REQUEST_ALL_PSS_MSG: {
1840 synchronized (ActivityManagerService.this) {
1841 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1845 case START_PROFILES_MSG: {
1846 synchronized (ActivityManagerService.this) {
1847 startProfilesLocked();
1852 synchronized (ActivityManagerService.this) {
1853 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1854 ProcessRecord r = mLruProcesses.get(i);
1855 if (r.thread != null) {
1857 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1858 } catch (RemoteException ex) {
1859 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1866 case SYSTEM_USER_START_MSG: {
1867 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1868 Integer.toString(msg.arg1), msg.arg1);
1869 mSystemServiceManager.startUser(msg.arg1);
1872 case SYSTEM_USER_CURRENT_MSG: {
1873 mBatteryStatsService.noteEvent(
1874 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1875 Integer.toString(msg.arg2), msg.arg2);
1876 mBatteryStatsService.noteEvent(
1877 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1878 Integer.toString(msg.arg1), msg.arg1);
1879 mSystemServiceManager.switchUser(msg.arg1);
1882 case ENTER_ANIMATION_COMPLETE_MSG: {
1883 synchronized (ActivityManagerService.this) {
1884 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1885 if (r != null && r.app != null && r.app.thread != null) {
1887 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1888 } catch (RemoteException e) {
1894 case FINISH_BOOTING_MSG: {
1895 if (msg.arg1 != 0) {
1898 if (msg.arg2 != 0) {
1899 enableScreenAfterBoot();
1903 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1905 Locale l = (Locale) msg.obj;
1906 IBinder service = ServiceManager.getService("mount");
1907 IMountService mountService = IMountService.Stub.asInterface(service);
1908 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1909 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1910 } catch (RemoteException e) {
1911 Log.e(TAG, "Error storing locale for decryption UI", e);
1915 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1916 synchronized (ActivityManagerService.this) {
1917 int i = mTaskStackListeners.beginBroadcast();
1921 // Make a one-way callback to the listener
1922 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1923 } catch (RemoteException e){
1924 // Handled by the RemoteCallbackList
1927 mTaskStackListeners.finishBroadcast();
1931 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1932 final int uid = msg.arg1;
1933 final byte[] firstPacket = (byte[]) msg.obj;
1935 synchronized (mPidsSelfLocked) {
1936 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1937 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1940 p.thread.notifyCleartextNetwork(firstPacket);
1941 } catch (RemoteException ignored) {
1948 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1949 final String procName;
1951 final long memLimit;
1952 final String reportPackage;
1953 synchronized (ActivityManagerService.this) {
1954 procName = mMemWatchDumpProcName;
1955 uid = mMemWatchDumpUid;
1956 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1958 val = mMemWatchProcesses.get(procName, 0);
1961 memLimit = val.first;
1962 reportPackage = val.second;
1965 reportPackage = null;
1968 if (procName == null) {
1972 if (DEBUG_PSS) Slog.d(TAG_PSS,
1973 "Showing dump heap notification from " + procName + "/" + uid);
1975 INotificationManager inm = NotificationManager.getService();
1980 String text = mContext.getString(R.string.dump_heap_notification, procName);
1983 Intent deleteIntent = new Intent();
1984 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1985 Intent intent = new Intent();
1986 intent.setClassName("android", DumpHeapActivity.class.getName());
1987 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
1988 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
1989 if (reportPackage != null) {
1990 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
1992 int userId = UserHandle.getUserId(uid);
1993 Notification notification = new Notification.Builder(mContext)
1994 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1997 .setAutoCancel(true)
1999 .setColor(mContext.getColor(
2000 com.android.internal.R.color.system_notification_accent_color))
2001 .setContentTitle(text)
2003 mContext.getText(R.string.dump_heap_notification_detail))
2004 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2005 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2006 new UserHandle(userId)))
2007 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2008 deleteIntent, 0, UserHandle.OWNER))
2012 int[] outId = new int[1];
2013 inm.enqueueNotificationWithTag("android", "android", null,
2014 R.string.dump_heap_notification,
2015 notification, outId, userId);
2016 } catch (RuntimeException e) {
2017 Slog.w(ActivityManagerService.TAG,
2018 "Error showing notification for dump heap", e);
2019 } catch (RemoteException e) {
2022 case DELETE_DUMPHEAP_MSG: {
2023 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2024 DumpHeapActivity.JAVA_URI,
2025 Intent.FLAG_GRANT_READ_URI_PERMISSION
2026 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2027 UserHandle.myUserId());
2028 synchronized (ActivityManagerService.this) {
2029 mMemWatchDumpFile = null;
2030 mMemWatchDumpProcName = null;
2031 mMemWatchDumpPid = -1;
2032 mMemWatchDumpUid = -1;
2035 case FOREGROUND_PROFILE_CHANGED_MSG: {
2036 dispatchForegroundProfileChanged(msg.arg1);
2038 case REPORT_TIME_TRACKER_MSG: {
2039 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2040 tracker.deliverResult(mContext);
2042 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2043 dispatchUserSwitchComplete(msg.arg1);
2045 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2046 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2048 connection.shutdown();
2049 } catch (RemoteException e) {
2050 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2052 // Only a UiAutomation can set this flag and now that
2053 // it is finished we make sure it is reset to its default.
2054 mUserIsMonkey = false;
2056 case APP_BOOST_DEACTIVATE_MSG : {
2057 synchronized(ActivityManagerService.this) {
2059 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2060 nativeMigrateFromBoost();
2062 mBoostStartTime = 0;
2064 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2065 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2074 static final int COLLECT_PSS_BG_MSG = 1;
2076 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2078 public void handleMessage(Message msg) {
2080 case COLLECT_PSS_BG_MSG: {
2081 long start = SystemClock.uptimeMillis();
2082 MemInfoReader memInfo = null;
2083 synchronized (ActivityManagerService.this) {
2084 if (mFullPssPending) {
2085 mFullPssPending = false;
2086 memInfo = new MemInfoReader();
2089 if (memInfo != null) {
2090 updateCpuStatsNow();
2091 long nativeTotalPss = 0;
2092 synchronized (mProcessCpuTracker) {
2093 final int N = mProcessCpuTracker.countStats();
2094 for (int j=0; j<N; j++) {
2095 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2096 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2097 // This is definitely an application process; skip it.
2100 synchronized (mPidsSelfLocked) {
2101 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2102 // This is one of our own processes; skip it.
2106 nativeTotalPss += Debug.getPss(st.pid, null, null);
2109 memInfo.readMemInfo();
2110 synchronized (ActivityManagerService.this) {
2111 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2112 + (SystemClock.uptimeMillis()-start) + "ms");
2113 final long cachedKb = memInfo.getCachedSizeKb();
2114 final long freeKb = memInfo.getFreeSizeKb();
2115 final long zramKb = memInfo.getZramTotalSizeKb();
2116 final long kernelKb = memInfo.getKernelUsedSizeKb();
2117 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2118 kernelKb*1024, nativeTotalPss*1024);
2119 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2125 long[] tmp = new long[1];
2131 synchronized (ActivityManagerService.this) {
2132 if (mPendingPssProcesses.size() <= 0) {
2133 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2134 "Collected PSS of " + num + " processes in "
2135 + (SystemClock.uptimeMillis() - start) + "ms");
2136 mPendingPssProcesses.clear();
2139 proc = mPendingPssProcesses.remove(0);
2140 procState = proc.pssProcState;
2141 lastPssTime = proc.lastPssTime;
2142 if (proc.thread != null && procState == proc.setProcState
2143 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2144 < SystemClock.uptimeMillis()) {
2152 long pss = Debug.getPss(pid, tmp, null);
2153 synchronized (ActivityManagerService.this) {
2154 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2155 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2157 recordPssSampleLocked(proc, procState, pss, tmp[0],
2158 SystemClock.uptimeMillis());
2168 public void setSystemProcess() {
2170 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2171 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2172 ServiceManager.addService("meminfo", new MemBinder(this));
2173 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2174 ServiceManager.addService("dbinfo", new DbBinder(this));
2175 if (MONITOR_CPU_USAGE) {
2176 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2178 ServiceManager.addService("permission", new PermissionController(this));
2179 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2181 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2182 "android", STOCK_PM_FLAGS);
2183 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2185 synchronized (this) {
2186 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2187 app.persistent = true;
2189 app.maxAdj = ProcessList.SYSTEM_ADJ;
2190 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2191 synchronized (mPidsSelfLocked) {
2192 mPidsSelfLocked.put(app.pid, app);
2194 updateLruProcessLocked(app, false, null);
2195 updateOomAdjLocked();
2197 } catch (PackageManager.NameNotFoundException e) {
2198 throw new RuntimeException(
2199 "Unable to find android system package", e);
2203 public void setWindowManager(WindowManagerService wm) {
2204 mWindowManager = wm;
2205 mStackSupervisor.setWindowManager(wm);
2208 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2209 mUsageStatsService = usageStatsManager;
2212 public void startObservingNativeCrashes() {
2213 final NativeCrashListener ncl = new NativeCrashListener(this);
2217 public IAppOpsService getAppOpsService() {
2218 return mAppOpsService;
2221 static class MemBinder extends Binder {
2222 ActivityManagerService mActivityManagerService;
2223 MemBinder(ActivityManagerService activityManagerService) {
2224 mActivityManagerService = activityManagerService;
2228 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2229 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2230 != PackageManager.PERMISSION_GRANTED) {
2231 pw.println("Permission Denial: can't dump meminfo from from pid="
2232 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2233 + " without permission " + android.Manifest.permission.DUMP);
2237 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2241 static class GraphicsBinder extends Binder {
2242 ActivityManagerService mActivityManagerService;
2243 GraphicsBinder(ActivityManagerService activityManagerService) {
2244 mActivityManagerService = activityManagerService;
2248 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2249 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2250 != PackageManager.PERMISSION_GRANTED) {
2251 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2252 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2253 + " without permission " + android.Manifest.permission.DUMP);
2257 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2261 static class DbBinder extends Binder {
2262 ActivityManagerService mActivityManagerService;
2263 DbBinder(ActivityManagerService activityManagerService) {
2264 mActivityManagerService = activityManagerService;
2268 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2269 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2270 != PackageManager.PERMISSION_GRANTED) {
2271 pw.println("Permission Denial: can't dump dbinfo from from pid="
2272 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2273 + " without permission " + android.Manifest.permission.DUMP);
2277 mActivityManagerService.dumpDbInfo(fd, pw, args);
2281 static class CpuBinder extends Binder {
2282 ActivityManagerService mActivityManagerService;
2283 CpuBinder(ActivityManagerService activityManagerService) {
2284 mActivityManagerService = activityManagerService;
2288 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2289 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2290 != PackageManager.PERMISSION_GRANTED) {
2291 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2292 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2293 + " without permission " + android.Manifest.permission.DUMP);
2297 synchronized (mActivityManagerService.mProcessCpuTracker) {
2298 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2299 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2300 SystemClock.uptimeMillis()));
2305 public static final class Lifecycle extends SystemService {
2306 private final ActivityManagerService mService;
2308 public Lifecycle(Context context) {
2310 mService = new ActivityManagerService(context);
2314 public void onStart() {
2318 public ActivityManagerService getService() {
2323 // Note: This method is invoked on the main thread but may need to attach various
2324 // handlers to other threads. So take care to be explicit about the looper.
2325 public ActivityManagerService(Context systemContext) {
2326 mContext = systemContext;
2327 mFactoryTest = FactoryTest.getMode();
2328 mSystemThread = ActivityThread.currentActivityThread();
2330 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2332 mHandlerThread = new ServiceThread(TAG,
2333 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2334 mHandlerThread.start();
2335 mHandler = new MainHandler(mHandlerThread.getLooper());
2336 mUiHandler = new UiHandler();
2338 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2339 "foreground", BROADCAST_FG_TIMEOUT, false);
2340 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2341 "background", BROADCAST_BG_TIMEOUT, true);
2342 mBroadcastQueues[0] = mFgBroadcastQueue;
2343 mBroadcastQueues[1] = mBgBroadcastQueue;
2345 mServices = new ActiveServices(this);
2346 mProviderMap = new ProviderMap(this);
2348 // TODO: Move creation of battery stats service outside of activity manager service.
2349 File dataDir = Environment.getDataDirectory();
2350 File systemDir = new File(dataDir, "system");
2352 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2353 mBatteryStatsService.getActiveStatistics().readLocked();
2354 mBatteryStatsService.scheduleWriteToDisk();
2355 mOnBattery = DEBUG_POWER ? true
2356 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2357 mBatteryStatsService.getActiveStatistics().setCallback(this);
2359 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2361 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2363 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2365 // User 0 is the first and only user that runs at boot.
2366 mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2367 mUserLru.add(UserHandle.USER_OWNER);
2368 updateStartedUserArrayLocked();
2370 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2371 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2373 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2375 mConfiguration.setToDefaults();
2376 mConfiguration.setLocale(Locale.getDefault());
2378 mConfigurationSeq = mConfiguration.seq = 1;
2379 mProcessCpuTracker.init();
2381 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2382 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2383 mRecentTasks = new RecentTasks(this);
2384 mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2385 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2387 mProcessCpuThread = new Thread("CpuTracker") {
2393 synchronized(this) {
2394 final long now = SystemClock.uptimeMillis();
2395 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2396 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2397 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2398 // + ", write delay=" + nextWriteDelay);
2399 if (nextWriteDelay < nextCpuDelay) {
2400 nextCpuDelay = nextWriteDelay;
2402 if (nextCpuDelay > 0) {
2403 mProcessCpuMutexFree.set(true);
2404 this.wait(nextCpuDelay);
2407 } catch (InterruptedException e) {
2409 updateCpuStatsNow();
2410 } catch (Exception e) {
2411 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2417 Watchdog.getInstance().addMonitor(this);
2418 Watchdog.getInstance().addThread(mHandler);
2421 public void setSystemServiceManager(SystemServiceManager mgr) {
2422 mSystemServiceManager = mgr;
2425 public void setInstaller(Installer installer) {
2426 mInstaller = installer;
2429 private void start() {
2430 Process.removeAllProcessGroups();
2431 mProcessCpuThread.start();
2433 mBatteryStatsService.publish(mContext);
2434 mAppOpsService.publish(mContext);
2435 Slog.d("AppOps", "AppOpsService published");
2436 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2439 public void initPowerManagement() {
2440 mStackSupervisor.initPowerManagement();
2441 mBatteryStatsService.initPowerManagement();
2442 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2443 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2444 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2445 mVoiceWakeLock.setReferenceCounted(false);
2449 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2450 throws RemoteException {
2451 if (code == SYSPROPS_TRANSACTION) {
2452 // We need to tell all apps about the system property change.
2453 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2454 synchronized(this) {
2455 final int NP = mProcessNames.getMap().size();
2456 for (int ip=0; ip<NP; ip++) {
2457 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2458 final int NA = apps.size();
2459 for (int ia=0; ia<NA; ia++) {
2460 ProcessRecord app = apps.valueAt(ia);
2461 if (app.thread != null) {
2462 procs.add(app.thread.asBinder());
2468 int N = procs.size();
2469 for (int i=0; i<N; i++) {
2470 Parcel data2 = Parcel.obtain();
2472 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2473 } catch (RemoteException e) {
2479 return super.onTransact(code, data, reply, flags);
2480 } catch (RuntimeException e) {
2481 // The activity manager only throws security exceptions, so let's
2483 if (!(e instanceof SecurityException)) {
2484 Slog.wtf(TAG, "Activity Manager Crash", e);
2490 void updateCpuStats() {
2491 final long now = SystemClock.uptimeMillis();
2492 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2495 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2496 synchronized (mProcessCpuThread) {
2497 mProcessCpuThread.notify();
2502 void updateCpuStatsNow() {
2503 synchronized (mProcessCpuTracker) {
2504 mProcessCpuMutexFree.set(false);
2505 final long now = SystemClock.uptimeMillis();
2506 boolean haveNewCpuStats = false;
2508 if (MONITOR_CPU_USAGE &&
2509 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2510 mLastCpuTime.set(now);
2511 mProcessCpuTracker.update();
2512 if (mProcessCpuTracker.hasGoodLastStats()) {
2513 haveNewCpuStats = true;
2514 //Slog.i(TAG, mProcessCpu.printCurrentState());
2515 //Slog.i(TAG, "Total CPU usage: "
2516 // + mProcessCpu.getTotalCpuPercent() + "%");
2518 // Slog the cpu usage if the property is set.
2519 if ("true".equals(SystemProperties.get("events.cpu"))) {
2520 int user = mProcessCpuTracker.getLastUserTime();
2521 int system = mProcessCpuTracker.getLastSystemTime();
2522 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2523 int irq = mProcessCpuTracker.getLastIrqTime();
2524 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2525 int idle = mProcessCpuTracker.getLastIdleTime();
2527 int total = user + system + iowait + irq + softIrq + idle;
2528 if (total == 0) total = 1;
2530 EventLog.writeEvent(EventLogTags.CPU,
2531 ((user+system+iowait+irq+softIrq) * 100) / total,
2532 (user * 100) / total,
2533 (system * 100) / total,
2534 (iowait * 100) / total,
2535 (irq * 100) / total,
2536 (softIrq * 100) / total);
2541 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2542 synchronized(bstats) {
2543 synchronized(mPidsSelfLocked) {
2544 if (haveNewCpuStats) {
2545 if (bstats.startAddingCpuLocked()) {
2548 final int N = mProcessCpuTracker.countStats();
2549 for (int i=0; i<N; i++) {
2550 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2554 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2555 totalUTime += st.rel_utime;
2556 totalSTime += st.rel_stime;
2558 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2559 if (ps == null || !ps.isActive()) {
2560 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2561 pr.info.uid, pr.processName);
2563 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2564 pr.curCpuTime += st.rel_utime + st.rel_stime;
2566 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2567 if (ps == null || !ps.isActive()) {
2568 st.batteryStats = ps = bstats.getProcessStatsLocked(
2569 bstats.mapUid(st.uid), st.name);
2571 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2574 final int userTime = mProcessCpuTracker.getLastUserTime();
2575 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2576 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2577 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2578 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2579 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2580 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2581 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2586 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2587 mLastWriteTime = now;
2588 mBatteryStatsService.scheduleWriteToDisk();
2595 public void batteryNeedsCpuUpdate() {
2596 updateCpuStatsNow();
2600 public void batteryPowerChanged(boolean onBattery) {
2601 // When plugging in, update the CPU stats first before changing
2603 updateCpuStatsNow();
2604 synchronized (this) {
2605 synchronized(mPidsSelfLocked) {
2606 mOnBattery = DEBUG_POWER ? true : onBattery;
2612 public void batterySendBroadcast(Intent intent) {
2613 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2614 AppOpsManager.OP_NONE, null, false, false,
2615 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2619 * Initialize the application bind args. These are passed to each
2620 * process when the bindApplication() IPC is sent to the process. They're
2621 * lazily setup to make sure the services are running when they're asked for.
2623 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2624 if (mAppBindArgs == null) {
2625 mAppBindArgs = new HashMap<>();
2627 // Isolated processes won't get this optimization, so that we don't
2628 // violate the rules about which services they have access to.
2630 // Setup the application init args
2631 mAppBindArgs.put("package", ServiceManager.getService("package"));
2632 mAppBindArgs.put("window", ServiceManager.getService("window"));
2633 mAppBindArgs.put(Context.ALARM_SERVICE,
2634 ServiceManager.getService(Context.ALARM_SERVICE));
2637 return mAppBindArgs;
2640 final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2641 if (r != null && mFocusedActivity != r) {
2642 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2643 ActivityRecord last = mFocusedActivity;
2644 mFocusedActivity = r;
2645 if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2646 && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2647 if (mCurAppTimeTracker != r.appTimeTracker) {
2648 // We are switching app tracking. Complete the current one.
2649 if (mCurAppTimeTracker != null) {
2650 mCurAppTimeTracker.stop();
2651 mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2652 mCurAppTimeTracker).sendToTarget();
2653 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2654 mCurAppTimeTracker = null;
2656 if (r.appTimeTracker != null) {
2657 mCurAppTimeTracker = r.appTimeTracker;
2658 startTimeTrackingFocusedActivityLocked();
2661 startTimeTrackingFocusedActivityLocked();
2664 r.appTimeTracker = null;
2666 if (r.task != null && r.task.voiceInteractor != null) {
2667 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2669 finishRunningVoiceLocked();
2670 if (last != null && last.task.voiceSession != null) {
2671 // We had been in a voice interaction session, but now focused has
2672 // move to something different. Just finish the session, we can't
2673 // return to it and retain the proper state and synchronization with
2674 // the voice interaction service.
2675 finishVoiceTask(last.task.voiceSession);
2678 if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2679 mWindowManager.setFocusedApp(r.appToken, true);
2681 applyUpdateLockStateLocked(r);
2682 if (mFocusedActivity.userId != mLastFocusedUserId) {
2683 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2684 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2685 mFocusedActivity.userId, 0));
2686 mLastFocusedUserId = mFocusedActivity.userId;
2689 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2690 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2691 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2694 final void clearFocusedActivity(ActivityRecord r) {
2695 if (mFocusedActivity == r) {
2696 ActivityStack stack = mStackSupervisor.getFocusedStack();
2697 if (stack != null) {
2698 ActivityRecord top = stack.topActivity();
2699 if (top != null && top.userId != mLastFocusedUserId) {
2700 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2701 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2703 mLastFocusedUserId = top.userId;
2706 mFocusedActivity = null;
2707 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2712 public void setFocusedStack(int stackId) {
2713 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2714 synchronized (ActivityManagerService.this) {
2715 ActivityStack stack = mStackSupervisor.getStack(stackId);
2716 if (stack != null) {
2717 ActivityRecord r = stack.topRunningActivityLocked(null);
2719 setFocusedActivityLocked(r, "setFocusedStack");
2720 mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2726 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2728 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2729 synchronized (ActivityManagerService.this) {
2730 if (listener != null) {
2731 mTaskStackListeners.register(listener);
2737 public void notifyActivityDrawn(IBinder token) {
2738 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2739 synchronized (this) {
2740 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2742 r.task.stack.notifyActivityDrawnLocked(r);
2747 final void applyUpdateLockStateLocked(ActivityRecord r) {
2748 // Modifications to the UpdateLock state are done on our handler, outside
2749 // the activity manager's locks. The new state is determined based on the
2750 // state *now* of the relevant activity record. The object is passed to
2751 // the handler solely for logging detail, not to be consulted/modified.
2752 final boolean nextState = r != null && r.immersive;
2753 mHandler.sendMessage(
2754 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2757 final void showAskCompatModeDialogLocked(ActivityRecord r) {
2758 Message msg = Message.obtain();
2759 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2760 msg.obj = r.task.askedCompatMode ? null : r;
2761 mUiHandler.sendMessage(msg);
2764 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2765 String what, Object obj, ProcessRecord srcApp) {
2766 app.lastActivityTime = now;
2768 if (app.activities.size() > 0) {
2769 // Don't want to touch dependent processes that are hosting activities.
2773 int lrui = mLruProcesses.lastIndexOf(app);
2775 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2776 + what + " " + obj + " from " + srcApp);
2780 if (lrui >= index) {
2781 // Don't want to cause this to move dependent processes *back* in the
2782 // list as if they were less frequently used.
2786 if (lrui >= mLruProcessActivityStart) {
2787 // Don't want to touch dependent processes that are hosting activities.
2791 mLruProcesses.remove(lrui);
2795 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2796 + " in LRU list: " + app);
2797 mLruProcesses.add(index, app);
2801 private static void killProcessGroup(int uid, int pid) {
2802 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2803 Process.killProcessGroup(uid, pid);
2804 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2807 final void removeLruProcessLocked(ProcessRecord app) {
2808 int lrui = mLruProcesses.lastIndexOf(app);
2811 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2812 Process.killProcessQuiet(app.pid);
2813 killProcessGroup(app.info.uid, app.pid);
2815 if (lrui <= mLruProcessActivityStart) {
2816 mLruProcessActivityStart--;
2818 if (lrui <= mLruProcessServiceStart) {
2819 mLruProcessServiceStart--;
2821 mLruProcesses.remove(lrui);
2825 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2826 ProcessRecord client) {
2827 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2828 || app.treatLikeActivity;
2829 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2830 if (!activityChange && hasActivity) {
2831 // The process has activities, so we are only allowing activity-based adjustments
2832 // to move it. It should be kept in the front of the list with other
2833 // processes that have activities, and we don't want those to change their
2834 // order except due to activity operations.
2839 final long now = SystemClock.uptimeMillis();
2840 app.lastActivityTime = now;
2842 // First a quick reject: if the app is already at the position we will
2843 // put it, then there is nothing to do.
2845 final int N = mLruProcesses.size();
2846 if (N > 0 && mLruProcesses.get(N-1) == app) {
2847 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2851 if (mLruProcessServiceStart > 0
2852 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2853 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2858 int lrui = mLruProcesses.lastIndexOf(app);
2860 if (app.persistent && lrui >= 0) {
2861 // We don't care about the position of persistent processes, as long as
2862 // they are in the list.
2863 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2867 /* In progress: compute new position first, so we can avoid doing work
2868 if the process is not actually going to move. Not yet working.
2871 boolean inActivity = false, inService = false;
2873 // Process has activities, put it at the very tipsy-top.
2874 addIndex = mLruProcesses.size();
2875 nextIndex = mLruProcessServiceStart;
2877 } else if (hasService) {
2878 // Process has services, put it at the top of the service list.
2879 addIndex = mLruProcessActivityStart;
2880 nextIndex = mLruProcessServiceStart;
2884 // Process not otherwise of interest, it goes to the top of the non-service area.
2885 addIndex = mLruProcessServiceStart;
2886 if (client != null) {
2887 int clientIndex = mLruProcesses.lastIndexOf(client);
2888 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2890 if (clientIndex >= 0 && addIndex > clientIndex) {
2891 addIndex = clientIndex;
2894 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2897 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2898 + mLruProcessActivityStart + "): " + app);
2902 if (lrui < mLruProcessActivityStart) {
2903 mLruProcessActivityStart--;
2905 if (lrui < mLruProcessServiceStart) {
2906 mLruProcessServiceStart--;
2909 if (addIndex > lrui) {
2912 if (nextIndex > lrui) {
2916 mLruProcesses.remove(lrui);
2920 mLruProcesses.add(addIndex, app);
2922 mLruProcessActivityStart++;
2925 mLruProcessActivityStart++;
2931 final int N = mLruProcesses.size();
2932 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2933 // Process doesn't have activities, but has clients with
2934 // activities... move it up, but one below the top (the top
2935 // should always have a real activity).
2936 if (DEBUG_LRU) Slog.d(TAG_LRU,
2937 "Adding to second-top of LRU activity list: " + app);
2938 mLruProcesses.add(N - 1, app);
2939 // To keep it from spamming the LRU list (by making a bunch of clients),
2940 // we will push down any other entries owned by the app.
2941 final int uid = app.info.uid;
2942 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2943 ProcessRecord subProc = mLruProcesses.get(i);
2944 if (subProc.info.uid == uid) {
2945 // We want to push this one down the list. If the process after
2946 // it is for the same uid, however, don't do so, because we don't
2947 // want them internally to be re-ordered.
2948 if (mLruProcesses.get(i - 1).info.uid != uid) {
2949 if (DEBUG_LRU) Slog.d(TAG_LRU,
2950 "Pushing uid " + uid + " swapping at " + i + ": "
2951 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2952 ProcessRecord tmp = mLruProcesses.get(i);
2953 mLruProcesses.set(i, mLruProcesses.get(i - 1));
2954 mLruProcesses.set(i - 1, tmp);
2958 // A gap, we can stop here.
2963 // Process has activities, put it at the very tipsy-top.
2964 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2965 mLruProcesses.add(app);
2967 nextIndex = mLruProcessServiceStart;
2968 } else if (hasService) {
2969 // Process has services, put it at the top of the service list.
2970 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2971 mLruProcesses.add(mLruProcessActivityStart, app);
2972 nextIndex = mLruProcessServiceStart;
2973 mLruProcessActivityStart++;
2975 // Process not otherwise of interest, it goes to the top of the non-service area.
2976 int index = mLruProcessServiceStart;
2977 if (client != null) {
2978 // If there is a client, don't allow the process to be moved up higher
2979 // in the list than that client.
2980 int clientIndex = mLruProcesses.lastIndexOf(client);
2981 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
2982 + " when updating " + app);
2983 if (clientIndex <= lrui) {
2984 // Don't allow the client index restriction to push it down farther in the
2985 // list than it already is.
2988 if (clientIndex >= 0 && index > clientIndex) {
2989 index = clientIndex;
2992 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
2993 mLruProcesses.add(index, app);
2994 nextIndex = index-1;
2995 mLruProcessActivityStart++;
2996 mLruProcessServiceStart++;
2999 // If the app is currently using a content provider or service,
3000 // bump those processes as well.
3001 for (int j=app.connections.size()-1; j>=0; j--) {
3002 ConnectionRecord cr = app.connections.valueAt(j);
3003 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3004 && cr.binding.service.app != null
3005 && cr.binding.service.app.lruSeq != mLruSeq
3006 && !cr.binding.service.app.persistent) {
3007 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3008 "service connection", cr, app);
3011 for (int j=app.conProviders.size()-1; j>=0; j--) {
3012 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3013 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3014 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3015 "provider reference", cpr, app);
3020 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3021 if (uid == Process.SYSTEM_UID) {
3022 // The system gets to run in any process. If there are multiple
3023 // processes with the same uid, just pick the first (this
3024 // should never happen).
3025 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3026 if (procs == null) return null;
3027 final int procCount = procs.size();
3028 for (int i = 0; i < procCount; i++) {
3029 final int procUid = procs.keyAt(i);
3030 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3031 // Don't use an app process or different user process for system component.
3034 return procs.valueAt(i);
3037 ProcessRecord proc = mProcessNames.get(processName, uid);
3038 if (false && proc != null && !keepIfLarge
3039 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3040 && proc.lastCachedPss >= 4000) {
3041 // Turn this condition on to cause killing to happen regularly, for testing.
3042 if (proc.baseProcessTracker != null) {
3043 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3045 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3046 } else if (proc != null && !keepIfLarge
3047 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3048 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3049 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3050 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3051 if (proc.baseProcessTracker != null) {
3052 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3054 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3060 void ensurePackageDexOpt(String packageName) {
3061 IPackageManager pm = AppGlobals.getPackageManager();
3063 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3066 } catch (RemoteException e) {
3070 boolean isNextTransitionForward() {
3071 int transit = mWindowManager.getPendingAppTransition();
3072 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3073 || transit == AppTransition.TRANSIT_TASK_OPEN
3074 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3077 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3078 String processName, String abiOverride, int uid, Runnable crashHandler) {
3079 synchronized(this) {
3080 ApplicationInfo info = new ApplicationInfo();
3081 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3082 // For isolated processes, the former contains the parent's uid and the latter the
3083 // actual uid of the isolated process.
3084 // In the special case introduced by this method (which is, starting an isolated
3085 // process directly from the SystemServer without an actual parent app process) the
3086 // closest thing to a parent's uid is SYSTEM_UID.
3087 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3088 // the |isolated| logic in the ProcessRecord constructor.
3089 info.uid = Process.SYSTEM_UID;
3090 info.processName = processName;
3091 info.className = entryPoint;
3092 info.packageName = "android";
3093 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3094 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3095 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3096 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3098 return proc != null ? proc.pid : 0;
3102 final ProcessRecord startProcessLocked(String processName,
3103 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3104 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3105 boolean isolated, boolean keepIfLarge) {
3106 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3107 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3108 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3109 null /* crashHandler */);
3112 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3113 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3114 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3115 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3116 long startTime = SystemClock.elapsedRealtime();
3119 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3120 checkTime(startTime, "startProcess: after getProcessRecord");
3122 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3123 // If we are in the background, then check to see if this process
3124 // is bad. If so, we will just silently fail.
3125 if (mBadProcesses.get(info.processName, info.uid) != null) {
3126 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3127 + "/" + info.processName);
3131 // When the user is explicitly starting a process, then clear its
3132 // crash count so that we won't make it bad until they see at
3133 // least one crash dialog again, and make the process good again
3134 // if it had been bad.
3135 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3136 + "/" + info.processName);
3137 mProcessCrashTimes.remove(info.processName, info.uid);
3138 if (mBadProcesses.get(info.processName, info.uid) != null) {
3139 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3140 UserHandle.getUserId(info.uid), info.uid,
3142 mBadProcesses.remove(info.processName, info.uid);
3149 // If this is an isolated process, it can't re-use an existing process.
3153 // app launch boost for big.little configurations
3154 // use cpusets to migrate freshly launched tasks to big cores
3155 synchronized(ActivityManagerService.this) {
3156 nativeMigrateToBoost();
3158 mBoostStartTime = SystemClock.uptimeMillis();
3159 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3160 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3163 // We don't have to do anything more if:
3164 // (1) There is an existing application record; and
3165 // (2) The caller doesn't think it is dead, OR there is no thread
3166 // object attached to it so we know it couldn't have crashed; and
3167 // (3) There is a pid assigned to it, so it is either starting or
3169 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3170 + " app=" + app + " knownToBeDead=" + knownToBeDead
3171 + " thread=" + (app != null ? app.thread : null)
3172 + " pid=" + (app != null ? app.pid : -1));
3173 if (app != null && app.pid > 0) {
3174 if (!knownToBeDead || app.thread == null) {
3175 // We already have the app running, or are waiting for it to
3176 // come up (we have a pid but not yet its thread), so keep it.
3177 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3178 // If this is a new package in the process, add the package to the list
3179 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3180 checkTime(startTime, "startProcess: done, added package to proc");
3184 // An application record is attached to a previous process,
3186 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3187 checkTime(startTime, "startProcess: bad proc running, killing");
3188 killProcessGroup(app.info.uid, app.pid);
3189 handleAppDiedLocked(app, true, true);
3190 checkTime(startTime, "startProcess: done killing old proc");
3193 String hostingNameStr = hostingName != null
3194 ? hostingName.flattenToShortString() : null;
3197 checkTime(startTime, "startProcess: creating new process record");
3198 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3200 Slog.w(TAG, "Failed making new process record for "
3201 + processName + "/" + info.uid + " isolated=" + isolated);
3204 app.crashHandler = crashHandler;
3205 checkTime(startTime, "startProcess: done creating new process record");
3207 // If this is a new package in the process, add the package to the list
3208 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3209 checkTime(startTime, "startProcess: added package to existing proc");
3212 // If the system is not ready yet, then hold off on starting this
3213 // process until it is.
3214 if (!mProcessesReady
3215 && !isAllowedWhileBooting(info)
3216 && !allowWhileBooting) {
3217 if (!mProcessesOnHold.contains(app)) {
3218 mProcessesOnHold.add(app);
3220 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3221 "System not ready, putting on hold: " + app);
3222 checkTime(startTime, "startProcess: returning with proc on hold");
3226 checkTime(startTime, "startProcess: stepping in to startProcess");
3228 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3229 checkTime(startTime, "startProcess: done starting proc!");
3230 return (app.pid != 0) ? app : null;
3233 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3234 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3237 private final void startProcessLocked(ProcessRecord app,
3238 String hostingType, String hostingNameStr) {
3239 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3240 null /* entryPoint */, null /* entryPointArgs */);
3243 private final void startProcessLocked(ProcessRecord app, String hostingType,
3244 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3245 long startTime = SystemClock.elapsedRealtime();
3246 if (app.pid > 0 && app.pid != MY_PID) {
3247 checkTime(startTime, "startProcess: removing from pids map");
3248 synchronized (mPidsSelfLocked) {
3249 mPidsSelfLocked.remove(app.pid);
3250 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3252 checkTime(startTime, "startProcess: done removing from pids map");
3256 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3257 "startProcessLocked removing on hold: " + app);
3258 mProcessesOnHold.remove(app);
3260 checkTime(startTime, "startProcess: starting to update cpu stats");
3262 checkTime(startTime, "startProcess: done updating cpu stats");
3266 if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3267 // This is caught below as if we had failed to fork zygote
3268 throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3270 } catch (RemoteException e) {
3271 throw e.rethrowAsRuntimeException();
3276 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3277 if (!app.isolated) {
3278 int[] permGids = null;
3280 checkTime(startTime, "startProcess: getting gids from package manager");
3281 final IPackageManager pm = AppGlobals.getPackageManager();
3282 permGids = pm.getPackageGids(app.info.packageName, app.userId);
3283 MountServiceInternal mountServiceInternal = LocalServices.getService(
3284 MountServiceInternal.class);
3285 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3286 app.info.packageName);
3287 } catch (RemoteException e) {
3288 throw e.rethrowAsRuntimeException();
3292 * Add shared application and profile GIDs so applications can share some
3293 * resources like shared libraries and access user-wide resources
3295 if (ArrayUtils.isEmpty(permGids)) {
3298 gids = new int[permGids.length + 2];
3299 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3301 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3302 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3304 checkTime(startTime, "startProcess: building args");
3305 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3306 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3307 && mTopComponent != null
3308 && app.processName.equals(mTopComponent.getPackageName())) {
3311 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3312 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3317 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3318 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3319 // Also turn on CheckJNI for debuggable apps. It's quite
3320 // awkward to turn on otherwise.
3321 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3323 // Run the app in safe mode if its manifest requests so or the
3324 // system is booted in safe mode.
3325 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3326 mSafeMode == true) {
3327 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3329 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3330 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3332 String jitDebugProperty = SystemProperties.get("debug.usejit");
3333 if ("true".equals(jitDebugProperty)) {
3334 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3335 } else if (!"false".equals(jitDebugProperty)) {
3336 // If we didn't force disable by setting false, defer to the dalvik vm options.
3337 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3338 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3341 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3342 if ("true".equals(genDebugInfoProperty)) {
3343 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3345 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3346 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3348 if ("1".equals(SystemProperties.get("debug.assert"))) {
3349 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3352 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3353 if (requiredAbi == null) {
3354 requiredAbi = Build.SUPPORTED_ABIS[0];
3357 String instructionSet = null;
3358 if (app.info.primaryCpuAbi != null) {
3359 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3363 app.requiredAbi = requiredAbi;
3364 app.instructionSet = instructionSet;
3366 // Start the process. It will either succeed and return a result containing
3367 // the PID of the new process, or else throw a RuntimeException.
3368 boolean isActivityProcess = (entryPoint == null);
3369 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3370 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3372 checkTime(startTime, "startProcess: asking zygote to start proc");
3373 Process.ProcessStartResult startResult = Process.start(entryPoint,
3374 app.processName, uid, uid, gids, debugFlags, mountExternal,
3375 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3376 app.info.dataDir, entryPointArgs);
3377 checkTime(startTime, "startProcess: returned from zygote!");
3378 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3381 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3383 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3384 checkTime(startTime, "startProcess: done updating battery stats");
3386 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3387 UserHandle.getUserId(uid), startResult.pid, uid,
3388 app.processName, hostingType,
3389 hostingNameStr != null ? hostingNameStr : "");
3391 if (app.persistent) {
3392 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3395 checkTime(startTime, "startProcess: building log message");
3396 StringBuilder buf = mStringBuilder;
3398 buf.append("Start proc ");
3399 buf.append(startResult.pid);
3401 buf.append(app.processName);
3403 UserHandle.formatUid(buf, uid);
3404 if (!isActivityProcess) {
3406 buf.append(entryPoint);
3409 buf.append(" for ");
3410 buf.append(hostingType);
3411 if (hostingNameStr != null) {
3413 buf.append(hostingNameStr);
3415 Slog.i(TAG, buf.toString());
3416 app.setPid(startResult.pid);
3417 app.usingWrapper = startResult.usingWrapper;
3418 app.removed = false;
3420 app.killedByAm = false;
3421 checkTime(startTime, "startProcess: starting to update pids map");
3422 synchronized (mPidsSelfLocked) {
3423 this.mPidsSelfLocked.put(startResult.pid, app);
3424 if (isActivityProcess) {
3425 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3427 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3428 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3431 checkTime(startTime, "startProcess: done updating pids map");
3432 } catch (RuntimeException e) {
3433 // XXX do better error recovery.
3435 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3437 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3439 Slog.e(TAG, "Failure starting process " + app.processName, e);
3443 void updateUsageStats(ActivityRecord component, boolean resumed) {
3444 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3445 "updateUsageStats: comp=" + component + "res=" + resumed);
3446 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3448 if (mUsageStatsService != null) {
3449 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3450 UsageEvents.Event.MOVE_TO_FOREGROUND);
3452 synchronized (stats) {
3453 stats.noteActivityResumedLocked(component.app.uid);
3456 if (mUsageStatsService != null) {
3457 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3458 UsageEvents.Event.MOVE_TO_BACKGROUND);
3460 synchronized (stats) {
3461 stats.noteActivityPausedLocked(component.app.uid);
3466 Intent getHomeIntent() {
3467 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3468 intent.setComponent(mTopComponent);
3469 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3470 intent.addCategory(Intent.CATEGORY_HOME);
3475 boolean startHomeActivityLocked(int userId, String reason) {
3476 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3477 && mTopAction == null) {
3478 // We are running in factory test mode, but unable to find
3479 // the factory test app, so just sit around displaying the
3480 // error message and don't try to start anything.
3483 Intent intent = getHomeIntent();
3484 ActivityInfo aInfo =
3485 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3486 if (aInfo != null) {
3487 intent.setComponent(new ComponentName(
3488 aInfo.applicationInfo.packageName, aInfo.name));
3489 // Don't do this if the home app is currently being
3491 aInfo = new ActivityInfo(aInfo);
3492 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3493 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3494 aInfo.applicationInfo.uid, true);
3495 if (app == null || app.instrumentationClass == null) {
3496 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3497 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3504 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3505 ActivityInfo ai = null;
3506 ComponentName comp = intent.getComponent();
3510 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3512 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3514 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3518 ai = info.activityInfo;
3521 } catch (RemoteException e) {
3529 * Starts the "new version setup screen" if appropriate.
3531 void startSetupActivityLocked() {
3532 // Only do this once per boot.
3533 if (mCheckedForSetup) {
3537 // We will show this screen if the current one is a different
3538 // version than the last one shown, and we are not running in
3539 // low-level factory test mode.
3540 final ContentResolver resolver = mContext.getContentResolver();
3541 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3542 Settings.Global.getInt(resolver,
3543 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3544 mCheckedForSetup = true;
3546 // See if we should be showing the platform update setup UI.
3547 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3548 List<ResolveInfo> ris = mContext.getPackageManager()
3549 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3551 // We don't allow third party apps to replace this.
3552 ResolveInfo ri = null;
3553 for (int i=0; ris != null && i<ris.size(); i++) {
3554 if ((ris.get(i).activityInfo.applicationInfo.flags
3555 & ApplicationInfo.FLAG_SYSTEM) != 0) {
3562 String vers = ri.activityInfo.metaData != null
3563 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3565 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3566 vers = ri.activityInfo.applicationInfo.metaData.getString(
3567 Intent.METADATA_SETUP_VERSION);
3569 String lastVers = Settings.Secure.getString(
3570 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3571 if (vers != null && !vers.equals(lastVers)) {
3572 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3573 intent.setComponent(new ComponentName(
3574 ri.activityInfo.packageName, ri.activityInfo.name));
3575 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3576 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3583 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3584 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3587 void enforceNotIsolatedCaller(String caller) {
3588 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3589 throw new SecurityException("Isolated process not allowed to call " + caller);
3593 void enforceShellRestriction(String restriction, int userHandle) {
3594 if (Binder.getCallingUid() == Process.SHELL_UID) {
3596 || mUserManager.hasUserRestriction(restriction, userHandle)) {
3597 throw new SecurityException("Shell does not have permission to access user "
3604 public int getFrontActivityScreenCompatMode() {
3605 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3606 synchronized (this) {
3607 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3612 public void setFrontActivityScreenCompatMode(int mode) {
3613 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3614 "setFrontActivityScreenCompatMode");
3615 synchronized (this) {
3616 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3621 public int getPackageScreenCompatMode(String packageName) {
3622 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3623 synchronized (this) {
3624 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3629 public void setPackageScreenCompatMode(String packageName, int mode) {
3630 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3631 "setPackageScreenCompatMode");
3632 synchronized (this) {
3633 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3638 public boolean getPackageAskScreenCompat(String packageName) {
3639 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3640 synchronized (this) {
3641 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3646 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3647 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3648 "setPackageAskScreenCompat");
3649 synchronized (this) {
3650 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3654 private boolean hasUsageStatsPermission(String callingPackage) {
3655 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3656 Binder.getCallingUid(), callingPackage);
3657 if (mode == AppOpsManager.MODE_DEFAULT) {
3658 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3659 == PackageManager.PERMISSION_GRANTED;
3661 return mode == AppOpsManager.MODE_ALLOWED;
3665 public int getPackageProcessState(String packageName, String callingPackage) {
3666 if (!hasUsageStatsPermission(callingPackage)) {
3667 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3668 "getPackageProcessState");
3671 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3672 synchronized (this) {
3673 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3674 final ProcessRecord proc = mLruProcesses.get(i);
3675 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3676 || procState > proc.setProcState) {
3677 boolean found = false;
3678 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3679 if (proc.pkgList.keyAt(j).equals(packageName)) {
3680 procState = proc.setProcState;
3684 if (proc.pkgDeps != null && !found) {
3685 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3686 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3687 procState = proc.setProcState;
3699 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3700 synchronized (this) {
3701 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3705 if (app.trimMemoryLevel < level && app.thread != null &&
3706 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3707 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3709 app.thread.scheduleTrimMemory(level);
3710 app.trimMemoryLevel = level;
3712 } catch (RemoteException e) {
3713 // Fallthrough to failure case.
3720 private void dispatchProcessesChanged() {
3722 synchronized (this) {
3723 N = mPendingProcessChanges.size();
3724 if (mActiveProcessChanges.length < N) {
3725 mActiveProcessChanges = new ProcessChangeItem[N];
3727 mPendingProcessChanges.toArray(mActiveProcessChanges);
3728 mPendingProcessChanges.clear();
3729 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3730 "*** Delivering " + N + " process changes");
3733 int i = mProcessObservers.beginBroadcast();
3736 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3737 if (observer != null) {
3739 for (int j=0; j<N; j++) {
3740 ProcessChangeItem item = mActiveProcessChanges[j];
3741 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3742 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3743 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3744 + item.uid + ": " + item.foregroundActivities);
3745 observer.onForegroundActivitiesChanged(item.pid, item.uid,
3746 item.foregroundActivities);
3748 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3749 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3750 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3751 + ": " + item.processState);
3752 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3755 } catch (RemoteException e) {
3759 mProcessObservers.finishBroadcast();
3761 synchronized (this) {
3762 for (int j=0; j<N; j++) {
3763 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3768 private void dispatchProcessDied(int pid, int uid) {
3769 int i = mProcessObservers.beginBroadcast();
3772 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3773 if (observer != null) {
3775 observer.onProcessDied(pid, uid);
3776 } catch (RemoteException e) {
3780 mProcessObservers.finishBroadcast();
3783 private void dispatchUidsChanged() {
3785 synchronized (this) {
3786 N = mPendingUidChanges.size();
3787 if (mActiveUidChanges.length < N) {
3788 mActiveUidChanges = new UidRecord.ChangeItem[N];
3790 for (int i=0; i<N; i++) {
3791 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3792 mActiveUidChanges[i] = change;
3793 change.uidRecord.pendingChange = null;
3794 change.uidRecord = null;
3796 mPendingUidChanges.clear();
3797 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3798 "*** Delivering " + N + " uid changes");
3801 if (mLocalPowerManager != null) {
3802 for (int j=0; j<N; j++) {
3803 UidRecord.ChangeItem item = mActiveUidChanges[j];
3805 mLocalPowerManager.uidGone(item.uid);
3807 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3812 int i = mUidObservers.beginBroadcast();
3815 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3816 if (observer != null) {
3818 for (int j=0; j<N; j++) {
3819 UidRecord.ChangeItem item = mActiveUidChanges[j];
3821 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3822 "UID gone uid=" + item.uid);
3823 observer.onUidGone(item.uid);
3825 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3826 "UID CHANGED uid=" + item.uid
3827 + ": " + item.processState);
3828 observer.onUidStateChanged(item.uid, item.processState);
3831 } catch (RemoteException e) {
3835 mUidObservers.finishBroadcast();
3837 synchronized (this) {
3838 for (int j=0; j<N; j++) {
3839 mAvailUidChanges.add(mActiveUidChanges[j]);
3845 public final int startActivity(IApplicationThread caller, String callingPackage,
3846 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3847 int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3848 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3849 resultWho, requestCode, startFlags, profilerInfo, options,
3850 UserHandle.getCallingUserId());
3854 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3855 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3856 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3857 enforceNotIsolatedCaller("startActivity");
3858 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3859 false, ALLOW_FULL_ONLY, "startActivity", null);
3860 // TODO: Switch to user app stacks here.
3861 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3862 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3863 profilerInfo, null, null, options, false, userId, null, null);
3867 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3868 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3869 int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3872 // This is very dangerous -- it allows you to perform a start activity (including
3873 // permission grants) as any app that may launch one of your own activities. So
3874 // we will only allow this to be done from activities that are part of the core framework,
3875 // and then only when they are running as the system.
3876 final ActivityRecord sourceRecord;
3877 final int targetUid;
3878 final String targetPackage;
3879 synchronized (this) {
3880 if (resultTo == null) {
3881 throw new SecurityException("Must be called from an activity");
3883 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3884 if (sourceRecord == null) {
3885 throw new SecurityException("Called with bad activity token: " + resultTo);
3887 if (!sourceRecord.info.packageName.equals("android")) {
3888 throw new SecurityException(
3889 "Must be called from an activity that is declared in the android package");
3891 if (sourceRecord.app == null) {
3892 throw new SecurityException("Called without a process attached to activity");
3894 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3895 // This is still okay, as long as this activity is running under the
3896 // uid of the original calling activity.
3897 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3898 throw new SecurityException(
3899 "Calling activity in uid " + sourceRecord.app.uid
3900 + " must be system uid or original calling uid "
3901 + sourceRecord.launchedFromUid);
3904 if (ignoreTargetSecurity) {
3905 if (intent.getComponent() == null) {
3906 throw new SecurityException(
3907 "Component must be specified with ignoreTargetSecurity");
3909 if (intent.getSelector() != null) {
3910 throw new SecurityException(
3911 "Selector not allowed with ignoreTargetSecurity");
3914 targetUid = sourceRecord.launchedFromUid;
3915 targetPackage = sourceRecord.launchedFromPackage;
3918 if (userId == UserHandle.USER_NULL) {
3919 userId = UserHandle.getUserId(sourceRecord.app.uid);
3922 // TODO: Switch to user app stacks here.
3924 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3925 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3926 null, null, options, ignoreTargetSecurity, userId, null, null);
3928 } catch (SecurityException e) {
3929 // XXX need to figure out how to propagate to original app.
3930 // A SecurityException here is generally actually a fault of the original
3931 // calling activity (such as a fairly granting permissions), so propagate it
3934 StringBuilder msg = new StringBuilder();
3935 msg.append("While launching");
3936 msg.append(intent.toString());
3938 msg.append(e.getMessage());
3945 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3946 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3947 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3948 enforceNotIsolatedCaller("startActivityAndWait");
3949 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3950 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3951 WaitResult res = new WaitResult();
3952 // TODO: Switch to user app stacks here.
3953 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3954 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3955 options, false, userId, null, null);
3960 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3961 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3962 int startFlags, Configuration config, Bundle options, int userId) {
3963 enforceNotIsolatedCaller("startActivityWithConfig");
3964 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3965 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3966 // TODO: Switch to user app stacks here.
3967 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3968 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3969 null, null, config, options, false, userId, null, null);
3974 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
3975 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
3976 int requestCode, int flagsMask, int flagsValues, Bundle options)
3977 throws TransactionTooLargeException {
3978 enforceNotIsolatedCaller("startActivityIntentSender");
3979 // Refuse possible leaked file descriptors
3980 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3981 throw new IllegalArgumentException("File descriptors passed in Intent");
3984 IIntentSender sender = intent.getTarget();
3985 if (!(sender instanceof PendingIntentRecord)) {
3986 throw new IllegalArgumentException("Bad PendingIntent object");
3989 PendingIntentRecord pir = (PendingIntentRecord)sender;
3991 synchronized (this) {
3992 // If this is coming from the currently resumed activity, it is
3993 // effectively saying that app switches are allowed at this point.
3994 final ActivityStack stack = getFocusedStack();
3995 if (stack.mResumedActivity != null &&
3996 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3997 mAppSwitchesAllowedTime = 0;
4000 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4001 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
4006 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4007 Intent intent, String resolvedType, IVoiceInteractionSession session,
4008 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4009 Bundle options, int userId) {
4010 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4011 != PackageManager.PERMISSION_GRANTED) {
4012 String msg = "Permission Denial: startVoiceActivity() from pid="
4013 + Binder.getCallingPid()
4014 + ", uid=" + Binder.getCallingUid()
4015 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4017 throw new SecurityException(msg);
4019 if (session == null || interactor == null) {
4020 throw new NullPointerException("null session or interactor");
4022 userId = handleIncomingUser(callingPid, callingUid, userId,
4023 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
4024 // TODO: Switch to user app stacks here.
4025 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4026 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4027 null, options, false, userId, null, null);
4031 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4032 synchronized (this) {
4033 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4035 mVoiceWakeLock.acquire();
4037 mVoiceWakeLock.release();
4044 public boolean startNextMatchingActivity(IBinder callingActivity,
4045 Intent intent, Bundle options) {
4046 // Refuse possible leaked file descriptors
4047 if (intent != null && intent.hasFileDescriptors() == true) {
4048 throw new IllegalArgumentException("File descriptors passed in Intent");
4051 synchronized (this) {
4052 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4054 ActivityOptions.abort(options);
4057 if (r.app == null || r.app.thread == null) {
4058 // The caller is not running... d'oh!
4059 ActivityOptions.abort(options);
4062 intent = new Intent(intent);
4063 // The caller is not allowed to change the data.
4064 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4065 // And we are resetting to find the next component...
4066 intent.setComponent(null);
4068 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4070 ActivityInfo aInfo = null;
4072 List<ResolveInfo> resolves =
4073 AppGlobals.getPackageManager().queryIntentActivities(
4074 intent, r.resolvedType,
4075 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4076 UserHandle.getCallingUserId());
4078 // Look for the original activity in the list...
4079 final int N = resolves != null ? resolves.size() : 0;
4080 for (int i=0; i<N; i++) {
4081 ResolveInfo rInfo = resolves.get(i);
4082 if (rInfo.activityInfo.packageName.equals(r.packageName)
4083 && rInfo.activityInfo.name.equals(r.info.name)) {
4084 // We found the current one... the next matching is
4088 aInfo = resolves.get(i).activityInfo;
4091 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4092 + "/" + r.info.name);
4093 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4094 + "/" + aInfo.name);
4099 } catch (RemoteException e) {
4102 if (aInfo == null) {
4103 // Nobody who is next!
4104 ActivityOptions.abort(options);
4105 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4109 intent.setComponent(new ComponentName(
4110 aInfo.applicationInfo.packageName, aInfo.name));
4111 intent.setFlags(intent.getFlags()&~(
4112 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4113 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4114 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4115 Intent.FLAG_ACTIVITY_NEW_TASK));
4117 // Okay now we need to start the new activity, replacing the
4118 // currently running activity. This is a little tricky because
4119 // we want to start the new one as if the current one is finished,
4120 // but not finish the current one first so that there is no flicker.
4122 final boolean wasFinishing = r.finishing;
4125 // Propagate reply information over to the new activity.
4126 final ActivityRecord resultTo = r.resultTo;
4127 final String resultWho = r.resultWho;
4128 final int requestCode = r.requestCode;
4130 if (resultTo != null) {
4131 resultTo.removeResultsLocked(r, resultWho, requestCode);
4134 final long origId = Binder.clearCallingIdentity();
4135 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4136 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4137 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4138 -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4139 Binder.restoreCallingIdentity(origId);
4141 r.finishing = wasFinishing;
4142 if (res != ActivityManager.START_SUCCESS) {
4150 public final int startActivityFromRecents(int taskId, Bundle options) {
4151 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4152 String msg = "Permission Denial: startActivityFromRecents called without " +
4153 START_TASKS_FROM_RECENTS;
4155 throw new SecurityException(msg);
4157 return startActivityFromRecentsInner(taskId, options);
4160 final int startActivityFromRecentsInner(int taskId, Bundle options) {
4161 final TaskRecord task;
4162 final int callingUid;
4163 final String callingPackage;
4164 final Intent intent;
4166 synchronized (this) {
4167 task = mStackSupervisor.anyTaskForIdLocked(taskId);
4169 throw new IllegalArgumentException("Task " + taskId + " not found.");
4171 if (task.getRootActivity() != null) {
4172 moveTaskToFrontLocked(task.taskId, 0, null);
4173 return ActivityManager.START_TASK_TO_FRONT;
4175 callingUid = task.mCallingUid;
4176 callingPackage = task.mCallingPackage;
4177 intent = task.intent;
4178 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4179 userId = task.userId;
4181 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4182 options, userId, null, task);
4185 final int startActivityInPackage(int uid, String callingPackage,
4186 Intent intent, String resolvedType, IBinder resultTo,
4187 String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4188 IActivityContainer container, TaskRecord inTask) {
4190 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4191 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4193 // TODO: Switch to user app stacks here.
4194 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4195 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4196 null, null, null, options, false, userId, container, inTask);
4201 public final int startActivities(IApplicationThread caller, String callingPackage,
4202 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4204 enforceNotIsolatedCaller("startActivities");
4205 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4206 false, ALLOW_FULL_ONLY, "startActivity", null);
4207 // TODO: Switch to user app stacks here.
4208 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4209 resolvedTypes, resultTo, options, userId);
4213 final int startActivitiesInPackage(int uid, String callingPackage,
4214 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4215 Bundle options, int userId) {
4217 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4218 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4219 // TODO: Switch to user app stacks here.
4220 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4221 resultTo, options, userId);
4226 public void reportActivityFullyDrawn(IBinder token) {
4227 synchronized (this) {
4228 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4232 r.reportFullyDrawnLocked();
4237 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4238 synchronized (this) {
4239 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4243 if (r.task != null && r.task.mResizeable) {
4244 // Fixed screen orientation isn't supported with resizeable activities.
4247 final long origId = Binder.clearCallingIdentity();
4248 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4249 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4250 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4251 if (config != null) {
4252 r.frozenBeforeDestroy = true;
4253 if (!updateConfigurationLocked(config, r, false, false)) {
4254 mStackSupervisor.resumeTopActivitiesLocked();
4257 Binder.restoreCallingIdentity(origId);
4262 public int getRequestedOrientation(IBinder token) {
4263 synchronized (this) {
4264 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4266 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4268 return mWindowManager.getAppOrientation(r.appToken);
4273 * This is the internal entry point for handling Activity.finish().
4275 * @param token The Binder token referencing the Activity we want to finish.
4276 * @param resultCode Result code, if any, from this Activity.
4277 * @param resultData Result data (Intent), if any, from this Activity.
4278 * @param finishTask Whether to finish the task associated with this Activity. Only applies to
4279 * the root Activity in the task.
4281 * @return Returns true if the activity successfully finished, or false if it is still running.
4284 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4285 boolean finishTask) {
4286 // Refuse possible leaked file descriptors
4287 if (resultData != null && resultData.hasFileDescriptors() == true) {
4288 throw new IllegalArgumentException("File descriptors passed in Intent");
4291 synchronized(this) {
4292 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4296 // Keep track of the root activity of the task before we finish it
4297 TaskRecord tr = r.task;
4298 ActivityRecord rootR = tr.getRootActivity();
4299 if (rootR == null) {
4300 Slog.w(TAG, "Finishing task with all activities already finished");
4302 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4304 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4305 mStackSupervisor.isLastLockedTask(tr)) {
4306 Slog.i(TAG, "Not finishing task in lock task mode");
4307 mStackSupervisor.showLockTaskToast();
4310 if (mController != null) {
4311 // Find the first activity that is not finishing.
4312 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4314 // ask watcher if this is allowed
4315 boolean resumeOK = true;
4317 resumeOK = mController.activityResuming(next.packageName);
4318 } catch (RemoteException e) {
4320 Watchdog.getInstance().setActivityController(null);
4324 Slog.i(TAG, "Not finishing activity because controller resumed");
4329 final long origId = Binder.clearCallingIdentity();
4332 if (finishTask && r == rootR) {
4333 // If requested, remove the task that is associated to this activity only if it
4334 // was the root activity in the task. The result code and data is ignored
4335 // because we don't support returning them across task boundaries.
4336 res = removeTaskByIdLocked(tr.taskId, false);
4338 Slog.i(TAG, "Removing task failed to finish activity");
4341 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4342 resultData, "app-request", true);
4344 Slog.i(TAG, "Failed to finish by app-request");
4349 Binder.restoreCallingIdentity(origId);
4355 public final void finishHeavyWeightApp() {
4356 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4357 != PackageManager.PERMISSION_GRANTED) {
4358 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4359 + Binder.getCallingPid()
4360 + ", uid=" + Binder.getCallingUid()
4361 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4363 throw new SecurityException(msg);
4366 synchronized(this) {
4367 if (mHeavyWeightProcess == null) {
4371 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4372 for (int i = 0; i < activities.size(); i++) {
4373 ActivityRecord r = activities.get(i);
4374 if (!r.finishing && r.isInStackLocked()) {
4375 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4376 null, "finish-heavy", true);
4380 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4381 mHeavyWeightProcess.userId, 0));
4382 mHeavyWeightProcess = null;
4387 public void crashApplication(int uid, int initialPid, String packageName,
4389 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4390 != PackageManager.PERMISSION_GRANTED) {
4391 String msg = "Permission Denial: crashApplication() from pid="
4392 + Binder.getCallingPid()
4393 + ", uid=" + Binder.getCallingUid()
4394 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4396 throw new SecurityException(msg);
4399 synchronized(this) {
4400 ProcessRecord proc = null;
4402 // Figure out which process to kill. We don't trust that initialPid
4403 // still has any relation to current pids, so must scan through the
4405 synchronized (mPidsSelfLocked) {
4406 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4407 ProcessRecord p = mPidsSelfLocked.valueAt(i);
4411 if (p.pid == initialPid) {
4415 if (p.pkgList.containsKey(packageName)) {
4422 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4423 + " initialPid=" + initialPid
4424 + " packageName=" + packageName);
4428 if (proc.thread != null) {
4429 if (proc.pid == Process.myPid()) {
4430 Log.w(TAG, "crashApplication: trying to crash self!");
4433 long ident = Binder.clearCallingIdentity();
4435 proc.thread.scheduleCrash(message);
4436 } catch (RemoteException e) {
4438 Binder.restoreCallingIdentity(ident);
4444 public final void finishSubActivity(IBinder token, String resultWho,
4446 synchronized(this) {
4447 final long origId = Binder.clearCallingIdentity();
4448 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4450 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4452 Binder.restoreCallingIdentity(origId);
4457 public boolean finishActivityAffinity(IBinder token) {
4458 synchronized(this) {
4459 final long origId = Binder.clearCallingIdentity();
4461 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4466 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4468 final TaskRecord task = r.task;
4469 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4470 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4471 mStackSupervisor.showLockTaskToast();
4474 return task.stack.finishActivityAffinityLocked(r);
4476 Binder.restoreCallingIdentity(origId);
4482 public void finishVoiceTask(IVoiceInteractionSession session) {
4483 synchronized(this) {
4484 final long origId = Binder.clearCallingIdentity();
4486 mStackSupervisor.finishVoiceTask(session);
4488 Binder.restoreCallingIdentity(origId);
4495 public boolean releaseActivityInstance(IBinder token) {
4496 synchronized(this) {
4497 final long origId = Binder.clearCallingIdentity();
4499 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4503 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4505 Binder.restoreCallingIdentity(origId);
4511 public void releaseSomeActivities(IApplicationThread appInt) {
4512 synchronized(this) {
4513 final long origId = Binder.clearCallingIdentity();
4515 ProcessRecord app = getRecordForAppLocked(appInt);
4516 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4518 Binder.restoreCallingIdentity(origId);
4524 public boolean willActivityBeVisible(IBinder token) {
4525 synchronized(this) {
4526 ActivityStack stack = ActivityRecord.getStackLocked(token);
4527 if (stack != null) {
4528 return stack.willActivityBeVisibleLocked(token);
4535 public void overridePendingTransition(IBinder token, String packageName,
4536 int enterAnim, int exitAnim) {
4537 synchronized(this) {
4538 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4543 final long origId = Binder.clearCallingIdentity();
4545 if (self.state == ActivityState.RESUMED
4546 || self.state == ActivityState.PAUSING) {
4547 mWindowManager.overridePendingAppTransition(packageName,
4548 enterAnim, exitAnim, null);
4551 Binder.restoreCallingIdentity(origId);
4556 * Main function for removing an existing process from the activity manager
4557 * as a result of that process going away. Clears out all connections
4560 private final void handleAppDiedLocked(ProcessRecord app,
4561 boolean restarting, boolean allowRestart) {
4563 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4564 if (!kept && !restarting) {
4565 removeLruProcessLocked(app);
4567 ProcessList.remove(pid);
4571 if (mProfileProc == app) {
4572 clearProfilerLocked();
4575 // Remove this application's activities from active lists.
4576 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4578 app.activities.clear();
4580 if (app.instrumentationClass != null) {
4581 Slog.w(TAG, "Crash of app " + app.processName
4582 + " running instrumentation " + app.instrumentationClass);
4583 Bundle info = new Bundle();
4584 info.putString("shortMsg", "Process crashed.");
4585 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4588 if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4589 // If there was nothing to resume, and we are not already
4590 // restarting this process, but there is a visible activity that
4591 // is hosted by the process... then make sure all visible
4592 // activities are running, taking care of restarting this
4594 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4598 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4599 IBinder threadBinder = thread.asBinder();
4600 // Find the application record.
4601 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4602 ProcessRecord rec = mLruProcesses.get(i);
4603 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4610 final ProcessRecord getRecordForAppLocked(
4611 IApplicationThread thread) {
4612 if (thread == null) {
4616 int appIndex = getLRURecordIndexForAppLocked(thread);
4617 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4620 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4621 // If there are no longer any background processes running,
4622 // and the app that died was not running instrumentation,
4623 // then tell everyone we are now low on memory.
4624 boolean haveBg = false;
4625 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4626 ProcessRecord rec = mLruProcesses.get(i);
4627 if (rec.thread != null
4628 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4635 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4637 long now = SystemClock.uptimeMillis();
4638 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4641 mLastMemUsageReportTime = now;
4644 final ArrayList<ProcessMemInfo> memInfos
4645 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4646 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4647 long now = SystemClock.uptimeMillis();
4648 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4649 ProcessRecord rec = mLruProcesses.get(i);
4650 if (rec == dyingProc || rec.thread == null) {
4654 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4655 rec.setProcState, rec.adjType, rec.makeAdjReason()));
4657 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4658 // The low memory report is overriding any current
4659 // state for a GC request. Make sure to do
4660 // heavy/important/visible/foreground processes first.
4661 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4662 rec.lastRequestedGc = 0;
4664 rec.lastRequestedGc = rec.lastLowMemory;
4666 rec.reportLowMemory = true;
4667 rec.lastLowMemory = now;
4668 mProcessesToGc.remove(rec);
4669 addProcessToGcListLocked(rec);
4673 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4674 mHandler.sendMessage(msg);
4676 scheduleAppGcsLocked();
4680 final void appDiedLocked(ProcessRecord app) {
4681 appDiedLocked(app, app.pid, app.thread, false);
4684 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4685 boolean fromBinderDied) {
4686 // First check if this ProcessRecord is actually active for the pid.
4687 synchronized (mPidsSelfLocked) {
4688 ProcessRecord curProc = mPidsSelfLocked.get(pid);
4689 if (curProc != app) {
4690 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4695 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4696 synchronized (stats) {
4697 stats.noteProcessDiedLocked(app.info.uid, pid);
4701 if (!fromBinderDied) {
4702 Process.killProcessQuiet(pid);
4704 killProcessGroup(app.info.uid, pid);
4708 // Clean up already done if the process has been re-started.
4709 if (app.pid == pid && app.thread != null &&
4710 app.thread.asBinder() == thread.asBinder()) {
4711 boolean doLowMem = app.instrumentationClass == null;
4712 boolean doOomAdj = doLowMem;
4713 if (!app.killedByAm) {
4714 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4716 mAllowLowerMemLevel = true;
4718 // Note that we always want to do oom adj to update our state with the
4719 // new number of procs.
4720 mAllowLowerMemLevel = false;
4723 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4724 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4725 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4726 handleAppDiedLocked(app, false, true);
4729 updateOomAdjLocked();
4732 doLowMemReportIfNeededLocked(app);
4734 } else if (app.pid != pid) {
4735 // A new process has already been started.
4736 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4737 + ") has died and restarted (pid " + app.pid + ").");
4738 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4739 } else if (DEBUG_PROCESSES) {
4740 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4741 + thread.asBinder());
4746 * If a stack trace dump file is configured, dump process stack traces.
4747 * @param clearTraces causes the dump file to be erased prior to the new
4748 * traces being written, if true; when false, the new traces will be
4749 * appended to any existing file content.
4750 * @param firstPids of dalvik VM processes to dump stack traces for first
4751 * @param lastPids of dalvik VM processes to dump stack traces for last
4752 * @param nativeProcs optional list of native process names to dump stack crawls
4753 * @return file containing stack traces, or null if no dump file is configured
4755 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4756 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4757 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4758 if (tracesPath == null || tracesPath.length() == 0) {
4762 File tracesFile = new File(tracesPath);
4764 File tracesDir = tracesFile.getParentFile();
4765 if (!tracesDir.exists()) {
4767 if (!SELinux.restorecon(tracesDir)) {
4771 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4773 if (clearTraces && tracesFile.exists()) tracesFile.delete();
4774 tracesFile.createNewFile();
4775 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4776 } catch (IOException e) {
4777 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4781 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4785 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4786 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4787 // Use a FileObserver to detect when traces finish writing.
4788 // The order of traces is considered important to maintain for legibility.
4789 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4791 public synchronized void onEvent(int event, String path) { notify(); }
4795 observer.startWatching();
4797 // First collect all of the stacks of the most important pids.
4798 if (firstPids != null) {
4800 int num = firstPids.size();
4801 for (int i = 0; i < num; i++) {
4802 synchronized (observer) {
4803 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4804 observer.wait(200); // Wait for write-close, give up after 200msec
4807 } catch (InterruptedException e) {
4812 // Next collect the stacks of the native pids
4813 if (nativeProcs != null) {
4814 int[] pids = Process.getPidsForCommands(nativeProcs);
4816 for (int pid : pids) {
4817 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4822 // Lastly, measure CPU usage.
4823 if (processCpuTracker != null) {
4824 processCpuTracker.init();
4826 processCpuTracker.update();
4828 synchronized (processCpuTracker) {
4829 processCpuTracker.wait(500); // measure over 1/2 second.
4831 } catch (InterruptedException e) {
4833 processCpuTracker.update();
4835 // We'll take the stack crawls of just the top apps using CPU.
4836 final int N = processCpuTracker.countWorkingStats();
4838 for (int i=0; i<N && numProcs<5; i++) {
4839 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4840 if (lastPids.indexOfKey(stats.pid) >= 0) {
4843 synchronized (observer) {
4844 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4845 observer.wait(200); // Wait for write-close, give up after 200msec
4847 } catch (InterruptedException e) {
4855 observer.stopWatching();
4859 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4860 if (true || IS_USER_BUILD) {
4863 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4864 if (tracesPath == null || tracesPath.length() == 0) {
4868 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4869 StrictMode.allowThreadDiskWrites();
4871 final File tracesFile = new File(tracesPath);
4872 final File tracesDir = tracesFile.getParentFile();
4873 final File tracesTmp = new File(tracesDir, "__tmp__");
4875 if (!tracesDir.exists()) {
4877 if (!SELinux.restorecon(tracesDir.getPath())) {
4881 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4883 if (tracesFile.exists()) {
4885 tracesFile.renameTo(tracesTmp);
4887 StringBuilder sb = new StringBuilder();
4888 Time tobj = new Time();
4889 tobj.set(System.currentTimeMillis());
4890 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4892 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4893 sb.append(" since ");
4895 FileOutputStream fos = new FileOutputStream(tracesFile);
4896 fos.write(sb.toString().getBytes());
4898 fos.write("\n*** No application process!".getBytes());
4901 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4902 } catch (IOException e) {
4903 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4908 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4909 firstPids.add(app.pid);
4910 dumpStackTraces(tracesPath, firstPids, null, null, null);
4913 File lastTracesFile = null;
4914 File curTracesFile = null;
4915 for (int i=9; i>=0; i--) {
4916 String name = String.format(Locale.US, "slow%02d.txt", i);
4917 curTracesFile = new File(tracesDir, name);
4918 if (curTracesFile.exists()) {
4919 if (lastTracesFile != null) {
4920 curTracesFile.renameTo(lastTracesFile);
4922 curTracesFile.delete();
4925 lastTracesFile = curTracesFile;
4927 tracesFile.renameTo(curTracesFile);
4928 if (tracesTmp.exists()) {
4929 tracesTmp.renameTo(tracesFile);
4932 StrictMode.setThreadPolicy(oldPolicy);
4936 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4937 ActivityRecord parent, boolean aboveSystem, final String annotation) {
4938 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4939 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4941 if (mController != null) {
4943 // 0 == continue, -1 = kill process immediately
4944 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4945 if (res < 0 && app.pid != MY_PID) {
4946 app.kill("anr", true);
4948 } catch (RemoteException e) {
4950 Watchdog.getInstance().setActivityController(null);
4954 long anrTime = SystemClock.uptimeMillis();
4955 if (MONITOR_CPU_USAGE) {
4956 updateCpuStatsNow();
4959 synchronized (this) {
4960 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4961 if (mShuttingDown) {
4962 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4964 } else if (app.notResponding) {
4965 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4967 } else if (app.crashing) {
4968 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4972 // In case we come through here for the same app before completing
4973 // this one, mark as anring now so we will bail out.
4974 app.notResponding = true;
4976 // Log the ANR to the event log.
4977 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4978 app.processName, app.info.flags, annotation);
4980 // Dump thread traces as quickly as we can, starting with "interesting" processes.
4981 firstPids.add(app.pid);
4983 int parentPid = app.pid;
4984 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4985 if (parentPid != app.pid) firstPids.add(parentPid);
4987 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4989 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4990 ProcessRecord r = mLruProcesses.get(i);
4991 if (r != null && r.thread != null) {
4993 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4997 lastPids.put(pid, Boolean.TRUE);
5004 // Log the ANR to the main log.
5005 StringBuilder info = new StringBuilder();
5007 info.append("ANR in ").append(app.processName);
5008 if (activity != null && activity.shortComponentName != null) {
5009 info.append(" (").append(activity.shortComponentName).append(")");
5012 info.append("PID: ").append(app.pid).append("\n");
5013 if (annotation != null) {
5014 info.append("Reason: ").append(annotation).append("\n");
5016 if (parent != null && parent != activity) {
5017 info.append("Parent: ").append(parent.shortComponentName).append("\n");
5020 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5022 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5023 NATIVE_STACKS_OF_INTEREST);
5025 String cpuInfo = null;
5026 if (MONITOR_CPU_USAGE) {
5027 updateCpuStatsNow();
5028 synchronized (mProcessCpuTracker) {
5029 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5031 info.append(processCpuTracker.printCurrentLoad());
5032 info.append(cpuInfo);
5035 info.append(processCpuTracker.printCurrentState(anrTime));
5037 Slog.e(TAG, info.toString());
5038 if (tracesFile == null) {
5039 // There is no trace file, so dump (only) the alleged culprit's threads to the log
5040 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5043 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5044 cpuInfo, tracesFile, null);
5046 if (mController != null) {
5048 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5049 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5051 if (res < 0 && app.pid != MY_PID) {
5052 app.kill("anr", true);
5054 synchronized (this) {
5055 mServices.scheduleServiceTimeoutLocked(app);
5060 } catch (RemoteException e) {
5062 Watchdog.getInstance().setActivityController(null);
5066 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5067 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5068 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5070 synchronized (this) {
5071 mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5073 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5074 app.kill("bg anr", true);
5078 // Set the app's notResponding state, and look up the errorReportReceiver
5079 makeAppNotRespondingLocked(app,
5080 activity != null ? activity.shortComponentName : null,
5081 annotation != null ? "ANR " + annotation : "ANR",
5084 // Bring up the infamous App Not Responding dialog
5085 Message msg = Message.obtain();
5086 HashMap<String, Object> map = new HashMap<String, Object>();
5087 msg.what = SHOW_NOT_RESPONDING_MSG;
5089 msg.arg1 = aboveSystem ? 1 : 0;
5090 map.put("app", app);
5091 if (activity != null) {
5092 map.put("activity", activity);
5095 mUiHandler.sendMessage(msg);
5099 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5100 if (!mLaunchWarningShown) {
5101 mLaunchWarningShown = true;
5102 mUiHandler.post(new Runnable() {
5105 synchronized (ActivityManagerService.this) {
5106 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5108 mUiHandler.postDelayed(new Runnable() {
5111 synchronized (ActivityManagerService.this) {
5113 mLaunchWarningShown = false;
5124 public boolean clearApplicationUserData(final String packageName,
5125 final IPackageDataObserver observer, int userId) {
5126 enforceNotIsolatedCaller("clearApplicationUserData");
5127 if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5128 throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5130 int uid = Binder.getCallingUid();
5131 int pid = Binder.getCallingPid();
5132 userId = handleIncomingUser(pid, uid,
5133 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5134 long callingId = Binder.clearCallingIdentity();
5136 IPackageManager pm = AppGlobals.getPackageManager();
5138 synchronized(this) {
5140 pkgUid = pm.getPackageUid(packageName, userId);
5141 } catch (RemoteException e) {
5144 Slog.w(TAG, "Invalid packageName: " + packageName);
5145 if (observer != null) {
5147 observer.onRemoveCompleted(packageName, false);
5148 } catch (RemoteException e) {
5149 Slog.i(TAG, "Observer no longer exists.");
5154 if (uid == pkgUid || checkComponentPermission(
5155 android.Manifest.permission.CLEAR_APP_USER_DATA,
5157 == PackageManager.PERMISSION_GRANTED) {
5158 forceStopPackageLocked(packageName, pkgUid, "clear data");
5160 throw new SecurityException("PID " + pid + " does not have permission "
5161 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5162 + " of package " + packageName);
5165 // Remove all tasks match the cleared application package and user
5166 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5167 final TaskRecord tr = mRecentTasks.get(i);
5168 final String taskPackageName =
5169 tr.getBaseIntent().getComponent().getPackageName();
5170 if (tr.userId != userId) continue;
5171 if (!taskPackageName.equals(packageName)) continue;
5172 removeTaskByIdLocked(tr.taskId, false);
5177 // Clear application user data
5178 pm.clearApplicationUserData(packageName, observer, userId);
5180 synchronized(this) {
5181 // Remove all permissions granted from/to this package
5182 removeUriPermissionsForPackageLocked(packageName, userId, true);
5185 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5186 Uri.fromParts("package", packageName, null));
5187 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5188 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5189 null, null, 0, null, null, null, null, false, false, userId);
5190 } catch (RemoteException e) {
5193 Binder.restoreCallingIdentity(callingId);
5199 public void killBackgroundProcesses(final String packageName, int userId) {
5200 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5201 != PackageManager.PERMISSION_GRANTED &&
5202 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5203 != PackageManager.PERMISSION_GRANTED) {
5204 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5205 + Binder.getCallingPid()
5206 + ", uid=" + Binder.getCallingUid()
5207 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5209 throw new SecurityException(msg);
5212 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5213 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5214 long callingId = Binder.clearCallingIdentity();
5216 IPackageManager pm = AppGlobals.getPackageManager();
5217 synchronized(this) {
5220 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5221 } catch (RemoteException e) {
5224 Slog.w(TAG, "Invalid packageName: " + packageName);
5227 killPackageProcessesLocked(packageName, appId, userId,
5228 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5231 Binder.restoreCallingIdentity(callingId);
5236 public void killAllBackgroundProcesses() {
5237 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5238 != PackageManager.PERMISSION_GRANTED) {
5239 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5240 + Binder.getCallingPid()
5241 + ", uid=" + Binder.getCallingUid()
5242 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5244 throw new SecurityException(msg);
5247 long callingId = Binder.clearCallingIdentity();
5249 synchronized(this) {
5250 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5251 final int NP = mProcessNames.getMap().size();
5252 for (int ip=0; ip<NP; ip++) {
5253 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5254 final int NA = apps.size();
5255 for (int ia=0; ia<NA; ia++) {
5256 ProcessRecord app = apps.valueAt(ia);
5257 if (app.persistent) {
5258 // we don't kill persistent processes
5263 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5270 int N = procs.size();
5271 for (int i=0; i<N; i++) {
5272 removeProcessLocked(procs.get(i), false, true, "kill all background");
5274 mAllowLowerMemLevel = true;
5275 updateOomAdjLocked();
5276 doLowMemReportIfNeededLocked(null);
5279 Binder.restoreCallingIdentity(callingId);
5284 public void forceStopPackage(final String packageName, int userId) {
5285 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5286 != PackageManager.PERMISSION_GRANTED) {
5287 String msg = "Permission Denial: forceStopPackage() from pid="
5288 + Binder.getCallingPid()
5289 + ", uid=" + Binder.getCallingUid()
5290 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5292 throw new SecurityException(msg);
5294 final int callingPid = Binder.getCallingPid();
5295 userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5296 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5297 long callingId = Binder.clearCallingIdentity();
5299 IPackageManager pm = AppGlobals.getPackageManager();
5300 synchronized(this) {
5301 int[] users = userId == UserHandle.USER_ALL
5302 ? getUsersLocked() : new int[] { userId };
5303 for (int user : users) {
5306 pkgUid = pm.getPackageUid(packageName, user);
5307 } catch (RemoteException e) {
5310 Slog.w(TAG, "Invalid packageName: " + packageName);
5314 pm.setPackageStoppedState(packageName, true, user);
5315 } catch (RemoteException e) {
5316 } catch (IllegalArgumentException e) {
5317 Slog.w(TAG, "Failed trying to unstop package "
5318 + packageName + ": " + e);
5320 if (isUserRunningLocked(user, false)) {
5321 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5326 Binder.restoreCallingIdentity(callingId);
5331 public void addPackageDependency(String packageName) {
5332 synchronized (this) {
5333 int callingPid = Binder.getCallingPid();
5334 if (callingPid == Process.myPid()) {
5339 synchronized (mPidsSelfLocked) {
5340 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5343 if (proc.pkgDeps == null) {
5344 proc.pkgDeps = new ArraySet<String>(1);
5346 proc.pkgDeps.add(packageName);
5352 * The pkg name and app id have to be specified.
5355 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5359 // Make sure the uid is valid.
5361 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5364 int callerUid = Binder.getCallingUid();
5365 // Only the system server can kill an application
5366 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5367 // Post an aysnc message to kill the application
5368 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5371 Bundle bundle = new Bundle();
5372 bundle.putString("pkg", pkg);
5373 bundle.putString("reason", reason);
5375 mHandler.sendMessage(msg);
5377 throw new SecurityException(callerUid + " cannot kill pkg: " +
5383 public void closeSystemDialogs(String reason) {
5384 enforceNotIsolatedCaller("closeSystemDialogs");
5386 final int pid = Binder.getCallingPid();
5387 final int uid = Binder.getCallingUid();
5388 final long origId = Binder.clearCallingIdentity();
5390 synchronized (this) {
5391 // Only allow this from foreground processes, so that background
5392 // applications can't abuse it to prevent system UI from being shown.
5393 if (uid >= Process.FIRST_APPLICATION_UID) {
5395 synchronized (mPidsSelfLocked) {
5396 proc = mPidsSelfLocked.get(pid);
5398 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5399 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5400 + " from background process " + proc);
5404 closeSystemDialogsLocked(reason);
5407 Binder.restoreCallingIdentity(origId);
5411 void closeSystemDialogsLocked(String reason) {
5412 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5413 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5414 | Intent.FLAG_RECEIVER_FOREGROUND);
5415 if (reason != null) {
5416 intent.putExtra("reason", reason);
5418 mWindowManager.closeSystemDialogs(reason);
5420 mStackSupervisor.closeSystemDialogsLocked();
5422 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5423 AppOpsManager.OP_NONE, null, false, false,
5424 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5428 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5429 enforceNotIsolatedCaller("getProcessMemoryInfo");
5430 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5431 for (int i=pids.length-1; i>=0; i--) {
5434 synchronized (this) {
5435 synchronized (mPidsSelfLocked) {
5436 proc = mPidsSelfLocked.get(pids[i]);
5437 oomAdj = proc != null ? proc.setAdj : 0;
5440 infos[i] = new Debug.MemoryInfo();
5441 Debug.getMemoryInfo(pids[i], infos[i]);
5443 synchronized (this) {
5444 if (proc.thread != null && proc.setAdj == oomAdj) {
5445 // Record this for posterity if the process has been stable.
5446 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5447 infos[i].getTotalUss(), false, proc.pkgList);
5456 public long[] getProcessPss(int[] pids) {
5457 enforceNotIsolatedCaller("getProcessPss");
5458 long[] pss = new long[pids.length];
5459 for (int i=pids.length-1; i>=0; i--) {
5462 synchronized (this) {
5463 synchronized (mPidsSelfLocked) {
5464 proc = mPidsSelfLocked.get(pids[i]);
5465 oomAdj = proc != null ? proc.setAdj : 0;
5468 long[] tmpUss = new long[1];
5469 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5471 synchronized (this) {
5472 if (proc.thread != null && proc.setAdj == oomAdj) {
5473 // Record this for posterity if the process has been stable.
5474 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5483 public void killApplicationProcess(String processName, int uid) {
5484 if (processName == null) {
5488 int callerUid = Binder.getCallingUid();
5489 // Only the system server can kill an application
5490 if (callerUid == Process.SYSTEM_UID) {
5491 synchronized (this) {
5492 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5493 if (app != null && app.thread != null) {
5495 app.thread.scheduleSuicide();
5496 } catch (RemoteException e) {
5497 // If the other end already died, then our work here is done.
5500 Slog.w(TAG, "Process/uid not found attempting kill of "
5501 + processName + " / " + uid);
5505 throw new SecurityException(callerUid + " cannot kill app process: " +
5510 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5511 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5512 false, true, false, false, UserHandle.getUserId(uid), reason);
5513 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5514 Uri.fromParts("package", packageName, null));
5515 if (!mProcessesReady) {
5516 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5517 | Intent.FLAG_RECEIVER_FOREGROUND);
5519 intent.putExtra(Intent.EXTRA_UID, uid);
5520 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5521 broadcastIntentLocked(null, null, intent,
5522 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5523 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5526 private void forceStopUserLocked(int userId, String reason) {
5527 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5528 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5529 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5530 | Intent.FLAG_RECEIVER_FOREGROUND);
5531 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5532 broadcastIntentLocked(null, null, intent,
5533 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5534 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5537 private final boolean killPackageProcessesLocked(String packageName, int appId,
5538 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5539 boolean doit, boolean evenPersistent, String reason) {
5540 ArrayList<ProcessRecord> procs = new ArrayList<>();
5542 // Remove all processes this package may have touched: all with the
5543 // same UID (except for the system or root user), and all whose name
5544 // matches the package name.
5545 final int NP = mProcessNames.getMap().size();
5546 for (int ip=0; ip<NP; ip++) {
5547 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5548 final int NA = apps.size();
5549 for (int ia=0; ia<NA; ia++) {
5550 ProcessRecord app = apps.valueAt(ia);
5551 if (app.persistent && !evenPersistent) {
5552 // we don't kill persistent processes
5562 // Skip process if it doesn't meet our oom adj requirement.
5563 if (app.setAdj < minOomAdj) {
5567 // If no package is specified, we call all processes under the
5569 if (packageName == null) {
5570 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5573 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5576 // Package has been specified, we want to hit all processes
5577 // that match it. We need to qualify this by the processes
5578 // that are running under the specified app and user ID.
5580 final boolean isDep = app.pkgDeps != null
5581 && app.pkgDeps.contains(packageName);
5582 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5585 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5588 if (!app.pkgList.containsKey(packageName) && !isDep) {
5593 // Process has passed all conditions, kill it!
5602 int N = procs.size();
5603 for (int i=0; i<N; i++) {
5604 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5606 updateOomAdjLocked();
5610 private void cleanupDisabledPackageComponentsLocked(
5611 String packageName, int userId, boolean killProcess, String[] changedClasses) {
5613 Set<String> disabledClasses = null;
5614 boolean packageDisabled = false;
5615 IPackageManager pm = AppGlobals.getPackageManager();
5617 if (changedClasses == null) {
5618 // Nothing changed...
5622 // Determine enable/disable state of the package and its components.
5623 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5624 for (int i = changedClasses.length - 1; i >= 0; i--) {
5625 final String changedClass = changedClasses[i];
5627 if (changedClass.equals(packageName)) {
5629 // Entire package setting changed
5630 enabled = pm.getApplicationEnabledSetting(packageName,
5631 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5632 } catch (Exception e) {
5633 // No such package/component; probably racing with uninstall. In any
5634 // event it means we have nothing further to do here.
5637 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5638 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5639 if (packageDisabled) {
5640 // Entire package is disabled.
5641 // No need to continue to check component states.
5642 disabledClasses = null;
5647 enabled = pm.getComponentEnabledSetting(
5648 new ComponentName(packageName, changedClass),
5649 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5650 } catch (Exception e) {
5651 // As above, probably racing with uninstall.
5654 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5655 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5656 if (disabledClasses == null) {
5657 disabledClasses = new ArraySet<>(changedClasses.length);
5659 disabledClasses.add(changedClass);
5664 if (!packageDisabled && disabledClasses == null) {
5665 // Nothing to do here...
5669 // Clean-up disabled activities.
5670 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5671 packageName, disabledClasses, true, false, userId) && mBooted) {
5672 mStackSupervisor.resumeTopActivitiesLocked();
5673 mStackSupervisor.scheduleIdleLocked();
5676 // Clean-up disabled tasks
5677 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5679 // Clean-up disabled services.
5680 mServices.bringDownDisabledPackageServicesLocked(
5681 packageName, disabledClasses, userId, false, killProcess, true);
5683 // Clean-up disabled providers.
5684 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5685 mProviderMap.collectPackageProvidersLocked(
5686 packageName, disabledClasses, true, false, userId, providers);
5687 for (int i = providers.size() - 1; i >= 0; i--) {
5688 removeDyingProviderLocked(null, providers.get(i), true);
5691 // Clean-up disabled broadcast receivers.
5692 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5693 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5694 packageName, disabledClasses, userId, true);
5699 private final boolean forceStopPackageLocked(String packageName, int appId,
5700 boolean callerWillRestart, boolean purgeCache, boolean doit,
5701 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5704 if (userId == UserHandle.USER_ALL && packageName == null) {
5705 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5708 if (appId < 0 && packageName != null) {
5710 appId = UserHandle.getAppId(
5711 AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5712 } catch (RemoteException e) {
5717 if (packageName != null) {
5718 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5719 + " user=" + userId + ": " + reason);
5721 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5724 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5725 for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5726 SparseArray<Long> ba = pmap.valueAt(ip);
5727 for (i = ba.size() - 1; i >= 0; i--) {
5728 boolean remove = false;
5729 final int entUid = ba.keyAt(i);
5730 if (packageName != null) {
5731 if (userId == UserHandle.USER_ALL) {
5732 if (UserHandle.getAppId(entUid) == appId) {
5736 if (entUid == UserHandle.getUid(userId, appId)) {
5740 } else if (UserHandle.getUserId(entUid) == userId) {
5747 if (ba.size() == 0) {
5753 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5754 -100, callerWillRestart, true, doit, evenPersistent,
5755 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5757 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5758 packageName, null, doit, evenPersistent, userId)) {
5762 didSomething = true;
5765 if (mServices.bringDownDisabledPackageServicesLocked(
5766 packageName, null, userId, evenPersistent, true, doit)) {
5770 didSomething = true;
5773 if (packageName == null) {
5774 // Remove all sticky broadcasts from this user.
5775 mStickyBroadcasts.remove(userId);
5778 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5779 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5780 userId, providers)) {
5784 didSomething = true;
5786 for (i = providers.size() - 1; i >= 0; i--) {
5787 removeDyingProviderLocked(null, providers.get(i), true);
5790 // Remove transient permissions granted from/to this package/user
5791 removeUriPermissionsForPackageLocked(packageName, userId, false);
5794 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5795 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5796 packageName, null, userId, doit);
5800 if (packageName == null || uninstalling) {
5801 // Remove pending intents. For now we only do this when force
5802 // stopping users, because we have some problems when doing this
5803 // for packages -- app widgets are not currently cleaned up for
5804 // such packages, so they can be left with bad pending intents.
5805 if (mIntentSenderRecords.size() > 0) {
5806 Iterator<WeakReference<PendingIntentRecord>> it
5807 = mIntentSenderRecords.values().iterator();
5808 while (it.hasNext()) {
5809 WeakReference<PendingIntentRecord> wpir = it.next();
5814 PendingIntentRecord pir = wpir.get();
5819 if (packageName == null) {
5820 // Stopping user, remove all objects for the user.
5821 if (pir.key.userId != userId) {
5822 // Not the same user, skip it.
5826 if (UserHandle.getAppId(pir.uid) != appId) {
5827 // Different app id, skip it.
5830 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5831 // Different user, skip it.
5834 if (!pir.key.packageName.equals(packageName)) {
5835 // Different package, skip it.
5842 didSomething = true;
5844 pir.canceled = true;
5845 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5846 pir.key.activity.pendingResults.remove(pir.ref);
5853 if (purgeCache && packageName != null) {
5854 AttributeCache ac = AttributeCache.instance();
5856 ac.removePackage(packageName);
5860 mStackSupervisor.resumeTopActivitiesLocked();
5861 mStackSupervisor.scheduleIdleLocked();
5865 return didSomething;
5868 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5869 ProcessRecord old = mProcessNames.remove(name, uid);
5871 old.uidRecord.numProcs--;
5872 if (old.uidRecord.numProcs == 0) {
5873 // No more processes using this uid, tell clients it is gone.
5874 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5875 "No more processes in " + old.uidRecord);
5876 enqueueUidChangeLocked(old.uidRecord, true);
5877 mActiveUids.remove(uid);
5879 old.uidRecord = null;
5881 mIsolatedProcesses.remove(uid);
5885 private final void addProcessNameLocked(ProcessRecord proc) {
5886 // We shouldn't already have a process under this name, but just in case we
5887 // need to clean up whatever may be there now.
5888 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5889 if (old == proc && proc.persistent) {
5890 // We are re-adding a persistent process. Whatevs! Just leave it there.
5891 Slog.w(TAG, "Re-adding persistent process " + proc);
5892 } else if (old != null) {
5893 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5895 UidRecord uidRec = mActiveUids.get(proc.uid);
5896 if (uidRec == null) {
5897 uidRec = new UidRecord(proc.uid);
5898 // This is the first appearance of the uid, report it now!
5899 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5900 "Creating new process uid: " + uidRec);
5901 mActiveUids.put(proc.uid, uidRec);
5902 enqueueUidChangeLocked(uidRec, false);
5904 proc.uidRecord = uidRec;
5906 mProcessNames.put(proc.processName, proc.uid, proc);
5907 if (proc.isolated) {
5908 mIsolatedProcesses.put(proc.uid, proc);
5912 private final boolean removeProcessLocked(ProcessRecord app,
5913 boolean callerWillRestart, boolean allowRestart, String reason) {
5914 final String name = app.processName;
5915 final int uid = app.uid;
5916 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5917 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5919 removeProcessNameLocked(name, uid);
5920 if (mHeavyWeightProcess == app) {
5921 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5922 mHeavyWeightProcess.userId, 0));
5923 mHeavyWeightProcess = null;
5925 boolean needRestart = false;
5926 if (app.pid > 0 && app.pid != MY_PID) {
5928 synchronized (mPidsSelfLocked) {
5929 mPidsSelfLocked.remove(pid);
5930 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5932 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5934 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5936 boolean willRestart = false;
5937 if (app.persistent && !app.isolated) {
5938 if (!callerWillRestart) {
5944 app.kill(reason, true);
5945 handleAppDiedLocked(app, willRestart, allowRestart);
5947 removeLruProcessLocked(app);
5948 addAppLocked(app.info, false, null /* ABI override */);
5951 mRemovedProcesses.add(app);
5957 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
5958 cleanupAppInLaunchingProvidersLocked(app, true);
5959 removeProcessLocked(app, false, true, "timeout publishing content providers");
5962 private final void processStartTimedOutLocked(ProcessRecord app) {
5963 final int pid = app.pid;
5964 boolean gone = false;
5965 synchronized (mPidsSelfLocked) {
5966 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5967 if (knownApp != null && knownApp.thread == null) {
5968 mPidsSelfLocked.remove(pid);
5974 Slog.w(TAG, "Process " + app + " failed to attach");
5975 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5976 pid, app.uid, app.processName);
5977 removeProcessNameLocked(app.processName, app.uid);
5978 if (mHeavyWeightProcess == app) {
5979 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5980 mHeavyWeightProcess.userId, 0));
5981 mHeavyWeightProcess = null;
5983 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5985 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5987 // Take care of any launching providers waiting for this process.
5988 cleanupAppInLaunchingProvidersLocked(app, true);
5989 // Take care of any services that are waiting for the process.
5990 mServices.processStartTimedOutLocked(app);
5991 app.kill("start timeout", true);
5992 removeLruProcessLocked(app);
5993 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5994 Slog.w(TAG, "Unattached app died before backup, skipping");
5996 IBackupManager bm = IBackupManager.Stub.asInterface(
5997 ServiceManager.getService(Context.BACKUP_SERVICE));
5998 bm.agentDisconnected(app.info.packageName);
5999 } catch (RemoteException e) {
6000 // Can't happen; the backup manager is local
6003 if (isPendingBroadcastProcessLocked(pid)) {
6004 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6005 skipPendingBroadcastLocked(pid);
6008 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6012 private final boolean attachApplicationLocked(IApplicationThread thread,
6015 // Find the application record that is being attached... either via
6016 // the pid if we are running in multiple processes, or just pull the
6017 // next app record if we are emulating process with anonymous threads.
6019 if (pid != MY_PID && pid >= 0) {
6020 synchronized (mPidsSelfLocked) {
6021 app = mPidsSelfLocked.get(pid);
6028 Slog.w(TAG, "No pending application record for pid " + pid
6029 + " (IApplicationThread " + thread + "); dropping process");
6030 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6031 if (pid > 0 && pid != MY_PID) {
6032 Process.killProcessQuiet(pid);
6033 //TODO: killProcessGroup(app.info.uid, pid);
6036 thread.scheduleExit();
6037 } catch (Exception e) {
6038 // Ignore exceptions.
6044 // If this application record is still attached to a previous
6045 // process, clean it up now.
6046 if (app.thread != null) {
6047 handleAppDiedLocked(app, true, true);
6050 // Tell the process all about itself.
6052 if (DEBUG_ALL) Slog.v(
6053 TAG, "Binding process pid " + pid + " to record " + app);
6055 final String processName = app.processName;
6057 AppDeathRecipient adr = new AppDeathRecipient(
6059 thread.asBinder().linkToDeath(adr, 0);
6060 app.deathRecipient = adr;
6061 } catch (RemoteException e) {
6062 app.resetPackageList(mProcessStats);
6063 startProcessLocked(app, "link fail", processName);
6067 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6069 app.makeActive(thread, mProcessStats);
6070 app.curAdj = app.setAdj = -100;
6071 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6072 app.forcingToForeground = null;
6073 updateProcessForegroundLocked(app, false, false);
6074 app.hasShownUi = false;
6075 app.debugging = false;
6077 app.killedByAm = false;
6079 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6081 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6082 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6084 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6085 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6087 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6091 Slog.i(TAG, "Launching preboot mode app: " + app);
6094 if (DEBUG_ALL) Slog.v(
6095 TAG, "New app record " + app
6096 + " thread=" + thread.asBinder() + " pid=" + pid);
6098 int testMode = IApplicationThread.DEBUG_OFF;
6099 if (mDebugApp != null && mDebugApp.equals(processName)) {
6100 testMode = mWaitForDebugger
6101 ? IApplicationThread.DEBUG_WAIT
6102 : IApplicationThread.DEBUG_ON;
6103 app.debugging = true;
6104 if (mDebugTransient) {
6105 mDebugApp = mOrigDebugApp;
6106 mWaitForDebugger = mOrigWaitForDebugger;
6109 String profileFile = app.instrumentationProfileFile;
6110 ParcelFileDescriptor profileFd = null;
6111 int samplingInterval = 0;
6112 boolean profileAutoStop = false;
6113 if (mProfileApp != null && mProfileApp.equals(processName)) {
6115 profileFile = mProfileFile;
6116 profileFd = mProfileFd;
6117 samplingInterval = mSamplingInterval;
6118 profileAutoStop = mAutoStopProfiler;
6120 boolean enableOpenGlTrace = false;
6121 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6122 enableOpenGlTrace = true;
6123 mOpenGlTraceApp = null;
6126 // If the app is being launched for restore or full backup, set it up specially
6127 boolean isRestrictedBackupMode = false;
6128 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6129 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6130 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6131 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6134 ensurePackageDexOpt(app.instrumentationInfo != null
6135 ? app.instrumentationInfo.packageName
6136 : app.info.packageName);
6137 if (app.instrumentationClass != null) {
6138 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6140 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6141 + processName + " with config " + mConfiguration);
6142 ApplicationInfo appInfo = app.instrumentationInfo != null
6143 ? app.instrumentationInfo : app.info;
6144 app.compat = compatibilityInfoForPackageLocked(appInfo);
6145 if (profileFd != null) {
6146 profileFd = profileFd.dup();
6148 ProfilerInfo profilerInfo = profileFile == null ? null
6149 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6150 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6151 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6152 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6153 isRestrictedBackupMode || !normalMode, app.persistent,
6154 new Configuration(mConfiguration), app.compat,
6155 getCommonServicesLocked(app.isolated),
6156 mCoreSettingsObserver.getCoreSettingsLocked());
6157 updateLruProcessLocked(app, false, null);
6158 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6159 } catch (Exception e) {
6160 // todo: Yikes! What should we do? For now we will try to
6161 // start another process, but that could easily get us in
6162 // an infinite loop of restarting processes...
6163 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6165 app.resetPackageList(mProcessStats);
6166 app.unlinkDeathRecipient();
6167 startProcessLocked(app, "bind fail", processName);
6171 // Remove this record from the list of starting applications.
6172 mPersistentStartingProcesses.remove(app);
6173 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6174 "Attach application locked removing on hold: " + app);
6175 mProcessesOnHold.remove(app);
6177 boolean badApp = false;
6178 boolean didSomething = false;
6180 // See if the top visible activity is waiting to run in this process...
6183 if (mStackSupervisor.attachApplicationLocked(app)) {
6184 didSomething = true;
6186 } catch (Exception e) {
6187 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6192 // Find any services that should be running in this process...
6195 didSomething |= mServices.attachApplicationLocked(app, processName);
6196 } catch (Exception e) {
6197 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6202 // Check if a next-broadcast receiver is in this process...
6203 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6205 didSomething |= sendPendingBroadcastsLocked(app);
6206 } catch (Exception e) {
6207 // If the app died trying to launch the receiver we declare it 'bad'
6208 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6213 // Check whether the next backup agent is in this process...
6214 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6215 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6216 "New app is backup target, launching agent for " + app);
6217 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6219 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6220 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6221 mBackupTarget.backupMode);
6222 } catch (Exception e) {
6223 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6229 app.kill("error during init", true);
6230 handleAppDiedLocked(app, false, true);
6234 if (!didSomething) {
6235 updateOomAdjLocked();
6242 public final void attachApplication(IApplicationThread thread) {
6243 synchronized (this) {
6244 int callingPid = Binder.getCallingPid();
6245 final long origId = Binder.clearCallingIdentity();
6246 attachApplicationLocked(thread, callingPid);
6247 Binder.restoreCallingIdentity(origId);
6252 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6253 final long origId = Binder.clearCallingIdentity();
6254 synchronized (this) {
6255 ActivityStack stack = ActivityRecord.getStackLocked(token);
6256 if (stack != null) {
6258 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6259 if (stopProfiling) {
6260 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6263 } catch (IOException e) {
6265 clearProfilerLocked();
6270 Binder.restoreCallingIdentity(origId);
6273 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6274 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6275 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6278 void enableScreenAfterBoot() {
6279 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6280 SystemClock.uptimeMillis());
6281 mWindowManager.enableScreenAfterBoot();
6283 synchronized (this) {
6284 updateEventDispatchingLocked();
6289 public void showBootMessage(final CharSequence msg, final boolean always) {
6290 if (Binder.getCallingUid() != Process.myUid()) {
6291 // These days only the core system can call this, so apps can't get in
6292 // the way of what we show about running them.
6294 mWindowManager.showBootMessage(msg, always);
6298 public void keyguardWaitingForActivityDrawn() {
6299 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6300 final long token = Binder.clearCallingIdentity();
6302 synchronized (this) {
6303 if (DEBUG_LOCKSCREEN) logLockScreen("");
6304 mWindowManager.keyguardWaitingForActivityDrawn();
6305 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6306 mLockScreenShown = LOCK_SCREEN_LEAVING;
6307 updateSleepIfNeededLocked();
6311 Binder.restoreCallingIdentity(token);
6316 public void keyguardGoingAway(boolean disableWindowAnimations,
6317 boolean keyguardGoingToNotificationShade) {
6318 enforceNotIsolatedCaller("keyguardGoingAway");
6319 final long token = Binder.clearCallingIdentity();
6321 synchronized (this) {
6322 if (DEBUG_LOCKSCREEN) logLockScreen("");
6323 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6324 keyguardGoingToNotificationShade);
6325 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6326 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6327 updateSleepIfNeededLocked();
6331 Binder.restoreCallingIdentity(token);
6335 final void finishBooting() {
6336 synchronized (this) {
6337 if (!mBootAnimationComplete) {
6338 mCallFinishBooting = true;
6341 mCallFinishBooting = false;
6344 ArraySet<String> completedIsas = new ArraySet<String>();
6345 for (String abi : Build.SUPPORTED_ABIS) {
6346 Process.establishZygoteConnectionForAbi(abi);
6347 final String instructionSet = VMRuntime.getInstructionSet(abi);
6348 if (!completedIsas.contains(instructionSet)) {
6349 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6350 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6352 completedIsas.add(instructionSet);
6356 IntentFilter pkgFilter = new IntentFilter();
6357 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6358 pkgFilter.addDataScheme("package");
6359 mContext.registerReceiver(new BroadcastReceiver() {
6361 public void onReceive(Context context, Intent intent) {
6362 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6364 for (String pkg : pkgs) {
6365 synchronized (ActivityManagerService.this) {
6366 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6367 0, "query restart")) {
6368 setResultCode(Activity.RESULT_OK);
6377 IntentFilter dumpheapFilter = new IntentFilter();
6378 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6379 mContext.registerReceiver(new BroadcastReceiver() {
6381 public void onReceive(Context context, Intent intent) {
6382 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6383 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6385 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6390 // Let system services know.
6391 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6393 synchronized (this) {
6394 // Ensure that any processes we had put on hold are now started
6396 final int NP = mProcessesOnHold.size();
6398 ArrayList<ProcessRecord> procs =
6399 new ArrayList<ProcessRecord>(mProcessesOnHold);
6400 for (int ip=0; ip<NP; ip++) {
6401 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6403 startProcessLocked(procs.get(ip), "on-hold", null);
6407 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6408 // Start looking for apps that are abusing wake locks.
6409 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6410 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6411 // Tell anyone interested that we are done booting!
6412 SystemProperties.set("sys.boot_completed", "1");
6414 // And trigger dev.bootcomplete if we are not showing encryption progress
6415 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6416 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6417 SystemProperties.set("dev.bootcomplete", "1");
6419 for (int i=0; i<mStartedUsers.size(); i++) {
6420 UserState uss = mStartedUsers.valueAt(i);
6421 if (uss.mState == UserState.STATE_BOOTING) {
6422 uss.mState = UserState.STATE_RUNNING;
6423 final int userId = mStartedUsers.keyAt(i);
6424 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6425 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6426 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6427 broadcastIntentLocked(null, null, intent, null,
6428 new IIntentReceiver.Stub() {
6430 public void performReceive(Intent intent, int resultCode,
6431 String data, Bundle extras, boolean ordered,
6432 boolean sticky, int sendingUser) {
6433 synchronized (ActivityManagerService.this) {
6434 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6440 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6441 AppOpsManager.OP_NONE, null, true, false,
6442 MY_PID, Process.SYSTEM_UID, userId);
6445 scheduleStartProfilesLocked();
6451 public void bootAnimationComplete() {
6452 final boolean callFinishBooting;
6453 synchronized (this) {
6454 callFinishBooting = mCallFinishBooting;
6455 mBootAnimationComplete = true;
6457 if (callFinishBooting) {
6462 final void ensureBootCompleted() {
6464 boolean enableScreen;
6465 synchronized (this) {
6468 enableScreen = !mBooted;
6477 enableScreenAfterBoot();
6482 public final void activityResumed(IBinder token) {
6483 final long origId = Binder.clearCallingIdentity();
6484 synchronized(this) {
6485 ActivityStack stack = ActivityRecord.getStackLocked(token);
6486 if (stack != null) {
6487 ActivityRecord.activityResumedLocked(token);
6490 Binder.restoreCallingIdentity(origId);
6494 public final void activityPaused(IBinder token) {
6495 final long origId = Binder.clearCallingIdentity();
6496 synchronized(this) {
6497 ActivityStack stack = ActivityRecord.getStackLocked(token);
6498 if (stack != null) {
6499 stack.activityPausedLocked(token, false);
6502 Binder.restoreCallingIdentity(origId);
6506 public final void activityStopped(IBinder token, Bundle icicle,
6507 PersistableBundle persistentState, CharSequence description) {
6508 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6510 // Refuse possible leaked file descriptors
6511 if (icicle != null && icicle.hasFileDescriptors()) {
6512 throw new IllegalArgumentException("File descriptors passed in Bundle");
6515 final long origId = Binder.clearCallingIdentity();
6517 synchronized (this) {
6518 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6520 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6526 Binder.restoreCallingIdentity(origId);
6530 public final void activityDestroyed(IBinder token) {
6531 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6532 synchronized (this) {
6533 ActivityStack stack = ActivityRecord.getStackLocked(token);
6534 if (stack != null) {
6535 stack.activityDestroyedLocked(token, "activityDestroyed");
6541 public final void backgroundResourcesReleased(IBinder token) {
6542 final long origId = Binder.clearCallingIdentity();
6544 synchronized (this) {
6545 ActivityStack stack = ActivityRecord.getStackLocked(token);
6546 if (stack != null) {
6547 stack.backgroundResourcesReleased();
6551 Binder.restoreCallingIdentity(origId);
6556 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6557 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6561 public final void notifyEnterAnimationComplete(IBinder token) {
6562 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6566 public String getCallingPackage(IBinder token) {
6567 synchronized (this) {
6568 ActivityRecord r = getCallingRecordLocked(token);
6569 return r != null ? r.info.packageName : null;
6574 public ComponentName getCallingActivity(IBinder token) {
6575 synchronized (this) {
6576 ActivityRecord r = getCallingRecordLocked(token);
6577 return r != null ? r.intent.getComponent() : null;
6581 private ActivityRecord getCallingRecordLocked(IBinder token) {
6582 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6590 public ComponentName getActivityClassForToken(IBinder token) {
6591 synchronized(this) {
6592 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6596 return r.intent.getComponent();
6601 public String getPackageForToken(IBinder token) {
6602 synchronized(this) {
6603 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6607 return r.packageName;
6612 public boolean isRootVoiceInteraction(IBinder token) {
6613 synchronized(this) {
6614 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6618 return r.rootVoiceInteraction;
6623 public IIntentSender getIntentSender(int type,
6624 String packageName, IBinder token, String resultWho,
6625 int requestCode, Intent[] intents, String[] resolvedTypes,
6626 int flags, Bundle options, int userId) {
6627 enforceNotIsolatedCaller("getIntentSender");
6628 // Refuse possible leaked file descriptors
6629 if (intents != null) {
6630 if (intents.length < 1) {
6631 throw new IllegalArgumentException("Intents array length must be >= 1");
6633 for (int i=0; i<intents.length; i++) {
6634 Intent intent = intents[i];
6635 if (intent != null) {
6636 if (intent.hasFileDescriptors()) {
6637 throw new IllegalArgumentException("File descriptors passed in Intent");
6639 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6640 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6641 throw new IllegalArgumentException(
6642 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6644 intents[i] = new Intent(intent);
6647 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6648 throw new IllegalArgumentException(
6649 "Intent array length does not match resolvedTypes length");
6652 if (options != null) {
6653 if (options.hasFileDescriptors()) {
6654 throw new IllegalArgumentException("File descriptors passed in options");
6658 synchronized(this) {
6659 int callingUid = Binder.getCallingUid();
6660 int origUserId = userId;
6661 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6662 type == ActivityManager.INTENT_SENDER_BROADCAST,
6663 ALLOW_NON_FULL, "getIntentSender", null);
6664 if (origUserId == UserHandle.USER_CURRENT) {
6665 // We don't want to evaluate this until the pending intent is
6666 // actually executed. However, we do want to always do the
6667 // security checking for it above.
6668 userId = UserHandle.USER_CURRENT;
6671 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6672 int uid = AppGlobals.getPackageManager()
6673 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6674 if (!UserHandle.isSameApp(callingUid, uid)) {
6675 String msg = "Permission Denial: getIntentSender() from pid="
6676 + Binder.getCallingPid()
6677 + ", uid=" + Binder.getCallingUid()
6678 + ", (need uid=" + uid + ")"
6679 + " is not allowed to send as package " + packageName;
6681 throw new SecurityException(msg);
6685 return getIntentSenderLocked(type, packageName, callingUid, userId,
6686 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6688 } catch (RemoteException e) {
6689 throw new SecurityException(e);
6694 IIntentSender getIntentSenderLocked(int type, String packageName,
6695 int callingUid, int userId, IBinder token, String resultWho,
6696 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6698 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6699 ActivityRecord activity = null;
6700 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6701 activity = ActivityRecord.isInStackLocked(token);
6702 if (activity == null) {
6705 if (activity.finishing) {
6710 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6711 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6712 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6713 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6714 |PendingIntent.FLAG_UPDATE_CURRENT);
6716 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6717 type, packageName, activity, resultWho,
6718 requestCode, intents, resolvedTypes, flags, options, userId);
6719 WeakReference<PendingIntentRecord> ref;
6720 ref = mIntentSenderRecords.get(key);
6721 PendingIntentRecord rec = ref != null ? ref.get() : null;
6723 if (!cancelCurrent) {
6724 if (updateCurrent) {
6725 if (rec.key.requestIntent != null) {
6726 rec.key.requestIntent.replaceExtras(intents != null ?
6727 intents[intents.length - 1] : null);
6729 if (intents != null) {
6730 intents[intents.length-1] = rec.key.requestIntent;
6731 rec.key.allIntents = intents;
6732 rec.key.allResolvedTypes = resolvedTypes;
6734 rec.key.allIntents = null;
6735 rec.key.allResolvedTypes = null;
6740 rec.canceled = true;
6741 mIntentSenderRecords.remove(key);
6746 rec = new PendingIntentRecord(this, key, callingUid);
6747 mIntentSenderRecords.put(key, rec.ref);
6748 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6749 if (activity.pendingResults == null) {
6750 activity.pendingResults
6751 = new HashSet<WeakReference<PendingIntentRecord>>();
6753 activity.pendingResults.add(rec.ref);
6759 public void cancelIntentSender(IIntentSender sender) {
6760 if (!(sender instanceof PendingIntentRecord)) {
6763 synchronized(this) {
6764 PendingIntentRecord rec = (PendingIntentRecord)sender;
6766 int uid = AppGlobals.getPackageManager()
6767 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6768 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6769 String msg = "Permission Denial: cancelIntentSender() from pid="
6770 + Binder.getCallingPid()
6771 + ", uid=" + Binder.getCallingUid()
6772 + " is not allowed to cancel packges "
6773 + rec.key.packageName;
6775 throw new SecurityException(msg);
6777 } catch (RemoteException e) {
6778 throw new SecurityException(e);
6780 cancelIntentSenderLocked(rec, true);
6784 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6785 rec.canceled = true;
6786 mIntentSenderRecords.remove(rec.key);
6787 if (cleanActivity && rec.key.activity != null) {
6788 rec.key.activity.pendingResults.remove(rec.ref);
6793 public String getPackageForIntentSender(IIntentSender pendingResult) {
6794 if (!(pendingResult instanceof PendingIntentRecord)) {
6798 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6799 return res.key.packageName;
6800 } catch (ClassCastException e) {
6806 public int getUidForIntentSender(IIntentSender sender) {
6807 if (sender instanceof PendingIntentRecord) {
6809 PendingIntentRecord res = (PendingIntentRecord)sender;
6811 } catch (ClassCastException e) {
6818 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6819 if (!(pendingResult instanceof PendingIntentRecord)) {
6823 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6824 if (res.key.allIntents == null) {
6827 for (int i=0; i<res.key.allIntents.length; i++) {
6828 Intent intent = res.key.allIntents[i];
6829 if (intent.getPackage() != null && intent.getComponent() != null) {
6834 } catch (ClassCastException e) {
6840 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6841 if (!(pendingResult instanceof PendingIntentRecord)) {
6845 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6846 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6850 } catch (ClassCastException e) {
6856 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6857 if (!(pendingResult instanceof PendingIntentRecord)) {
6861 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6862 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6863 } catch (ClassCastException e) {
6869 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6870 if (!(pendingResult instanceof PendingIntentRecord)) {
6874 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6875 synchronized (this) {
6876 return getTagForIntentSenderLocked(res, prefix);
6878 } catch (ClassCastException e) {
6883 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6884 final Intent intent = res.key.requestIntent;
6885 if (intent != null) {
6886 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6887 || res.lastTagPrefix.equals(prefix))) {
6890 res.lastTagPrefix = prefix;
6891 final StringBuilder sb = new StringBuilder(128);
6892 if (prefix != null) {
6895 if (intent.getAction() != null) {
6896 sb.append(intent.getAction());
6897 } else if (intent.getComponent() != null) {
6898 intent.getComponent().appendShortString(sb);
6902 return res.lastTag = sb.toString();
6908 public void setProcessLimit(int max) {
6909 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6910 "setProcessLimit()");
6911 synchronized (this) {
6912 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6913 mProcessLimitOverride = max;
6919 public int getProcessLimit() {
6920 synchronized (this) {
6921 return mProcessLimitOverride;
6925 void foregroundTokenDied(ForegroundToken token) {
6926 synchronized (ActivityManagerService.this) {
6927 synchronized (mPidsSelfLocked) {
6929 = mForegroundProcesses.get(token.pid);
6933 mForegroundProcesses.remove(token.pid);
6934 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6938 pr.forcingToForeground = null;
6939 updateProcessForegroundLocked(pr, false, false);
6941 updateOomAdjLocked();
6946 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6947 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6948 "setProcessForeground()");
6949 synchronized(this) {
6950 boolean changed = false;
6952 synchronized (mPidsSelfLocked) {
6953 ProcessRecord pr = mPidsSelfLocked.get(pid);
6954 if (pr == null && isForeground) {
6955 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6958 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6959 if (oldToken != null) {
6960 oldToken.token.unlinkToDeath(oldToken, 0);
6961 mForegroundProcesses.remove(pid);
6963 pr.forcingToForeground = null;
6967 if (isForeground && token != null) {
6968 ForegroundToken newToken = new ForegroundToken() {
6970 public void binderDied() {
6971 foregroundTokenDied(this);
6975 newToken.token = token;
6977 token.linkToDeath(newToken, 0);
6978 mForegroundProcesses.put(pid, newToken);
6979 pr.forcingToForeground = token;
6981 } catch (RemoteException e) {
6982 // If the process died while doing this, we will later
6983 // do the cleanup with the process death link.
6989 updateOomAdjLocked();
6994 // =========================================================
6996 // =========================================================
6998 static class ProcessInfoService extends IProcessInfoService.Stub {
6999 final ActivityManagerService mActivityManagerService;
7000 ProcessInfoService(ActivityManagerService activityManagerService) {
7001 mActivityManagerService = activityManagerService;
7005 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7006 mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
7011 * For each PID in the given input array, write the current process state
7012 * for that process into the output array, or -1 to indicate that no
7013 * process with the given PID exists.
7015 public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
7017 throw new NullPointerException("pids");
7018 } else if (states == null) {
7019 throw new NullPointerException("states");
7020 } else if (pids.length != states.length) {
7021 throw new IllegalArgumentException("input and output arrays have different lengths!");
7024 synchronized (mPidsSelfLocked) {
7025 for (int i = 0; i < pids.length; i++) {
7026 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7027 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7033 // =========================================================
7035 // =========================================================
7037 static class PermissionController extends IPermissionController.Stub {
7038 ActivityManagerService mActivityManagerService;
7039 PermissionController(ActivityManagerService activityManagerService) {
7040 mActivityManagerService = activityManagerService;
7044 public boolean checkPermission(String permission, int pid, int uid) {
7045 return mActivityManagerService.checkPermission(permission, pid,
7046 uid) == PackageManager.PERMISSION_GRANTED;
7050 public String[] getPackagesForUid(int uid) {
7051 return mActivityManagerService.mContext.getPackageManager()
7052 .getPackagesForUid(uid);
7056 public boolean isRuntimePermission(String permission) {
7058 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7059 .getPermissionInfo(permission, 0);
7060 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7061 } catch (NameNotFoundException nnfe) {
7062 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7068 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7070 public int checkComponentPermission(String permission, int pid, int uid,
7071 int owningUid, boolean exported) {
7072 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7073 owningUid, exported);
7077 public Object getAMSLock() {
7078 return ActivityManagerService.this;
7083 * This can be called with or without the global lock held.
7085 int checkComponentPermission(String permission, int pid, int uid,
7086 int owningUid, boolean exported) {
7087 if (pid == MY_PID) {
7088 return PackageManager.PERMISSION_GRANTED;
7090 return ActivityManager.checkComponentPermission(permission, uid,
7091 owningUid, exported);
7095 * As the only public entry point for permissions checking, this method
7096 * can enforce the semantic that requesting a check on a null global
7097 * permission is automatically denied. (Internally a null permission
7098 * string is used when calling {@link #checkComponentPermission} in cases
7099 * when only uid-based security is needed.)
7101 * This can be called with or without the global lock held.
7104 public int checkPermission(String permission, int pid, int uid) {
7105 if (permission == null) {
7106 return PackageManager.PERMISSION_DENIED;
7108 return checkComponentPermission(permission, pid, uid, -1, true);
7112 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7113 if (permission == null) {
7114 return PackageManager.PERMISSION_DENIED;
7117 // We might be performing an operation on behalf of an indirect binder
7118 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7119 // client identity accordingly before proceeding.
7120 Identity tlsIdentity = sCallerIdentity.get();
7121 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7122 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7123 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7124 uid = tlsIdentity.uid;
7125 pid = tlsIdentity.pid;
7128 return checkComponentPermission(permission, pid, uid, -1, true);
7132 * Binder IPC calls go through the public entry point.
7133 * This can be called with or without the global lock held.
7135 int checkCallingPermission(String permission) {
7136 return checkPermission(permission,
7137 Binder.getCallingPid(),
7138 UserHandle.getAppId(Binder.getCallingUid()));
7142 * This can be called with or without the global lock held.
7144 void enforceCallingPermission(String permission, String func) {
7145 if (checkCallingPermission(permission)
7146 == PackageManager.PERMISSION_GRANTED) {
7150 String msg = "Permission Denial: " + func + " from pid="
7151 + Binder.getCallingPid()
7152 + ", uid=" + Binder.getCallingUid()
7153 + " requires " + permission;
7155 throw new SecurityException(msg);
7159 * Determine if UID is holding permissions required to access {@link Uri} in
7160 * the given {@link ProviderInfo}. Final permission checking is always done
7161 * in {@link ContentProvider}.
7163 private final boolean checkHoldingPermissionsLocked(
7164 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7165 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7166 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7167 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7168 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7169 != PERMISSION_GRANTED) {
7173 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7176 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7177 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7178 if (pi.applicationInfo.uid == uid) {
7180 } else if (!pi.exported) {
7184 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7185 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7187 // check if target holds top-level <provider> permissions
7188 if (!readMet && pi.readPermission != null && considerUidPermissions
7189 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7192 if (!writeMet && pi.writePermission != null && considerUidPermissions
7193 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7197 // track if unprotected read/write is allowed; any denied
7198 // <path-permission> below removes this ability
7199 boolean allowDefaultRead = pi.readPermission == null;
7200 boolean allowDefaultWrite = pi.writePermission == null;
7202 // check if target holds any <path-permission> that match uri
7203 final PathPermission[] pps = pi.pathPermissions;
7205 final String path = grantUri.uri.getPath();
7207 while (i > 0 && (!readMet || !writeMet)) {
7209 PathPermission pp = pps[i];
7210 if (pp.match(path)) {
7212 final String pprperm = pp.getReadPermission();
7213 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7214 "Checking read perm for " + pprperm + " for " + pp.getPath()
7215 + ": match=" + pp.match(path)
7216 + " check=" + pm.checkUidPermission(pprperm, uid));
7217 if (pprperm != null) {
7218 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7219 == PERMISSION_GRANTED) {
7222 allowDefaultRead = false;
7227 final String ppwperm = pp.getWritePermission();
7228 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7229 "Checking write perm " + ppwperm + " for " + pp.getPath()
7230 + ": match=" + pp.match(path)
7231 + " check=" + pm.checkUidPermission(ppwperm, uid));
7232 if (ppwperm != null) {
7233 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7234 == PERMISSION_GRANTED) {
7237 allowDefaultWrite = false;
7245 // grant unprotected <provider> read/write, if not blocked by
7246 // <path-permission> above
7247 if (allowDefaultRead) readMet = true;
7248 if (allowDefaultWrite) writeMet = true;
7250 } catch (RemoteException e) {
7254 return readMet && writeMet;
7257 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7258 ProviderInfo pi = null;
7259 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7264 pi = AppGlobals.getPackageManager().resolveContentProvider(
7265 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7266 } catch (RemoteException ex) {
7272 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7273 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7274 if (targetUris != null) {
7275 return targetUris.get(grantUri);
7280 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7281 String targetPkg, int targetUid, GrantUri grantUri) {
7282 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7283 if (targetUris == null) {
7284 targetUris = Maps.newArrayMap();
7285 mGrantedUriPermissions.put(targetUid, targetUris);
7288 UriPermission perm = targetUris.get(grantUri);
7290 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7291 targetUris.put(grantUri, perm);
7297 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7298 final int modeFlags) {
7299 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7300 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7301 : UriPermission.STRENGTH_OWNED;
7303 // Root gets to do everything.
7308 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7309 if (perms == null) return false;
7311 // First look for exact match
7312 final UriPermission exactPerm = perms.get(grantUri);
7313 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7317 // No exact match, look for prefixes
7318 final int N = perms.size();
7319 for (int i = 0; i < N; i++) {
7320 final UriPermission perm = perms.valueAt(i);
7321 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7322 && perm.getStrength(modeFlags) >= minStrength) {
7331 * @param uri This uri must NOT contain an embedded userId.
7332 * @param userId The userId in which the uri is to be resolved.
7335 public int checkUriPermission(Uri uri, int pid, int uid,
7336 final int modeFlags, int userId, IBinder callerToken) {
7337 enforceNotIsolatedCaller("checkUriPermission");
7339 // Another redirected-binder-call permissions check as in
7340 // {@link checkPermissionWithToken}.
7341 Identity tlsIdentity = sCallerIdentity.get();
7342 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7343 uid = tlsIdentity.uid;
7344 pid = tlsIdentity.pid;
7347 // Our own process gets to do everything.
7348 if (pid == MY_PID) {
7349 return PackageManager.PERMISSION_GRANTED;
7351 synchronized (this) {
7352 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7353 ? PackageManager.PERMISSION_GRANTED
7354 : PackageManager.PERMISSION_DENIED;
7359 * Check if the targetPkg can be granted permission to access uri by
7360 * the callingUid using the given modeFlags. Throws a security exception
7361 * if callingUid is not allowed to do this. Returns the uid of the target
7362 * if the URI permission grant should be performed; returns -1 if it is not
7363 * needed (for example targetPkg already has permission to access the URI).
7364 * If you already know the uid of the target, you can supply it in
7365 * lastTargetUid else set that to -1.
7367 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7368 final int modeFlags, int lastTargetUid) {
7369 if (!Intent.isAccessUriMode(modeFlags)) {
7373 if (targetPkg != null) {
7374 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7375 "Checking grant " + targetPkg + " permission to " + grantUri);
7378 final IPackageManager pm = AppGlobals.getPackageManager();
7380 // If this is not a content: uri, we can't do anything with it.
7381 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7382 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7383 "Can't grant URI permission for non-content URI: " + grantUri);
7387 final String authority = grantUri.uri.getAuthority();
7388 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7390 Slog.w(TAG, "No content provider found for permission check: " +
7391 grantUri.uri.toSafeString());
7395 int targetUid = lastTargetUid;
7396 if (targetUid < 0 && targetPkg != null) {
7398 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7399 if (targetUid < 0) {
7400 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7401 "Can't grant URI permission no uid for: " + targetPkg);
7404 } catch (RemoteException ex) {
7409 if (targetUid >= 0) {
7410 // First... does the target actually need this permission?
7411 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7412 // No need to grant the target this permission.
7413 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7414 "Target " + targetPkg + " already has full permission to " + grantUri);
7418 // First... there is no target package, so can anyone access it?
7419 boolean allowed = pi.exported;
7420 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7421 if (pi.readPermission != null) {
7425 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7426 if (pi.writePermission != null) {
7435 /* There is a special cross user grant if:
7436 * - The target is on another user.
7437 * - Apps on the current user can access the uri without any uid permissions.
7438 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7439 * grant uri permissions.
7441 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7442 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7443 modeFlags, false /*without considering the uid permissions*/);
7445 // Second... is the provider allowing granting of URI permissions?
7446 if (!specialCrossUserGrant) {
7447 if (!pi.grantUriPermissions) {
7448 throw new SecurityException("Provider " + pi.packageName
7450 + " does not allow granting of Uri permissions (uri "
7453 if (pi.uriPermissionPatterns != null) {
7454 final int N = pi.uriPermissionPatterns.length;
7455 boolean allowed = false;
7456 for (int i=0; i<N; i++) {
7457 if (pi.uriPermissionPatterns[i] != null
7458 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7464 throw new SecurityException("Provider " + pi.packageName
7466 + " does not allow granting of permission to path of Uri "
7472 // Third... does the caller itself have permission to access
7474 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7475 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7476 // Require they hold a strong enough Uri permission
7477 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7478 throw new SecurityException("Uid " + callingUid
7479 + " does not have permission to uri " + grantUri);
7487 * @param uri This uri must NOT contain an embedded userId.
7488 * @param userId The userId in which the uri is to be resolved.
7491 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7492 final int modeFlags, int userId) {
7493 enforceNotIsolatedCaller("checkGrantUriPermission");
7494 synchronized(this) {
7495 return checkGrantUriPermissionLocked(callingUid, targetPkg,
7496 new GrantUri(userId, uri, false), modeFlags, -1);
7500 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7501 final int modeFlags, UriPermissionOwner owner) {
7502 if (!Intent.isAccessUriMode(modeFlags)) {
7506 // So here we are: the caller has the assumed permission
7507 // to the uri, and the target doesn't. Let's now give this to
7510 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7511 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7513 final String authority = grantUri.uri.getAuthority();
7514 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7516 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7520 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7521 grantUri.prefix = true;
7523 final UriPermission perm = findOrCreateUriPermissionLocked(
7524 pi.packageName, targetPkg, targetUid, grantUri);
7525 perm.grantModes(modeFlags, owner);
7528 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7529 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7530 if (targetPkg == null) {
7531 throw new NullPointerException("targetPkg");
7534 final IPackageManager pm = AppGlobals.getPackageManager();
7536 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7537 } catch (RemoteException ex) {
7541 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7543 if (targetUid < 0) {
7547 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7551 static class NeededUriGrants extends ArrayList<GrantUri> {
7552 final String targetPkg;
7553 final int targetUid;
7556 NeededUriGrants(String targetPkg, int targetUid, int flags) {
7557 this.targetPkg = targetPkg;
7558 this.targetUid = targetUid;
7564 * Like checkGrantUriPermissionLocked, but takes an Intent.
7566 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7567 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7568 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7569 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7570 + " clip=" + (intent != null ? intent.getClipData() : null)
7571 + " from " + intent + "; flags=0x"
7572 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7574 if (targetPkg == null) {
7575 throw new NullPointerException("targetPkg");
7578 if (intent == null) {
7581 Uri data = intent.getData();
7582 ClipData clip = intent.getClipData();
7583 if (data == null && clip == null) {
7586 // Default userId for uris in the intent (if they don't specify it themselves)
7587 int contentUserHint = intent.getContentUserHint();
7588 if (contentUserHint == UserHandle.USER_CURRENT) {
7589 contentUserHint = UserHandle.getUserId(callingUid);
7591 final IPackageManager pm = AppGlobals.getPackageManager();
7593 if (needed != null) {
7594 targetUid = needed.targetUid;
7597 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7598 } catch (RemoteException ex) {
7601 if (targetUid < 0) {
7602 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7603 "Can't grant URI permission no uid for: " + targetPkg
7604 + " on user " + targetUserId);
7609 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7610 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7612 if (targetUid > 0) {
7613 if (needed == null) {
7614 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7616 needed.add(grantUri);
7620 for (int i=0; i<clip.getItemCount(); i++) {
7621 Uri uri = clip.getItemAt(i).getUri();
7623 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7624 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7626 if (targetUid > 0) {
7627 if (needed == null) {
7628 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7630 needed.add(grantUri);
7633 Intent clipIntent = clip.getItemAt(i).getIntent();
7634 if (clipIntent != null) {
7635 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7636 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7637 if (newNeeded != null) {
7649 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7651 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7652 UriPermissionOwner owner) {
7653 if (needed != null) {
7654 for (int i=0; i<needed.size(); i++) {
7655 GrantUri grantUri = needed.get(i);
7656 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7657 grantUri, needed.flags, owner);
7662 void grantUriPermissionFromIntentLocked(int callingUid,
7663 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7664 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7665 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7666 if (needed == null) {
7670 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7674 * @param uri This uri must NOT contain an embedded userId.
7675 * @param userId The userId in which the uri is to be resolved.
7678 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7679 final int modeFlags, int userId) {
7680 enforceNotIsolatedCaller("grantUriPermission");
7681 GrantUri grantUri = new GrantUri(userId, uri, false);
7682 synchronized(this) {
7683 final ProcessRecord r = getRecordForAppLocked(caller);
7685 throw new SecurityException("Unable to find app for caller "
7687 + " when granting permission to uri " + grantUri);
7689 if (targetPkg == null) {
7690 throw new IllegalArgumentException("null target");
7692 if (grantUri == null) {
7693 throw new IllegalArgumentException("null uri");
7696 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7697 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7698 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7699 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7701 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7702 UserHandle.getUserId(r.uid));
7706 void removeUriPermissionIfNeededLocked(UriPermission perm) {
7707 if (perm.modeFlags == 0) {
7708 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7710 if (perms != null) {
7711 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7712 "Removing " + perm.targetUid + " permission to " + perm.uri);
7714 perms.remove(perm.uri);
7715 if (perms.isEmpty()) {
7716 mGrantedUriPermissions.remove(perm.targetUid);
7722 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7723 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7724 "Revoking all granted permissions to " + grantUri);
7726 final IPackageManager pm = AppGlobals.getPackageManager();
7727 final String authority = grantUri.uri.getAuthority();
7728 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7730 Slog.w(TAG, "No content provider found for permission revoke: "
7731 + grantUri.toSafeString());
7735 // Does the caller have this permission on the URI?
7736 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7737 // If they don't have direct access to the URI, then revoke any
7738 // ownerless URI permissions that have been granted to them.
7739 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7740 if (perms != null) {
7741 boolean persistChanged = false;
7742 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7743 final UriPermission perm = it.next();
7744 if (perm.uri.sourceUserId == grantUri.sourceUserId
7745 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7746 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7747 "Revoking non-owned " + perm.targetUid
7748 + " permission to " + perm.uri);
7749 persistChanged |= perm.revokeModes(
7750 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7751 if (perm.modeFlags == 0) {
7756 if (perms.isEmpty()) {
7757 mGrantedUriPermissions.remove(callingUid);
7759 if (persistChanged) {
7760 schedulePersistUriGrants();
7766 boolean persistChanged = false;
7768 // Go through all of the permissions and remove any that match.
7769 int N = mGrantedUriPermissions.size();
7770 for (int i = 0; i < N; i++) {
7771 final int targetUid = mGrantedUriPermissions.keyAt(i);
7772 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7774 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7775 final UriPermission perm = it.next();
7776 if (perm.uri.sourceUserId == grantUri.sourceUserId
7777 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7778 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7779 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7780 persistChanged |= perm.revokeModes(
7781 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7782 if (perm.modeFlags == 0) {
7788 if (perms.isEmpty()) {
7789 mGrantedUriPermissions.remove(targetUid);
7795 if (persistChanged) {
7796 schedulePersistUriGrants();
7801 * @param uri This uri must NOT contain an embedded userId.
7802 * @param userId The userId in which the uri is to be resolved.
7805 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7807 enforceNotIsolatedCaller("revokeUriPermission");
7808 synchronized(this) {
7809 final ProcessRecord r = getRecordForAppLocked(caller);
7811 throw new SecurityException("Unable to find app for caller "
7813 + " when revoking permission to uri " + uri);
7816 Slog.w(TAG, "revokeUriPermission: null uri");
7820 if (!Intent.isAccessUriMode(modeFlags)) {
7824 final String authority = uri.getAuthority();
7825 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7827 Slog.w(TAG, "No content provider found for permission revoke: "
7828 + uri.toSafeString());
7832 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7837 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7840 * @param packageName Package name to match, or {@code null} to apply to all
7842 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7844 * @param persistable If persistable grants should be removed.
7846 private void removeUriPermissionsForPackageLocked(
7847 String packageName, int userHandle, boolean persistable) {
7848 if (userHandle == UserHandle.USER_ALL && packageName == null) {
7849 throw new IllegalArgumentException("Must narrow by either package or user");
7852 boolean persistChanged = false;
7854 int N = mGrantedUriPermissions.size();
7855 for (int i = 0; i < N; i++) {
7856 final int targetUid = mGrantedUriPermissions.keyAt(i);
7857 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7859 // Only inspect grants matching user
7860 if (userHandle == UserHandle.USER_ALL
7861 || userHandle == UserHandle.getUserId(targetUid)) {
7862 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7863 final UriPermission perm = it.next();
7865 // Only inspect grants matching package
7866 if (packageName == null || perm.sourcePkg.equals(packageName)
7867 || perm.targetPkg.equals(packageName)) {
7868 persistChanged |= perm.revokeModes(persistable
7869 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7871 // Only remove when no modes remain; any persisted grants
7872 // will keep this alive.
7873 if (perm.modeFlags == 0) {
7879 if (perms.isEmpty()) {
7880 mGrantedUriPermissions.remove(targetUid);
7887 if (persistChanged) {
7888 schedulePersistUriGrants();
7893 public IBinder newUriPermissionOwner(String name) {
7894 enforceNotIsolatedCaller("newUriPermissionOwner");
7895 synchronized(this) {
7896 UriPermissionOwner owner = new UriPermissionOwner(this, name);
7897 return owner.getExternalTokenLocked();
7902 * @param uri This uri must NOT contain an embedded userId.
7903 * @param sourceUserId The userId in which the uri is to be resolved.
7904 * @param targetUserId The userId of the app that receives the grant.
7907 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7908 final int modeFlags, int sourceUserId, int targetUserId) {
7909 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7910 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7911 synchronized(this) {
7912 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7913 if (owner == null) {
7914 throw new IllegalArgumentException("Unknown owner: " + token);
7916 if (fromUid != Binder.getCallingUid()) {
7917 if (Binder.getCallingUid() != Process.myUid()) {
7918 // Only system code can grant URI permissions on behalf
7920 throw new SecurityException("nice try");
7923 if (targetPkg == null) {
7924 throw new IllegalArgumentException("null target");
7927 throw new IllegalArgumentException("null uri");
7930 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7931 modeFlags, owner, targetUserId);
7936 * @param uri This uri must NOT contain an embedded userId.
7937 * @param userId The userId in which the uri is to be resolved.
7940 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7941 synchronized(this) {
7942 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7943 if (owner == null) {
7944 throw new IllegalArgumentException("Unknown owner: " + token);
7948 owner.removeUriPermissionsLocked(mode);
7950 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7955 private void schedulePersistUriGrants() {
7956 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7957 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7958 10 * DateUtils.SECOND_IN_MILLIS);
7962 private void writeGrantedUriPermissions() {
7963 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
7965 // Snapshot permissions so we can persist without lock
7966 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7967 synchronized (this) {
7968 final int size = mGrantedUriPermissions.size();
7969 for (int i = 0; i < size; i++) {
7970 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7971 for (UriPermission perm : perms.values()) {
7972 if (perm.persistedModeFlags != 0) {
7973 persist.add(perm.snapshot());
7979 FileOutputStream fos = null;
7981 fos = mGrantFile.startWrite();
7983 XmlSerializer out = new FastXmlSerializer();
7984 out.setOutput(fos, StandardCharsets.UTF_8.name());
7985 out.startDocument(null, true);
7986 out.startTag(null, TAG_URI_GRANTS);
7987 for (UriPermission.Snapshot perm : persist) {
7988 out.startTag(null, TAG_URI_GRANT);
7989 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7990 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7991 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7992 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7993 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7994 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7995 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7996 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7997 out.endTag(null, TAG_URI_GRANT);
7999 out.endTag(null, TAG_URI_GRANTS);
8002 mGrantFile.finishWrite(fos);
8003 } catch (IOException e) {
8005 mGrantFile.failWrite(fos);
8010 private void readGrantedUriPermissionsLocked() {
8011 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8013 final long now = System.currentTimeMillis();
8015 FileInputStream fis = null;
8017 fis = mGrantFile.openRead();
8018 final XmlPullParser in = Xml.newPullParser();
8019 in.setInput(fis, StandardCharsets.UTF_8.name());
8022 while ((type = in.next()) != END_DOCUMENT) {
8023 final String tag = in.getName();
8024 if (type == START_TAG) {
8025 if (TAG_URI_GRANT.equals(tag)) {
8026 final int sourceUserId;
8027 final int targetUserId;
8028 final int userHandle = readIntAttribute(in,
8029 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8030 if (userHandle != UserHandle.USER_NULL) {
8031 // For backwards compatibility.
8032 sourceUserId = userHandle;
8033 targetUserId = userHandle;
8035 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8036 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8038 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8039 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8040 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8041 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8042 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8043 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8045 // Sanity check that provider still belongs to source package
8046 final ProviderInfo pi = getProviderInfoLocked(
8047 uri.getAuthority(), sourceUserId);
8048 if (pi != null && sourcePkg.equals(pi.packageName)) {
8051 targetUid = AppGlobals.getPackageManager()
8052 .getPackageUid(targetPkg, targetUserId);
8053 } catch (RemoteException e) {
8055 if (targetUid != -1) {
8056 final UriPermission perm = findOrCreateUriPermissionLocked(
8057 sourcePkg, targetPkg, targetUid,
8058 new GrantUri(sourceUserId, uri, prefix));
8059 perm.initPersistedModes(modeFlags, createdTime);
8062 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8063 + " but instead found " + pi);
8068 } catch (FileNotFoundException e) {
8069 // Missing grants is okay
8070 } catch (IOException e) {
8071 Slog.wtf(TAG, "Failed reading Uri grants", e);
8072 } catch (XmlPullParserException e) {
8073 Slog.wtf(TAG, "Failed reading Uri grants", e);
8075 IoUtils.closeQuietly(fis);
8080 * @param uri This uri must NOT contain an embedded userId.
8081 * @param userId The userId in which the uri is to be resolved.
8084 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8085 enforceNotIsolatedCaller("takePersistableUriPermission");
8087 Preconditions.checkFlagsArgument(modeFlags,
8088 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8090 synchronized (this) {
8091 final int callingUid = Binder.getCallingUid();
8092 boolean persistChanged = false;
8093 GrantUri grantUri = new GrantUri(userId, uri, false);
8095 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8096 new GrantUri(userId, uri, false));
8097 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8098 new GrantUri(userId, uri, true));
8100 final boolean exactValid = (exactPerm != null)
8101 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8102 final boolean prefixValid = (prefixPerm != null)
8103 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8105 if (!(exactValid || prefixValid)) {
8106 throw new SecurityException("No persistable permission grants found for UID "
8107 + callingUid + " and Uri " + grantUri.toSafeString());
8111 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8114 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8117 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8119 if (persistChanged) {
8120 schedulePersistUriGrants();
8126 * @param uri This uri must NOT contain an embedded userId.
8127 * @param userId The userId in which the uri is to be resolved.
8130 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8131 enforceNotIsolatedCaller("releasePersistableUriPermission");
8133 Preconditions.checkFlagsArgument(modeFlags,
8134 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8136 synchronized (this) {
8137 final int callingUid = Binder.getCallingUid();
8138 boolean persistChanged = false;
8140 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8141 new GrantUri(userId, uri, false));
8142 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8143 new GrantUri(userId, uri, true));
8144 if (exactPerm == null && prefixPerm == null) {
8145 throw new SecurityException("No permission grants found for UID " + callingUid
8146 + " and Uri " + uri.toSafeString());
8149 if (exactPerm != null) {
8150 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8151 removeUriPermissionIfNeededLocked(exactPerm);
8153 if (prefixPerm != null) {
8154 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8155 removeUriPermissionIfNeededLocked(prefixPerm);
8158 if (persistChanged) {
8159 schedulePersistUriGrants();
8165 * Prune any older {@link UriPermission} for the given UID until outstanding
8166 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8168 * @return if any mutations occured that require persisting.
8170 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8171 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8172 if (perms == null) return false;
8173 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8175 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8176 for (UriPermission perm : perms.values()) {
8177 if (perm.persistedModeFlags != 0) {
8178 persisted.add(perm);
8182 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8183 if (trimCount <= 0) return false;
8185 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8186 for (int i = 0; i < trimCount; i++) {
8187 final UriPermission perm = persisted.get(i);
8189 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8190 "Trimming grant created at " + perm.persistedCreateTime);
8192 perm.releasePersistableModes(~0);
8193 removeUriPermissionIfNeededLocked(perm);
8200 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8201 String packageName, boolean incoming) {
8202 enforceNotIsolatedCaller("getPersistedUriPermissions");
8203 Preconditions.checkNotNull(packageName, "packageName");
8205 final int callingUid = Binder.getCallingUid();
8206 final IPackageManager pm = AppGlobals.getPackageManager();
8208 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8209 if (packageUid != callingUid) {
8210 throw new SecurityException(
8211 "Package " + packageName + " does not belong to calling UID " + callingUid);
8213 } catch (RemoteException e) {
8214 throw new SecurityException("Failed to verify package name ownership");
8217 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8218 synchronized (this) {
8220 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8222 if (perms == null) {
8223 Slog.w(TAG, "No permission grants found for " + packageName);
8225 for (UriPermission perm : perms.values()) {
8226 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8227 result.add(perm.buildPersistedPublicApiObject());
8232 final int size = mGrantedUriPermissions.size();
8233 for (int i = 0; i < size; i++) {
8234 final ArrayMap<GrantUri, UriPermission> perms =
8235 mGrantedUriPermissions.valueAt(i);
8236 for (UriPermission perm : perms.values()) {
8237 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8238 result.add(perm.buildPersistedPublicApiObject());
8244 return new ParceledListSlice<android.content.UriPermission>(result);
8248 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8249 synchronized (this) {
8251 who != null ? getRecordForAppLocked(who) : null;
8252 if (app == null) return;
8254 Message msg = Message.obtain();
8255 msg.what = WAIT_FOR_DEBUGGER_MSG;
8257 msg.arg1 = waiting ? 1 : 0;
8258 mUiHandler.sendMessage(msg);
8263 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8264 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8265 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8266 outInfo.availMem = Process.getFreeMemory();
8267 outInfo.totalMem = Process.getTotalMemory();
8268 outInfo.threshold = homeAppMem;
8269 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8270 outInfo.hiddenAppThreshold = cachedAppMem;
8271 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8272 ProcessList.SERVICE_ADJ);
8273 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8274 ProcessList.VISIBLE_APP_ADJ);
8275 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8276 ProcessList.FOREGROUND_APP_ADJ);
8279 // =========================================================
8281 // =========================================================
8284 public List<IAppTask> getAppTasks(String callingPackage) {
8285 int callingUid = Binder.getCallingUid();
8286 long ident = Binder.clearCallingIdentity();
8288 synchronized(this) {
8289 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8291 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8293 final int N = mRecentTasks.size();
8294 for (int i = 0; i < N; i++) {
8295 TaskRecord tr = mRecentTasks.get(i);
8296 // Skip tasks that do not match the caller. We don't need to verify
8297 // callingPackage, because we are also limiting to callingUid and know
8298 // that will limit to the correct security sandbox.
8299 if (tr.effectiveUid != callingUid) {
8302 Intent intent = tr.getBaseIntent();
8303 if (intent == null ||
8304 !callingPackage.equals(intent.getComponent().getPackageName())) {
8307 ActivityManager.RecentTaskInfo taskInfo =
8308 createRecentTaskInfoFromTaskRecord(tr);
8309 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8313 Binder.restoreCallingIdentity(ident);
8320 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8321 final int callingUid = Binder.getCallingUid();
8322 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8324 synchronized(this) {
8325 if (DEBUG_ALL) Slog.v(
8326 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8328 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8331 // TODO: Improve with MRU list from all ActivityStacks.
8332 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8339 * Creates a new RecentTaskInfo from a TaskRecord.
8341 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8342 // Update the task description to reflect any changes in the task stack
8343 tr.updateTaskDescription();
8345 // Compose the recent task info
8346 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8347 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8348 rti.persistentId = tr.taskId;
8349 rti.baseIntent = new Intent(tr.getBaseIntent());
8350 rti.origActivity = tr.origActivity;
8351 rti.description = tr.lastDescription;
8352 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8353 rti.userId = tr.userId;
8354 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8355 rti.firstActiveTime = tr.firstActiveTime;
8356 rti.lastActiveTime = tr.lastActiveTime;
8357 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8358 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8359 rti.numActivities = 0;
8361 ActivityRecord base = null;
8362 ActivityRecord top = null;
8365 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8366 tmp = tr.mActivities.get(i);
8367 if (tmp.finishing) {
8371 if (top == null || (top.state == ActivityState.INITIALIZING)) {
8374 rti.numActivities++;
8377 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8378 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8383 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8384 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8385 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8387 if (checkPermission(android.Manifest.permission.GET_TASKS,
8388 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8389 // Temporary compatibility: some existing apps on the system image may
8390 // still be requesting the old permission and not switched to the new
8391 // one; if so, we'll still allow them full access. This means we need
8392 // to see if they are holding the old permission and are a system app.
8394 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8396 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8397 + " is using old GET_TASKS but privileged; allowing");
8399 } catch (RemoteException e) {
8404 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8405 + " does not hold REAL_GET_TASKS; limiting output");
8411 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8412 final int callingUid = Binder.getCallingUid();
8413 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8414 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8416 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8417 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8418 synchronized (this) {
8419 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8421 final boolean detailed = checkCallingPermission(
8422 android.Manifest.permission.GET_DETAILED_TASKS)
8423 == PackageManager.PERMISSION_GRANTED;
8425 final int recentsCount = mRecentTasks.size();
8426 ArrayList<ActivityManager.RecentTaskInfo> res =
8427 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8429 final Set<Integer> includedUsers;
8430 if (includeProfiles) {
8431 includedUsers = getProfileIdsLocked(userId);
8433 includedUsers = new HashSet<>();
8435 includedUsers.add(Integer.valueOf(userId));
8437 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8438 TaskRecord tr = mRecentTasks.get(i);
8439 // Only add calling user or related users recent tasks
8440 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8441 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8445 // Return the entry if desired by the caller. We always return
8446 // the first entry, because callers always expect this to be the
8447 // foreground app. We may filter others if the caller has
8448 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8449 // we should exclude the entry.
8453 || (tr.intent == null)
8454 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8457 // If the caller doesn't have the GET_TASKS permission, then only
8458 // allow them to see a small subset of tasks -- their own and home.
8459 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8460 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8464 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8465 if (tr.stack != null && tr.stack.isHomeStack()) {
8466 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8467 "Skipping, home stack task: " + tr);
8471 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8472 // Don't include auto remove tasks that are finished or finishing.
8473 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8474 "Skipping, auto-remove without activity: " + tr);
8477 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8478 && !tr.isAvailable) {
8479 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8480 "Skipping, unavail real act: " + tr);
8484 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8486 rti.baseIntent.replaceExtras((Bundle)null);
8498 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8499 synchronized (this) {
8500 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8501 "getTaskThumbnail()");
8502 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8504 return tr.getTaskThumbnailLocked();
8511 public int addAppTask(IBinder activityToken, Intent intent,
8512 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8513 final int callingUid = Binder.getCallingUid();
8514 final long callingIdent = Binder.clearCallingIdentity();
8517 synchronized (this) {
8518 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8520 throw new IllegalArgumentException("Activity does not exist; token="
8523 ComponentName comp = intent.getComponent();
8525 throw new IllegalArgumentException("Intent " + intent
8526 + " must specify explicit component");
8528 if (thumbnail.getWidth() != mThumbnailWidth
8529 || thumbnail.getHeight() != mThumbnailHeight) {
8530 throw new IllegalArgumentException("Bad thumbnail size: got "
8531 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8532 + mThumbnailWidth + "x" + mThumbnailHeight);
8534 if (intent.getSelector() != null) {
8535 intent.setSelector(null);
8537 if (intent.getSourceBounds() != null) {
8538 intent.setSourceBounds(null);
8540 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8541 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8542 // The caller has added this as an auto-remove task... that makes no
8543 // sense, so turn off auto-remove.
8544 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8546 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8547 // Must be a new task.
8548 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8550 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8551 mLastAddedTaskActivity = null;
8553 ActivityInfo ainfo = mLastAddedTaskActivity;
8554 if (ainfo == null) {
8555 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8556 comp, 0, UserHandle.getUserId(callingUid));
8557 if (ainfo.applicationInfo.uid != callingUid) {
8558 throw new SecurityException(
8559 "Can't add task for another application: target uid="
8560 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8564 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8565 intent, description);
8567 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8569 // If this would have caused a trim, then we'll abort because that
8570 // means it would be added at the end of the list but then just removed.
8571 return INVALID_TASK_ID;
8574 final int N = mRecentTasks.size();
8575 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8576 final TaskRecord tr = mRecentTasks.remove(N - 1);
8577 tr.removedFromRecents();
8580 task.inRecents = true;
8581 mRecentTasks.add(task);
8582 r.task.stack.addTask(task, false, false);
8584 task.setLastThumbnail(thumbnail);
8585 task.freeLastThumbnail();
8590 Binder.restoreCallingIdentity(callingIdent);
8595 public Point getAppTaskThumbnailSize() {
8596 synchronized (this) {
8597 return new Point(mThumbnailWidth, mThumbnailHeight);
8602 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8603 synchronized (this) {
8604 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8606 r.setTaskDescription(td);
8607 r.task.updateTaskDescription();
8613 public void setTaskResizeable(int taskId, boolean resizeable) {
8614 synchronized (this) {
8615 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8617 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8620 if (task.mResizeable != resizeable) {
8621 task.mResizeable = resizeable;
8622 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8623 mStackSupervisor.resumeTopActivitiesLocked();
8629 public void resizeTask(int taskId, Rect bounds) {
8630 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8632 long ident = Binder.clearCallingIdentity();
8634 synchronized (this) {
8635 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8637 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8640 mStackSupervisor.resizeTaskLocked(task, bounds);
8643 Binder.restoreCallingIdentity(ident);
8648 public Bitmap getTaskDescriptionIcon(String filename) {
8649 if (!FileUtils.isValidExtFilename(filename)
8650 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8651 throw new IllegalArgumentException("Bad filename: " + filename);
8653 return mTaskPersister.getTaskDescriptionIcon(filename);
8657 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8658 throws RemoteException {
8659 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8660 opts.getCustomInPlaceResId() == 0) {
8661 throw new IllegalArgumentException("Expected in-place ActivityOption " +
8662 "with valid animation");
8664 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8665 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8666 opts.getCustomInPlaceResId());
8667 mWindowManager.executeAppTransition();
8670 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8671 mRecentTasks.remove(tr);
8672 tr.removedFromRecents();
8673 ComponentName component = tr.getBaseIntent().getComponent();
8674 if (component == null) {
8675 Slog.w(TAG, "No component for base intent of task: " + tr);
8679 // Find any running services associated with this app and stop if needed.
8680 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8686 // Determine if the process(es) for this task should be killed.
8687 final String pkg = component.getPackageName();
8688 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8689 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8690 for (int i = 0; i < pmap.size(); i++) {
8692 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8693 for (int j = 0; j < uids.size(); j++) {
8694 ProcessRecord proc = uids.valueAt(j);
8695 if (proc.userId != tr.userId) {
8696 // Don't kill process for a different user.
8699 if (proc == mHomeProcess) {
8700 // Don't kill the home process along with tasks from the same package.
8703 if (!proc.pkgList.containsKey(pkg)) {
8704 // Don't kill process that is not associated with this task.
8708 for (int k = 0; k < proc.activities.size(); k++) {
8709 TaskRecord otherTask = proc.activities.get(k).task;
8710 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8711 // Don't kill process(es) that has an activity in a different task that is
8717 if (proc.foregroundServices) {
8718 // Don't kill process(es) with foreground service.
8722 // Add process to kill list.
8723 procsToKill.add(proc);
8727 // Kill the running processes.
8728 for (int i = 0; i < procsToKill.size(); i++) {
8729 ProcessRecord pr = procsToKill.get(i);
8730 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8731 && pr.curReceiver == null) {
8732 pr.kill("remove task", true);
8734 // We delay killing processes that are not in the background or running a receiver.
8735 pr.waitingToKill = "remove task";
8740 private void removeTasksByPackageNameLocked(String packageName, int userId) {
8741 // Remove all tasks with activities in the specified package from the list of recent tasks
8742 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8743 TaskRecord tr = mRecentTasks.get(i);
8744 if (tr.userId != userId) continue;
8746 ComponentName cn = tr.intent.getComponent();
8747 if (cn != null && cn.getPackageName().equals(packageName)) {
8748 // If the package name matches, remove the task.
8749 removeTaskByIdLocked(tr.taskId, true);
8754 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8757 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8758 TaskRecord tr = mRecentTasks.get(i);
8759 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8763 ComponentName cn = tr.intent.getComponent();
8764 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8765 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8766 if (sameComponent) {
8767 removeTaskByIdLocked(tr.taskId, false);
8773 * Removes the task with the specified task id.
8775 * @param taskId Identifier of the task to be removed.
8776 * @param killProcess Kill any process associated with the task if possible.
8777 * @return Returns true if the given task was found and removed.
8779 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8780 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8782 tr.removeTaskActivitiesLocked();
8783 cleanUpRemovedTaskLocked(tr, killProcess);
8784 if (tr.isPersistable) {
8785 notifyTaskPersisterLocked(null, true);
8789 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8794 public boolean removeTask(int taskId) {
8795 synchronized (this) {
8796 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8798 long ident = Binder.clearCallingIdentity();
8800 return removeTaskByIdLocked(taskId, true);
8802 Binder.restoreCallingIdentity(ident);
8808 * TODO: Add mController hook
8811 public void moveTaskToFront(int taskId, int flags, Bundle options) {
8812 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8814 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8815 synchronized(this) {
8816 moveTaskToFrontLocked(taskId, flags, options);
8820 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8821 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8822 Binder.getCallingUid(), -1, -1, "Task to front")) {
8823 ActivityOptions.abort(options);
8826 final long origId = Binder.clearCallingIdentity();
8828 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8830 Slog.d(TAG, "Could not find task for id: "+ taskId);
8833 if (mStackSupervisor.isLockTaskModeViolation(task)) {
8834 mStackSupervisor.showLockTaskToast();
8835 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8838 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8839 if (prev != null && prev.isRecentsActivity()) {
8840 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8842 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8844 Binder.restoreCallingIdentity(origId);
8846 ActivityOptions.abort(options);
8850 * Moves an activity, and all of the other activities within the same task, to the bottom
8851 * of the history stack. The activity's order within the task is unchanged.
8853 * @param token A reference to the activity we wish to move
8854 * @param nonRoot If false then this only works if the activity is the root
8855 * of a task; if true it will work for any activity in a task.
8856 * @return Returns true if the move completed, false if not.
8859 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8860 enforceNotIsolatedCaller("moveActivityTaskToBack");
8861 synchronized(this) {
8862 final long origId = Binder.clearCallingIdentity();
8864 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8865 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8867 if (mStackSupervisor.isLockedTask(task)) {
8868 mStackSupervisor.showLockTaskToast();
8871 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8874 Binder.restoreCallingIdentity(origId);
8881 public void moveTaskBackwards(int task) {
8882 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8883 "moveTaskBackwards()");
8885 synchronized(this) {
8886 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8887 Binder.getCallingUid(), -1, -1, "Task backwards")) {
8890 final long origId = Binder.clearCallingIdentity();
8891 moveTaskBackwardsLocked(task);
8892 Binder.restoreCallingIdentity(origId);
8896 private final void moveTaskBackwardsLocked(int task) {
8897 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8901 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8902 IActivityContainerCallback callback) throws RemoteException {
8903 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8904 "createActivityContainer()");
8905 synchronized (this) {
8906 if (parentActivityToken == null) {
8907 throw new IllegalArgumentException("parent token must not be null");
8909 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8913 if (callback == null) {
8914 throw new IllegalArgumentException("callback must not be null");
8916 return mStackSupervisor.createVirtualActivityContainer(r, callback);
8921 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8922 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8923 "deleteActivityContainer()");
8924 synchronized (this) {
8925 mStackSupervisor.deleteActivityContainer(container);
8930 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8931 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8932 "createStackOnDisplay()");
8933 synchronized (this) {
8934 final int stackId = mStackSupervisor.getNextStackId();
8935 final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8936 if (stack == null) {
8939 return stack.mActivityContainer;
8944 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8945 synchronized (this) {
8946 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8947 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8948 return stack.mActivityContainer.getDisplayId();
8950 return Display.DEFAULT_DISPLAY;
8955 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8956 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8957 "moveTaskToStack()");
8958 if (stackId == HOME_STACK_ID) {
8959 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8960 new RuntimeException("here").fillInStackTrace());
8962 synchronized (this) {
8963 long ident = Binder.clearCallingIdentity();
8965 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
8966 + " to stackId=" + stackId + " toTop=" + toTop);
8967 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
8969 Binder.restoreCallingIdentity(ident);
8975 public void resizeStack(int stackId, Rect bounds) {
8976 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8978 long ident = Binder.clearCallingIdentity();
8980 synchronized (this) {
8981 mStackSupervisor.resizeStackLocked(stackId, bounds);
8984 Binder.restoreCallingIdentity(ident);
8989 public List<StackInfo> getAllStackInfos() {
8990 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8991 "getAllStackInfos()");
8992 long ident = Binder.clearCallingIdentity();
8994 synchronized (this) {
8995 return mStackSupervisor.getAllStackInfosLocked();
8998 Binder.restoreCallingIdentity(ident);
9003 public StackInfo getStackInfo(int stackId) {
9004 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9006 long ident = Binder.clearCallingIdentity();
9008 synchronized (this) {
9009 return mStackSupervisor.getStackInfoLocked(stackId);
9012 Binder.restoreCallingIdentity(ident);
9017 public boolean isInHomeStack(int taskId) {
9018 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9020 long ident = Binder.clearCallingIdentity();
9022 synchronized (this) {
9023 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
9024 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9027 Binder.restoreCallingIdentity(ident);
9032 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9033 synchronized(this) {
9034 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9039 public void updateDeviceOwner(String packageName) {
9040 final int callingUid = Binder.getCallingUid();
9041 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9042 throw new SecurityException("updateDeviceOwner called from non-system process");
9044 synchronized (this) {
9045 mDeviceOwnerName = packageName;
9050 public void updateLockTaskPackages(int userId, String[] packages) {
9051 final int callingUid = Binder.getCallingUid();
9052 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9053 throw new SecurityException("updateLockTaskPackage called from non-system process");
9055 synchronized (this) {
9056 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9057 Arrays.toString(packages));
9058 mLockTaskPackages.put(userId, packages);
9059 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9064 void startLockTaskModeLocked(TaskRecord task) {
9065 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9066 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9070 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9071 // is initiated by system after the pinning request was shown and locked mode is initiated
9072 // by an authorized app directly
9073 final int callingUid = Binder.getCallingUid();
9074 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9075 long ident = Binder.clearCallingIdentity();
9077 final ActivityStack stack = mStackSupervisor.getFocusedStack();
9078 if (!isSystemInitiated) {
9079 task.mLockTaskUid = callingUid;
9080 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9081 // startLockTask() called by app and task mode is lockTaskModeDefault.
9082 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9083 StatusBarManagerInternal statusBarManager =
9084 LocalServices.getService(StatusBarManagerInternal.class);
9085 if (statusBarManager != null) {
9086 statusBarManager.showScreenPinningRequest();
9091 if (stack == null || task != stack.topTask()) {
9092 throw new IllegalArgumentException("Invalid task, not in foreground");
9095 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9097 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9098 ActivityManager.LOCK_TASK_MODE_PINNED :
9099 ActivityManager.LOCK_TASK_MODE_LOCKED,
9100 "startLockTask", true);
9102 Binder.restoreCallingIdentity(ident);
9107 public void startLockTaskMode(int taskId) {
9108 synchronized (this) {
9109 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9111 startLockTaskModeLocked(task);
9117 public void startLockTaskMode(IBinder token) {
9118 synchronized (this) {
9119 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9123 final TaskRecord task = r.task;
9125 startLockTaskModeLocked(task);
9131 public void startLockTaskModeOnCurrent() throws RemoteException {
9132 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9133 "startLockTaskModeOnCurrent");
9134 long ident = Binder.clearCallingIdentity();
9136 synchronized (this) {
9137 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9139 startLockTaskModeLocked(r.task);
9143 Binder.restoreCallingIdentity(ident);
9148 public void stopLockTaskMode() {
9149 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9150 if (lockTask == null) {
9151 // Our work here is done.
9155 final int callingUid = Binder.getCallingUid();
9156 final int lockTaskUid = lockTask.mLockTaskUid;
9157 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9158 // It is possible lockTaskMode was started by the system process because
9159 // android:lockTaskMode is set to a locking value in the application manifest instead of
9160 // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9161 // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9162 if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9163 callingUid != lockTaskUid
9164 && (lockTaskUid != 0
9165 || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9166 throw new SecurityException("Invalid uid, expected " + lockTaskUid
9167 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9170 long ident = Binder.clearCallingIdentity();
9172 Log.d(TAG, "stopLockTaskMode");
9174 synchronized (this) {
9175 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9176 "stopLockTask", true);
9179 Binder.restoreCallingIdentity(ident);
9184 public void stopLockTaskModeOnCurrent() throws RemoteException {
9185 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9186 "stopLockTaskModeOnCurrent");
9187 long ident = Binder.clearCallingIdentity();
9191 Binder.restoreCallingIdentity(ident);
9196 public boolean isInLockTaskMode() {
9197 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9201 public int getLockTaskModeState() {
9202 synchronized (this) {
9203 return mStackSupervisor.getLockTaskModeState();
9208 public void showLockTaskEscapeMessage(IBinder token) {
9209 synchronized (this) {
9210 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9214 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9218 // =========================================================
9219 // CONTENT PROVIDERS
9220 // =========================================================
9222 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9223 List<ProviderInfo> providers = null;
9225 ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9226 queryContentProviders(app.processName, app.uid,
9227 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9228 providers = slice != null ? slice.getList() : null;
9229 } catch (RemoteException ex) {
9231 if (DEBUG_MU) Slog.v(TAG_MU,
9232 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9233 int userId = app.userId;
9234 if (providers != null) {
9235 int N = providers.size();
9236 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9237 for (int i=0; i<N; i++) {
9239 (ProviderInfo)providers.get(i);
9240 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9241 cpi.name, cpi.flags);
9242 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9243 // This is a singleton provider, but a user besides the
9244 // default user is asking to initialize a process it runs
9245 // in... well, no, it doesn't actually run in this process,
9246 // it runs in the process of the default user. Get rid of it.
9247 providers.remove(i);
9253 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9254 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9256 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9257 mProviderMap.putProviderByClass(comp, cpr);
9259 if (DEBUG_MU) Slog.v(TAG_MU,
9260 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9261 app.pubProviders.put(cpi.name, cpr);
9262 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9263 // Don't add this if it is a platform component that is marked
9264 // to run in multiple processes, because this is actually
9265 // part of the framework so doesn't make sense to track as a
9266 // separate apk in the process.
9267 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9270 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9277 * Check if {@link ProcessRecord} has a possible chance at accessing the
9278 * given {@link ProviderInfo}. Final permission checking is always done
9279 * in {@link ContentProvider}.
9281 private final String checkContentProviderPermissionLocked(
9282 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9283 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9284 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9285 boolean checkedGrants = false;
9287 // Looking for cross-user grants before enforcing the typical cross-users permissions
9288 int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9289 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9290 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9293 checkedGrants = true;
9295 userId = handleIncomingUser(callingPid, callingUid, userId,
9296 false, ALLOW_NON_FULL,
9297 "checkContentProviderPermissionLocked " + cpi.authority, null);
9298 if (userId != tmpTargetUserId) {
9299 // When we actually went to determine the final targer user ID, this ended
9300 // up different than our initial check for the authority. This is because
9301 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9302 // SELF. So we need to re-check the grants again.
9303 checkedGrants = false;
9306 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9307 cpi.applicationInfo.uid, cpi.exported)
9308 == PackageManager.PERMISSION_GRANTED) {
9311 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9312 cpi.applicationInfo.uid, cpi.exported)
9313 == PackageManager.PERMISSION_GRANTED) {
9317 PathPermission[] pps = cpi.pathPermissions;
9322 PathPermission pp = pps[i];
9323 String pprperm = pp.getReadPermission();
9324 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9325 cpi.applicationInfo.uid, cpi.exported)
9326 == PackageManager.PERMISSION_GRANTED) {
9329 String ppwperm = pp.getWritePermission();
9330 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9331 cpi.applicationInfo.uid, cpi.exported)
9332 == PackageManager.PERMISSION_GRANTED) {
9337 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9342 if (!cpi.exported) {
9343 msg = "Permission Denial: opening provider " + cpi.name
9344 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9345 + ", uid=" + callingUid + ") that is not exported from uid "
9346 + cpi.applicationInfo.uid;
9348 msg = "Permission Denial: opening provider " + cpi.name
9349 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9350 + ", uid=" + callingUid + ") requires "
9351 + cpi.readPermission + " or " + cpi.writePermission;
9358 * Returns if the ContentProvider has granted a uri to callingUid
9360 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9361 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9362 if (perms != null) {
9363 for (int i=perms.size()-1; i>=0; i--) {
9364 GrantUri grantUri = perms.keyAt(i);
9365 if (grantUri.sourceUserId == userId || !checkUser) {
9366 if (matchesProvider(grantUri.uri, cpi)) {
9376 * Returns true if the uri authority is one of the authorities specified in the provider.
9378 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9379 String uriAuth = uri.getAuthority();
9380 String cpiAuth = cpi.authority;
9381 if (cpiAuth.indexOf(';') == -1) {
9382 return cpiAuth.equals(uriAuth);
9384 String[] cpiAuths = cpiAuth.split(";");
9385 int length = cpiAuths.length;
9386 for (int i = 0; i < length; i++) {
9387 if (cpiAuths[i].equals(uriAuth)) return true;
9392 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9393 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9395 for (int i=0; i<r.conProviders.size(); i++) {
9396 ContentProviderConnection conn = r.conProviders.get(i);
9397 if (conn.provider == cpr) {
9398 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9399 "Adding provider requested by "
9400 + r.processName + " from process "
9401 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9402 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9405 conn.numStableIncs++;
9407 conn.unstableCount++;
9408 conn.numUnstableIncs++;
9413 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9415 conn.stableCount = 1;
9416 conn.numStableIncs = 1;
9418 conn.unstableCount = 1;
9419 conn.numUnstableIncs = 1;
9421 cpr.connections.add(conn);
9422 r.conProviders.add(conn);
9423 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9426 cpr.addExternalProcessHandleLocked(externalProcessToken);
9430 boolean decProviderCountLocked(ContentProviderConnection conn,
9431 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9433 cpr = conn.provider;
9434 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9435 "Removing provider requested by "
9436 + conn.client.processName + " from process "
9437 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9438 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9442 conn.unstableCount--;
9444 if (conn.stableCount == 0 && conn.unstableCount == 0) {
9445 cpr.connections.remove(conn);
9446 conn.client.conProviders.remove(conn);
9447 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9452 cpr.removeExternalProcessHandleLocked(externalProcessToken);
9456 private void checkTime(long startTime, String where) {
9457 long now = SystemClock.elapsedRealtime();
9458 if ((now-startTime) > 1000) {
9459 // If we are taking more than a second, log about it.
9460 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9464 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9465 String name, IBinder token, boolean stable, int userId) {
9466 ContentProviderRecord cpr;
9467 ContentProviderConnection conn = null;
9468 ProviderInfo cpi = null;
9470 synchronized(this) {
9471 long startTime = SystemClock.elapsedRealtime();
9473 ProcessRecord r = null;
9474 if (caller != null) {
9475 r = getRecordForAppLocked(caller);
9477 throw new SecurityException(
9478 "Unable to find app for caller " + caller
9479 + " (pid=" + Binder.getCallingPid()
9480 + ") when getting content provider " + name);
9484 boolean checkCrossUser = true;
9486 checkTime(startTime, "getContentProviderImpl: getProviderByName");
9488 // First check if this content provider has been published...
9489 cpr = mProviderMap.getProviderByName(name, userId);
9490 // If that didn't work, check if it exists for user 0 and then
9491 // verify that it's a singleton provider before using it.
9492 if (cpr == null && userId != UserHandle.USER_OWNER) {
9493 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9496 if (isSingleton(cpi.processName, cpi.applicationInfo,
9497 cpi.name, cpi.flags)
9498 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9499 userId = UserHandle.USER_OWNER;
9500 checkCrossUser = false;
9508 boolean providerRunning = cpr != null;
9509 if (providerRunning) {
9512 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9513 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9515 throw new SecurityException(msg);
9517 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9519 if (r != null && cpr.canRunHere(r)) {
9520 // This provider has been published or is in the process
9521 // of being published... but it is also allowed to run
9522 // in the caller's process, so don't make a connection
9523 // and just let the caller instantiate its own instance.
9524 ContentProviderHolder holder = cpr.newHolder(null);
9525 // don't give caller the provider object, it needs
9527 holder.provider = null;
9531 final long origId = Binder.clearCallingIdentity();
9533 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9535 // In this case the provider instance already exists, so we can
9536 // return it right away.
9537 conn = incProviderCountLocked(r, cpr, token, stable);
9538 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9539 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9540 // If this is a perceptible app accessing the provider,
9541 // make sure to count it as being accessed and thus
9542 // back up on the LRU list. This is good because
9543 // content providers are often expensive to start.
9544 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9545 updateLruProcessLocked(cpr.proc, false, null);
9546 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9550 if (cpr.proc != null) {
9552 if (cpr.name.flattenToShortString().equals(
9553 "com.android.providers.calendar/.CalendarProvider2")) {
9554 Slog.v(TAG, "****************** KILLING "
9555 + cpr.name.flattenToShortString());
9556 Process.killProcess(cpr.proc.pid);
9559 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9560 boolean success = updateOomAdjLocked(cpr.proc);
9561 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9562 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9563 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9564 // NOTE: there is still a race here where a signal could be
9565 // pending on the process even though we managed to update its
9566 // adj level. Not sure what to do about this, but at least
9567 // the race is now smaller.
9569 // Uh oh... it looks like the provider's process
9570 // has been killed on us. We need to wait for a new
9571 // process to be started, and make sure its death
9572 // doesn't kill our process.
9573 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9574 + " is crashing; detaching " + r);
9575 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9576 checkTime(startTime, "getContentProviderImpl: before appDied");
9577 appDiedLocked(cpr.proc);
9578 checkTime(startTime, "getContentProviderImpl: after appDied");
9580 // This wasn't the last ref our process had on
9581 // the provider... we have now been killed, bail.
9584 providerRunning = false;
9589 Binder.restoreCallingIdentity(origId);
9593 if (!providerRunning) {
9595 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9596 cpi = AppGlobals.getPackageManager().
9597 resolveContentProvider(name,
9598 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9599 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9600 } catch (RemoteException ex) {
9605 // If the provider is a singleton AND
9606 // (it's a call within the same user || the provider is a
9608 // Then allow connecting to the singleton provider
9609 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9610 cpi.name, cpi.flags)
9611 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9613 userId = UserHandle.USER_OWNER;
9615 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9616 checkTime(startTime, "getContentProviderImpl: got app info for user");
9619 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9620 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9622 throw new SecurityException(msg);
9624 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9626 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9627 && !cpi.processName.equals("system")) {
9628 // If this content provider does not run in the system
9629 // process, and the system is not yet ready to run other
9630 // processes, then fail fast instead of hanging.
9631 throw new IllegalArgumentException(
9632 "Attempt to launch content provider before system ready");
9635 // Make sure that the user who owns this provider is running. If not,
9636 // we don't want to allow it to run.
9637 if (!isUserRunningLocked(userId, false)) {
9638 Slog.w(TAG, "Unable to launch app "
9639 + cpi.applicationInfo.packageName + "/"
9640 + cpi.applicationInfo.uid + " for provider "
9641 + name + ": user " + userId + " is stopped");
9645 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9646 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9647 cpr = mProviderMap.getProviderByClass(comp, userId);
9648 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9649 final boolean firstClass = cpr == null;
9651 final long ident = Binder.clearCallingIdentity();
9653 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9654 ApplicationInfo ai =
9655 AppGlobals.getPackageManager().
9657 cpi.applicationInfo.packageName,
9658 STOCK_PM_FLAGS, userId);
9659 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9661 Slog.w(TAG, "No package info for content provider "
9665 ai = getAppInfoForUser(ai, userId);
9666 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9667 } catch (RemoteException ex) {
9668 // pm is in same process, this will never happen.
9670 Binder.restoreCallingIdentity(ident);
9674 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9676 if (r != null && cpr.canRunHere(r)) {
9677 // If this is a multiprocess provider, then just return its
9678 // info and allow the caller to instantiate it. Only do
9679 // this if the provider is the same user as the caller's
9680 // process, or can run as root (so can be in any process).
9681 return cpr.newHolder(null);
9684 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9685 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9686 + cpr.info.name + " callers=" + Debug.getCallers(6));
9688 // This is single process, and our app is now connecting to it.
9689 // See if we are already in the process of launching this
9691 final int N = mLaunchingProviders.size();
9693 for (i = 0; i < N; i++) {
9694 if (mLaunchingProviders.get(i) == cpr) {
9699 // If the provider is not already being launched, then get it
9702 final long origId = Binder.clearCallingIdentity();
9705 // Content provider is now in use, its package can't be stopped.
9707 checkTime(startTime, "getContentProviderImpl: before set stopped state");
9708 AppGlobals.getPackageManager().setPackageStoppedState(
9709 cpr.appInfo.packageName, false, userId);
9710 checkTime(startTime, "getContentProviderImpl: after set stopped state");
9711 } catch (RemoteException e) {
9712 } catch (IllegalArgumentException e) {
9713 Slog.w(TAG, "Failed trying to unstop package "
9714 + cpr.appInfo.packageName + ": " + e);
9717 // Use existing process if already started
9718 checkTime(startTime, "getContentProviderImpl: looking for process record");
9719 ProcessRecord proc = getProcessRecordLocked(
9720 cpi.processName, cpr.appInfo.uid, false);
9721 if (proc != null && proc.thread != null) {
9722 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9723 "Installing in existing process " + proc);
9724 if (!proc.pubProviders.containsKey(cpi.name)) {
9725 checkTime(startTime, "getContentProviderImpl: scheduling install");
9726 proc.pubProviders.put(cpi.name, cpr);
9728 proc.thread.scheduleInstallProvider(cpi);
9729 } catch (RemoteException e) {
9733 checkTime(startTime, "getContentProviderImpl: before start process");
9734 proc = startProcessLocked(cpi.processName,
9735 cpr.appInfo, false, 0, "content provider",
9736 new ComponentName(cpi.applicationInfo.packageName,
9737 cpi.name), false, false, false);
9738 checkTime(startTime, "getContentProviderImpl: after start process");
9740 Slog.w(TAG, "Unable to launch app "
9741 + cpi.applicationInfo.packageName + "/"
9742 + cpi.applicationInfo.uid + " for provider "
9743 + name + ": process is bad");
9747 cpr.launchingApp = proc;
9748 mLaunchingProviders.add(cpr);
9750 Binder.restoreCallingIdentity(origId);
9754 checkTime(startTime, "getContentProviderImpl: updating data structures");
9756 // Make sure the provider is published (the same provider class
9757 // may be published under multiple names).
9759 mProviderMap.putProviderByClass(comp, cpr);
9762 mProviderMap.putProviderByName(name, cpr);
9763 conn = incProviderCountLocked(r, cpr, token, stable);
9765 conn.waiting = true;
9768 checkTime(startTime, "getContentProviderImpl: done!");
9771 // Wait for the provider to be published...
9772 synchronized (cpr) {
9773 while (cpr.provider == null) {
9774 if (cpr.launchingApp == null) {
9775 Slog.w(TAG, "Unable to launch app "
9776 + cpi.applicationInfo.packageName + "/"
9777 + cpi.applicationInfo.uid + " for provider "
9778 + name + ": launching app became null");
9779 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9780 UserHandle.getUserId(cpi.applicationInfo.uid),
9781 cpi.applicationInfo.packageName,
9782 cpi.applicationInfo.uid, name);
9786 if (DEBUG_MU) Slog.v(TAG_MU,
9787 "Waiting to start provider " + cpr
9788 + " launchingApp=" + cpr.launchingApp);
9790 conn.waiting = true;
9793 } catch (InterruptedException ex) {
9796 conn.waiting = false;
9801 return cpr != null ? cpr.newHolder(conn) : null;
9805 public final ContentProviderHolder getContentProvider(
9806 IApplicationThread caller, String name, int userId, boolean stable) {
9807 enforceNotIsolatedCaller("getContentProvider");
9808 if (caller == null) {
9809 String msg = "null IApplicationThread when getting content provider "
9812 throw new SecurityException(msg);
9814 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9815 // with cross-user grant.
9816 return getContentProviderImpl(caller, name, null, stable, userId);
9819 public ContentProviderHolder getContentProviderExternal(
9820 String name, int userId, IBinder token) {
9821 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9822 "Do not have permission in call getContentProviderExternal()");
9823 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9824 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9825 return getContentProviderExternalUnchecked(name, token, userId);
9828 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9829 IBinder token, int userId) {
9830 return getContentProviderImpl(null, name, token, true, userId);
9834 * Drop a content provider from a ProcessRecord's bookkeeping
9836 public void removeContentProvider(IBinder connection, boolean stable) {
9837 enforceNotIsolatedCaller("removeContentProvider");
9838 long ident = Binder.clearCallingIdentity();
9840 synchronized (this) {
9841 ContentProviderConnection conn;
9843 conn = (ContentProviderConnection)connection;
9844 } catch (ClassCastException e) {
9845 String msg ="removeContentProvider: " + connection
9846 + " not a ContentProviderConnection";
9848 throw new IllegalArgumentException(msg);
9851 throw new NullPointerException("connection is null");
9853 if (decProviderCountLocked(conn, null, null, stable)) {
9854 updateOomAdjLocked();
9858 Binder.restoreCallingIdentity(ident);
9862 public void removeContentProviderExternal(String name, IBinder token) {
9863 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9864 "Do not have permission in call removeContentProviderExternal()");
9865 int userId = UserHandle.getCallingUserId();
9866 long ident = Binder.clearCallingIdentity();
9868 removeContentProviderExternalUnchecked(name, token, userId);
9870 Binder.restoreCallingIdentity(ident);
9874 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9875 synchronized (this) {
9876 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9878 //remove from mProvidersByClass
9879 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9883 //update content provider record entry info
9884 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9885 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9886 if (localCpr.hasExternalProcessHandles()) {
9887 if (localCpr.removeExternalProcessHandleLocked(token)) {
9888 updateOomAdjLocked();
9890 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9891 + " with no external reference for token: "
9895 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9896 + " with no external references.");
9901 public final void publishContentProviders(IApplicationThread caller,
9902 List<ContentProviderHolder> providers) {
9903 if (providers == null) {
9907 enforceNotIsolatedCaller("publishContentProviders");
9908 synchronized (this) {
9909 final ProcessRecord r = getRecordForAppLocked(caller);
9910 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9912 throw new SecurityException(
9913 "Unable to find app for caller " + caller
9914 + " (pid=" + Binder.getCallingPid()
9915 + ") when publishing content providers");
9918 final long origId = Binder.clearCallingIdentity();
9920 final int N = providers.size();
9921 for (int i = 0; i < N; i++) {
9922 ContentProviderHolder src = providers.get(i);
9923 if (src == null || src.info == null || src.provider == null) {
9926 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9927 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9929 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9930 mProviderMap.putProviderByClass(comp, dst);
9931 String names[] = dst.info.authority.split(";");
9932 for (int j = 0; j < names.length; j++) {
9933 mProviderMap.putProviderByName(names[j], dst);
9936 int launchingCount = mLaunchingProviders.size();
9938 boolean wasInLaunchingProviders = false;
9939 for (j = 0; j < launchingCount; j++) {
9940 if (mLaunchingProviders.get(j) == dst) {
9941 mLaunchingProviders.remove(j);
9942 wasInLaunchingProviders = true;
9947 if (wasInLaunchingProviders) {
9948 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
9950 synchronized (dst) {
9951 dst.provider = src.provider;
9955 updateOomAdjLocked(r);
9956 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
9957 src.info.authority);
9961 Binder.restoreCallingIdentity(origId);
9965 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9966 ContentProviderConnection conn;
9968 conn = (ContentProviderConnection)connection;
9969 } catch (ClassCastException e) {
9970 String msg ="refContentProvider: " + connection
9971 + " not a ContentProviderConnection";
9973 throw new IllegalArgumentException(msg);
9976 throw new NullPointerException("connection is null");
9979 synchronized (this) {
9981 conn.numStableIncs += stable;
9983 stable = conn.stableCount + stable;
9985 throw new IllegalStateException("stableCount < 0: " + stable);
9989 conn.numUnstableIncs += unstable;
9991 unstable = conn.unstableCount + unstable;
9993 throw new IllegalStateException("unstableCount < 0: " + unstable);
9996 if ((stable+unstable) <= 0) {
9997 throw new IllegalStateException("ref counts can't go to zero here: stable="
9998 + stable + " unstable=" + unstable);
10000 conn.stableCount = stable;
10001 conn.unstableCount = unstable;
10006 public void unstableProviderDied(IBinder connection) {
10007 ContentProviderConnection conn;
10009 conn = (ContentProviderConnection)connection;
10010 } catch (ClassCastException e) {
10011 String msg ="refContentProvider: " + connection
10012 + " not a ContentProviderConnection";
10014 throw new IllegalArgumentException(msg);
10016 if (conn == null) {
10017 throw new NullPointerException("connection is null");
10020 // Safely retrieve the content provider associated with the connection.
10021 IContentProvider provider;
10022 synchronized (this) {
10023 provider = conn.provider.provider;
10026 if (provider == null) {
10027 // Um, yeah, we're way ahead of you.
10031 // Make sure the caller is being honest with us.
10032 if (provider.asBinder().pingBinder()) {
10033 // Er, no, still looks good to us.
10034 synchronized (this) {
10035 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10036 + " says " + conn + " died, but we don't agree");
10041 // Well look at that! It's dead!
10042 synchronized (this) {
10043 if (conn.provider.provider != provider) {
10044 // But something changed... good enough.
10048 ProcessRecord proc = conn.provider.proc;
10049 if (proc == null || proc.thread == null) {
10050 // Seems like the process is already cleaned up.
10054 // As far as we're concerned, this is just like receiving a
10055 // death notification... just a bit prematurely.
10056 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10057 + ") early provider death");
10058 final long ident = Binder.clearCallingIdentity();
10060 appDiedLocked(proc);
10062 Binder.restoreCallingIdentity(ident);
10068 public void appNotRespondingViaProvider(IBinder connection) {
10069 enforceCallingPermission(
10070 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10072 final ContentProviderConnection conn = (ContentProviderConnection) connection;
10073 if (conn == null) {
10074 Slog.w(TAG, "ContentProviderConnection is null");
10078 final ProcessRecord host = conn.provider.proc;
10079 if (host == null) {
10080 Slog.w(TAG, "Failed to find hosting ProcessRecord");
10084 final long token = Binder.clearCallingIdentity();
10086 appNotResponding(host, null, null, false, "ContentProvider not responding");
10088 Binder.restoreCallingIdentity(token);
10092 public final void installSystemProviders() {
10093 List<ProviderInfo> providers;
10094 synchronized (this) {
10095 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10096 providers = generateApplicationProvidersLocked(app);
10097 if (providers != null) {
10098 for (int i=providers.size()-1; i>=0; i--) {
10099 ProviderInfo pi = (ProviderInfo)providers.get(i);
10100 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10101 Slog.w(TAG, "Not installing system proc provider " + pi.name
10102 + ": not system .apk");
10103 providers.remove(i);
10108 if (providers != null) {
10109 mSystemThread.installSystemProviders(providers);
10112 mCoreSettingsObserver = new CoreSettingsObserver(this);
10114 //mUsageStatsService.monitorPackages();
10118 * Allows apps to retrieve the MIME type of a URI.
10119 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10120 * users, then it does not need permission to access the ContentProvider.
10121 * Either, it needs cross-user uri grants.
10123 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10125 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10126 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10128 public String getProviderMimeType(Uri uri, int userId) {
10129 enforceNotIsolatedCaller("getProviderMimeType");
10130 final String name = uri.getAuthority();
10131 int callingUid = Binder.getCallingUid();
10132 int callingPid = Binder.getCallingPid();
10134 boolean clearedIdentity = false;
10135 userId = unsafeConvertIncomingUser(userId);
10136 if (canClearIdentity(callingPid, callingUid, userId)) {
10137 clearedIdentity = true;
10138 ident = Binder.clearCallingIdentity();
10140 ContentProviderHolder holder = null;
10142 holder = getContentProviderExternalUnchecked(name, null, userId);
10143 if (holder != null) {
10144 return holder.provider.getType(uri);
10146 } catch (RemoteException e) {
10147 Log.w(TAG, "Content provider dead retrieving " + uri, e);
10150 // We need to clear the identity to call removeContentProviderExternalUnchecked
10151 if (!clearedIdentity) {
10152 ident = Binder.clearCallingIdentity();
10155 if (holder != null) {
10156 removeContentProviderExternalUnchecked(name, null, userId);
10159 Binder.restoreCallingIdentity(ident);
10166 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10167 if (UserHandle.getUserId(callingUid) == userId) {
10170 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10171 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10172 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10173 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10179 // =========================================================
10180 // GLOBAL MANAGEMENT
10181 // =========================================================
10183 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10184 boolean isolated, int isolatedUid) {
10185 String proc = customProcess != null ? customProcess : info.processName;
10186 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10187 final int userId = UserHandle.getUserId(info.uid);
10188 int uid = info.uid;
10190 if (isolatedUid == 0) {
10191 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10193 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10194 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10195 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10197 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10198 mNextIsolatedProcessUid++;
10199 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10200 // No process for this uid, use it.
10204 if (stepsLeft <= 0) {
10209 // Special case for startIsolatedProcess (internal only), where
10210 // the uid of the isolated process is specified by the caller.
10214 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10215 if (!mBooted && !mBooting
10216 && userId == UserHandle.USER_OWNER
10217 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10218 r.persistent = true;
10220 addProcessNameLocked(r);
10224 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10225 String abiOverride) {
10228 app = getProcessRecordLocked(info.processName, info.uid, true);
10234 app = newProcessRecordLocked(info, null, isolated, 0);
10235 updateLruProcessLocked(app, false, null);
10236 updateOomAdjLocked();
10239 // This package really, really can not be stopped.
10241 AppGlobals.getPackageManager().setPackageStoppedState(
10242 info.packageName, false, UserHandle.getUserId(app.uid));
10243 } catch (RemoteException e) {
10244 } catch (IllegalArgumentException e) {
10245 Slog.w(TAG, "Failed trying to unstop package "
10246 + info.packageName + ": " + e);
10249 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10250 app.persistent = true;
10251 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10253 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10254 mPersistentStartingProcesses.add(app);
10255 startProcessLocked(app, "added application", app.processName, abiOverride,
10256 null /* entryPoint */, null /* entryPointArgs */);
10262 public void unhandledBack() {
10263 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10264 "unhandledBack()");
10266 synchronized(this) {
10267 final long origId = Binder.clearCallingIdentity();
10269 getFocusedStack().unhandledBackLocked();
10271 Binder.restoreCallingIdentity(origId);
10276 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10277 enforceNotIsolatedCaller("openContentUri");
10278 final int userId = UserHandle.getCallingUserId();
10279 String name = uri.getAuthority();
10280 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10281 ParcelFileDescriptor pfd = null;
10283 // We record the binder invoker's uid in thread-local storage before
10284 // going to the content provider to open the file. Later, in the code
10285 // that handles all permissions checks, we look for this uid and use
10286 // that rather than the Activity Manager's own uid. The effect is that
10287 // we do the check against the caller's permissions even though it looks
10288 // to the content provider like the Activity Manager itself is making
10290 Binder token = new Binder();
10291 sCallerIdentity.set(new Identity(
10292 token, Binder.getCallingPid(), Binder.getCallingUid()));
10294 pfd = cph.provider.openFile(null, uri, "r", null, token);
10295 } catch (FileNotFoundException e) {
10296 // do nothing; pfd will be returned null
10298 // Ensure that whatever happens, we clean up the identity state
10299 sCallerIdentity.remove();
10300 // Ensure we're done with the provider.
10301 removeContentProviderExternalUnchecked(name, null, userId);
10304 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10309 // Actually is sleeping or shutting down or whatever else in the future
10310 // is an inactive state.
10311 public boolean isSleepingOrShuttingDown() {
10312 return isSleeping() || mShuttingDown;
10315 public boolean isSleeping() {
10319 void onWakefulnessChanged(int wakefulness) {
10320 synchronized(this) {
10321 mWakefulness = wakefulness;
10322 updateSleepIfNeededLocked();
10326 void finishRunningVoiceLocked() {
10327 if (mRunningVoice != null) {
10328 mRunningVoice = null;
10329 mVoiceWakeLock.release();
10330 updateSleepIfNeededLocked();
10334 void startTimeTrackingFocusedActivityLocked() {
10335 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10336 mCurAppTimeTracker.start(mFocusedActivity.packageName);
10340 void updateSleepIfNeededLocked() {
10341 if (mSleeping && !shouldSleepLocked()) {
10343 startTimeTrackingFocusedActivityLocked();
10344 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10345 mStackSupervisor.comeOutOfSleepIfNeededLocked();
10346 updateOomAdjLocked();
10347 } else if (!mSleeping && shouldSleepLocked()) {
10349 if (mCurAppTimeTracker != null) {
10350 mCurAppTimeTracker.stop();
10352 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10353 mStackSupervisor.goingToSleepLocked();
10354 updateOomAdjLocked();
10356 // Initialize the wake times of all processes.
10357 checkExcessivePowerUsageLocked(false);
10358 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10359 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10360 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10364 private boolean shouldSleepLocked() {
10365 // Resume applications while running a voice interactor.
10366 if (mRunningVoice != null) {
10370 // TODO: Transform the lock screen state into a sleep token instead.
10371 switch (mWakefulness) {
10372 case PowerManagerInternal.WAKEFULNESS_AWAKE:
10373 case PowerManagerInternal.WAKEFULNESS_DREAMING:
10374 case PowerManagerInternal.WAKEFULNESS_DOZING:
10375 // Pause applications whenever the lock screen is shown or any sleep
10376 // tokens have been acquired.
10377 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10378 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10380 // If we're asleep then pause applications unconditionally.
10385 /** Pokes the task persister. */
10386 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10387 if (task != null && task.stack != null && task.stack.isHomeStack()) {
10388 // Never persist the home stack.
10391 mTaskPersister.wakeup(task, flush);
10394 /** Notifies all listeners when the task stack has changed. */
10395 void notifyTaskStackChangedLocked() {
10396 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10397 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10398 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10402 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10403 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10407 public boolean shutdown(int timeout) {
10408 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10409 != PackageManager.PERMISSION_GRANTED) {
10410 throw new SecurityException("Requires permission "
10411 + android.Manifest.permission.SHUTDOWN);
10414 boolean timedout = false;
10416 synchronized(this) {
10417 mShuttingDown = true;
10418 updateEventDispatchingLocked();
10419 timedout = mStackSupervisor.shutdownLocked(timeout);
10422 mAppOpsService.shutdown();
10423 if (mUsageStatsService != null) {
10424 mUsageStatsService.prepareShutdown();
10426 mBatteryStatsService.shutdown();
10427 synchronized (this) {
10428 mProcessStats.shutdownLocked();
10429 notifyTaskPersisterLocked(null, true);
10435 public final void activitySlept(IBinder token) {
10436 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10438 final long origId = Binder.clearCallingIdentity();
10440 synchronized (this) {
10441 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10443 mStackSupervisor.activitySleptLocked(r);
10447 Binder.restoreCallingIdentity(origId);
10450 private String lockScreenShownToString() {
10451 switch (mLockScreenShown) {
10452 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10453 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10454 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10455 default: return "Unknown=" + mLockScreenShown;
10459 void logLockScreen(String msg) {
10460 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10461 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10462 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10463 + " mSleeping=" + mSleeping);
10466 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10467 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10468 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10469 boolean wasRunningVoice = mRunningVoice != null;
10470 mRunningVoice = session;
10471 if (!wasRunningVoice) {
10472 mVoiceWakeLock.acquire();
10473 updateSleepIfNeededLocked();
10478 private void updateEventDispatchingLocked() {
10479 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10482 public void setLockScreenShown(boolean shown) {
10483 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10484 != PackageManager.PERMISSION_GRANTED) {
10485 throw new SecurityException("Requires permission "
10486 + android.Manifest.permission.DEVICE_POWER);
10489 synchronized(this) {
10490 long ident = Binder.clearCallingIdentity();
10492 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10493 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10494 updateSleepIfNeededLocked();
10496 Binder.restoreCallingIdentity(ident);
10502 public void stopAppSwitches() {
10503 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10504 != PackageManager.PERMISSION_GRANTED) {
10505 throw new SecurityException("Requires permission "
10506 + android.Manifest.permission.STOP_APP_SWITCHES);
10509 synchronized(this) {
10510 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10511 + APP_SWITCH_DELAY_TIME;
10512 mDidAppSwitch = false;
10513 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10514 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10515 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10519 public void resumeAppSwitches() {
10520 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10521 != PackageManager.PERMISSION_GRANTED) {
10522 throw new SecurityException("Requires permission "
10523 + android.Manifest.permission.STOP_APP_SWITCHES);
10526 synchronized(this) {
10527 // Note that we don't execute any pending app switches... we will
10528 // let those wait until either the timeout, or the next start
10529 // activity request.
10530 mAppSwitchesAllowedTime = 0;
10534 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10535 int callingPid, int callingUid, String name) {
10536 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10540 int perm = checkComponentPermission(
10541 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10542 sourceUid, -1, true);
10543 if (perm == PackageManager.PERMISSION_GRANTED) {
10547 // If the actual IPC caller is different from the logical source, then
10548 // also see if they are allowed to control app switches.
10549 if (callingUid != -1 && callingUid != sourceUid) {
10550 perm = checkComponentPermission(
10551 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10552 callingUid, -1, true);
10553 if (perm == PackageManager.PERMISSION_GRANTED) {
10558 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10562 public void setDebugApp(String packageName, boolean waitForDebugger,
10563 boolean persistent) {
10564 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10567 long ident = Binder.clearCallingIdentity();
10569 // Note that this is not really thread safe if there are multiple
10570 // callers into it at the same time, but that's not a situation we
10573 final ContentResolver resolver = mContext.getContentResolver();
10574 Settings.Global.putString(
10575 resolver, Settings.Global.DEBUG_APP,
10577 Settings.Global.putInt(
10578 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10579 waitForDebugger ? 1 : 0);
10582 synchronized (this) {
10584 mOrigDebugApp = mDebugApp;
10585 mOrigWaitForDebugger = mWaitForDebugger;
10587 mDebugApp = packageName;
10588 mWaitForDebugger = waitForDebugger;
10589 mDebugTransient = !persistent;
10590 if (packageName != null) {
10591 forceStopPackageLocked(packageName, -1, false, false, true, true,
10592 false, UserHandle.USER_ALL, "set debug app");
10596 Binder.restoreCallingIdentity(ident);
10600 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10601 synchronized (this) {
10602 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10603 if (!isDebuggable) {
10604 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10605 throw new SecurityException("Process not debuggable: " + app.packageName);
10609 mOpenGlTraceApp = processName;
10613 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10614 synchronized (this) {
10615 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10616 if (!isDebuggable) {
10617 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10618 throw new SecurityException("Process not debuggable: " + app.packageName);
10621 mProfileApp = processName;
10622 mProfileFile = profilerInfo.profileFile;
10623 if (mProfileFd != null) {
10625 mProfileFd.close();
10626 } catch (IOException e) {
10630 mProfileFd = profilerInfo.profileFd;
10631 mSamplingInterval = profilerInfo.samplingInterval;
10632 mAutoStopProfiler = profilerInfo.autoStopProfiler;
10638 public void setAlwaysFinish(boolean enabled) {
10639 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10640 "setAlwaysFinish()");
10642 Settings.Global.putInt(
10643 mContext.getContentResolver(),
10644 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10646 synchronized (this) {
10647 mAlwaysFinishActivities = enabled;
10652 public void setActivityController(IActivityController controller) {
10653 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10654 "setActivityController()");
10655 synchronized (this) {
10656 mController = controller;
10657 Watchdog.getInstance().setActivityController(controller);
10662 public void setUserIsMonkey(boolean userIsMonkey) {
10663 synchronized (this) {
10664 synchronized (mPidsSelfLocked) {
10665 final int callingPid = Binder.getCallingPid();
10666 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10667 if (precessRecord == null) {
10668 throw new SecurityException("Unknown process: " + callingPid);
10670 if (precessRecord.instrumentationUiAutomationConnection == null) {
10671 throw new SecurityException("Only an instrumentation process "
10672 + "with a UiAutomation can call setUserIsMonkey");
10675 mUserIsMonkey = userIsMonkey;
10680 public boolean isUserAMonkey() {
10681 synchronized (this) {
10682 // If there is a controller also implies the user is a monkey.
10683 return (mUserIsMonkey || mController != null);
10687 public void requestBugReport() {
10688 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10689 SystemProperties.set("ctl.start", "bugreport");
10692 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10693 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10696 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10697 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10698 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10700 return KEY_DISPATCHING_TIMEOUT;
10704 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10705 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10706 != PackageManager.PERMISSION_GRANTED) {
10707 throw new SecurityException("Requires permission "
10708 + android.Manifest.permission.FILTER_EVENTS);
10710 ProcessRecord proc;
10712 synchronized (this) {
10713 synchronized (mPidsSelfLocked) {
10714 proc = mPidsSelfLocked.get(pid);
10716 timeout = getInputDispatchingTimeoutLocked(proc);
10719 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10727 * Handle input dispatching timeouts.
10728 * Returns whether input dispatching should be aborted or not.
10730 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10731 final ActivityRecord activity, final ActivityRecord parent,
10732 final boolean aboveSystem, String reason) {
10733 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10734 != PackageManager.PERMISSION_GRANTED) {
10735 throw new SecurityException("Requires permission "
10736 + android.Manifest.permission.FILTER_EVENTS);
10739 final String annotation;
10740 if (reason == null) {
10741 annotation = "Input dispatching timed out";
10743 annotation = "Input dispatching timed out (" + reason + ")";
10746 if (proc != null) {
10747 synchronized (this) {
10748 if (proc.debugging) {
10753 // Give more time since we were dexopting.
10754 mDidDexOpt = false;
10758 if (proc.instrumentationClass != null) {
10759 Bundle info = new Bundle();
10760 info.putString("shortMsg", "keyDispatchingTimedOut");
10761 info.putString("longMsg", annotation);
10762 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10766 mHandler.post(new Runnable() {
10768 public void run() {
10769 appNotResponding(proc, activity, parent, aboveSystem, annotation);
10778 public Bundle getAssistContextExtras(int requestType) {
10779 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10780 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10784 synchronized (pae) {
10785 while (!pae.haveResult) {
10788 } catch (InterruptedException e) {
10792 synchronized (this) {
10793 buildAssistBundleLocked(pae, pae.result);
10794 mPendingAssistExtras.remove(pae);
10795 mUiHandler.removeCallbacks(pae);
10801 public boolean isAssistDataAllowedOnCurrentActivity() {
10802 int userId = mCurrentUserId;
10803 synchronized (this) {
10804 ActivityRecord activity = getFocusedStack().topActivity();
10805 if (activity == null) {
10808 userId = activity.userId;
10810 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10811 Context.DEVICE_POLICY_SERVICE);
10812 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10816 public boolean showAssistFromActivity(IBinder token, Bundle args) {
10817 long ident = Binder.clearCallingIdentity();
10819 synchronized (this) {
10820 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10821 ActivityRecord top = getFocusedStack().topActivity();
10822 if (top != caller) {
10823 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10824 + " is not current top " + top);
10827 if (!top.nowVisible) {
10828 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10829 + " is not visible");
10833 AssistUtils utils = new AssistUtils(mContext);
10834 return utils.showSessionForActiveService(args,
10835 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10837 Binder.restoreCallingIdentity(ident);
10842 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10843 IBinder activityToken) {
10844 return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10845 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10848 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10849 IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10851 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10852 "enqueueAssistContext()");
10853 synchronized (this) {
10854 ActivityRecord activity = getFocusedStack().topActivity();
10855 if (activity == null) {
10856 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10859 if (activity.app == null || activity.app.thread == null) {
10860 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10863 if (activityToken != null) {
10864 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10865 if (activity != caller) {
10866 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10867 + " is not current top " + activity);
10871 PendingAssistExtras pae;
10872 Bundle extras = new Bundle();
10873 if (args != null) {
10874 extras.putAll(args);
10876 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10877 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10878 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10880 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10882 mPendingAssistExtras.add(pae);
10883 mUiHandler.postDelayed(pae, timeout);
10884 } catch (RemoteException e) {
10885 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10892 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10893 IResultReceiver receiver;
10894 synchronized (this) {
10895 mPendingAssistExtras.remove(pae);
10896 receiver = pae.receiver;
10898 if (receiver != null) {
10899 // Caller wants result sent back to them.
10901 pae.receiver.send(0, null);
10902 } catch (RemoteException e) {
10907 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10908 if (result != null) {
10909 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
10911 if (pae.hint != null) {
10912 pae.extras.putBoolean(pae.hint, true);
10916 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
10917 AssistContent content, Uri referrer) {
10918 PendingAssistExtras pae = (PendingAssistExtras)token;
10919 synchronized (pae) {
10920 pae.result = extras;
10921 pae.structure = structure;
10922 pae.content = content;
10923 if (referrer != null) {
10924 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
10926 pae.haveResult = true;
10928 if (pae.intent == null && pae.receiver == null) {
10929 // Caller is just waiting for the result.
10934 // We are now ready to launch the assist activity.
10935 IResultReceiver sendReceiver = null;
10936 Bundle sendBundle = null;
10937 synchronized (this) {
10938 buildAssistBundleLocked(pae, extras);
10939 boolean exists = mPendingAssistExtras.remove(pae);
10940 mUiHandler.removeCallbacks(pae);
10945 if ((sendReceiver=pae.receiver) != null) {
10946 // Caller wants result sent back to them.
10947 sendBundle = new Bundle();
10948 sendBundle.putBundle("data", pae.extras);
10949 sendBundle.putParcelable("structure", pae.structure);
10950 sendBundle.putParcelable("content", pae.content);
10953 if (sendReceiver != null) {
10955 sendReceiver.send(0, sendBundle);
10956 } catch (RemoteException e) {
10961 long ident = Binder.clearCallingIdentity();
10963 pae.intent.replaceExtras(pae.extras);
10964 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10965 | Intent.FLAG_ACTIVITY_SINGLE_TOP
10966 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
10967 closeSystemDialogs("assist");
10969 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
10970 } catch (ActivityNotFoundException e) {
10971 Slog.w(TAG, "No activity to handle assist action.", e);
10974 Binder.restoreCallingIdentity(ident);
10978 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
10980 return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
10981 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
10984 public void registerProcessObserver(IProcessObserver observer) {
10985 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10986 "registerProcessObserver()");
10987 synchronized (this) {
10988 mProcessObservers.register(observer);
10993 public void unregisterProcessObserver(IProcessObserver observer) {
10994 synchronized (this) {
10995 mProcessObservers.unregister(observer);
10999 public void registerUidObserver(IUidObserver observer) {
11000 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11001 "registerUidObserver()");
11002 synchronized (this) {
11003 mUidObservers.register(observer);
11008 public void unregisterUidObserver(IUidObserver observer) {
11009 synchronized (this) {
11010 mUidObservers.unregister(observer);
11015 public boolean convertFromTranslucent(IBinder token) {
11016 final long origId = Binder.clearCallingIdentity();
11018 synchronized (this) {
11019 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11023 final boolean translucentChanged = r.changeWindowTranslucency(true);
11024 if (translucentChanged) {
11025 r.task.stack.releaseBackgroundResources(r);
11026 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11028 mWindowManager.setAppFullscreen(token, true);
11029 return translucentChanged;
11032 Binder.restoreCallingIdentity(origId);
11037 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11038 final long origId = Binder.clearCallingIdentity();
11040 synchronized (this) {
11041 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11045 int index = r.task.mActivities.lastIndexOf(r);
11047 ActivityRecord under = r.task.mActivities.get(index - 1);
11048 under.returningOptions = options;
11050 final boolean translucentChanged = r.changeWindowTranslucency(false);
11051 if (translucentChanged) {
11052 r.task.stack.convertActivityToTranslucent(r);
11054 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11055 mWindowManager.setAppFullscreen(token, false);
11056 return translucentChanged;
11059 Binder.restoreCallingIdentity(origId);
11064 public boolean requestVisibleBehind(IBinder token, boolean visible) {
11065 final long origId = Binder.clearCallingIdentity();
11067 synchronized (this) {
11068 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11070 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11075 Binder.restoreCallingIdentity(origId);
11080 public boolean isBackgroundVisibleBehind(IBinder token) {
11081 final long origId = Binder.clearCallingIdentity();
11083 synchronized (this) {
11084 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11085 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11086 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11087 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11091 Binder.restoreCallingIdentity(origId);
11096 public ActivityOptions getActivityOptions(IBinder token) {
11097 final long origId = Binder.clearCallingIdentity();
11099 synchronized (this) {
11100 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11102 final ActivityOptions activityOptions = r.pendingOptions;
11103 r.pendingOptions = null;
11104 return activityOptions;
11109 Binder.restoreCallingIdentity(origId);
11114 public void setImmersive(IBinder token, boolean immersive) {
11115 synchronized(this) {
11116 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11118 throw new IllegalArgumentException();
11120 r.immersive = immersive;
11122 // update associated state if we're frontmost
11123 if (r == mFocusedActivity) {
11124 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11125 applyUpdateLockStateLocked(r);
11131 public boolean isImmersive(IBinder token) {
11132 synchronized (this) {
11133 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11135 throw new IllegalArgumentException();
11137 return r.immersive;
11141 public boolean isTopActivityImmersive() {
11142 enforceNotIsolatedCaller("startActivity");
11143 synchronized (this) {
11144 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11145 return (r != null) ? r.immersive : false;
11150 public boolean isTopOfTask(IBinder token) {
11151 synchronized (this) {
11152 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11154 throw new IllegalArgumentException();
11156 return r.task.getTopActivity() == r;
11160 public final void enterSafeMode() {
11161 synchronized(this) {
11162 // It only makes sense to do this before the system is ready
11163 // and started launching other packages.
11164 if (!mSystemReady) {
11166 AppGlobals.getPackageManager().enterSafeMode();
11167 } catch (RemoteException e) {
11175 public final void showSafeModeOverlay() {
11176 View v = LayoutInflater.from(mContext).inflate(
11177 com.android.internal.R.layout.safe_mode, null);
11178 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11179 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11180 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11181 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11182 lp.gravity = Gravity.BOTTOM | Gravity.START;
11183 lp.format = v.getBackground().getOpacity();
11184 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11185 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11186 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11187 ((WindowManager)mContext.getSystemService(
11188 Context.WINDOW_SERVICE)).addView(v, lp);
11191 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11192 if (!(sender instanceof PendingIntentRecord)) {
11195 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11196 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11197 synchronized (stats) {
11198 if (mBatteryStatsService.isOnBattery()) {
11199 mBatteryStatsService.enforceCallingPermission();
11200 int MY_UID = Binder.getCallingUid();
11201 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11202 BatteryStatsImpl.Uid.Pkg pkg =
11203 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11204 sourcePkg != null ? sourcePkg : rec.key.packageName);
11205 pkg.noteWakeupAlarmLocked(tag);
11210 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11211 if (!(sender instanceof PendingIntentRecord)) {
11214 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11215 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11216 synchronized (stats) {
11217 mBatteryStatsService.enforceCallingPermission();
11218 int MY_UID = Binder.getCallingUid();
11219 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11220 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11224 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11225 if (!(sender instanceof PendingIntentRecord)) {
11228 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11229 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11230 synchronized (stats) {
11231 mBatteryStatsService.enforceCallingPermission();
11232 int MY_UID = Binder.getCallingUid();
11233 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11234 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11238 public boolean killPids(int[] pids, String pReason, boolean secure) {
11239 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11240 throw new SecurityException("killPids only available to the system");
11242 String reason = (pReason == null) ? "Unknown" : pReason;
11243 // XXX Note: don't acquire main activity lock here, because the window
11244 // manager calls in with its locks held.
11246 boolean killed = false;
11247 synchronized (mPidsSelfLocked) {
11248 int[] types = new int[pids.length];
11250 for (int i=0; i<pids.length; i++) {
11251 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11252 if (proc != null) {
11253 int type = proc.setAdj;
11255 if (type > worstType) {
11261 // If the worst oom_adj is somewhere in the cached proc LRU range,
11262 // then constrain it so we will kill all cached procs.
11263 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11264 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11265 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11268 // If this is not a secure call, don't let it kill processes that
11270 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11271 worstType = ProcessList.SERVICE_ADJ;
11274 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11275 for (int i=0; i<pids.length; i++) {
11276 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11277 if (proc == null) {
11280 int adj = proc.setAdj;
11281 if (adj >= worstType && !proc.killedByAm) {
11282 proc.kill(reason, true);
11291 public void killUid(int appId, int userId, String reason) {
11292 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11293 synchronized (this) {
11294 final long identity = Binder.clearCallingIdentity();
11296 killPackageProcessesLocked(null, appId, userId,
11297 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11298 reason != null ? reason : "kill uid");
11300 Binder.restoreCallingIdentity(identity);
11306 public boolean killProcessesBelowForeground(String reason) {
11307 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11308 throw new SecurityException("killProcessesBelowForeground() only available to system");
11311 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11314 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11315 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11316 throw new SecurityException("killProcessesBelowAdj() only available to system");
11319 boolean killed = false;
11320 synchronized (mPidsSelfLocked) {
11321 final int size = mPidsSelfLocked.size();
11322 for (int i = 0; i < size; i++) {
11323 final int pid = mPidsSelfLocked.keyAt(i);
11324 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11325 if (proc == null) continue;
11327 final int adj = proc.setAdj;
11328 if (adj > belowAdj && !proc.killedByAm) {
11329 proc.kill(reason, true);
11338 public void hang(final IBinder who, boolean allowRestart) {
11339 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11340 != PackageManager.PERMISSION_GRANTED) {
11341 throw new SecurityException("Requires permission "
11342 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11345 final IBinder.DeathRecipient death = new DeathRecipient() {
11347 public void binderDied() {
11348 synchronized (this) {
11355 who.linkToDeath(death, 0);
11356 } catch (RemoteException e) {
11357 Slog.w(TAG, "hang: given caller IBinder is already dead.");
11361 synchronized (this) {
11362 Watchdog.getInstance().setAllowRestart(allowRestart);
11363 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11364 synchronized (death) {
11365 while (who.isBinderAlive()) {
11368 } catch (InterruptedException e) {
11372 Watchdog.getInstance().setAllowRestart(true);
11377 public void restart() {
11378 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11379 != PackageManager.PERMISSION_GRANTED) {
11380 throw new SecurityException("Requires permission "
11381 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11384 Log.i(TAG, "Sending shutdown broadcast...");
11386 BroadcastReceiver br = new BroadcastReceiver() {
11387 @Override public void onReceive(Context context, Intent intent) {
11388 // Now the broadcast is done, finish up the low-level shutdown.
11389 Log.i(TAG, "Shutting down activity manager...");
11391 Log.i(TAG, "Shutdown complete, restarting!");
11392 Process.killProcess(Process.myPid());
11397 // First send the high-level shut down broadcast.
11398 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11399 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11400 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11401 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11402 mContext.sendOrderedBroadcastAsUser(intent,
11403 UserHandle.ALL, null, br, mHandler, 0, null, null);
11405 br.onReceive(mContext, intent);
11408 private long getLowRamTimeSinceIdle(long now) {
11409 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11413 public void performIdleMaintenance() {
11414 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11415 != PackageManager.PERMISSION_GRANTED) {
11416 throw new SecurityException("Requires permission "
11417 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11420 synchronized (this) {
11421 final long now = SystemClock.uptimeMillis();
11422 final long timeSinceLastIdle = now - mLastIdleTime;
11423 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11424 mLastIdleTime = now;
11425 mLowRamTimeSinceLastIdle = 0;
11426 if (mLowRamStartTime != 0) {
11427 mLowRamStartTime = now;
11430 StringBuilder sb = new StringBuilder(128);
11431 sb.append("Idle maintenance over ");
11432 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11433 sb.append(" low RAM for ");
11434 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11435 Slog.i(TAG, sb.toString());
11437 // If at least 1/3 of our time since the last idle period has been spent
11438 // with RAM low, then we want to kill processes.
11439 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11441 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11442 ProcessRecord proc = mLruProcesses.get(i);
11443 if (proc.notCachedSinceIdle) {
11444 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11445 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11446 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11447 if (doKilling && proc.initialIdlePss != 0
11448 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11449 sb = new StringBuilder(128);
11451 sb.append(proc.processName);
11452 sb.append(" in idle maint: pss=");
11453 sb.append(proc.lastPss);
11454 sb.append(", initialPss=");
11455 sb.append(proc.initialIdlePss);
11456 sb.append(", period=");
11457 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11458 sb.append(", lowRamPeriod=");
11459 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11460 Slog.wtfQuiet(TAG, sb.toString());
11461 proc.kill("idle maint (pss " + proc.lastPss
11462 + " from " + proc.initialIdlePss + ")", true);
11465 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11466 proc.notCachedSinceIdle = true;
11467 proc.initialIdlePss = 0;
11468 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11469 mTestPssMode, isSleeping(), now);
11473 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11474 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11478 private void retrieveSettings() {
11479 final ContentResolver resolver = mContext.getContentResolver();
11480 String debugApp = Settings.Global.getString(
11481 resolver, Settings.Global.DEBUG_APP);
11482 boolean waitForDebugger = Settings.Global.getInt(
11483 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11484 boolean alwaysFinishActivities = Settings.Global.getInt(
11485 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11486 boolean forceRtl = Settings.Global.getInt(
11487 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11488 // Transfer any global setting for forcing RTL layout, into a System Property
11489 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11491 Configuration configuration = new Configuration();
11492 Settings.System.getConfiguration(resolver, configuration);
11494 // This will take care of setting the correct layout direction flags
11495 configuration.setLayoutDirection(configuration.locale);
11498 synchronized (this) {
11499 mDebugApp = mOrigDebugApp = debugApp;
11500 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11501 mAlwaysFinishActivities = alwaysFinishActivities;
11502 // This happens before any activities are started, so we can
11503 // change mConfiguration in-place.
11504 updateConfigurationLocked(configuration, null, false, true);
11505 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11506 "Initial config: " + mConfiguration);
11510 /** Loads resources after the current configuration has been set. */
11511 private void loadResourcesOnSystemReady() {
11512 final Resources res = mContext.getResources();
11513 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11514 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11515 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11518 public boolean testIsSystemReady() {
11519 // no need to synchronize(this) just to read & return the value
11520 return mSystemReady;
11523 private static File getCalledPreBootReceiversFile() {
11524 File dataDir = Environment.getDataDirectory();
11525 File systemDir = new File(dataDir, "system");
11526 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11530 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11531 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11532 File file = getCalledPreBootReceiversFile();
11533 FileInputStream fis = null;
11535 fis = new FileInputStream(file);
11536 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11537 int fvers = dis.readInt();
11538 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11539 String vers = dis.readUTF();
11540 String codename = dis.readUTF();
11541 String build = dis.readUTF();
11542 if (android.os.Build.VERSION.RELEASE.equals(vers)
11543 && android.os.Build.VERSION.CODENAME.equals(codename)
11544 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11545 int num = dis.readInt();
11548 String pkg = dis.readUTF();
11549 String cls = dis.readUTF();
11550 lastDoneReceivers.add(new ComponentName(pkg, cls));
11554 } catch (FileNotFoundException e) {
11555 } catch (IOException e) {
11556 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11561 } catch (IOException e) {
11565 return lastDoneReceivers;
11568 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11569 File file = getCalledPreBootReceiversFile();
11570 FileOutputStream fos = null;
11571 DataOutputStream dos = null;
11573 fos = new FileOutputStream(file);
11574 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11575 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11576 dos.writeUTF(android.os.Build.VERSION.RELEASE);
11577 dos.writeUTF(android.os.Build.VERSION.CODENAME);
11578 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11579 dos.writeInt(list.size());
11580 for (int i=0; i<list.size(); i++) {
11581 dos.writeUTF(list.get(i).getPackageName());
11582 dos.writeUTF(list.get(i).getClassName());
11584 } catch (IOException e) {
11585 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11588 FileUtils.sync(fos);
11592 } catch (IOException e) {
11593 // TODO Auto-generated catch block
11594 e.printStackTrace();
11600 final class PreBootContinuation extends IIntentReceiver.Stub {
11601 final Intent intent;
11602 final Runnable onFinishCallback;
11603 final ArrayList<ComponentName> doneReceivers;
11604 final List<ResolveInfo> ris;
11610 PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11611 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11613 onFinishCallback = _onFinishCallback;
11614 doneReceivers = _doneReceivers;
11620 if (lastRi != curRi) {
11621 ActivityInfo ai = ris.get(curRi).activityInfo;
11622 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11623 intent.setComponent(comp);
11624 doneReceivers.add(comp);
11626 CharSequence label = ai.loadLabel(mContext.getPackageManager());
11627 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11629 Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11630 + " for user " + users[curUser]);
11631 EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11632 broadcastIntentLocked(null, null, intent, null, this,
11633 0, null, null, null, AppOpsManager.OP_NONE,
11634 null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11637 public void performReceive(Intent intent, int resultCode,
11638 String data, Bundle extras, boolean ordered,
11639 boolean sticky, int sendingUser) {
11641 if (curUser >= users.length) {
11644 if (curRi >= ris.size()) {
11645 // All done sending broadcasts!
11646 if (onFinishCallback != null) {
11647 // The raw IIntentReceiver interface is called
11648 // with the AM lock held, so redispatch to
11649 // execute our code without the lock.
11650 mHandler.post(onFinishCallback);
11659 private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11660 ArrayList<ComponentName> doneReceivers, int userId) {
11661 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11662 List<ResolveInfo> ris = null;
11664 ris = AppGlobals.getPackageManager().queryIntentReceivers(
11665 intent, null, 0, userId);
11666 } catch (RemoteException e) {
11671 for (int i=ris.size()-1; i>=0; i--) {
11672 if ((ris.get(i).activityInfo.applicationInfo.flags
11673 &ApplicationInfo.FLAG_SYSTEM) == 0) {
11677 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11679 // For User 0, load the version number. When delivering to a new user, deliver
11680 // to all receivers.
11681 if (userId == UserHandle.USER_OWNER) {
11682 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11683 for (int i=0; i<ris.size(); i++) {
11684 ActivityInfo ai = ris.get(i).activityInfo;
11685 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11686 if (lastDoneReceivers.contains(comp)) {
11687 // We already did the pre boot receiver for this app with the current
11688 // platform version, so don't do it again...
11691 // ...however, do keep it as one that has been done, so we don't
11692 // forget about it when rewriting the file of last done receivers.
11693 doneReceivers.add(comp);
11698 if (ris.size() <= 0) {
11702 // If primary user, send broadcast to all available users, else just to userId
11703 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11704 : new int[] { userId };
11705 if (users.length <= 0) {
11709 PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11715 public void systemReady(final Runnable goingCallback) {
11716 synchronized(this) {
11717 if (mSystemReady) {
11718 // If we're done calling all the receivers, run the next "boot phase" passed in
11719 // by the SystemServer
11720 if (goingCallback != null) {
11721 goingCallback.run();
11726 mLocalDeviceIdleController
11727 = LocalServices.getService(DeviceIdleController.LocalService.class);
11729 // Make sure we have the current profile info, since it is needed for
11730 // security checks.
11731 updateCurrentProfileIdsLocked();
11733 mRecentTasks.clear();
11734 mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11735 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11736 mTaskPersister.startPersisting();
11738 // Check to see if there are any update receivers to run.
11740 if (mWaitingUpdate) {
11743 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11744 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11745 public void run() {
11746 synchronized (ActivityManagerService.this) {
11749 showBootMessage(mContext.getText(
11750 R.string.android_upgrading_complete),
11752 writeLastDonePreBootReceivers(doneReceivers);
11753 systemReady(goingCallback);
11755 }, doneReceivers, UserHandle.USER_OWNER);
11757 if (mWaitingUpdate) {
11763 mAppOpsService.systemReady();
11764 mSystemReady = true;
11767 ArrayList<ProcessRecord> procsToKill = null;
11768 synchronized(mPidsSelfLocked) {
11769 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11770 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11771 if (!isAllowedWhileBooting(proc.info)){
11772 if (procsToKill == null) {
11773 procsToKill = new ArrayList<ProcessRecord>();
11775 procsToKill.add(proc);
11780 synchronized(this) {
11781 if (procsToKill != null) {
11782 for (int i=procsToKill.size()-1; i>=0; i--) {
11783 ProcessRecord proc = procsToKill.get(i);
11784 Slog.i(TAG, "Removing system update proc: " + proc);
11785 removeProcessLocked(proc, true, false, "system update done");
11789 // Now that we have cleaned up any update processes, we
11790 // are ready to start launching real processes and know that
11791 // we won't trample on them any more.
11792 mProcessesReady = true;
11795 Slog.i(TAG, "System now ready");
11796 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11797 SystemClock.uptimeMillis());
11799 synchronized(this) {
11800 // Make sure we have no pre-ready processes sitting around.
11802 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11803 ResolveInfo ri = mContext.getPackageManager()
11804 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11806 CharSequence errorMsg = null;
11808 ActivityInfo ai = ri.activityInfo;
11809 ApplicationInfo app = ai.applicationInfo;
11810 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11811 mTopAction = Intent.ACTION_FACTORY_TEST;
11813 mTopComponent = new ComponentName(app.packageName,
11816 errorMsg = mContext.getResources().getText(
11817 com.android.internal.R.string.factorytest_not_system);
11820 errorMsg = mContext.getResources().getText(
11821 com.android.internal.R.string.factorytest_no_action);
11823 if (errorMsg != null) {
11826 mTopComponent = null;
11827 Message msg = Message.obtain();
11828 msg.what = SHOW_FACTORY_ERROR_MSG;
11829 msg.getData().putCharSequence("msg", errorMsg);
11830 mUiHandler.sendMessage(msg);
11835 retrieveSettings();
11836 loadResourcesOnSystemReady();
11838 synchronized (this) {
11839 readGrantedUriPermissionsLocked();
11842 if (goingCallback != null) goingCallback.run();
11844 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11845 Integer.toString(mCurrentUserId), mCurrentUserId);
11846 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11847 Integer.toString(mCurrentUserId), mCurrentUserId);
11848 mSystemServiceManager.startUser(mCurrentUserId);
11850 synchronized (this) {
11851 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11853 List apps = AppGlobals.getPackageManager().
11854 getPersistentApplications(STOCK_PM_FLAGS);
11855 if (apps != null) {
11856 int N = apps.size();
11858 for (i=0; i<N; i++) {
11859 ApplicationInfo info
11860 = (ApplicationInfo)apps.get(i);
11861 if (info != null &&
11862 !info.packageName.equals("android")) {
11863 addAppLocked(info, false, null /* ABI override */);
11867 } catch (RemoteException ex) {
11868 // pm is in same process, this will never happen.
11872 // Start up initial activity.
11874 startHomeActivityLocked(mCurrentUserId, "systemReady");
11877 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11878 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11879 + " data partition or your device will be unstable.");
11880 mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11882 } catch (RemoteException e) {
11885 if (!Build.isBuildConsistent()) {
11886 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11887 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11890 long ident = Binder.clearCallingIdentity();
11892 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11893 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11894 | Intent.FLAG_RECEIVER_FOREGROUND);
11895 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11896 broadcastIntentLocked(null, null, intent,
11897 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11898 null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11899 intent = new Intent(Intent.ACTION_USER_STARTING);
11900 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11901 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11902 broadcastIntentLocked(null, null, intent,
11903 null, new IIntentReceiver.Stub() {
11905 public void performReceive(Intent intent, int resultCode, String data,
11906 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11907 throws RemoteException {
11910 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
11911 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11912 } catch (Throwable t) {
11913 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11915 Binder.restoreCallingIdentity(ident);
11917 mStackSupervisor.resumeTopActivitiesLocked();
11918 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11922 private boolean makeAppCrashingLocked(ProcessRecord app,
11923 String shortMsg, String longMsg, String stackTrace) {
11924 app.crashing = true;
11925 app.crashingReport = generateProcessError(app,
11926 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11927 startAppProblemLocked(app);
11928 app.stopFreezingAllLocked();
11929 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
11932 private void makeAppNotRespondingLocked(ProcessRecord app,
11933 String activity, String shortMsg, String longMsg) {
11934 app.notResponding = true;
11935 app.notRespondingReport = generateProcessError(app,
11936 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11937 activity, shortMsg, longMsg, null);
11938 startAppProblemLocked(app);
11939 app.stopFreezingAllLocked();
11943 * Generate a process error record, suitable for attachment to a ProcessRecord.
11945 * @param app The ProcessRecord in which the error occurred.
11946 * @param condition Crashing, Application Not Responding, etc. Values are defined in
11947 * ActivityManager.AppErrorStateInfo
11948 * @param activity The activity associated with the crash, if known.
11949 * @param shortMsg Short message describing the crash.
11950 * @param longMsg Long message describing the crash.
11951 * @param stackTrace Full crash stack trace, may be null.
11953 * @return Returns a fully-formed AppErrorStateInfo record.
11955 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11956 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11957 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11959 report.condition = condition;
11960 report.processName = app.processName;
11961 report.pid = app.pid;
11962 report.uid = app.info.uid;
11963 report.tag = activity;
11964 report.shortMsg = shortMsg;
11965 report.longMsg = longMsg;
11966 report.stackTrace = stackTrace;
11971 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11972 synchronized (this) {
11973 app.crashing = false;
11974 app.crashingReport = null;
11975 app.notResponding = false;
11976 app.notRespondingReport = null;
11977 if (app.anrDialog == fromDialog) {
11978 app.anrDialog = null;
11980 if (app.waitDialog == fromDialog) {
11981 app.waitDialog = null;
11983 if (app.pid > 0 && app.pid != MY_PID) {
11984 handleAppCrashLocked(app, "user-terminated" /*reason*/,
11985 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
11986 app.kill("user request after error", true);
11991 private boolean handleAppCrashLocked(ProcessRecord app, String reason,
11992 String shortMsg, String longMsg, String stackTrace) {
11993 long now = SystemClock.uptimeMillis();
11996 if (!app.isolated) {
11997 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12001 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12002 // This process loses!
12003 Slog.w(TAG, "Process " + app.info.processName
12004 + " has crashed too many times: killing!");
12005 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12006 app.userId, app.info.processName, app.uid);
12007 mStackSupervisor.handleAppCrashLocked(app);
12008 if (!app.persistent) {
12009 // We don't want to start this process again until the user
12010 // explicitly does so... but for persistent process, we really
12011 // need to keep it running. If a persistent process is actually
12012 // repeatedly crashing, then badness for everyone.
12013 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12014 app.info.processName);
12015 if (!app.isolated) {
12016 // XXX We don't have a way to mark isolated processes
12017 // as bad, since they don't have a peristent identity.
12018 mBadProcesses.put(app.info.processName, app.uid,
12019 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12020 mProcessCrashTimes.remove(app.info.processName, app.uid);
12023 app.removed = true;
12024 // Don't let services in this process be restarted and potentially
12025 // annoy the user repeatedly. Unless it is persistent, since those
12026 // processes run critical code.
12027 removeProcessLocked(app, false, false, "crash");
12028 mStackSupervisor.resumeTopActivitiesLocked();
12031 mStackSupervisor.resumeTopActivitiesLocked();
12033 mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12036 // Bump up the crash count of any services currently running in the proc.
12037 for (int i=app.services.size()-1; i>=0; i--) {
12038 // Any services running in the application need to be placed
12039 // back in the pending list.
12040 ServiceRecord sr = app.services.valueAt(i);
12044 // If the crashing process is what we consider to be the "home process" and it has been
12045 // replaced by a third-party app, clear the package preferred activities from packages
12046 // with a home activity running in the process to prevent a repeatedly crashing app
12047 // from blocking the user to manually clear the list.
12048 final ArrayList<ActivityRecord> activities = app.activities;
12049 if (app == mHomeProcess && activities.size() > 0
12050 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12051 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12052 final ActivityRecord r = activities.get(activityNdx);
12053 if (r.isHomeActivity()) {
12054 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12056 ActivityThread.getPackageManager()
12057 .clearPackagePreferredActivities(r.packageName);
12058 } catch (RemoteException c) {
12059 // pm is in same process, this will never happen.
12065 if (!app.isolated) {
12066 // XXX Can't keep track of crash times for isolated processes,
12067 // because they don't have a perisistent identity.
12068 mProcessCrashTimes.put(app.info.processName, app.uid, now);
12071 if (app.crashHandler != null) mHandler.post(app.crashHandler);
12075 void startAppProblemLocked(ProcessRecord app) {
12076 // If this app is not running under the current user, then we
12077 // can't give it a report button because that would require
12078 // launching the report UI under a different user.
12079 app.errorReportReceiver = null;
12081 for (int userId : mCurrentProfileIds) {
12082 if (app.userId == userId) {
12083 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12084 mContext, app.info.packageName, app.info.flags);
12087 skipCurrentReceiverLocked(app);
12090 void skipCurrentReceiverLocked(ProcessRecord app) {
12091 for (BroadcastQueue queue : mBroadcastQueues) {
12092 queue.skipCurrentReceiverLocked(app);
12097 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12098 * The application process will exit immediately after this call returns.
12099 * @param app object of the crashing app, null for the system server
12100 * @param crashInfo describing the exception
12102 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12103 ProcessRecord r = findAppProcess(app, "Crash");
12104 final String processName = app == null ? "system_server"
12105 : (r == null ? "unknown" : r.processName);
12107 handleApplicationCrashInner("crash", r, processName, crashInfo);
12110 /* Native crash reporting uses this inner version because it needs to be somewhat
12111 * decoupled from the AM-managed cleanup lifecycle
12113 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12114 ApplicationErrorReport.CrashInfo crashInfo) {
12115 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12116 UserHandle.getUserId(Binder.getCallingUid()), processName,
12117 r == null ? -1 : r.info.flags,
12118 crashInfo.exceptionClassName,
12119 crashInfo.exceptionMessage,
12120 crashInfo.throwFileName,
12121 crashInfo.throwLineNumber);
12123 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12125 crashApplication(r, crashInfo);
12128 public void handleApplicationStrictModeViolation(
12131 StrictMode.ViolationInfo info) {
12132 ProcessRecord r = findAppProcess(app, "StrictMode");
12137 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12138 Integer stackFingerprint = info.hashCode();
12139 boolean logIt = true;
12140 synchronized (mAlreadyLoggedViolatedStacks) {
12141 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12143 // TODO: sub-sample into EventLog for these, with
12144 // the info.durationMillis? Then we'd get
12145 // the relative pain numbers, without logging all
12146 // the stack traces repeatedly. We'd want to do
12147 // likewise in the client code, which also does
12148 // dup suppression, before the Binder call.
12150 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12151 mAlreadyLoggedViolatedStacks.clear();
12153 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12157 logStrictModeViolationToDropBox(r, info);
12161 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12162 AppErrorResult result = new AppErrorResult();
12163 synchronized (this) {
12164 final long origId = Binder.clearCallingIdentity();
12166 Message msg = Message.obtain();
12167 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12168 HashMap<String, Object> data = new HashMap<String, Object>();
12169 data.put("result", result);
12170 data.put("app", r);
12171 data.put("violationMask", violationMask);
12172 data.put("info", info);
12174 mUiHandler.sendMessage(msg);
12176 Binder.restoreCallingIdentity(origId);
12178 int res = result.get();
12179 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12183 // Depending on the policy in effect, there could be a bunch of
12184 // these in quick succession so we try to batch these together to
12185 // minimize disk writes, number of dropbox entries, and maximize
12186 // compression, by having more fewer, larger records.
12187 private void logStrictModeViolationToDropBox(
12188 ProcessRecord process,
12189 StrictMode.ViolationInfo info) {
12190 if (info == null) {
12193 final boolean isSystemApp = process == null ||
12194 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12195 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12196 final String processName = process == null ? "unknown" : process.processName;
12197 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12198 final DropBoxManager dbox = (DropBoxManager)
12199 mContext.getSystemService(Context.DROPBOX_SERVICE);
12201 // Exit early if the dropbox isn't configured to accept this report type.
12202 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12204 boolean bufferWasEmpty;
12205 boolean needsFlush;
12206 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12207 synchronized (sb) {
12208 bufferWasEmpty = sb.length() == 0;
12209 appendDropBoxProcessHeaders(process, processName, sb);
12210 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12211 sb.append("System-App: ").append(isSystemApp).append("\n");
12212 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12213 if (info.violationNumThisLoop != 0) {
12214 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12216 if (info.numAnimationsRunning != 0) {
12217 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12219 if (info.broadcastIntentAction != null) {
12220 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12222 if (info.durationMillis != -1) {
12223 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12225 if (info.numInstances != -1) {
12226 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12228 if (info.tags != null) {
12229 for (String tag : info.tags) {
12230 sb.append("Span-Tag: ").append(tag).append("\n");
12234 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12235 sb.append(info.crashInfo.stackTrace);
12238 if (info.message != null) {
12239 sb.append(info.message);
12243 // Only buffer up to ~64k. Various logging bits truncate
12245 needsFlush = (sb.length() > 64 * 1024);
12248 // Flush immediately if the buffer's grown too large, or this
12249 // is a non-system app. Non-system apps are isolated with a
12250 // different tag & policy and not batched.
12252 // Batching is useful during internal testing with
12253 // StrictMode settings turned up high. Without batching,
12254 // thousands of separate files could be created on boot.
12255 if (!isSystemApp || needsFlush) {
12256 new Thread("Error dump: " + dropboxTag) {
12258 public void run() {
12260 synchronized (sb) {
12261 report = sb.toString();
12262 sb.delete(0, sb.length());
12265 if (report.length() != 0) {
12266 dbox.addText(dropboxTag, report);
12273 // System app batching:
12274 if (!bufferWasEmpty) {
12275 // An existing dropbox-writing thread is outstanding, so
12276 // we don't need to start it up. The existing thread will
12277 // catch the buffer appends we just did.
12281 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12282 // (After this point, we shouldn't access AMS internal data structures.)
12283 new Thread("Error dump: " + dropboxTag) {
12285 public void run() {
12286 // 5 second sleep to let stacks arrive and be batched together
12288 Thread.sleep(5000); // 5 seconds
12289 } catch (InterruptedException e) {}
12291 String errorReport;
12292 synchronized (mStrictModeBuffer) {
12293 errorReport = mStrictModeBuffer.toString();
12294 if (errorReport.length() == 0) {
12297 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12298 mStrictModeBuffer.trimToSize();
12300 dbox.addText(dropboxTag, errorReport);
12306 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12307 * @param app object of the crashing app, null for the system server
12308 * @param tag reported by the caller
12309 * @param system whether this wtf is coming from the system
12310 * @param crashInfo describing the context of the error
12311 * @return true if the process should exit immediately (WTF is fatal)
12313 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12314 final ApplicationErrorReport.CrashInfo crashInfo) {
12315 final int callingUid = Binder.getCallingUid();
12316 final int callingPid = Binder.getCallingPid();
12319 // If this is coming from the system, we could very well have low-level
12320 // system locks held, so we want to do this all asynchronously. And we
12321 // never want this to become fatal, so there is that too.
12322 mHandler.post(new Runnable() {
12323 @Override public void run() {
12324 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12330 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12333 if (r != null && r.pid != Process.myPid() &&
12334 Settings.Global.getInt(mContext.getContentResolver(),
12335 Settings.Global.WTF_IS_FATAL, 0) != 0) {
12336 crashApplication(r, crashInfo);
12343 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12344 final ApplicationErrorReport.CrashInfo crashInfo) {
12345 final ProcessRecord r = findAppProcess(app, "WTF");
12346 final String processName = app == null ? "system_server"
12347 : (r == null ? "unknown" : r.processName);
12349 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12350 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12352 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12358 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12359 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12361 private ProcessRecord findAppProcess(IBinder app, String reason) {
12366 synchronized (this) {
12367 final int NP = mProcessNames.getMap().size();
12368 for (int ip=0; ip<NP; ip++) {
12369 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12370 final int NA = apps.size();
12371 for (int ia=0; ia<NA; ia++) {
12372 ProcessRecord p = apps.valueAt(ia);
12373 if (p.thread != null && p.thread.asBinder() == app) {
12379 Slog.w(TAG, "Can't find mystery application for " + reason
12380 + " from pid=" + Binder.getCallingPid()
12381 + " uid=" + Binder.getCallingUid() + ": " + app);
12387 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12388 * to append various headers to the dropbox log text.
12390 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12391 StringBuilder sb) {
12392 // Watchdog thread ends up invoking this function (with
12393 // a null ProcessRecord) to add the stack file to dropbox.
12394 // Do not acquire a lock on this (am) in such cases, as it
12395 // could cause a potential deadlock, if and when watchdog
12396 // is invoked due to unavailability of lock on am and it
12397 // would prevent watchdog from killing system_server.
12398 if (process == null) {
12399 sb.append("Process: ").append(processName).append("\n");
12402 // Note: ProcessRecord 'process' is guarded by the service
12403 // instance. (notably process.pkgList, which could otherwise change
12404 // concurrently during execution of this method)
12405 synchronized (this) {
12406 sb.append("Process: ").append(processName).append("\n");
12407 int flags = process.info.flags;
12408 IPackageManager pm = AppGlobals.getPackageManager();
12409 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12410 for (int ip=0; ip<process.pkgList.size(); ip++) {
12411 String pkg = process.pkgList.keyAt(ip);
12412 sb.append("Package: ").append(pkg);
12414 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12416 sb.append(" v").append(pi.versionCode);
12417 if (pi.versionName != null) {
12418 sb.append(" (").append(pi.versionName).append(")");
12421 } catch (RemoteException e) {
12422 Slog.e(TAG, "Error getting package info: " + pkg, e);
12429 private static String processClass(ProcessRecord process) {
12430 if (process == null || process.pid == MY_PID) {
12431 return "system_server";
12432 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12433 return "system_app";
12440 * Write a description of an error (crash, WTF, ANR) to the drop box.
12441 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12442 * @param process which caused the error, null means the system server
12443 * @param activity which triggered the error, null if unknown
12444 * @param parent activity related to the error, null if unknown
12445 * @param subject line related to the error, null if absent
12446 * @param report in long form describing the error, null if absent
12447 * @param logFile to include in the report, null if none
12448 * @param crashInfo giving an application stack trace, null if absent
12450 public void addErrorToDropBox(String eventType,
12451 ProcessRecord process, String processName, ActivityRecord activity,
12452 ActivityRecord parent, String subject,
12453 final String report, final File logFile,
12454 final ApplicationErrorReport.CrashInfo crashInfo) {
12455 // NOTE -- this must never acquire the ActivityManagerService lock,
12456 // otherwise the watchdog may be prevented from resetting the system.
12458 final String dropboxTag = processClass(process) + "_" + eventType;
12459 final DropBoxManager dbox = (DropBoxManager)
12460 mContext.getSystemService(Context.DROPBOX_SERVICE);
12462 // Exit early if the dropbox isn't configured to accept this report type.
12463 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12465 final StringBuilder sb = new StringBuilder(1024);
12466 appendDropBoxProcessHeaders(process, processName, sb);
12467 if (activity != null) {
12468 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12470 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12471 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12473 if (parent != null && parent != activity) {
12474 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12476 if (subject != null) {
12477 sb.append("Subject: ").append(subject).append("\n");
12479 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12480 if (Debug.isDebuggerConnected()) {
12481 sb.append("Debugger: Connected\n");
12485 // Do the rest in a worker thread to avoid blocking the caller on I/O
12486 // (After this point, we shouldn't access AMS internal data structures.)
12487 Thread worker = new Thread("Error dump: " + dropboxTag) {
12489 public void run() {
12490 if (report != null) {
12493 if (logFile != null) {
12495 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12496 "\n\n[[TRUNCATED]]"));
12497 } catch (IOException e) {
12498 Slog.e(TAG, "Error reading " + logFile, e);
12501 if (crashInfo != null && crashInfo.stackTrace != null) {
12502 sb.append(crashInfo.stackTrace);
12505 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12506 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12510 // Merge several logcat streams, and take the last N lines
12511 InputStreamReader input = null;
12513 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12514 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12516 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12518 try { logcat.getOutputStream().close(); } catch (IOException e) {}
12519 try { logcat.getErrorStream().close(); } catch (IOException e) {}
12520 input = new InputStreamReader(logcat.getInputStream());
12523 char[] buf = new char[8192];
12524 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12525 } catch (IOException e) {
12526 Slog.e(TAG, "Error running logcat", e);
12528 if (input != null) try { input.close(); } catch (IOException e) {}
12532 dbox.addText(dropboxTag, sb.toString());
12536 if (process == null) {
12537 // If process is null, we are being called from some internal code
12538 // and may be about to die -- run this synchronously.
12546 * Bring up the "unexpected error" dialog box for a crashing app.
12547 * Deal with edge cases (intercepts from instrumented applications,
12548 * ActivityController, error intent receivers, that sort of thing).
12549 * @param r the application crashing
12550 * @param crashInfo describing the failure
12552 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12553 long timeMillis = System.currentTimeMillis();
12554 String shortMsg = crashInfo.exceptionClassName;
12555 String longMsg = crashInfo.exceptionMessage;
12556 String stackTrace = crashInfo.stackTrace;
12557 if (shortMsg != null && longMsg != null) {
12558 longMsg = shortMsg + ": " + longMsg;
12559 } else if (shortMsg != null) {
12560 longMsg = shortMsg;
12563 AppErrorResult result = new AppErrorResult();
12564 synchronized (this) {
12565 if (mController != null) {
12567 String name = r != null ? r.processName : null;
12568 int pid = r != null ? r.pid : Binder.getCallingPid();
12569 int uid = r != null ? r.info.uid : Binder.getCallingUid();
12570 if (!mController.appCrashed(name, pid,
12571 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12572 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12573 && "Native crash".equals(crashInfo.exceptionClassName)) {
12574 Slog.w(TAG, "Skip killing native crashed app " + name
12575 + "(" + pid + ") during testing");
12577 Slog.w(TAG, "Force-killing crashed app " + name
12578 + " at watcher's request");
12580 r.kill("crash", true);
12583 Process.killProcess(pid);
12584 killProcessGroup(uid, pid);
12589 } catch (RemoteException e) {
12590 mController = null;
12591 Watchdog.getInstance().setActivityController(null);
12595 final long origId = Binder.clearCallingIdentity();
12597 // If this process is running instrumentation, finish it.
12598 if (r != null && r.instrumentationClass != null) {
12599 Slog.w(TAG, "Error in app " + r.processName
12600 + " running instrumentation " + r.instrumentationClass + ":");
12601 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
12602 if (longMsg != null) Slog.w(TAG, " " + longMsg);
12603 Bundle info = new Bundle();
12604 info.putString("shortMsg", shortMsg);
12605 info.putString("longMsg", longMsg);
12606 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12607 Binder.restoreCallingIdentity(origId);
12611 // Log crash in battery stats.
12613 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12616 // If we can't identify the process or it's already exceeded its crash quota,
12617 // quit right away without showing a crash dialog.
12618 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12619 Binder.restoreCallingIdentity(origId);
12623 Message msg = Message.obtain();
12624 msg.what = SHOW_ERROR_MSG;
12625 HashMap data = new HashMap();
12626 data.put("result", result);
12627 data.put("app", r);
12629 mUiHandler.sendMessage(msg);
12631 Binder.restoreCallingIdentity(origId);
12634 int res = result.get();
12636 Intent appErrorIntent = null;
12637 synchronized (this) {
12638 if (r != null && !r.isolated) {
12639 // XXX Can't keep track of crash time for isolated processes,
12640 // since they don't have a persistent identity.
12641 mProcessCrashTimes.put(r.info.processName, r.uid,
12642 SystemClock.uptimeMillis());
12644 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12645 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12649 if (appErrorIntent != null) {
12651 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12652 } catch (ActivityNotFoundException e) {
12653 Slog.w(TAG, "bug report receiver dissappeared", e);
12658 Intent createAppErrorIntentLocked(ProcessRecord r,
12659 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12660 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12661 if (report == null) {
12664 Intent result = new Intent(Intent.ACTION_APP_ERROR);
12665 result.setComponent(r.errorReportReceiver);
12666 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12667 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12671 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12672 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12673 if (r.errorReportReceiver == null) {
12677 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12681 ApplicationErrorReport report = new ApplicationErrorReport();
12682 report.packageName = r.info.packageName;
12683 report.installerPackageName = r.errorReportReceiver.getPackageName();
12684 report.processName = r.processName;
12685 report.time = timeMillis;
12686 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12688 if (r.crashing || r.forceCrashReport) {
12689 report.type = ApplicationErrorReport.TYPE_CRASH;
12690 report.crashInfo = crashInfo;
12691 } else if (r.notResponding) {
12692 report.type = ApplicationErrorReport.TYPE_ANR;
12693 report.anrInfo = new ApplicationErrorReport.AnrInfo();
12695 report.anrInfo.activity = r.notRespondingReport.tag;
12696 report.anrInfo.cause = r.notRespondingReport.shortMsg;
12697 report.anrInfo.info = r.notRespondingReport.longMsg;
12703 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12704 enforceNotIsolatedCaller("getProcessesInErrorState");
12705 // assume our apps are happy - lazy create the list
12706 List<ActivityManager.ProcessErrorStateInfo> errList = null;
12708 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12709 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12710 int userId = UserHandle.getUserId(Binder.getCallingUid());
12712 synchronized (this) {
12714 // iterate across all processes
12715 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12716 ProcessRecord app = mLruProcesses.get(i);
12717 if (!allUsers && app.userId != userId) {
12720 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12721 // This one's in trouble, so we'll generate a report for it
12722 // crashes are higher priority (in case there's a crash *and* an anr)
12723 ActivityManager.ProcessErrorStateInfo report = null;
12724 if (app.crashing) {
12725 report = app.crashingReport;
12726 } else if (app.notResponding) {
12727 report = app.notRespondingReport;
12730 if (report != null) {
12731 if (errList == null) {
12732 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12734 errList.add(report);
12736 Slog.w(TAG, "Missing app error report, app = " + app.processName +
12737 " crashing = " + app.crashing +
12738 " notResponding = " + app.notResponding);
12747 static int procStateToImportance(int procState, int memAdj,
12748 ActivityManager.RunningAppProcessInfo currApp) {
12749 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12750 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12751 currApp.lru = memAdj;
12758 private void fillInProcMemInfo(ProcessRecord app,
12759 ActivityManager.RunningAppProcessInfo outInfo) {
12760 outInfo.pid = app.pid;
12761 outInfo.uid = app.info.uid;
12762 if (mHeavyWeightProcess == app) {
12763 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12765 if (app.persistent) {
12766 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12768 if (app.activities.size() > 0) {
12769 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12771 outInfo.lastTrimLevel = app.trimMemoryLevel;
12772 int adj = app.curAdj;
12773 int procState = app.curProcState;
12774 outInfo.importance = procStateToImportance(procState, adj, outInfo);
12775 outInfo.importanceReasonCode = app.adjTypeCode;
12776 outInfo.processState = app.curProcState;
12779 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12780 enforceNotIsolatedCaller("getRunningAppProcesses");
12782 final int callingUid = Binder.getCallingUid();
12784 // Lazy instantiation of list
12785 List<ActivityManager.RunningAppProcessInfo> runList = null;
12786 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12787 callingUid) == PackageManager.PERMISSION_GRANTED;
12788 final int userId = UserHandle.getUserId(callingUid);
12789 final boolean allUids = isGetTasksAllowed(
12790 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12792 synchronized (this) {
12793 // Iterate across all processes
12794 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12795 ProcessRecord app = mLruProcesses.get(i);
12796 if ((!allUsers && app.userId != userId)
12797 || (!allUids && app.uid != callingUid)) {
12800 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12801 // Generate process state info for running application
12802 ActivityManager.RunningAppProcessInfo currApp =
12803 new ActivityManager.RunningAppProcessInfo(app.processName,
12804 app.pid, app.getPackageList());
12805 fillInProcMemInfo(app, currApp);
12806 if (app.adjSource instanceof ProcessRecord) {
12807 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12808 currApp.importanceReasonImportance =
12809 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12810 app.adjSourceProcState);
12811 } else if (app.adjSource instanceof ActivityRecord) {
12812 ActivityRecord r = (ActivityRecord)app.adjSource;
12813 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12815 if (app.adjTarget instanceof ComponentName) {
12816 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12818 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12819 // + " lru=" + currApp.lru);
12820 if (runList == null) {
12821 runList = new ArrayList<>();
12823 runList.add(currApp);
12830 public List<ApplicationInfo> getRunningExternalApplications() {
12831 enforceNotIsolatedCaller("getRunningExternalApplications");
12832 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12833 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12834 if (runningApps != null && runningApps.size() > 0) {
12835 Set<String> extList = new HashSet<String>();
12836 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12837 if (app.pkgList != null) {
12838 for (String pkg : app.pkgList) {
12843 IPackageManager pm = AppGlobals.getPackageManager();
12844 for (String pkg : extList) {
12846 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12847 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12850 } catch (RemoteException e) {
12858 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12859 enforceNotIsolatedCaller("getMyMemoryState");
12860 synchronized (this) {
12861 ProcessRecord proc;
12862 synchronized (mPidsSelfLocked) {
12863 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12865 fillInProcMemInfo(proc, outInfo);
12870 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12871 if (checkCallingPermission(android.Manifest.permission.DUMP)
12872 != PackageManager.PERMISSION_GRANTED) {
12873 pw.println("Permission Denial: can't dump ActivityManager from from pid="
12874 + Binder.getCallingPid()
12875 + ", uid=" + Binder.getCallingUid()
12876 + " without permission "
12877 + android.Manifest.permission.DUMP);
12881 boolean dumpAll = false;
12882 boolean dumpClient = false;
12883 String dumpPackage = null;
12886 while (opti < args.length) {
12887 String opt = args[opti];
12888 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12892 if ("-a".equals(opt)) {
12894 } else if ("-c".equals(opt)) {
12896 } else if ("-p".equals(opt)) {
12897 if (opti < args.length) {
12898 dumpPackage = args[opti];
12901 pw.println("Error: -p option requires package argument");
12905 } else if ("-h".equals(opt)) {
12906 pw.println("Activity manager dump options:");
12907 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ...");
12908 pw.println(" cmd may be one of:");
12909 pw.println(" a[ctivities]: activity stack state");
12910 pw.println(" r[recents]: recent activities state");
12911 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12912 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
12913 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
12914 pw.println(" o[om]: out of memory management");
12915 pw.println(" perm[issions]: URI permission grant state");
12916 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
12917 pw.println(" provider [COMP_SPEC]: provider client-side state");
12918 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
12919 pw.println(" as[sociations]: tracked app associations");
12920 pw.println(" service [COMP_SPEC]: service client-side state");
12921 pw.println(" package [PACKAGE_NAME]: all state related to given package");
12922 pw.println(" all: dump all activities");
12923 pw.println(" top: dump the top activity");
12924 pw.println(" write: write all pending state to storage");
12925 pw.println(" track-associations: enable association tracking");
12926 pw.println(" untrack-associations: disable and clear association tracking");
12927 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
12928 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
12929 pw.println(" a partial substring in a component name, a");
12930 pw.println(" hex object identifier.");
12931 pw.println(" -a: include all available server state.");
12932 pw.println(" -c: include client state.");
12933 pw.println(" -p: limit output to given package.");
12936 pw.println("Unknown argument: " + opt + "; use -h for help");
12940 long origId = Binder.clearCallingIdentity();
12941 boolean more = false;
12942 // Is the caller requesting to dump a particular piece of data?
12943 if (opti < args.length) {
12944 String cmd = args[opti];
12946 if ("activities".equals(cmd) || "a".equals(cmd)) {
12947 synchronized (this) {
12948 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
12950 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12951 synchronized (this) {
12952 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
12954 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12957 if (opti >= args.length) {
12959 newArgs = EMPTY_STRING_ARRAY;
12961 dumpPackage = args[opti];
12963 newArgs = new String[args.length - opti];
12964 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12965 args.length - opti);
12967 synchronized (this) {
12968 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
12970 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12973 if (opti >= args.length) {
12975 newArgs = EMPTY_STRING_ARRAY;
12977 dumpPackage = args[opti];
12979 newArgs = new String[args.length - opti];
12980 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12981 args.length - opti);
12983 synchronized (this) {
12984 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
12986 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12989 if (opti >= args.length) {
12991 newArgs = EMPTY_STRING_ARRAY;
12993 dumpPackage = args[opti];
12995 newArgs = new String[args.length - opti];
12996 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12997 args.length - opti);
12999 synchronized (this) {
13000 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13002 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13003 synchronized (this) {
13004 dumpOomLocked(fd, pw, args, opti, true);
13006 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13007 synchronized (this) {
13008 dumpPermissionsLocked(fd, pw, args, opti, true, null);
13010 } else if ("provider".equals(cmd)) {
13013 if (opti >= args.length) {
13015 newArgs = EMPTY_STRING_ARRAY;
13019 newArgs = new String[args.length - opti];
13020 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13022 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13023 pw.println("No providers match: " + name);
13024 pw.println("Use -h for help.");
13026 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13027 synchronized (this) {
13028 dumpProvidersLocked(fd, pw, args, opti, true, null);
13030 } else if ("service".equals(cmd)) {
13033 if (opti >= args.length) {
13035 newArgs = EMPTY_STRING_ARRAY;
13039 newArgs = new String[args.length - opti];
13040 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13041 args.length - opti);
13043 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13044 pw.println("No services match: " + name);
13045 pw.println("Use -h for help.");
13047 } else if ("package".equals(cmd)) {
13049 if (opti >= args.length) {
13050 pw.println("package: no package name specified");
13051 pw.println("Use -h for help.");
13053 dumpPackage = args[opti];
13055 newArgs = new String[args.length - opti];
13056 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13057 args.length - opti);
13062 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13063 synchronized (this) {
13064 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13066 } else if ("services".equals(cmd) || "s".equals(cmd)) {
13067 synchronized (this) {
13068 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13070 } else if ("write".equals(cmd)) {
13071 mTaskPersister.flush();
13072 pw.println("All tasks persisted.");
13074 } else if ("track-associations".equals(cmd)) {
13075 synchronized (this) {
13076 if (!mTrackingAssociations) {
13077 mTrackingAssociations = true;
13078 pw.println("Association tracking started.");
13080 pw.println("Association tracking already enabled.");
13084 } else if ("untrack-associations".equals(cmd)) {
13085 synchronized (this) {
13086 if (mTrackingAssociations) {
13087 mTrackingAssociations = false;
13088 mAssociations.clear();
13089 pw.println("Association tracking stopped.");
13091 pw.println("Association tracking not running.");
13096 // Dumping a single activity?
13097 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13098 pw.println("Bad activity command, or no activities match: " + cmd);
13099 pw.println("Use -h for help.");
13103 Binder.restoreCallingIdentity(origId);
13108 // No piece of data specified, dump everything.
13109 synchronized (this) {
13110 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13113 pw.println("-------------------------------------------------------------------------------");
13115 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13118 pw.println("-------------------------------------------------------------------------------");
13120 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13123 pw.println("-------------------------------------------------------------------------------");
13125 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13128 pw.println("-------------------------------------------------------------------------------");
13130 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13133 pw.println("-------------------------------------------------------------------------------");
13135 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13138 pw.println("-------------------------------------------------------------------------------");
13140 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13141 if (mAssociations.size() > 0) {
13144 pw.println("-------------------------------------------------------------------------------");
13146 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13150 pw.println("-------------------------------------------------------------------------------");
13152 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13154 Binder.restoreCallingIdentity(origId);
13157 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13158 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13159 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13161 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13163 boolean needSep = printedAnything;
13165 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13166 dumpPackage, needSep, " mFocusedActivity: ");
13168 printedAnything = true;
13172 if (dumpPackage == null) {
13177 printedAnything = true;
13178 mStackSupervisor.dump(pw, " ");
13181 if (!printedAnything) {
13182 pw.println(" (nothing)");
13186 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13187 int opti, boolean dumpAll, String dumpPackage) {
13188 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13190 boolean printedAnything = false;
13192 if (mRecentTasks != null && mRecentTasks.size() > 0) {
13193 boolean printedHeader = false;
13195 final int N = mRecentTasks.size();
13196 for (int i=0; i<N; i++) {
13197 TaskRecord tr = mRecentTasks.get(i);
13198 if (dumpPackage != null) {
13199 if (tr.realActivity == null ||
13200 !dumpPackage.equals(tr.realActivity)) {
13204 if (!printedHeader) {
13205 pw.println(" Recent tasks:");
13206 printedHeader = true;
13207 printedAnything = true;
13209 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
13212 mRecentTasks.get(i).dump(pw, " ");
13217 if (!printedAnything) {
13218 pw.println(" (nothing)");
13222 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13223 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13224 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13227 if (dumpPackage != null) {
13228 IPackageManager pm = AppGlobals.getPackageManager();
13230 dumpUid = pm.getPackageUid(dumpPackage, 0);
13231 } catch (RemoteException e) {
13235 boolean printedAnything = false;
13237 final long now = SystemClock.uptimeMillis();
13239 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13240 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13241 = mAssociations.valueAt(i1);
13242 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13243 SparseArray<ArrayMap<String, Association>> sourceUids
13244 = targetComponents.valueAt(i2);
13245 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13246 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13247 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13248 Association ass = sourceProcesses.valueAt(i4);
13249 if (dumpPackage != null) {
13250 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13251 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13255 printedAnything = true;
13257 pw.print(ass.mTargetProcess);
13259 UserHandle.formatUid(pw, ass.mTargetUid);
13261 pw.print(ass.mSourceProcess);
13263 UserHandle.formatUid(pw, ass.mSourceUid);
13266 pw.print(ass.mTargetComponent.flattenToShortString());
13269 long dur = ass.mTime;
13270 if (ass.mNesting > 0) {
13271 dur += now - ass.mStartTime;
13273 TimeUtils.formatDuration(dur, pw);
13275 pw.print(ass.mCount);
13276 pw.println(" times)");
13277 if (ass.mNesting > 0) {
13279 pw.print(" Currently active: ");
13280 TimeUtils.formatDuration(now - ass.mStartTime, pw);
13289 if (!printedAnything) {
13290 pw.println(" (nothing)");
13294 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13295 int opti, boolean dumpAll, String dumpPackage) {
13296 boolean needSep = false;
13297 boolean printedAnything = false;
13300 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13303 final int NP = mProcessNames.getMap().size();
13304 for (int ip=0; ip<NP; ip++) {
13305 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13306 final int NA = procs.size();
13307 for (int ia=0; ia<NA; ia++) {
13308 ProcessRecord r = procs.valueAt(ia);
13309 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13313 pw.println(" All known processes:");
13315 printedAnything = true;
13317 pw.print(r.persistent ? " *PERS*" : " *APP*");
13318 pw.print(" UID "); pw.print(procs.keyAt(ia));
13319 pw.print(" "); pw.println(r);
13321 if (r.persistent) {
13328 if (mIsolatedProcesses.size() > 0) {
13329 boolean printed = false;
13330 for (int i=0; i<mIsolatedProcesses.size(); i++) {
13331 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13332 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13339 pw.println(" Isolated process list (sorted by uid):");
13340 printedAnything = true;
13344 pw.println(String.format("%sIsolated #%2d: %s",
13345 " ", i, r.toString()));
13349 if (mActiveUids.size() > 0) {
13353 pw.println(" UID states:");
13354 for (int i=0; i<mActiveUids.size(); i++) {
13355 UidRecord uidRec = mActiveUids.valueAt(i);
13356 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
13357 pw.print(": "); pw.println(uidRec);
13360 printedAnything = true;
13363 if (mLruProcesses.size() > 0) {
13367 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13368 pw.print(" total, non-act at ");
13369 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13370 pw.print(", non-svc at ");
13371 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13373 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
13375 printedAnything = true;
13378 if (dumpAll || dumpPackage != null) {
13379 synchronized (mPidsSelfLocked) {
13380 boolean printed = false;
13381 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13382 ProcessRecord r = mPidsSelfLocked.valueAt(i);
13383 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13387 if (needSep) pw.println();
13389 pw.println(" PID mappings:");
13391 printedAnything = true;
13393 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13394 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13399 if (mForegroundProcesses.size() > 0) {
13400 synchronized (mPidsSelfLocked) {
13401 boolean printed = false;
13402 for (int i=0; i<mForegroundProcesses.size(); i++) {
13403 ProcessRecord r = mPidsSelfLocked.get(
13404 mForegroundProcesses.valueAt(i).pid);
13405 if (dumpPackage != null && (r == null
13406 || !r.pkgList.containsKey(dumpPackage))) {
13410 if (needSep) pw.println();
13412 pw.println(" Foreground Processes:");
13414 printedAnything = true;
13416 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
13417 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13422 if (mPersistentStartingProcesses.size() > 0) {
13423 if (needSep) pw.println();
13425 printedAnything = true;
13426 pw.println(" Persisent processes that are starting:");
13427 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
13428 "Starting Norm", "Restarting PERS", dumpPackage);
13431 if (mRemovedProcesses.size() > 0) {
13432 if (needSep) pw.println();
13434 printedAnything = true;
13435 pw.println(" Processes that are being removed:");
13436 dumpProcessList(pw, this, mRemovedProcesses, " ",
13437 "Removed Norm", "Removed PERS", dumpPackage);
13440 if (mProcessesOnHold.size() > 0) {
13441 if (needSep) pw.println();
13443 printedAnything = true;
13444 pw.println(" Processes that are on old until the system is ready:");
13445 dumpProcessList(pw, this, mProcessesOnHold, " ",
13446 "OnHold Norm", "OnHold PERS", dumpPackage);
13449 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13451 if (mProcessCrashTimes.getMap().size() > 0) {
13452 boolean printed = false;
13453 long now = SystemClock.uptimeMillis();
13454 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13455 final int NP = pmap.size();
13456 for (int ip=0; ip<NP; ip++) {
13457 String pname = pmap.keyAt(ip);
13458 SparseArray<Long> uids = pmap.valueAt(ip);
13459 final int N = uids.size();
13460 for (int i=0; i<N; i++) {
13461 int puid = uids.keyAt(i);
13462 ProcessRecord r = mProcessNames.get(pname, puid);
13463 if (dumpPackage != null && (r == null
13464 || !r.pkgList.containsKey(dumpPackage))) {
13468 if (needSep) pw.println();
13470 pw.println(" Time since processes crashed:");
13472 printedAnything = true;
13474 pw.print(" Process "); pw.print(pname);
13475 pw.print(" uid "); pw.print(puid);
13476 pw.print(": last crashed ");
13477 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13478 pw.println(" ago");
13483 if (mBadProcesses.getMap().size() > 0) {
13484 boolean printed = false;
13485 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13486 final int NP = pmap.size();
13487 for (int ip=0; ip<NP; ip++) {
13488 String pname = pmap.keyAt(ip);
13489 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13490 final int N = uids.size();
13491 for (int i=0; i<N; i++) {
13492 int puid = uids.keyAt(i);
13493 ProcessRecord r = mProcessNames.get(pname, puid);
13494 if (dumpPackage != null && (r == null
13495 || !r.pkgList.containsKey(dumpPackage))) {
13499 if (needSep) pw.println();
13501 pw.println(" Bad processes:");
13502 printedAnything = true;
13504 BadProcessInfo info = uids.valueAt(i);
13505 pw.print(" Bad process "); pw.print(pname);
13506 pw.print(" uid "); pw.print(puid);
13507 pw.print(": crashed at time "); pw.println(info.time);
13508 if (info.shortMsg != null) {
13509 pw.print(" Short msg: "); pw.println(info.shortMsg);
13511 if (info.longMsg != null) {
13512 pw.print(" Long msg: "); pw.println(info.longMsg);
13514 if (info.stack != null) {
13515 pw.println(" Stack:");
13517 for (int pos=0; pos<info.stack.length(); pos++) {
13518 if (info.stack.charAt(pos) == '\n') {
13520 pw.write(info.stack, lastPos, pos-lastPos);
13525 if (lastPos < info.stack.length()) {
13527 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13535 if (dumpPackage == null) {
13538 pw.println(" mStartedUsers:");
13539 for (int i=0; i<mStartedUsers.size(); i++) {
13540 UserState uss = mStartedUsers.valueAt(i);
13541 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
13542 pw.print(": "); uss.dump("", pw);
13544 pw.print(" mStartedUserArray: [");
13545 for (int i=0; i<mStartedUserArray.length; i++) {
13546 if (i > 0) pw.print(", ");
13547 pw.print(mStartedUserArray[i]);
13550 pw.print(" mUserLru: [");
13551 for (int i=0; i<mUserLru.size(); i++) {
13552 if (i > 0) pw.print(", ");
13553 pw.print(mUserLru.get(i));
13557 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13559 synchronized (mUserProfileGroupIdsSelfLocked) {
13560 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13561 pw.println(" mUserProfileGroupIds:");
13562 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13563 pw.print(" User #");
13564 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13565 pw.print(" -> profile #");
13566 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13571 if (mHomeProcess != null && (dumpPackage == null
13572 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13577 pw.println(" mHomeProcess: " + mHomeProcess);
13579 if (mPreviousProcess != null && (dumpPackage == null
13580 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13585 pw.println(" mPreviousProcess: " + mPreviousProcess);
13588 StringBuilder sb = new StringBuilder(128);
13589 sb.append(" mPreviousProcessVisibleTime: ");
13590 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13593 if (mHeavyWeightProcess != null && (dumpPackage == null
13594 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13599 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13601 if (dumpPackage == null) {
13602 pw.println(" mConfiguration: " + mConfiguration);
13605 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13606 if (mCompatModePackages.getPackages().size() > 0) {
13607 boolean printed = false;
13608 for (Map.Entry<String, Integer> entry
13609 : mCompatModePackages.getPackages().entrySet()) {
13610 String pkg = entry.getKey();
13611 int mode = entry.getValue();
13612 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13616 pw.println(" mScreenCompatPackages:");
13619 pw.print(" "); pw.print(pkg); pw.print(": ");
13620 pw.print(mode); pw.println();
13624 if (dumpPackage == null) {
13625 pw.println(" mWakefulness="
13626 + PowerManagerInternal.wakefulnessToString(mWakefulness));
13627 pw.println(" mSleepTokens=" + mSleepTokens);
13628 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
13629 + lockScreenShownToString());
13630 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13631 if (mRunningVoice != null) {
13632 pw.println(" mRunningVoice=" + mRunningVoice);
13633 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
13636 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13637 || mOrigWaitForDebugger) {
13638 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13639 || dumpPackage.equals(mOrigDebugApp)) {
13644 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13645 + " mDebugTransient=" + mDebugTransient
13646 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13649 if (mCurAppTimeTracker != null) {
13650 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
13652 if (mMemWatchProcesses.getMap().size() > 0) {
13653 pw.println(" Mem watch processes:");
13654 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13655 = mMemWatchProcesses.getMap();
13656 for (int i=0; i<procs.size(); i++) {
13657 final String proc = procs.keyAt(i);
13658 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13659 for (int j=0; j<uids.size(); j++) {
13664 StringBuilder sb = new StringBuilder();
13665 sb.append(" ").append(proc).append('/');
13666 UserHandle.formatUid(sb, uids.keyAt(j));
13667 Pair<Long, String> val = uids.valueAt(j);
13668 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13669 if (val.second != null) {
13670 sb.append(", report to ").append(val.second);
13672 pw.println(sb.toString());
13675 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13676 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13677 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13678 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13680 if (mOpenGlTraceApp != null) {
13681 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13686 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
13689 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13690 || mProfileFd != null) {
13691 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13696 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13697 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13698 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13699 + mAutoStopProfiler);
13700 pw.println(" mProfileType=" + mProfileType);
13703 if (dumpPackage == null) {
13704 if (mAlwaysFinishActivities || mController != null) {
13705 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
13706 + " mController=" + mController);
13709 pw.println(" Total persistent processes: " + numPers);
13710 pw.println(" mProcessesReady=" + mProcessesReady
13711 + " mSystemReady=" + mSystemReady
13712 + " mBooted=" + mBooted
13713 + " mFactoryTest=" + mFactoryTest);
13714 pw.println(" mBooting=" + mBooting
13715 + " mCallFinishBooting=" + mCallFinishBooting
13716 + " mBootAnimationComplete=" + mBootAnimationComplete);
13717 pw.print(" mLastPowerCheckRealtime=");
13718 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13720 pw.print(" mLastPowerCheckUptime=");
13721 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13723 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13724 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13725 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13726 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
13727 + " (" + mLruProcesses.size() + " total)"
13728 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13729 + " mNumServiceProcs=" + mNumServiceProcs
13730 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13731 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
13732 + " mLastMemoryLevel" + mLastMemoryLevel
13733 + " mLastNumProcesses" + mLastNumProcesses);
13734 long now = SystemClock.uptimeMillis();
13735 pw.print(" mLastIdleTime=");
13736 TimeUtils.formatDuration(now, mLastIdleTime, pw);
13737 pw.print(" mLowRamSinceLastIdle=");
13738 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13743 if (!printedAnything) {
13744 pw.println(" (nothing)");
13748 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13749 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13750 if (mProcessesToGc.size() > 0) {
13751 boolean printed = false;
13752 long now = SystemClock.uptimeMillis();
13753 for (int i=0; i<mProcessesToGc.size(); i++) {
13754 ProcessRecord proc = mProcessesToGc.get(i);
13755 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13759 if (needSep) pw.println();
13761 pw.println(" Processes that are waiting to GC:");
13764 pw.print(" Process "); pw.println(proc);
13765 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
13766 pw.print(", last gced=");
13767 pw.print(now-proc.lastRequestedGc);
13768 pw.print(" ms ago, last lowMem=");
13769 pw.print(now-proc.lastLowMemory);
13770 pw.println(" ms ago");
13777 void printOomLevel(PrintWriter pw, String name, int adj) {
13781 if (adj < 10) pw.print(' ');
13783 if (adj > -10) pw.print(' ');
13789 pw.print(mProcessList.getMemLevel(adj)/1024);
13790 pw.println(" kB)");
13793 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13794 int opti, boolean dumpAll) {
13795 boolean needSep = false;
13797 if (mLruProcesses.size() > 0) {
13798 if (needSep) pw.println();
13800 pw.println(" OOM levels:");
13801 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13802 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13803 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13804 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13805 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13806 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13807 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13808 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13809 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13810 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13811 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13812 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13813 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13814 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13816 if (needSep) pw.println();
13817 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
13818 pw.print(" total, non-act at ");
13819 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13820 pw.print(", non-svc at ");
13821 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13823 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
13827 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13830 pw.println(" mHomeProcess: " + mHomeProcess);
13831 pw.println(" mPreviousProcess: " + mPreviousProcess);
13832 if (mHeavyWeightProcess != null) {
13833 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13840 * There are three ways to call this:
13841 * - no provider specified: dump all the providers
13842 * - a flattened component name that matched an existing provider was specified as the
13843 * first arg: dump that one provider
13844 * - the first arg isn't the flattened component name of an existing provider:
13845 * dump all providers whose component contains the first arg as a substring
13847 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13848 int opti, boolean dumpAll) {
13849 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13852 static class ItemMatcher {
13853 ArrayList<ComponentName> components;
13854 ArrayList<String> strings;
13855 ArrayList<Integer> objects;
13862 void build(String name) {
13863 ComponentName componentName = ComponentName.unflattenFromString(name);
13864 if (componentName != null) {
13865 if (components == null) {
13866 components = new ArrayList<ComponentName>();
13868 components.add(componentName);
13872 // Not a '/' separated full component name; maybe an object ID?
13874 objectId = Integer.parseInt(name, 16);
13875 if (objects == null) {
13876 objects = new ArrayList<Integer>();
13878 objects.add(objectId);
13880 } catch (RuntimeException e) {
13881 // Not an integer; just do string match.
13882 if (strings == null) {
13883 strings = new ArrayList<String>();
13891 int build(String[] args, int opti) {
13892 for (; opti<args.length; opti++) {
13893 String name = args[opti];
13894 if ("--".equals(name)) {
13902 boolean match(Object object, ComponentName comp) {
13906 if (components != null) {
13907 for (int i=0; i<components.size(); i++) {
13908 if (components.get(i).equals(comp)) {
13913 if (objects != null) {
13914 for (int i=0; i<objects.size(); i++) {
13915 if (System.identityHashCode(object) == objects.get(i)) {
13920 if (strings != null) {
13921 String flat = comp.flattenToString();
13922 for (int i=0; i<strings.size(); i++) {
13923 if (flat.contains(strings.get(i))) {
13933 * There are three things that cmd can be:
13934 * - a flattened component name that matches an existing activity
13935 * - the cmd arg isn't the flattened component name of an existing activity:
13936 * dump all activity whose component contains the cmd as a substring
13937 * - A hex number of the ActivityRecord object instance.
13939 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13940 int opti, boolean dumpAll) {
13941 ArrayList<ActivityRecord> activities;
13943 synchronized (this) {
13944 activities = mStackSupervisor.getDumpActivitiesLocked(name);
13947 if (activities.size() <= 0) {
13951 String[] newArgs = new String[args.length - opti];
13952 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13954 TaskRecord lastTask = null;
13955 boolean needSep = false;
13956 for (int i=activities.size()-1; i>=0; i--) {
13957 ActivityRecord r = activities.get(i);
13962 synchronized (this) {
13963 if (lastTask != r.task) {
13965 pw.print("TASK "); pw.print(lastTask.affinity);
13966 pw.print(" id="); pw.println(lastTask.taskId);
13968 lastTask.dump(pw, " ");
13972 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
13978 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
13979 * there is a thread associated with the activity.
13981 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
13982 final ActivityRecord r, String[] args, boolean dumpAll) {
13983 String innerPrefix = prefix + " ";
13984 synchronized (this) {
13985 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
13986 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
13988 if (r.app != null) pw.println(r.app.pid);
13989 else pw.println("(not running)");
13991 r.dump(pw, innerPrefix);
13994 if (r.app != null && r.app.thread != null) {
13995 // flush anything that is already in the PrintWriter since the thread is going
13996 // to write to the file descriptor directly
13999 TransferPipe tp = new TransferPipe();
14001 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14002 r.appToken, innerPrefix, args);
14007 } catch (IOException e) {
14008 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14009 } catch (RemoteException e) {
14010 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14015 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14016 int opti, boolean dumpAll, String dumpPackage) {
14017 boolean needSep = false;
14018 boolean onlyHistory = false;
14019 boolean printedAnything = false;
14021 if ("history".equals(dumpPackage)) {
14022 if (opti < args.length && "-s".equals(args[opti])) {
14025 onlyHistory = true;
14026 dumpPackage = null;
14029 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14030 if (!onlyHistory && dumpAll) {
14031 if (mRegisteredReceivers.size() > 0) {
14032 boolean printed = false;
14033 Iterator it = mRegisteredReceivers.values().iterator();
14034 while (it.hasNext()) {
14035 ReceiverList r = (ReceiverList)it.next();
14036 if (dumpPackage != null && (r.app == null ||
14037 !dumpPackage.equals(r.app.info.packageName))) {
14041 pw.println(" Registered Receivers:");
14044 printedAnything = true;
14046 pw.print(" * "); pw.println(r);
14051 if (mReceiverResolver.dump(pw, needSep ?
14052 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
14053 " ", dumpPackage, false, false)) {
14055 printedAnything = true;
14059 for (BroadcastQueue q : mBroadcastQueues) {
14060 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14061 printedAnything |= needSep;
14066 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14067 for (int user=0; user<mStickyBroadcasts.size(); user++) {
14072 printedAnything = true;
14073 pw.print(" Sticky broadcasts for user ");
14074 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14075 StringBuilder sb = new StringBuilder(128);
14076 for (Map.Entry<String, ArrayList<Intent>> ent
14077 : mStickyBroadcasts.valueAt(user).entrySet()) {
14078 pw.print(" * Sticky action "); pw.print(ent.getKey());
14081 ArrayList<Intent> intents = ent.getValue();
14082 final int N = intents.size();
14083 for (int i=0; i<N; i++) {
14085 sb.append(" Intent: ");
14086 intents.get(i).toShortString(sb, false, true, false, false);
14087 pw.println(sb.toString());
14088 Bundle bundle = intents.get(i).getExtras();
14089 if (bundle != null) {
14091 pw.println(bundle.toString());
14101 if (!onlyHistory && dumpAll) {
14103 for (BroadcastQueue queue : mBroadcastQueues) {
14104 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
14105 + queue.mBroadcastsScheduled);
14107 pw.println(" mHandler:");
14108 mHandler.dump(new PrintWriterPrinter(pw), " ");
14110 printedAnything = true;
14113 if (!printedAnything) {
14114 pw.println(" (nothing)");
14118 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14119 int opti, boolean dumpAll, String dumpPackage) {
14121 boolean printedAnything = false;
14123 ItemMatcher matcher = new ItemMatcher();
14124 matcher.build(args, opti);
14126 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14128 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14129 printedAnything |= needSep;
14131 if (mLaunchingProviders.size() > 0) {
14132 boolean printed = false;
14133 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14134 ContentProviderRecord r = mLaunchingProviders.get(i);
14135 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14139 if (needSep) pw.println();
14141 pw.println(" Launching content providers:");
14143 printedAnything = true;
14145 pw.print(" Launching #"); pw.print(i); pw.print(": ");
14150 if (!printedAnything) {
14151 pw.println(" (nothing)");
14155 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14156 int opti, boolean dumpAll, String dumpPackage) {
14157 boolean needSep = false;
14158 boolean printedAnything = false;
14160 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14162 if (mGrantedUriPermissions.size() > 0) {
14163 boolean printed = false;
14165 if (dumpPackage != null) {
14167 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14168 } catch (NameNotFoundException e) {
14172 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14173 int uid = mGrantedUriPermissions.keyAt(i);
14174 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14177 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14179 if (needSep) pw.println();
14181 pw.println(" Granted Uri Permissions:");
14183 printedAnything = true;
14185 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
14186 for (UriPermission perm : perms.values()) {
14187 pw.print(" "); pw.println(perm);
14189 perm.dump(pw, " ");
14195 if (!printedAnything) {
14196 pw.println(" (nothing)");
14200 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14201 int opti, boolean dumpAll, String dumpPackage) {
14202 boolean printed = false;
14204 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14206 if (mIntentSenderRecords.size() > 0) {
14207 Iterator<WeakReference<PendingIntentRecord>> it
14208 = mIntentSenderRecords.values().iterator();
14209 while (it.hasNext()) {
14210 WeakReference<PendingIntentRecord> ref = it.next();
14211 PendingIntentRecord rec = ref != null ? ref.get(): null;
14212 if (dumpPackage != null && (rec == null
14213 || !dumpPackage.equals(rec.key.packageName))) {
14218 pw.print(" * "); pw.println(rec);
14223 pw.print(" * "); pw.println(ref);
14229 pw.println(" (nothing)");
14233 private static final int dumpProcessList(PrintWriter pw,
14234 ActivityManagerService service, List list,
14235 String prefix, String normalLabel, String persistentLabel,
14236 String dumpPackage) {
14238 final int N = list.size()-1;
14239 for (int i=N; i>=0; i--) {
14240 ProcessRecord r = (ProcessRecord)list.get(i);
14241 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14244 pw.println(String.format("%s%s #%2d: %s",
14245 prefix, (r.persistent ? persistentLabel : normalLabel),
14247 if (r.persistent) {
14254 private static final boolean dumpProcessOomList(PrintWriter pw,
14255 ActivityManagerService service, List<ProcessRecord> origList,
14256 String prefix, String normalLabel, String persistentLabel,
14257 boolean inclDetails, String dumpPackage) {
14259 ArrayList<Pair<ProcessRecord, Integer>> list
14260 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14261 for (int i=0; i<origList.size(); i++) {
14262 ProcessRecord r = origList.get(i);
14263 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14266 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14269 if (list.size() <= 0) {
14273 Comparator<Pair<ProcessRecord, Integer>> comparator
14274 = new Comparator<Pair<ProcessRecord, Integer>>() {
14276 public int compare(Pair<ProcessRecord, Integer> object1,
14277 Pair<ProcessRecord, Integer> object2) {
14278 if (object1.first.setAdj != object2.first.setAdj) {
14279 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14281 if (object1.second.intValue() != object2.second.intValue()) {
14282 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14288 Collections.sort(list, comparator);
14290 final long curRealtime = SystemClock.elapsedRealtime();
14291 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14292 final long curUptime = SystemClock.uptimeMillis();
14293 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14295 for (int i=list.size()-1; i>=0; i--) {
14296 ProcessRecord r = list.get(i).first;
14297 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14299 switch (r.setSchedGroup) {
14300 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14303 case Process.THREAD_GROUP_DEFAULT:
14311 if (r.foregroundActivities) {
14313 } else if (r.foregroundServices) {
14318 String procState = ProcessList.makeProcStateString(r.curProcState);
14320 pw.print(r.persistent ? persistentLabel : normalLabel);
14322 int num = (origList.size()-1)-list.get(i).second;
14323 if (num < 10) pw.print(' ');
14328 pw.print(schedGroup);
14330 pw.print(foreground);
14332 pw.print(procState);
14334 if (r.trimMemoryLevel < 10) pw.print(' ');
14335 pw.print(r.trimMemoryLevel);
14337 pw.print(r.toShortString());
14339 pw.print(r.adjType);
14341 if (r.adjSource != null || r.adjTarget != null) {
14344 if (r.adjTarget instanceof ComponentName) {
14345 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14346 } else if (r.adjTarget != null) {
14347 pw.print(r.adjTarget.toString());
14349 pw.print("{null}");
14352 if (r.adjSource instanceof ProcessRecord) {
14354 pw.print(((ProcessRecord)r.adjSource).toShortString());
14356 } else if (r.adjSource != null) {
14357 pw.println(r.adjSource.toString());
14359 pw.println("{null}");
14365 pw.print("oom: max="); pw.print(r.maxAdj);
14366 pw.print(" curRaw="); pw.print(r.curRawAdj);
14367 pw.print(" setRaw="); pw.print(r.setRawAdj);
14368 pw.print(" cur="); pw.print(r.curAdj);
14369 pw.print(" set="); pw.println(r.setAdj);
14372 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14373 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14374 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14375 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14379 pw.print("cached="); pw.print(r.cached);
14380 pw.print(" empty="); pw.print(r.empty);
14381 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14383 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14384 if (r.lastWakeTime != 0) {
14386 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14387 synchronized (stats) {
14388 wtime = stats.getProcessWakeTime(r.info.uid,
14389 r.pid, curRealtime);
14391 long timeUsed = wtime - r.lastWakeTime;
14394 pw.print("keep awake over ");
14395 TimeUtils.formatDuration(realtimeSince, pw);
14396 pw.print(" used ");
14397 TimeUtils.formatDuration(timeUsed, pw);
14399 pw.print((timeUsed*100)/realtimeSince);
14402 if (r.lastCpuTime != 0) {
14403 long timeUsed = r.curCpuTime - r.lastCpuTime;
14406 pw.print("run cpu over ");
14407 TimeUtils.formatDuration(uptimeSince, pw);
14408 pw.print(" used ");
14409 TimeUtils.formatDuration(timeUsed, pw);
14411 pw.print((timeUsed*100)/uptimeSince);
14420 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14422 ArrayList<ProcessRecord> procs;
14423 synchronized (this) {
14424 if (args != null && args.length > start
14425 && args[start].charAt(0) != '-') {
14426 procs = new ArrayList<ProcessRecord>();
14429 pid = Integer.parseInt(args[start]);
14430 } catch (NumberFormatException e) {
14432 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14433 ProcessRecord proc = mLruProcesses.get(i);
14434 if (proc.pid == pid) {
14436 } else if (allPkgs && proc.pkgList != null
14437 && proc.pkgList.containsKey(args[start])) {
14439 } else if (proc.processName.equals(args[start])) {
14443 if (procs.size() <= 0) {
14447 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14453 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14454 PrintWriter pw, String[] args) {
14455 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14456 if (procs == null) {
14457 pw.println("No process found for: " + args[0]);
14461 long uptime = SystemClock.uptimeMillis();
14462 long realtime = SystemClock.elapsedRealtime();
14463 pw.println("Applications Graphics Acceleration Info:");
14464 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14466 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14467 ProcessRecord r = procs.get(i);
14468 if (r.thread != null) {
14469 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14472 TransferPipe tp = new TransferPipe();
14474 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14479 } catch (IOException e) {
14480 pw.println("Failure while dumping the app: " + r);
14482 } catch (RemoteException e) {
14483 pw.println("Got a RemoteException while dumping the app " + r);
14490 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14491 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14492 if (procs == null) {
14493 pw.println("No process found for: " + args[0]);
14497 pw.println("Applications Database Info:");
14499 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14500 ProcessRecord r = procs.get(i);
14501 if (r.thread != null) {
14502 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14505 TransferPipe tp = new TransferPipe();
14507 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14512 } catch (IOException e) {
14513 pw.println("Failure while dumping the app: " + r);
14515 } catch (RemoteException e) {
14516 pw.println("Got a RemoteException while dumping the app " + r);
14523 final static class MemItem {
14524 final boolean isProc;
14525 final String label;
14526 final String shortLabel;
14529 final boolean hasActivities;
14530 ArrayList<MemItem> subitems;
14532 public MemItem(String _label, String _shortLabel, long _pss, int _id,
14533 boolean _hasActivities) {
14536 shortLabel = _shortLabel;
14539 hasActivities = _hasActivities;
14542 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14545 shortLabel = _shortLabel;
14548 hasActivities = false;
14552 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14553 ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14554 if (sort && !isCompact) {
14555 Collections.sort(items, new Comparator<MemItem>() {
14557 public int compare(MemItem lhs, MemItem rhs) {
14558 if (lhs.pss < rhs.pss) {
14560 } else if (lhs.pss > rhs.pss) {
14568 for (int i=0; i<items.size(); i++) {
14569 MemItem mi = items.get(i);
14571 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14572 } else if (mi.isProc) {
14573 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14574 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14575 pw.println(mi.hasActivities ? ",a" : ",e");
14577 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14578 pw.println(mi.pss);
14580 if (mi.subitems != null) {
14581 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
14587 // These are in KB.
14588 static final long[] DUMP_MEM_BUCKETS = new long[] {
14589 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14590 120*1024, 160*1024, 200*1024,
14591 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14592 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14595 static final void appendMemBucket(StringBuilder out, long memKB, String label,
14596 boolean stackLike) {
14597 int start = label.lastIndexOf('.');
14598 if (start >= 0) start++;
14600 int end = label.length();
14601 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14602 if (DUMP_MEM_BUCKETS[i] >= memKB) {
14603 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14604 out.append(bucket);
14605 out.append(stackLike ? "MB." : "MB ");
14606 out.append(label, start, end);
14610 out.append(memKB/1024);
14611 out.append(stackLike ? "MB." : "MB ");
14612 out.append(label, start, end);
14615 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14616 ProcessList.NATIVE_ADJ,
14617 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14618 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14619 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14620 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14621 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14622 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14624 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14626 "System", "Persistent", "Persistent Service", "Foreground",
14627 "Visible", "Perceptible",
14628 "Heavy Weight", "Backup",
14629 "A Services", "Home",
14630 "Previous", "B Services", "Cached"
14632 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14634 "sys", "pers", "persvc", "fore",
14637 "servicea", "home",
14638 "prev", "serviceb", "cached"
14641 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14642 long realtime, boolean isCheckinRequest, boolean isCompact) {
14643 if (isCheckinRequest || isCompact) {
14644 // short checkin version
14645 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14647 pw.println("Applications Memory Usage (kB):");
14648 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14652 private static final int KSM_SHARED = 0;
14653 private static final int KSM_SHARING = 1;
14654 private static final int KSM_UNSHARED = 2;
14655 private static final int KSM_VOLATILE = 3;
14657 private final long[] getKsmInfo() {
14658 long[] longOut = new long[4];
14659 final int[] SINGLE_LONG_FORMAT = new int[] {
14660 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14662 long[] longTmp = new long[1];
14663 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14664 SINGLE_LONG_FORMAT, null, longTmp, null);
14665 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14667 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14668 SINGLE_LONG_FORMAT, null, longTmp, null);
14669 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14671 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14672 SINGLE_LONG_FORMAT, null, longTmp, null);
14673 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14675 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14676 SINGLE_LONG_FORMAT, null, longTmp, null);
14677 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14681 final void dumpApplicationMemoryUsage(FileDescriptor fd,
14682 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14683 boolean dumpDetails = false;
14684 boolean dumpFullDetails = false;
14685 boolean dumpDalvik = false;
14686 boolean dumpSummaryOnly = false;
14687 boolean oomOnly = false;
14688 boolean isCompact = false;
14689 boolean localOnly = false;
14690 boolean packages = false;
14693 while (opti < args.length) {
14694 String opt = args[opti];
14695 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14699 if ("-a".equals(opt)) {
14700 dumpDetails = true;
14701 dumpFullDetails = true;
14703 } else if ("-d".equals(opt)) {
14705 } else if ("-c".equals(opt)) {
14707 } else if ("-s".equals(opt)) {
14708 dumpDetails = true;
14709 dumpSummaryOnly = true;
14710 } else if ("--oom".equals(opt)) {
14712 } else if ("--local".equals(opt)) {
14714 } else if ("--package".equals(opt)) {
14716 } else if ("-h".equals(opt)) {
14717 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14718 pw.println(" -a: include all available information for each process.");
14719 pw.println(" -d: include dalvik details.");
14720 pw.println(" -c: dump in a compact machine-parseable representation.");
14721 pw.println(" -s: dump only summary of application memory usage.");
14722 pw.println(" --oom: only show processes organized by oom adj.");
14723 pw.println(" --local: only collect details locally, don't call process.");
14724 pw.println(" --package: interpret process arg as package, dumping all");
14725 pw.println(" processes that have loaded that package.");
14726 pw.println("If [process] is specified it can be the name or ");
14727 pw.println("pid of a specific process to dump.");
14730 pw.println("Unknown argument: " + opt + "; use -h for help");
14734 final boolean isCheckinRequest = scanArgs(args, "--checkin");
14735 long uptime = SystemClock.uptimeMillis();
14736 long realtime = SystemClock.elapsedRealtime();
14737 final long[] tmpLong = new long[1];
14739 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14740 if (procs == null) {
14741 // No Java processes. Maybe they want to print a native process.
14742 if (args != null && args.length > opti
14743 && args[opti].charAt(0) != '-') {
14744 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14745 = new ArrayList<ProcessCpuTracker.Stats>();
14746 updateCpuStatsNow();
14749 findPid = Integer.parseInt(args[opti]);
14750 } catch (NumberFormatException e) {
14752 synchronized (mProcessCpuTracker) {
14753 final int N = mProcessCpuTracker.countStats();
14754 for (int i=0; i<N; i++) {
14755 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14756 if (st.pid == findPid || (st.baseName != null
14757 && st.baseName.equals(args[opti]))) {
14758 nativeProcs.add(st);
14762 if (nativeProcs.size() > 0) {
14763 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14765 Debug.MemoryInfo mi = null;
14766 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14767 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14768 final int pid = r.pid;
14769 if (!isCheckinRequest && dumpDetails) {
14770 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14773 mi = new Debug.MemoryInfo();
14775 if (dumpDetails || (!brief && !oomOnly)) {
14776 Debug.getMemoryInfo(pid, mi);
14778 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14779 mi.dalvikPrivateDirty = (int)tmpLong[0];
14781 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14782 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14783 if (isCheckinRequest) {
14790 pw.println("No process found for: " + args[opti]);
14794 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14795 dumpDetails = true;
14798 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14800 String[] innerArgs = new String[args.length-opti];
14801 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14803 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14804 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14805 long nativePss = 0;
14806 long dalvikPss = 0;
14807 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14810 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14812 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14813 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14814 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14817 long cachedPss = 0;
14819 Debug.MemoryInfo mi = null;
14820 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14821 final ProcessRecord r = procs.get(i);
14822 final IApplicationThread thread;
14825 final boolean hasActivities;
14826 synchronized (this) {
14829 oomAdj = r.getSetAdjWithServices();
14830 hasActivities = r.activities.size() > 0;
14832 if (thread != null) {
14833 if (!isCheckinRequest && dumpDetails) {
14834 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14837 mi = new Debug.MemoryInfo();
14839 if (dumpDetails || (!brief && !oomOnly)) {
14840 Debug.getMemoryInfo(pid, mi);
14842 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14843 mi.dalvikPrivateDirty = (int)tmpLong[0];
14847 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14848 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14849 if (isCheckinRequest) {
14855 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14856 dumpDalvik, dumpSummaryOnly, innerArgs);
14857 } catch (RemoteException e) {
14858 if (!isCheckinRequest) {
14859 pw.println("Got RemoteException!");
14866 final long myTotalPss = mi.getTotalPss();
14867 final long myTotalUss = mi.getTotalUss();
14869 synchronized (this) {
14870 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14871 // Record this for posterity if the process has been stable.
14872 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14876 if (!isCheckinRequest && mi != null) {
14877 totalPss += myTotalPss;
14878 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14879 (hasActivities ? " / activities)" : ")"),
14880 r.processName, myTotalPss, pid, hasActivities);
14881 procMems.add(pssItem);
14882 procMemsMap.put(pid, pssItem);
14884 nativePss += mi.nativePss;
14885 dalvikPss += mi.dalvikPss;
14886 for (int j=0; j<dalvikSubitemPss.length; j++) {
14887 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14889 otherPss += mi.otherPss;
14890 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14891 long mem = mi.getOtherPss(j);
14896 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14897 cachedPss += myTotalPss;
14900 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14901 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14902 || oomIndex == (oomPss.length-1)) {
14903 oomPss[oomIndex] += myTotalPss;
14904 if (oomProcs[oomIndex] == null) {
14905 oomProcs[oomIndex] = new ArrayList<MemItem>();
14907 oomProcs[oomIndex].add(pssItem);
14915 long nativeProcTotalPss = 0;
14917 if (!isCheckinRequest && procs.size() > 1 && !packages) {
14918 // If we are showing aggregations, also look for native processes to
14919 // include so that our aggregations are more accurate.
14920 updateCpuStatsNow();
14922 synchronized (mProcessCpuTracker) {
14923 final int N = mProcessCpuTracker.countStats();
14924 for (int i=0; i<N; i++) {
14925 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14926 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
14928 mi = new Debug.MemoryInfo();
14930 if (!brief && !oomOnly) {
14931 Debug.getMemoryInfo(st.pid, mi);
14933 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
14934 mi.nativePrivateDirty = (int)tmpLong[0];
14937 final long myTotalPss = mi.getTotalPss();
14938 totalPss += myTotalPss;
14939 nativeProcTotalPss += myTotalPss;
14941 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
14942 st.name, myTotalPss, st.pid, false);
14943 procMems.add(pssItem);
14945 nativePss += mi.nativePss;
14946 dalvikPss += mi.dalvikPss;
14947 for (int j=0; j<dalvikSubitemPss.length; j++) {
14948 dalvikSubitemPss[j] += mi.getOtherPss(
14949 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14951 otherPss += mi.otherPss;
14952 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14953 long mem = mi.getOtherPss(j);
14957 oomPss[0] += myTotalPss;
14958 if (oomProcs[0] == null) {
14959 oomProcs[0] = new ArrayList<MemItem>();
14961 oomProcs[0].add(pssItem);
14966 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
14968 catMems.add(new MemItem("Native", "Native", nativePss, -1));
14969 final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
14970 if (dalvikSubitemPss.length > 0) {
14971 dalvikItem.subitems = new ArrayList<MemItem>();
14972 for (int j=0; j<dalvikSubitemPss.length; j++) {
14973 final String name = Debug.MemoryInfo.getOtherLabel(
14974 Debug.MemoryInfo.NUM_OTHER_STATS + j);
14975 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
14978 catMems.add(dalvikItem);
14979 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
14980 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14981 String label = Debug.MemoryInfo.getOtherLabel(j);
14982 catMems.add(new MemItem(label, label, miscPss[j], j));
14985 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
14986 for (int j=0; j<oomPss.length; j++) {
14987 if (oomPss[j] != 0) {
14988 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
14989 : DUMP_MEM_OOM_LABEL[j];
14990 MemItem item = new MemItem(label, label, oomPss[j],
14991 DUMP_MEM_OOM_ADJ[j]);
14992 item.subitems = oomProcs[j];
14997 if (!brief && !oomOnly && !isCompact) {
14999 pw.println("Total PSS by process:");
15000 dumpMemItems(pw, " ", "proc", procMems, true, isCompact);
15004 pw.println("Total PSS by OOM adjustment:");
15006 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact);
15007 if (!brief && !oomOnly) {
15008 PrintWriter out = categoryPw != null ? categoryPw : pw;
15011 out.println("Total PSS by category:");
15013 dumpMemItems(out, " ", "cat", catMems, true, isCompact);
15018 MemInfoReader memInfo = new MemInfoReader();
15019 memInfo.readMemInfo();
15020 if (nativeProcTotalPss > 0) {
15021 synchronized (this) {
15022 final long cachedKb = memInfo.getCachedSizeKb();
15023 final long freeKb = memInfo.getFreeSizeKb();
15024 final long zramKb = memInfo.getZramTotalSizeKb();
15025 final long kernelKb = memInfo.getKernelUsedSizeKb();
15026 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15027 kernelKb*1024, nativeProcTotalPss*1024);
15028 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15029 nativeProcTotalPss);
15034 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
15035 pw.print(" kB (status ");
15036 switch (mLastMemoryLevel) {
15037 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15038 pw.println("normal)");
15040 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15041 pw.println("moderate)");
15043 case ProcessStats.ADJ_MEM_FACTOR_LOW:
15044 pw.println("low)");
15046 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15047 pw.println("critical)");
15050 pw.print(mLastMemoryLevel);
15054 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
15055 + memInfo.getFreeSizeKb()); pw.print(" kB (");
15056 pw.print(cachedPss); pw.print(" cached pss + ");
15057 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
15058 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
15060 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15061 pw.print(cachedPss + memInfo.getCachedSizeKb()
15062 + memInfo.getFreeSizeKb()); pw.print(",");
15063 pw.println(totalPss - cachedPss);
15067 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15068 + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15069 pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15070 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15071 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15072 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15073 - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15076 if (memInfo.getZramTotalSizeKb() != 0) {
15078 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15079 pw.print(" kB physical used for ");
15080 pw.print(memInfo.getSwapTotalSizeKb()
15081 - memInfo.getSwapFreeSizeKb());
15082 pw.print(" kB in swap (");
15083 pw.print(memInfo.getSwapTotalSizeKb());
15084 pw.println(" kB total swap)");
15086 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15087 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15088 pw.println(memInfo.getSwapFreeSizeKb());
15091 final long[] ksm = getKsmInfo();
15093 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15094 || ksm[KSM_VOLATILE] != 0) {
15095 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]);
15096 pw.print(" kB saved from shared ");
15097 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15098 pw.print(" "); pw.print(ksm[KSM_UNSHARED]);
15099 pw.print(" kB unshared; ");
15100 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15102 pw.print(" Tuning: ");
15103 pw.print(ActivityManager.staticGetMemoryClass());
15104 pw.print(" (large ");
15105 pw.print(ActivityManager.staticGetLargeMemoryClass());
15106 pw.print("), oom ");
15107 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15109 pw.print(", restore limit ");
15110 pw.print(mProcessList.getCachedRestoreThresholdKb());
15112 if (ActivityManager.isLowRamDeviceStatic()) {
15113 pw.print(" (low-ram)");
15115 if (ActivityManager.isHighEndGfx()) {
15116 pw.print(" (high-end-gfx)");
15120 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15121 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15122 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15123 pw.print("tuning,");
15124 pw.print(ActivityManager.staticGetMemoryClass());
15126 pw.print(ActivityManager.staticGetLargeMemoryClass());
15128 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15129 if (ActivityManager.isLowRamDeviceStatic()) {
15130 pw.print(",low-ram");
15132 if (ActivityManager.isHighEndGfx()) {
15133 pw.print(",high-end-gfx");
15141 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15142 long memtrack, String name) {
15144 sb.append(ProcessList.makeOomAdjString(oomAdj));
15146 sb.append(ProcessList.makeProcStateString(procState));
15148 ProcessList.appendRamKb(sb, pss);
15149 sb.append(" kB: ");
15151 if (memtrack > 0) {
15153 sb.append(memtrack);
15154 sb.append(" kB memtrack)");
15158 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15159 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15160 sb.append(" (pid ");
15163 sb.append(mi.adjType);
15165 if (mi.adjReason != null) {
15167 sb.append(mi.adjReason);
15172 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15173 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15174 for (int i=0, N=memInfos.size(); i<N; i++) {
15175 ProcessMemInfo mi = memInfos.get(i);
15176 infoMap.put(mi.pid, mi);
15178 updateCpuStatsNow();
15179 long[] memtrackTmp = new long[1];
15180 synchronized (mProcessCpuTracker) {
15181 final int N = mProcessCpuTracker.countStats();
15182 for (int i=0; i<N; i++) {
15183 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15184 if (st.vsize > 0) {
15185 long pss = Debug.getPss(st.pid, null, memtrackTmp);
15187 if (infoMap.indexOfKey(st.pid) < 0) {
15188 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15189 ProcessList.NATIVE_ADJ, -1, "native", null);
15191 mi.memtrack = memtrackTmp[0];
15200 long totalMemtrack = 0;
15201 for (int i=0, N=memInfos.size(); i<N; i++) {
15202 ProcessMemInfo mi = memInfos.get(i);
15204 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15205 mi.memtrack = memtrackTmp[0];
15207 totalPss += mi.pss;
15208 totalMemtrack += mi.memtrack;
15210 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15211 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15212 if (lhs.oomAdj != rhs.oomAdj) {
15213 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15215 if (lhs.pss != rhs.pss) {
15216 return lhs.pss < rhs.pss ? 1 : -1;
15222 StringBuilder tag = new StringBuilder(128);
15223 StringBuilder stack = new StringBuilder(128);
15224 tag.append("Low on memory -- ");
15225 appendMemBucket(tag, totalPss, "total", false);
15226 appendMemBucket(stack, totalPss, "total", true);
15228 StringBuilder fullNativeBuilder = new StringBuilder(1024);
15229 StringBuilder shortNativeBuilder = new StringBuilder(1024);
15230 StringBuilder fullJavaBuilder = new StringBuilder(1024);
15232 boolean firstLine = true;
15233 int lastOomAdj = Integer.MIN_VALUE;
15234 long extraNativeRam = 0;
15235 long extraNativeMemtrack = 0;
15236 long cachedPss = 0;
15237 for (int i=0, N=memInfos.size(); i<N; i++) {
15238 ProcessMemInfo mi = memInfos.get(i);
15240 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15241 cachedPss += mi.pss;
15244 if (mi.oomAdj != ProcessList.NATIVE_ADJ
15245 && (mi.oomAdj < ProcessList.SERVICE_ADJ
15246 || mi.oomAdj == ProcessList.HOME_APP_ADJ
15247 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15248 if (lastOomAdj != mi.oomAdj) {
15249 lastOomAdj = mi.oomAdj;
15250 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15253 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15258 stack.append("\n\t at ");
15266 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15267 appendMemBucket(tag, mi.pss, mi.name, false);
15269 appendMemBucket(stack, mi.pss, mi.name, true);
15270 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15271 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15273 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15274 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15275 stack.append(DUMP_MEM_OOM_LABEL[k]);
15277 stack.append(DUMP_MEM_OOM_ADJ[k]);
15284 appendMemInfo(fullNativeBuilder, mi);
15285 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15286 // The short form only has native processes that are >= 512K.
15287 if (mi.pss >= 512) {
15288 appendMemInfo(shortNativeBuilder, mi);
15290 extraNativeRam += mi.pss;
15291 extraNativeMemtrack += mi.memtrack;
15294 // Short form has all other details, but if we have collected RAM
15295 // from smaller native processes let's dump a summary of that.
15296 if (extraNativeRam > 0) {
15297 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15298 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15299 shortNativeBuilder.append('\n');
15300 extraNativeRam = 0;
15302 appendMemInfo(fullJavaBuilder, mi);
15306 fullJavaBuilder.append(" ");
15307 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15308 fullJavaBuilder.append(" kB: TOTAL");
15309 if (totalMemtrack > 0) {
15310 fullJavaBuilder.append(" (");
15311 fullJavaBuilder.append(totalMemtrack);
15312 fullJavaBuilder.append(" kB memtrack)");
15315 fullJavaBuilder.append("\n");
15317 MemInfoReader memInfo = new MemInfoReader();
15318 memInfo.readMemInfo();
15319 final long[] infos = memInfo.getRawInfo();
15321 StringBuilder memInfoBuilder = new StringBuilder(1024);
15322 Debug.getMemInfo(infos);
15323 memInfoBuilder.append(" MemInfo: ");
15324 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15325 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15326 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15327 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15328 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15329 memInfoBuilder.append(" ");
15330 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15331 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15332 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15333 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15334 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15335 memInfoBuilder.append(" ZRAM: ");
15336 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15337 memInfoBuilder.append(" kB RAM, ");
15338 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15339 memInfoBuilder.append(" kB swap total, ");
15340 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15341 memInfoBuilder.append(" kB swap free\n");
15343 final long[] ksm = getKsmInfo();
15344 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15345 || ksm[KSM_VOLATILE] != 0) {
15346 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15347 memInfoBuilder.append(" kB saved from shared ");
15348 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15349 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15350 memInfoBuilder.append(" kB unshared; ");
15351 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15353 memInfoBuilder.append(" Free RAM: ");
15354 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15355 + memInfo.getFreeSizeKb());
15356 memInfoBuilder.append(" kB\n");
15357 memInfoBuilder.append(" Used RAM: ");
15358 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15359 memInfoBuilder.append(" kB\n");
15360 memInfoBuilder.append(" Lost RAM: ");
15361 memInfoBuilder.append(memInfo.getTotalSizeKb()
15362 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15363 - memInfo.getKernelUsedSizeKb());
15364 memInfoBuilder.append(" kB\n");
15365 Slog.i(TAG, "Low on memory:");
15366 Slog.i(TAG, shortNativeBuilder.toString());
15367 Slog.i(TAG, fullJavaBuilder.toString());
15368 Slog.i(TAG, memInfoBuilder.toString());
15370 StringBuilder dropBuilder = new StringBuilder(1024);
15372 StringWriter oomSw = new StringWriter();
15373 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15374 StringWriter catSw = new StringWriter();
15375 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15376 String[] emptyArgs = new String[] { };
15377 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
15379 String oomString = oomSw.toString();
15381 dropBuilder.append("Low on memory:");
15382 dropBuilder.append(stack);
15383 dropBuilder.append('\n');
15384 dropBuilder.append(fullNativeBuilder);
15385 dropBuilder.append(fullJavaBuilder);
15386 dropBuilder.append('\n');
15387 dropBuilder.append(memInfoBuilder);
15388 dropBuilder.append('\n');
15390 dropBuilder.append(oomString);
15391 dropBuilder.append('\n');
15393 StringWriter catSw = new StringWriter();
15394 synchronized (ActivityManagerService.this) {
15395 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15396 String[] emptyArgs = new String[] { };
15398 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15400 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15401 false, false, null);
15403 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15406 dropBuilder.append(catSw.toString());
15407 addErrorToDropBox("lowmem", null, "system_server", null,
15408 null, tag.toString(), dropBuilder.toString(), null, null);
15409 //Slog.i(TAG, "Sent to dropbox:");
15410 //Slog.i(TAG, dropBuilder.toString());
15411 synchronized (ActivityManagerService.this) {
15412 long now = SystemClock.uptimeMillis();
15413 if (mLastMemUsageReportTime < now) {
15414 mLastMemUsageReportTime = now;
15420 * Searches array of arguments for the specified string
15421 * @param args array of argument strings
15422 * @param value value to search for
15423 * @return true if the value is contained in the array
15425 private static boolean scanArgs(String[] args, String value) {
15426 if (args != null) {
15427 for (String arg : args) {
15428 if (value.equals(arg)) {
15436 private final boolean removeDyingProviderLocked(ProcessRecord proc,
15437 ContentProviderRecord cpr, boolean always) {
15438 final boolean inLaunching = mLaunchingProviders.contains(cpr);
15440 if (!inLaunching || always) {
15441 synchronized (cpr) {
15442 cpr.launchingApp = null;
15445 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15446 String names[] = cpr.info.authority.split(";");
15447 for (int j = 0; j < names.length; j++) {
15448 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15452 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15453 ContentProviderConnection conn = cpr.connections.get(i);
15454 if (conn.waiting) {
15455 // If this connection is waiting for the provider, then we don't
15456 // need to mess with its process unless we are always removing
15457 // or for some reason the provider is not currently launching.
15458 if (inLaunching && !always) {
15462 ProcessRecord capp = conn.client;
15464 if (conn.stableCount > 0) {
15465 if (!capp.persistent && capp.thread != null
15467 && capp.pid != MY_PID) {
15468 capp.kill("depends on provider "
15469 + cpr.name.flattenToShortString()
15470 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15472 } else if (capp.thread != null && conn.provider.provider != null) {
15474 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15475 } catch (RemoteException e) {
15477 // In the protocol here, we don't expect the client to correctly
15478 // clean up this connection, we'll just remove it.
15479 cpr.connections.remove(i);
15480 if (conn.client.conProviders.remove(conn)) {
15481 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15486 if (inLaunching && always) {
15487 mLaunchingProviders.remove(cpr);
15489 return inLaunching;
15493 * Main code for cleaning up a process when it has gone away. This is
15494 * called both as a result of the process dying, or directly when stopping
15495 * a process when running in single process mode.
15497 * @return Returns true if the given process has been restarted, so the
15498 * app that was passed in must remain on the process lists.
15500 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15501 boolean restarting, boolean allowRestart, int index) {
15503 removeLruProcessLocked(app);
15504 ProcessList.remove(app.pid);
15507 mProcessesToGc.remove(app);
15508 mPendingPssProcesses.remove(app);
15510 // Dismiss any open dialogs.
15511 if (app.crashDialog != null && !app.forceCrashReport) {
15512 app.crashDialog.dismiss();
15513 app.crashDialog = null;
15515 if (app.anrDialog != null) {
15516 app.anrDialog.dismiss();
15517 app.anrDialog = null;
15519 if (app.waitDialog != null) {
15520 app.waitDialog.dismiss();
15521 app.waitDialog = null;
15524 app.crashing = false;
15525 app.notResponding = false;
15527 app.resetPackageList(mProcessStats);
15528 app.unlinkDeathRecipient();
15529 app.makeInactive(mProcessStats);
15530 app.waitingToKill = null;
15531 app.forcingToForeground = null;
15532 updateProcessForegroundLocked(app, false, false);
15533 app.foregroundActivities = false;
15534 app.hasShownUi = false;
15535 app.treatLikeActivity = false;
15536 app.hasAboveClient = false;
15537 app.hasClientActivities = false;
15539 mServices.killServicesLocked(app, allowRestart);
15541 boolean restart = false;
15543 // Remove published content providers.
15544 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15545 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15546 final boolean always = app.bad || !allowRestart;
15547 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15548 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15549 // We left the provider in the launching list, need to
15554 cpr.provider = null;
15557 app.pubProviders.clear();
15559 // Take care of any launching providers waiting for this process.
15560 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15564 // Unregister from connected content providers.
15565 if (!app.conProviders.isEmpty()) {
15566 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15567 ContentProviderConnection conn = app.conProviders.get(i);
15568 conn.provider.connections.remove(conn);
15569 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15570 conn.provider.name);
15572 app.conProviders.clear();
15575 // At this point there may be remaining entries in mLaunchingProviders
15576 // where we were the only one waiting, so they are no longer of use.
15577 // Look for these and clean up if found.
15578 // XXX Commented out for now. Trying to figure out a way to reproduce
15579 // the actual situation to identify what is actually going on.
15581 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15582 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15583 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15584 synchronized (cpr) {
15585 cpr.launchingApp = null;
15592 skipCurrentReceiverLocked(app);
15594 // Unregister any receivers.
15595 for (int i = app.receivers.size() - 1; i >= 0; i--) {
15596 removeReceiverLocked(app.receivers.valueAt(i));
15598 app.receivers.clear();
15600 // If the app is undergoing backup, tell the backup manager about it
15601 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15602 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15603 + mBackupTarget.appInfo + " died during backup");
15605 IBackupManager bm = IBackupManager.Stub.asInterface(
15606 ServiceManager.getService(Context.BACKUP_SERVICE));
15607 bm.agentDisconnected(app.info.packageName);
15608 } catch (RemoteException e) {
15609 // can't happen; backup manager is local
15613 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15614 ProcessChangeItem item = mPendingProcessChanges.get(i);
15615 if (item.pid == app.pid) {
15616 mPendingProcessChanges.remove(i);
15617 mAvailProcessChanges.add(item);
15620 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15622 // If the caller is restarting this app, then leave it in its
15623 // current lists and let the caller take care of it.
15628 if (!app.persistent || app.isolated) {
15629 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15630 "Removing non-persistent process during cleanup: " + app);
15631 removeProcessNameLocked(app.processName, app.uid);
15632 if (mHeavyWeightProcess == app) {
15633 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15634 mHeavyWeightProcess.userId, 0));
15635 mHeavyWeightProcess = null;
15637 } else if (!app.removed) {
15638 // This app is persistent, so we need to keep its record around.
15639 // If it is not already on the pending app list, add it there
15640 // and start a new process for it.
15641 if (mPersistentStartingProcesses.indexOf(app) < 0) {
15642 mPersistentStartingProcesses.add(app);
15646 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15647 TAG_CLEANUP, "Clean-up removing on hold: " + app);
15648 mProcessesOnHold.remove(app);
15650 if (app == mHomeProcess) {
15651 mHomeProcess = null;
15653 if (app == mPreviousProcess) {
15654 mPreviousProcess = null;
15657 if (restart && !app.isolated) {
15658 // We have components that still need to be running in the
15659 // process, so re-launch it.
15661 ProcessList.remove(app.pid);
15663 addProcessNameLocked(app);
15664 startProcessLocked(app, "restart", app.processName);
15666 } else if (app.pid > 0 && app.pid != MY_PID) {
15669 synchronized (mPidsSelfLocked) {
15670 mPidsSelfLocked.remove(app.pid);
15671 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15673 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15674 if (app.isolated) {
15675 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15682 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
15683 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15684 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15685 if (cpr.launchingApp == app) {
15692 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15693 // Look through the content providers we are waiting to have launched,
15694 // and if any run in this process then either schedule a restart of
15695 // the process or kill the client waiting for it if this process has
15697 boolean restart = false;
15698 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15699 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15700 if (cpr.launchingApp == app) {
15701 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15704 removeDyingProviderLocked(app, cpr, true);
15711 // =========================================================
15713 // =========================================================
15716 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15718 enforceNotIsolatedCaller("getServices");
15719 synchronized (this) {
15720 return mServices.getRunningServiceInfoLocked(maxNum, flags);
15725 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15726 enforceNotIsolatedCaller("getRunningServiceControlPanel");
15727 synchronized (this) {
15728 return mServices.getRunningServiceControlPanelLocked(name);
15733 public ComponentName startService(IApplicationThread caller, Intent service,
15734 String resolvedType, String callingPackage, int userId)
15735 throws TransactionTooLargeException {
15736 enforceNotIsolatedCaller("startService");
15737 // Refuse possible leaked file descriptors
15738 if (service != null && service.hasFileDescriptors() == true) {
15739 throw new IllegalArgumentException("File descriptors passed in Intent");
15742 if (callingPackage == null) {
15743 throw new IllegalArgumentException("callingPackage cannot be null");
15746 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15747 "startService: " + service + " type=" + resolvedType);
15748 synchronized(this) {
15749 final int callingPid = Binder.getCallingPid();
15750 final int callingUid = Binder.getCallingUid();
15751 final long origId = Binder.clearCallingIdentity();
15752 ComponentName res = mServices.startServiceLocked(caller, service,
15753 resolvedType, callingPid, callingUid, callingPackage, userId);
15754 Binder.restoreCallingIdentity(origId);
15759 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15760 String callingPackage, int userId)
15761 throws TransactionTooLargeException {
15762 synchronized(this) {
15763 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15764 "startServiceInPackage: " + service + " type=" + resolvedType);
15765 final long origId = Binder.clearCallingIdentity();
15766 ComponentName res = mServices.startServiceLocked(null, service,
15767 resolvedType, -1, uid, callingPackage, userId);
15768 Binder.restoreCallingIdentity(origId);
15774 public int stopService(IApplicationThread caller, Intent service,
15775 String resolvedType, int userId) {
15776 enforceNotIsolatedCaller("stopService");
15777 // Refuse possible leaked file descriptors
15778 if (service != null && service.hasFileDescriptors() == true) {
15779 throw new IllegalArgumentException("File descriptors passed in Intent");
15782 synchronized(this) {
15783 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15788 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15789 enforceNotIsolatedCaller("peekService");
15790 // Refuse possible leaked file descriptors
15791 if (service != null && service.hasFileDescriptors() == true) {
15792 throw new IllegalArgumentException("File descriptors passed in Intent");
15795 if (callingPackage == null) {
15796 throw new IllegalArgumentException("callingPackage cannot be null");
15799 synchronized(this) {
15800 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15805 public boolean stopServiceToken(ComponentName className, IBinder token,
15807 synchronized(this) {
15808 return mServices.stopServiceTokenLocked(className, token, startId);
15813 public void setServiceForeground(ComponentName className, IBinder token,
15814 int id, Notification notification, boolean removeNotification) {
15815 synchronized(this) {
15816 mServices.setServiceForegroundLocked(className, token, id, notification,
15817 removeNotification);
15822 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15823 boolean requireFull, String name, String callerPackage) {
15824 return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15825 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15828 int unsafeConvertIncomingUser(int userId) {
15829 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15830 ? mCurrentUserId : userId;
15833 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15834 int allowMode, String name, String callerPackage) {
15835 final int callingUserId = UserHandle.getUserId(callingUid);
15836 if (callingUserId == userId) {
15840 // Note that we may be accessing mCurrentUserId outside of a lock...
15841 // shouldn't be a big deal, if this is being called outside
15842 // of a locked context there is intrinsically a race with
15843 // the value the caller will receive and someone else changing it.
15844 // We assume that USER_CURRENT_OR_SELF will use the current user; later
15845 // we will switch to the calling user if access to the current user fails.
15846 int targetUserId = unsafeConvertIncomingUser(userId);
15848 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15849 final boolean allow;
15850 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15851 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15852 // If the caller has this permission, they always pass go. And collect $200.
15854 } else if (allowMode == ALLOW_FULL_ONLY) {
15855 // We require full access, sucks to be you.
15857 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15858 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15859 // If the caller does not have either permission, they are always doomed.
15861 } else if (allowMode == ALLOW_NON_FULL) {
15862 // We are blanket allowing non-full access, you lucky caller!
15864 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15865 // We may or may not allow this depending on whether the two users are
15866 // in the same profile.
15867 synchronized (mUserProfileGroupIdsSelfLocked) {
15868 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15869 UserInfo.NO_PROFILE_GROUP_ID);
15870 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15871 UserInfo.NO_PROFILE_GROUP_ID);
15872 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15873 && callingProfile == targetProfile;
15876 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15879 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15880 // In this case, they would like to just execute as their
15881 // owner user instead of failing.
15882 targetUserId = callingUserId;
15884 StringBuilder builder = new StringBuilder(128);
15885 builder.append("Permission Denial: ");
15886 builder.append(name);
15887 if (callerPackage != null) {
15888 builder.append(" from ");
15889 builder.append(callerPackage);
15891 builder.append(" asks to run as user ");
15892 builder.append(userId);
15893 builder.append(" but is calling from user ");
15894 builder.append(UserHandle.getUserId(callingUid));
15895 builder.append("; this requires ");
15896 builder.append(INTERACT_ACROSS_USERS_FULL);
15897 if (allowMode != ALLOW_FULL_ONLY) {
15898 builder.append(" or ");
15899 builder.append(INTERACT_ACROSS_USERS);
15901 String msg = builder.toString();
15903 throw new SecurityException(msg);
15907 if (!allowAll && targetUserId < 0) {
15908 throw new IllegalArgumentException(
15909 "Call does not support special user #" + targetUserId);
15911 // Check shell permission
15912 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
15913 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
15915 throw new SecurityException("Shell does not have permission to access user "
15916 + targetUserId + "\n " + Debug.getCallers(3));
15919 return targetUserId;
15922 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
15923 String className, int flags) {
15924 boolean result = false;
15925 // For apps that don't have pre-defined UIDs, check for permission
15926 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
15927 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15928 if (ActivityManager.checkUidPermission(
15929 INTERACT_ACROSS_USERS,
15930 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
15931 ComponentName comp = new ComponentName(aInfo.packageName, className);
15932 String msg = "Permission Denial: Component " + comp.flattenToShortString()
15933 + " requests FLAG_SINGLE_USER, but app does not hold "
15934 + INTERACT_ACROSS_USERS;
15936 throw new SecurityException(msg);
15938 // Permission passed
15941 } else if ("system".equals(componentProcessName)) {
15943 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
15944 // Phone app and persistent apps are allowed to export singleuser providers.
15945 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
15946 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
15948 if (DEBUG_MU) Slog.v(TAG_MU,
15949 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
15950 + Integer.toHexString(flags) + ") = " + result);
15955 * Checks to see if the caller is in the same app as the singleton
15956 * component, or the component is in a special app. It allows special apps
15957 * to export singleton components but prevents exporting singleton
15958 * components for regular apps.
15960 boolean isValidSingletonCall(int callingUid, int componentUid) {
15961 int componentAppId = UserHandle.getAppId(componentUid);
15962 return UserHandle.isSameApp(callingUid, componentUid)
15963 || componentAppId == Process.SYSTEM_UID
15964 || componentAppId == Process.PHONE_UID
15965 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
15966 == PackageManager.PERMISSION_GRANTED;
15969 public int bindService(IApplicationThread caller, IBinder token, Intent service,
15970 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
15971 int userId) throws TransactionTooLargeException {
15972 enforceNotIsolatedCaller("bindService");
15974 // Refuse possible leaked file descriptors
15975 if (service != null && service.hasFileDescriptors() == true) {
15976 throw new IllegalArgumentException("File descriptors passed in Intent");
15979 if (callingPackage == null) {
15980 throw new IllegalArgumentException("callingPackage cannot be null");
15983 synchronized(this) {
15984 return mServices.bindServiceLocked(caller, token, service,
15985 resolvedType, connection, flags, callingPackage, userId);
15989 public boolean unbindService(IServiceConnection connection) {
15990 synchronized (this) {
15991 return mServices.unbindServiceLocked(connection);
15995 public void publishService(IBinder token, Intent intent, IBinder service) {
15996 // Refuse possible leaked file descriptors
15997 if (intent != null && intent.hasFileDescriptors() == true) {
15998 throw new IllegalArgumentException("File descriptors passed in Intent");
16001 synchronized(this) {
16002 if (!(token instanceof ServiceRecord)) {
16003 throw new IllegalArgumentException("Invalid service token");
16005 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16009 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16010 // Refuse possible leaked file descriptors
16011 if (intent != null && intent.hasFileDescriptors() == true) {
16012 throw new IllegalArgumentException("File descriptors passed in Intent");
16015 synchronized(this) {
16016 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16020 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16021 synchronized(this) {
16022 if (!(token instanceof ServiceRecord)) {
16023 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16024 throw new IllegalArgumentException("Invalid service token");
16026 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16030 // =========================================================
16031 // BACKUP AND RESTORE
16032 // =========================================================
16034 // Cause the target app to be launched if necessary and its backup agent
16035 // instantiated. The backup agent will invoke backupAgentCreated() on the
16036 // activity manager to announce its creation.
16037 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16038 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16039 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16040 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16042 synchronized(this) {
16043 // !!! TODO: currently no check here that we're already bound
16044 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16045 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16046 synchronized (stats) {
16047 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16050 // Backup agent is now in use, its package can't be stopped.
16052 AppGlobals.getPackageManager().setPackageStoppedState(
16053 app.packageName, false, UserHandle.getUserId(app.uid));
16054 } catch (RemoteException e) {
16055 } catch (IllegalArgumentException e) {
16056 Slog.w(TAG, "Failed trying to unstop package "
16057 + app.packageName + ": " + e);
16060 BackupRecord r = new BackupRecord(ss, app, backupMode);
16061 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16062 ? new ComponentName(app.packageName, app.backupAgentName)
16063 : new ComponentName("android", "FullBackupAgent");
16064 // startProcessLocked() returns existing proc's record if it's already running
16065 ProcessRecord proc = startProcessLocked(app.processName, app,
16066 false, 0, "backup", hostingName, false, false, false);
16067 if (proc == null) {
16068 Slog.e(TAG, "Unable to start backup agent process " + r);
16074 mBackupAppName = app.packageName;
16076 // Try not to kill the process during backup
16077 updateOomAdjLocked(proc);
16079 // If the process is already attached, schedule the creation of the backup agent now.
16080 // If it is not yet live, this will be done when it attaches to the framework.
16081 if (proc.thread != null) {
16082 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16084 proc.thread.scheduleCreateBackupAgent(app,
16085 compatibilityInfoForPackageLocked(app), backupMode);
16086 } catch (RemoteException e) {
16087 // Will time out on the backup manager side
16090 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16092 // Invariants: at this point, the target app process exists and the application
16093 // is either already running or in the process of coming up. mBackupTarget and
16094 // mBackupAppName describe the app, so that when it binds back to the AM we
16095 // know that it's scheduled for a backup-agent operation.
16102 public void clearPendingBackup() {
16103 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16104 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16106 synchronized (this) {
16107 mBackupTarget = null;
16108 mBackupAppName = null;
16112 // A backup agent has just come up
16113 public void backupAgentCreated(String agentPackageName, IBinder agent) {
16114 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16117 synchronized(this) {
16118 if (!agentPackageName.equals(mBackupAppName)) {
16119 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16124 long oldIdent = Binder.clearCallingIdentity();
16126 IBackupManager bm = IBackupManager.Stub.asInterface(
16127 ServiceManager.getService(Context.BACKUP_SERVICE));
16128 bm.agentConnected(agentPackageName, agent);
16129 } catch (RemoteException e) {
16130 // can't happen; the backup manager service is local
16131 } catch (Exception e) {
16132 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16133 e.printStackTrace();
16135 Binder.restoreCallingIdentity(oldIdent);
16139 // done with this agent
16140 public void unbindBackupAgent(ApplicationInfo appInfo) {
16141 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16142 if (appInfo == null) {
16143 Slog.w(TAG, "unbind backup agent for null app");
16147 synchronized(this) {
16149 if (mBackupAppName == null) {
16150 Slog.w(TAG, "Unbinding backup agent with no active backup");
16154 if (!mBackupAppName.equals(appInfo.packageName)) {
16155 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16159 // Not backing this app up any more; reset its OOM adjustment
16160 final ProcessRecord proc = mBackupTarget.app;
16161 updateOomAdjLocked(proc);
16163 // If the app crashed during backup, 'thread' will be null here
16164 if (proc.thread != null) {
16166 proc.thread.scheduleDestroyBackupAgent(appInfo,
16167 compatibilityInfoForPackageLocked(appInfo));
16168 } catch (Exception e) {
16169 Slog.e(TAG, "Exception when unbinding backup agent:");
16170 e.printStackTrace();
16174 mBackupTarget = null;
16175 mBackupAppName = null;
16179 // =========================================================
16181 // =========================================================
16183 boolean isPendingBroadcastProcessLocked(int pid) {
16184 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16185 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16188 void skipPendingBroadcastLocked(int pid) {
16189 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16190 for (BroadcastQueue queue : mBroadcastQueues) {
16191 queue.skipPendingBroadcastLocked(pid);
16195 // The app just attached; send any pending broadcasts that it should receive
16196 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16197 boolean didSomething = false;
16198 for (BroadcastQueue queue : mBroadcastQueues) {
16199 didSomething |= queue.sendPendingBroadcastsLocked(app);
16201 return didSomething;
16204 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16205 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16206 enforceNotIsolatedCaller("registerReceiver");
16207 ArrayList<Intent> stickyIntents = null;
16208 ProcessRecord callerApp = null;
16211 synchronized(this) {
16212 if (caller != null) {
16213 callerApp = getRecordForAppLocked(caller);
16214 if (callerApp == null) {
16215 throw new SecurityException(
16216 "Unable to find app for caller " + caller
16217 + " (pid=" + Binder.getCallingPid()
16218 + ") when registering receiver " + receiver);
16220 if (callerApp.info.uid != Process.SYSTEM_UID &&
16221 !callerApp.pkgList.containsKey(callerPackage) &&
16222 !"android".equals(callerPackage)) {
16223 throw new SecurityException("Given caller package " + callerPackage
16224 + " is not running in process " + callerApp);
16226 callingUid = callerApp.info.uid;
16227 callingPid = callerApp.pid;
16229 callerPackage = null;
16230 callingUid = Binder.getCallingUid();
16231 callingPid = Binder.getCallingPid();
16234 userId = handleIncomingUser(callingPid, callingUid, userId,
16235 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16237 Iterator<String> actions = filter.actionsIterator();
16238 if (actions == null) {
16239 ArrayList<String> noAction = new ArrayList<String>(1);
16240 noAction.add(null);
16241 actions = noAction.iterator();
16244 // Collect stickies of users
16245 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16246 while (actions.hasNext()) {
16247 String action = actions.next();
16248 for (int id : userIds) {
16249 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16250 if (stickies != null) {
16251 ArrayList<Intent> intents = stickies.get(action);
16252 if (intents != null) {
16253 if (stickyIntents == null) {
16254 stickyIntents = new ArrayList<Intent>();
16256 stickyIntents.addAll(intents);
16263 ArrayList<Intent> allSticky = null;
16264 if (stickyIntents != null) {
16265 final ContentResolver resolver = mContext.getContentResolver();
16266 // Look for any matching sticky broadcasts...
16267 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16268 Intent intent = stickyIntents.get(i);
16269 // If intent has scheme "content", it will need to acccess
16270 // provider that needs to lock mProviderMap in ActivityThread
16271 // and also it may need to wait application response, so we
16272 // cannot lock ActivityManagerService here.
16273 if (filter.match(resolver, intent, true, TAG) >= 0) {
16274 if (allSticky == null) {
16275 allSticky = new ArrayList<Intent>();
16277 allSticky.add(intent);
16282 // The first sticky in the list is returned directly back to the client.
16283 Intent sticky = allSticky != null ? allSticky.get(0) : null;
16284 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16285 if (receiver == null) {
16289 synchronized (this) {
16290 if (callerApp != null && (callerApp.thread == null
16291 || callerApp.thread.asBinder() != caller.asBinder())) {
16292 // Original caller already died
16295 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16297 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16299 if (rl.app != null) {
16300 rl.app.receivers.add(rl);
16303 receiver.asBinder().linkToDeath(rl, 0);
16304 } catch (RemoteException e) {
16307 rl.linkedToDeath = true;
16309 mRegisteredReceivers.put(receiver.asBinder(), rl);
16310 } else if (rl.uid != callingUid) {
16311 throw new IllegalArgumentException(
16312 "Receiver requested to register for uid " + callingUid
16313 + " was previously registered for uid " + rl.uid);
16314 } else if (rl.pid != callingPid) {
16315 throw new IllegalArgumentException(
16316 "Receiver requested to register for pid " + callingPid
16317 + " was previously registered for pid " + rl.pid);
16318 } else if (rl.userId != userId) {
16319 throw new IllegalArgumentException(
16320 "Receiver requested to register for user " + userId
16321 + " was previously registered for user " + rl.userId);
16323 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16324 permission, callingUid, userId);
16326 if (!bf.debugCheck()) {
16327 Slog.w(TAG, "==> For Dynamic broadcast");
16329 mReceiverResolver.addFilter(bf);
16331 // Enqueue broadcasts for all existing stickies that match
16333 if (allSticky != null) {
16334 ArrayList receivers = new ArrayList();
16337 final int stickyCount = allSticky.size();
16338 for (int i = 0; i < stickyCount; i++) {
16339 Intent intent = allSticky.get(i);
16340 BroadcastQueue queue = broadcastQueueForIntent(intent);
16341 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16342 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16343 null, 0, null, null, false, true, true, -1);
16344 queue.enqueueParallelBroadcastLocked(r);
16345 queue.scheduleBroadcastsLocked();
16353 public void unregisterReceiver(IIntentReceiver receiver) {
16354 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16356 final long origId = Binder.clearCallingIdentity();
16358 boolean doTrim = false;
16360 synchronized(this) {
16361 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16363 final BroadcastRecord r = rl.curBroadcast;
16364 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16365 final boolean doNext = r.queue.finishReceiverLocked(
16366 r, r.resultCode, r.resultData, r.resultExtras,
16367 r.resultAbort, false);
16370 r.queue.processNextBroadcast(false);
16374 if (rl.app != null) {
16375 rl.app.receivers.remove(rl);
16377 removeReceiverLocked(rl);
16378 if (rl.linkedToDeath) {
16379 rl.linkedToDeath = false;
16380 rl.receiver.asBinder().unlinkToDeath(rl, 0);
16385 // If we actually concluded any broadcasts, we might now be able
16386 // to trim the recipients' apps from our working set
16388 trimApplications();
16393 Binder.restoreCallingIdentity(origId);
16397 void removeReceiverLocked(ReceiverList rl) {
16398 mRegisteredReceivers.remove(rl.receiver.asBinder());
16399 for (int i = rl.size() - 1; i >= 0; i--) {
16400 mReceiverResolver.removeFilter(rl.get(i));
16404 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16405 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16406 ProcessRecord r = mLruProcesses.get(i);
16407 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16409 r.thread.dispatchPackageBroadcast(cmd, packages);
16410 } catch (RemoteException ex) {
16416 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16417 int callingUid, int[] users) {
16418 List<ResolveInfo> receivers = null;
16420 HashSet<ComponentName> singleUserReceivers = null;
16421 boolean scannedFirstReceivers = false;
16422 for (int user : users) {
16423 // Skip users that have Shell restrictions
16424 if (callingUid == Process.SHELL_UID
16425 && getUserManagerLocked().hasUserRestriction(
16426 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16429 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16430 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16431 if (user != UserHandle.USER_OWNER && newReceivers != null) {
16432 // If this is not the primary user, we need to check for
16433 // any receivers that should be filtered out.
16434 for (int i=0; i<newReceivers.size(); i++) {
16435 ResolveInfo ri = newReceivers.get(i);
16436 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16437 newReceivers.remove(i);
16442 if (newReceivers != null && newReceivers.size() == 0) {
16443 newReceivers = null;
16445 if (receivers == null) {
16446 receivers = newReceivers;
16447 } else if (newReceivers != null) {
16448 // We need to concatenate the additional receivers
16449 // found with what we have do far. This would be easy,
16450 // but we also need to de-dup any receivers that are
16452 if (!scannedFirstReceivers) {
16453 // Collect any single user receivers we had already retrieved.
16454 scannedFirstReceivers = true;
16455 for (int i=0; i<receivers.size(); i++) {
16456 ResolveInfo ri = receivers.get(i);
16457 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16458 ComponentName cn = new ComponentName(
16459 ri.activityInfo.packageName, ri.activityInfo.name);
16460 if (singleUserReceivers == null) {
16461 singleUserReceivers = new HashSet<ComponentName>();
16463 singleUserReceivers.add(cn);
16467 // Add the new results to the existing results, tracking
16468 // and de-dupping single user receivers.
16469 for (int i=0; i<newReceivers.size(); i++) {
16470 ResolveInfo ri = newReceivers.get(i);
16471 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16472 ComponentName cn = new ComponentName(
16473 ri.activityInfo.packageName, ri.activityInfo.name);
16474 if (singleUserReceivers == null) {
16475 singleUserReceivers = new HashSet<ComponentName>();
16477 if (!singleUserReceivers.contains(cn)) {
16478 singleUserReceivers.add(cn);
16487 } catch (RemoteException ex) {
16488 // pm is in same process, this will never happen.
16493 private final int broadcastIntentLocked(ProcessRecord callerApp,
16494 String callerPackage, Intent intent, String resolvedType,
16495 IIntentReceiver resultTo, int resultCode, String resultData,
16496 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16497 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16498 intent = new Intent(intent);
16500 // By default broadcasts do not go to stopped apps.
16501 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16503 // If we have not finished booting, don't allow this to launch new processes.
16504 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16505 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16508 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16509 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16510 + " ordered=" + ordered + " userid=" + userId);
16511 if ((resultTo != null) && !ordered) {
16512 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16515 userId = handleIncomingUser(callingPid, callingUid, userId,
16516 true, ALLOW_NON_FULL, "broadcast", callerPackage);
16518 // Make sure that the user who is receiving this broadcast is running.
16519 // If not, we will just skip it. Make an exception for shutdown broadcasts
16520 // and upgrade steps.
16522 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16523 if ((callingUid != Process.SYSTEM_UID
16524 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16525 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16526 Slog.w(TAG, "Skipping broadcast of " + intent
16527 + ": user " + userId + " is stopped");
16528 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16532 BroadcastOptions brOptions = null;
16533 if (options != null) {
16534 brOptions = new BroadcastOptions(options);
16535 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16536 // See if the caller is allowed to do this. Note we are checking against
16537 // the actual real caller (not whoever provided the operation as say a
16538 // PendingIntent), because that who is actually supplied the arguments.
16539 if (checkComponentPermission(
16540 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16541 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16542 != PackageManager.PERMISSION_GRANTED) {
16543 String msg = "Permission Denial: " + intent.getAction()
16544 + " broadcast from " + callerPackage + " (pid=" + callingPid
16545 + ", uid=" + callingUid + ")"
16547 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16549 throw new SecurityException(msg);
16555 * Prevent non-system code (defined here to be non-persistent
16556 * processes) from sending protected broadcasts.
16558 int callingAppId = UserHandle.getAppId(callingUid);
16559 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16560 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16561 || callingAppId == Process.NFC_UID || callingUid == 0) {
16563 } else if (callerApp == null || !callerApp.persistent) {
16565 if (AppGlobals.getPackageManager().isProtectedBroadcast(
16566 intent.getAction())) {
16567 String msg = "Permission Denial: not allowed to send broadcast "
16568 + intent.getAction() + " from pid="
16569 + callingPid + ", uid=" + callingUid;
16571 throw new SecurityException(msg);
16572 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16573 // Special case for compatibility: we don't want apps to send this,
16574 // but historically it has not been protected and apps may be using it
16575 // to poke their own app widget. So, instead of making it protected,
16576 // just limit it to the caller.
16577 if (callerApp == null) {
16578 String msg = "Permission Denial: not allowed to send broadcast "
16579 + intent.getAction() + " from unknown caller.";
16581 throw new SecurityException(msg);
16582 } else if (intent.getComponent() != null) {
16583 // They are good enough to send to an explicit component... verify
16584 // it is being sent to the calling app.
16585 if (!intent.getComponent().getPackageName().equals(
16586 callerApp.info.packageName)) {
16587 String msg = "Permission Denial: not allowed to send broadcast "
16588 + intent.getAction() + " to "
16589 + intent.getComponent().getPackageName() + " from "
16590 + callerApp.info.packageName;
16592 throw new SecurityException(msg);
16595 // Limit broadcast to their own package.
16596 intent.setPackage(callerApp.info.packageName);
16599 } catch (RemoteException e) {
16600 Slog.w(TAG, "Remote exception", e);
16601 return ActivityManager.BROADCAST_SUCCESS;
16605 final String action = intent.getAction();
16606 if (action != null) {
16608 case Intent.ACTION_UID_REMOVED:
16609 case Intent.ACTION_PACKAGE_REMOVED:
16610 case Intent.ACTION_PACKAGE_CHANGED:
16611 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16612 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16613 // Handle special intents: if this broadcast is from the package
16614 // manager about a package being removed, we need to remove all of
16615 // its activities from the history stack.
16616 if (checkComponentPermission(
16617 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16618 callingPid, callingUid, -1, true)
16619 != PackageManager.PERMISSION_GRANTED) {
16620 String msg = "Permission Denial: " + intent.getAction()
16621 + " broadcast from " + callerPackage + " (pid=" + callingPid
16622 + ", uid=" + callingUid + ")"
16624 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16626 throw new SecurityException(msg);
16629 case Intent.ACTION_UID_REMOVED:
16630 final Bundle intentExtras = intent.getExtras();
16631 final int uid = intentExtras != null
16632 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16634 mBatteryStatsService.removeUid(uid);
16635 mAppOpsService.uidRemoved(uid);
16638 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16639 // If resources are unavailable just force stop all those packages
16640 // and flush the attribute cache as well.
16642 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16643 if (list != null && list.length > 0) {
16644 for (int i = 0; i < list.length; i++) {
16645 forceStopPackageLocked(list[i], -1, false, true, true,
16646 false, false, userId, "storage unmount");
16648 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16649 sendPackageBroadcastLocked(
16650 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16654 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16655 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16657 case Intent.ACTION_PACKAGE_REMOVED:
16658 case Intent.ACTION_PACKAGE_CHANGED:
16659 Uri data = intent.getData();
16661 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16662 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16663 boolean fullUninstall = removed &&
16664 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16665 final boolean killProcess =
16666 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16668 forceStopPackageLocked(ssp, UserHandle.getAppId(
16669 intent.getIntExtra(Intent.EXTRA_UID, -1)),
16670 false, true, true, false, fullUninstall, userId,
16671 removed ? "pkg removed" : "pkg changed");
16674 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16675 new String[] {ssp}, userId);
16676 if (fullUninstall) {
16677 mAppOpsService.packageRemoved(
16678 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16680 // Remove all permissions granted from/to this package
16681 removeUriPermissionsForPackageLocked(ssp, userId, true);
16683 removeTasksByPackageNameLocked(ssp, userId);
16684 mBatteryStatsService.notePackageUninstalled(ssp);
16687 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16688 intent.getStringArrayExtra(
16689 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16695 case Intent.ACTION_PACKAGE_ADDED:
16696 // Special case for adding a package: by default turn on compatibility mode.
16697 Uri data = intent.getData();
16699 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16700 final boolean replacing =
16701 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16702 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16705 ApplicationInfo ai = AppGlobals.getPackageManager().
16706 getApplicationInfo(ssp, 0, 0);
16707 mBatteryStatsService.notePackageInstalled(ssp,
16708 ai != null ? ai.versionCode : 0);
16709 } catch (RemoteException e) {
16713 case Intent.ACTION_TIMEZONE_CHANGED:
16714 // If this is the time zone changed action, queue up a message that will reset
16715 // the timezone of all currently running processes. This message will get
16716 // queued up before the broadcast happens.
16717 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16719 case Intent.ACTION_TIME_CHANGED:
16720 // If the user set the time, let all running processes know.
16721 final int is24Hour =
16722 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16724 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16725 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16726 synchronized (stats) {
16727 stats.noteCurrentTimeChangedLocked();
16730 case Intent.ACTION_CLEAR_DNS_CACHE:
16731 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16733 case Proxy.PROXY_CHANGE_ACTION:
16734 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16735 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16740 // Add to the sticky list if requested.
16742 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16743 callingPid, callingUid)
16744 != PackageManager.PERMISSION_GRANTED) {
16745 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16746 + callingPid + ", uid=" + callingUid
16747 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16749 throw new SecurityException(msg);
16751 if (requiredPermissions != null && requiredPermissions.length > 0) {
16752 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16753 + " and enforce permissions " + Arrays.toString(requiredPermissions));
16754 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16756 if (intent.getComponent() != null) {
16757 throw new SecurityException(
16758 "Sticky broadcasts can't target a specific component");
16760 // We use userId directly here, since the "all" target is maintained
16761 // as a separate set of sticky broadcasts.
16762 if (userId != UserHandle.USER_ALL) {
16763 // But first, if this is not a broadcast to all users, then
16764 // make sure it doesn't conflict with an existing broadcast to
16766 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16767 UserHandle.USER_ALL);
16768 if (stickies != null) {
16769 ArrayList<Intent> list = stickies.get(intent.getAction());
16770 if (list != null) {
16771 int N = list.size();
16773 for (i=0; i<N; i++) {
16774 if (intent.filterEquals(list.get(i))) {
16775 throw new IllegalArgumentException(
16776 "Sticky broadcast " + intent + " for user "
16777 + userId + " conflicts with existing global broadcast");
16783 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16784 if (stickies == null) {
16785 stickies = new ArrayMap<>();
16786 mStickyBroadcasts.put(userId, stickies);
16788 ArrayList<Intent> list = stickies.get(intent.getAction());
16789 if (list == null) {
16790 list = new ArrayList<>();
16791 stickies.put(intent.getAction(), list);
16793 final int stickiesCount = list.size();
16795 for (i = 0; i < stickiesCount; i++) {
16796 if (intent.filterEquals(list.get(i))) {
16797 // This sticky already exists, replace it.
16798 list.set(i, new Intent(intent));
16802 if (i >= stickiesCount) {
16803 list.add(new Intent(intent));
16808 if (userId == UserHandle.USER_ALL) {
16809 // Caller wants broadcast to go to all started users.
16810 users = mStartedUserArray;
16812 // Caller wants broadcast to go to one specific user.
16813 users = new int[] {userId};
16816 // Figure out who all will receive this broadcast.
16817 List receivers = null;
16818 List<BroadcastFilter> registeredReceivers = null;
16819 // Need to resolve the intent to interested receivers...
16820 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16822 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16824 if (intent.getComponent() == null) {
16825 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16826 // Query one target user at a time, excluding shell-restricted users
16827 UserManagerService ums = getUserManagerLocked();
16828 for (int i = 0; i < users.length; i++) {
16829 if (ums.hasUserRestriction(
16830 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16833 List<BroadcastFilter> registeredReceiversForUser =
16834 mReceiverResolver.queryIntent(intent,
16835 resolvedType, false, users[i]);
16836 if (registeredReceivers == null) {
16837 registeredReceivers = registeredReceiversForUser;
16838 } else if (registeredReceiversForUser != null) {
16839 registeredReceivers.addAll(registeredReceiversForUser);
16843 registeredReceivers = mReceiverResolver.queryIntent(intent,
16844 resolvedType, false, userId);
16848 final boolean replacePending =
16849 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16851 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16852 + " replacePending=" + replacePending);
16854 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16855 if (!ordered && NR > 0) {
16856 // If we are not serializing this broadcast, then send the
16857 // registered receivers separately so they don't wait for the
16858 // components to be launched.
16859 final BroadcastQueue queue = broadcastQueueForIntent(intent);
16860 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16861 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16862 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16863 resultExtras, ordered, sticky, false, userId);
16864 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16865 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16867 queue.enqueueParallelBroadcastLocked(r);
16868 queue.scheduleBroadcastsLocked();
16870 registeredReceivers = null;
16874 // Merge into one list.
16876 if (receivers != null) {
16877 // A special case for PACKAGE_ADDED: do not allow the package
16878 // being added to see this broadcast. This prevents them from
16879 // using this as a back door to get run as soon as they are
16880 // installed. Maybe in the future we want to have a special install
16881 // broadcast or such for apps, but we'd like to deliberately make
16883 String skipPackages[] = null;
16884 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16885 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16886 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16887 Uri data = intent.getData();
16888 if (data != null) {
16889 String pkgName = data.getSchemeSpecificPart();
16890 if (pkgName != null) {
16891 skipPackages = new String[] { pkgName };
16894 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
16895 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16897 if (skipPackages != null && (skipPackages.length > 0)) {
16898 for (String skipPackage : skipPackages) {
16899 if (skipPackage != null) {
16900 int NT = receivers.size();
16901 for (int it=0; it<NT; it++) {
16902 ResolveInfo curt = (ResolveInfo)receivers.get(it);
16903 if (curt.activityInfo.packageName.equals(skipPackage)) {
16904 receivers.remove(it);
16913 int NT = receivers != null ? receivers.size() : 0;
16915 ResolveInfo curt = null;
16916 BroadcastFilter curr = null;
16917 while (it < NT && ir < NR) {
16918 if (curt == null) {
16919 curt = (ResolveInfo)receivers.get(it);
16921 if (curr == null) {
16922 curr = registeredReceivers.get(ir);
16924 if (curr.getPriority() >= curt.priority) {
16925 // Insert this broadcast record into the final list.
16926 receivers.add(it, curr);
16932 // Skip to the next ResolveInfo in the final list.
16939 if (receivers == null) {
16940 receivers = new ArrayList();
16942 receivers.add(registeredReceivers.get(ir));
16946 if ((receivers != null && receivers.size() > 0)
16947 || resultTo != null) {
16948 BroadcastQueue queue = broadcastQueueForIntent(intent);
16949 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16950 callerPackage, callingPid, callingUid, resolvedType,
16951 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
16952 resultData, resultExtras, ordered, sticky, false, userId);
16954 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
16955 + ": prev had " + queue.mOrderedBroadcasts.size());
16956 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
16957 "Enqueueing broadcast " + r.intent.getAction());
16959 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
16961 queue.enqueueOrderedBroadcastLocked(r);
16962 queue.scheduleBroadcastsLocked();
16966 return ActivityManager.BROADCAST_SUCCESS;
16969 final Intent verifyBroadcastLocked(Intent intent) {
16970 // Refuse possible leaked file descriptors
16971 if (intent != null && intent.hasFileDescriptors() == true) {
16972 throw new IllegalArgumentException("File descriptors passed in Intent");
16975 int flags = intent.getFlags();
16977 if (!mProcessesReady) {
16978 // if the caller really truly claims to know what they're doing, go
16979 // ahead and allow the broadcast without launching any receivers
16980 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
16981 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
16982 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
16983 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
16984 + " before boot completion");
16985 throw new IllegalStateException("Cannot broadcast before boot completed");
16989 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
16990 throw new IllegalArgumentException(
16991 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
16997 public final int broadcastIntent(IApplicationThread caller,
16998 Intent intent, String resolvedType, IIntentReceiver resultTo,
16999 int resultCode, String resultData, Bundle resultExtras,
17000 String[] requiredPermissions, int appOp, Bundle options,
17001 boolean serialized, boolean sticky, int userId) {
17002 enforceNotIsolatedCaller("broadcastIntent");
17003 synchronized(this) {
17004 intent = verifyBroadcastLocked(intent);
17006 final ProcessRecord callerApp = getRecordForAppLocked(caller);
17007 final int callingPid = Binder.getCallingPid();
17008 final int callingUid = Binder.getCallingUid();
17009 final long origId = Binder.clearCallingIdentity();
17010 int res = broadcastIntentLocked(callerApp,
17011 callerApp != null ? callerApp.info.packageName : null,
17012 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17013 requiredPermissions, appOp, null, serialized, sticky,
17014 callingPid, callingUid, userId);
17015 Binder.restoreCallingIdentity(origId);
17021 int broadcastIntentInPackage(String packageName, int uid,
17022 Intent intent, String resolvedType, IIntentReceiver resultTo,
17023 int resultCode, String resultData, Bundle resultExtras,
17024 String requiredPermission, Bundle options, boolean serialized, boolean sticky,
17026 synchronized(this) {
17027 intent = verifyBroadcastLocked(intent);
17029 final long origId = Binder.clearCallingIdentity();
17030 String[] requiredPermissions = requiredPermission == null ? null
17031 : new String[] {requiredPermission};
17032 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17033 resultTo, resultCode, resultData, resultExtras,
17034 requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
17035 sticky, -1, uid, userId);
17036 Binder.restoreCallingIdentity(origId);
17041 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17042 // Refuse possible leaked file descriptors
17043 if (intent != null && intent.hasFileDescriptors() == true) {
17044 throw new IllegalArgumentException("File descriptors passed in Intent");
17047 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17048 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17050 synchronized(this) {
17051 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17052 != PackageManager.PERMISSION_GRANTED) {
17053 String msg = "Permission Denial: unbroadcastIntent() from pid="
17054 + Binder.getCallingPid()
17055 + ", uid=" + Binder.getCallingUid()
17056 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17058 throw new SecurityException(msg);
17060 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17061 if (stickies != null) {
17062 ArrayList<Intent> list = stickies.get(intent.getAction());
17063 if (list != null) {
17064 int N = list.size();
17066 for (i=0; i<N; i++) {
17067 if (intent.filterEquals(list.get(i))) {
17072 if (list.size() <= 0) {
17073 stickies.remove(intent.getAction());
17076 if (stickies.size() <= 0) {
17077 mStickyBroadcasts.remove(userId);
17083 void backgroundServicesFinishedLocked(int userId) {
17084 for (BroadcastQueue queue : mBroadcastQueues) {
17085 queue.backgroundServicesFinishedLocked(userId);
17089 public void finishReceiver(IBinder who, int resultCode, String resultData,
17090 Bundle resultExtras, boolean resultAbort, int flags) {
17091 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17093 // Refuse possible leaked file descriptors
17094 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17095 throw new IllegalArgumentException("File descriptors passed in Bundle");
17098 final long origId = Binder.clearCallingIdentity();
17100 boolean doNext = false;
17103 synchronized(this) {
17104 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17105 ? mFgBroadcastQueue : mBgBroadcastQueue;
17106 r = queue.getMatchingOrderedReceiver(who);
17108 doNext = r.queue.finishReceiverLocked(r, resultCode,
17109 resultData, resultExtras, resultAbort, true);
17114 r.queue.processNextBroadcast(false);
17116 trimApplications();
17118 Binder.restoreCallingIdentity(origId);
17122 // =========================================================
17124 // =========================================================
17126 public boolean startInstrumentation(ComponentName className,
17127 String profileFile, int flags, Bundle arguments,
17128 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17129 int userId, String abiOverride) {
17130 enforceNotIsolatedCaller("startInstrumentation");
17131 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17132 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17133 // Refuse possible leaked file descriptors
17134 if (arguments != null && arguments.hasFileDescriptors()) {
17135 throw new IllegalArgumentException("File descriptors passed in Bundle");
17138 synchronized(this) {
17139 InstrumentationInfo ii = null;
17140 ApplicationInfo ai = null;
17142 ii = mContext.getPackageManager().getInstrumentationInfo(
17143 className, STOCK_PM_FLAGS);
17144 ai = AppGlobals.getPackageManager().getApplicationInfo(
17145 ii.targetPackage, STOCK_PM_FLAGS, userId);
17146 } catch (PackageManager.NameNotFoundException e) {
17147 } catch (RemoteException e) {
17150 reportStartInstrumentationFailure(watcher, className,
17151 "Unable to find instrumentation info for: " + className);
17155 reportStartInstrumentationFailure(watcher, className,
17156 "Unable to find instrumentation target package: " + ii.targetPackage);
17160 int match = mContext.getPackageManager().checkSignatures(
17161 ii.targetPackage, ii.packageName);
17162 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17163 String msg = "Permission Denial: starting instrumentation "
17164 + className + " from pid="
17165 + Binder.getCallingPid()
17166 + ", uid=" + Binder.getCallingPid()
17167 + " not allowed because package " + ii.packageName
17168 + " does not have a signature matching the target "
17169 + ii.targetPackage;
17170 reportStartInstrumentationFailure(watcher, className, msg);
17171 throw new SecurityException(msg);
17174 final long origId = Binder.clearCallingIdentity();
17175 // Instrumentation can kill and relaunch even persistent processes
17176 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17178 ProcessRecord app = addAppLocked(ai, false, abiOverride);
17179 app.instrumentationClass = className;
17180 app.instrumentationInfo = ai;
17181 app.instrumentationProfileFile = profileFile;
17182 app.instrumentationArguments = arguments;
17183 app.instrumentationWatcher = watcher;
17184 app.instrumentationUiAutomationConnection = uiAutomationConnection;
17185 app.instrumentationResultClass = className;
17186 Binder.restoreCallingIdentity(origId);
17193 * Report errors that occur while attempting to start Instrumentation. Always writes the
17194 * error to the logs, but if somebody is watching, send the report there too. This enables
17195 * the "am" command to report errors with more information.
17197 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
17198 * @param cn The component name of the instrumentation.
17199 * @param report The error report.
17201 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17202 ComponentName cn, String report) {
17203 Slog.w(TAG, report);
17205 if (watcher != null) {
17206 Bundle results = new Bundle();
17207 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17208 results.putString("Error", report);
17209 watcher.instrumentationStatus(cn, -1, results);
17211 } catch (RemoteException e) {
17216 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17217 if (app.instrumentationWatcher != null) {
17219 // NOTE: IInstrumentationWatcher *must* be oneway here
17220 app.instrumentationWatcher.instrumentationFinished(
17221 app.instrumentationClass,
17224 } catch (RemoteException e) {
17228 // Can't call out of the system process with a lock held, so post a message.
17229 if (app.instrumentationUiAutomationConnection != null) {
17230 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17231 app.instrumentationUiAutomationConnection).sendToTarget();
17234 app.instrumentationWatcher = null;
17235 app.instrumentationUiAutomationConnection = null;
17236 app.instrumentationClass = null;
17237 app.instrumentationInfo = null;
17238 app.instrumentationProfileFile = null;
17239 app.instrumentationArguments = null;
17241 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17245 public void finishInstrumentation(IApplicationThread target,
17246 int resultCode, Bundle results) {
17247 int userId = UserHandle.getCallingUserId();
17248 // Refuse possible leaked file descriptors
17249 if (results != null && results.hasFileDescriptors()) {
17250 throw new IllegalArgumentException("File descriptors passed in Intent");
17253 synchronized(this) {
17254 ProcessRecord app = getRecordForAppLocked(target);
17256 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17259 final long origId = Binder.clearCallingIdentity();
17260 finishInstrumentationLocked(app, resultCode, results);
17261 Binder.restoreCallingIdentity(origId);
17265 // =========================================================
17267 // =========================================================
17269 public ConfigurationInfo getDeviceConfigurationInfo() {
17270 ConfigurationInfo config = new ConfigurationInfo();
17271 synchronized (this) {
17272 config.reqTouchScreen = mConfiguration.touchscreen;
17273 config.reqKeyboardType = mConfiguration.keyboard;
17274 config.reqNavigation = mConfiguration.navigation;
17275 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17276 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17277 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17279 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17280 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17281 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17283 config.reqGlEsVersion = GL_ES_VERSION;
17288 ActivityStack getFocusedStack() {
17289 return mStackSupervisor.getFocusedStack();
17293 public int getFocusedStackId() throws RemoteException {
17294 ActivityStack focusedStack = getFocusedStack();
17295 if (focusedStack != null) {
17296 return focusedStack.getStackId();
17301 public Configuration getConfiguration() {
17303 synchronized(this) {
17304 ci = new Configuration(mConfiguration);
17305 ci.userSetLocale = false;
17310 public void updatePersistentConfiguration(Configuration values) {
17311 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17312 "updateConfiguration()");
17313 enforceWriteSettingsPermission("updateConfiguration()");
17314 if (values == null) {
17315 throw new NullPointerException("Configuration must not be null");
17318 synchronized(this) {
17319 final long origId = Binder.clearCallingIdentity();
17320 updateConfigurationLocked(values, null, true, false);
17321 Binder.restoreCallingIdentity(origId);
17325 private void enforceWriteSettingsPermission(String func) {
17326 int uid = Binder.getCallingUid();
17327 if (uid == Process.ROOT_UID) {
17331 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17332 Settings.getPackageNameForUid(mContext, uid), false)) {
17336 String msg = "Permission Denial: " + func + " from pid="
17337 + Binder.getCallingPid()
17339 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17341 throw new SecurityException(msg);
17344 public void updateConfiguration(Configuration values) {
17345 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17346 "updateConfiguration()");
17348 synchronized(this) {
17349 if (values == null && mWindowManager != null) {
17350 // sentinel: fetch the current configuration from the window manager
17351 values = mWindowManager.computeNewConfiguration();
17354 if (mWindowManager != null) {
17355 mProcessList.applyDisplaySize(mWindowManager);
17358 final long origId = Binder.clearCallingIdentity();
17359 if (values != null) {
17360 Settings.System.clearConfiguration(values);
17362 updateConfigurationLocked(values, null, false, false);
17363 Binder.restoreCallingIdentity(origId);
17368 * Do either or both things: (1) change the current configuration, and (2)
17369 * make sure the given activity is running with the (now) current
17370 * configuration. Returns true if the activity has been left running, or
17371 * false if <var>starting</var> is being destroyed to match the new
17373 * @param persistent TODO
17375 boolean updateConfigurationLocked(Configuration values,
17376 ActivityRecord starting, boolean persistent, boolean initLocale) {
17379 if (values != null) {
17380 Configuration newConfig = new Configuration(mConfiguration);
17381 changes = newConfig.updateFrom(values);
17382 if (changes != 0) {
17383 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17384 "Updating configuration to: " + values);
17386 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17388 if (!initLocale && values.locale != null && values.userSetLocale) {
17389 final String languageTag = values.locale.toLanguageTag();
17390 SystemProperties.set("persist.sys.locale", languageTag);
17391 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17395 mConfigurationSeq++;
17396 if (mConfigurationSeq <= 0) {
17397 mConfigurationSeq = 1;
17399 newConfig.seq = mConfigurationSeq;
17400 mConfiguration = newConfig;
17401 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17402 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17403 //mUsageStatsService.noteStartConfig(newConfig);
17405 final Configuration configCopy = new Configuration(mConfiguration);
17407 // TODO: If our config changes, should we auto dismiss any currently
17408 // showing dialogs?
17409 mShowDialogs = shouldShowDialogs(newConfig);
17411 AttributeCache ac = AttributeCache.instance();
17413 ac.updateConfiguration(configCopy);
17416 // Make sure all resources in our process are updated
17417 // right now, so that anyone who is going to retrieve
17418 // resource values after we return will be sure to get
17419 // the new ones. This is especially important during
17420 // boot, where the first config change needs to guarantee
17421 // all resources have that config before following boot
17422 // code is executed.
17423 mSystemThread.applyConfigurationToResources(configCopy);
17425 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17426 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17427 msg.obj = new Configuration(configCopy);
17428 mHandler.sendMessage(msg);
17431 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17432 ProcessRecord app = mLruProcesses.get(i);
17434 if (app.thread != null) {
17435 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17436 + app.processName + " new config " + mConfiguration);
17437 app.thread.scheduleConfigurationChanged(configCopy);
17439 } catch (Exception e) {
17442 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17443 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17444 | Intent.FLAG_RECEIVER_REPLACE_PENDING
17445 | Intent.FLAG_RECEIVER_FOREGROUND);
17446 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17447 null, AppOpsManager.OP_NONE, null, false, false,
17448 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17449 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17450 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17451 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17452 if (!mProcessesReady) {
17453 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17455 broadcastIntentLocked(null, null, intent,
17456 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17457 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17462 boolean kept = true;
17463 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17464 // mainStack is null during startup.
17465 if (mainStack != null) {
17466 if (changes != 0 && starting == null) {
17467 // If the configuration changed, and the caller is not already
17468 // in the process of starting an activity, then find the top
17469 // activity to check if its configuration needs to change.
17470 starting = mainStack.topRunningActivityLocked(null);
17473 if (starting != null) {
17474 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17475 // And we need to make sure at this point that all other activities
17476 // are made visible with the correct configuration.
17477 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17481 if (values != null && mWindowManager != null) {
17482 mWindowManager.setNewConfiguration(mConfiguration);
17489 * Decide based on the configuration whether we should shouw the ANR,
17490 * crash, etc dialogs. The idea is that if there is no affordnace to
17491 * press the on-screen buttons, we shouldn't show the dialog.
17493 * A thought: SystemUI might also want to get told about this, the Power
17494 * dialog / global actions also might want different behaviors.
17496 private static final boolean shouldShowDialogs(Configuration config) {
17497 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17498 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17499 && config.navigation == Configuration.NAVIGATION_NONAV);
17503 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17504 synchronized (this) {
17505 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17506 if (srec != null) {
17507 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17513 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17514 Intent resultData) {
17516 synchronized (this) {
17517 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17519 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17525 public int getLaunchedFromUid(IBinder activityToken) {
17526 ActivityRecord srec;
17527 synchronized (this) {
17528 srec = ActivityRecord.forTokenLocked(activityToken);
17530 if (srec == null) {
17533 return srec.launchedFromUid;
17536 public String getLaunchedFromPackage(IBinder activityToken) {
17537 ActivityRecord srec;
17538 synchronized (this) {
17539 srec = ActivityRecord.forTokenLocked(activityToken);
17541 if (srec == null) {
17544 return srec.launchedFromPackage;
17547 // =========================================================
17548 // LIFETIME MANAGEMENT
17549 // =========================================================
17551 // Returns which broadcast queue the app is the current [or imminent] receiver
17552 // on, or 'null' if the app is not an active broadcast recipient.
17553 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17554 BroadcastRecord r = app.curReceiver;
17559 // It's not the current receiver, but it might be starting up to become one
17560 synchronized (this) {
17561 for (BroadcastQueue queue : mBroadcastQueues) {
17562 r = queue.mPendingBroadcast;
17563 if (r != null && r.curApp == app) {
17564 // found it; report which queue it's in
17573 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17574 ComponentName targetComponent, String targetProcess) {
17575 if (!mTrackingAssociations) {
17578 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17579 = mAssociations.get(targetUid);
17580 if (components == null) {
17581 components = new ArrayMap<>();
17582 mAssociations.put(targetUid, components);
17584 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17585 if (sourceUids == null) {
17586 sourceUids = new SparseArray<>();
17587 components.put(targetComponent, sourceUids);
17589 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17590 if (sourceProcesses == null) {
17591 sourceProcesses = new ArrayMap<>();
17592 sourceUids.put(sourceUid, sourceProcesses);
17594 Association ass = sourceProcesses.get(sourceProcess);
17596 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17598 sourceProcesses.put(sourceProcess, ass);
17602 if (ass.mNesting == 1) {
17603 ass.mStartTime = SystemClock.uptimeMillis();
17608 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17609 ComponentName targetComponent) {
17610 if (!mTrackingAssociations) {
17613 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17614 = mAssociations.get(targetUid);
17615 if (components == null) {
17618 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17619 if (sourceUids == null) {
17622 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17623 if (sourceProcesses == null) {
17626 Association ass = sourceProcesses.get(sourceProcess);
17627 if (ass == null || ass.mNesting <= 0) {
17631 if (ass.mNesting == 0) {
17632 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17636 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17637 boolean doingAll, long now) {
17638 if (mAdjSeq == app.adjSeq) {
17639 // This adjustment has already been computed.
17640 return app.curRawAdj;
17643 if (app.thread == null) {
17644 app.adjSeq = mAdjSeq;
17645 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17646 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17647 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17650 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17651 app.adjSource = null;
17652 app.adjTarget = null;
17654 app.cached = false;
17656 final int activitiesSize = app.activities.size();
17658 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17659 // The max adjustment doesn't allow this app to be anything
17660 // below foreground, so it is not worth doing work for it.
17661 app.adjType = "fixed";
17662 app.adjSeq = mAdjSeq;
17663 app.curRawAdj = app.maxAdj;
17664 app.foregroundActivities = false;
17665 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17666 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17667 // System processes can do UI, and when they do we want to have
17668 // them trim their memory after the user leaves the UI. To
17669 // facilitate this, here we need to determine whether or not it
17670 // is currently showing UI.
17671 app.systemNoUi = true;
17672 if (app == TOP_APP) {
17673 app.systemNoUi = false;
17674 } else if (activitiesSize > 0) {
17675 for (int j = 0; j < activitiesSize; j++) {
17676 final ActivityRecord r = app.activities.get(j);
17678 app.systemNoUi = false;
17682 if (!app.systemNoUi) {
17683 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17685 return (app.curAdj=app.maxAdj);
17688 app.systemNoUi = false;
17690 final int PROCESS_STATE_TOP = mTopProcessState;
17692 // Determine the importance of the process, starting with most
17693 // important to least, and assign an appropriate OOM adjustment.
17697 boolean foregroundActivities = false;
17698 BroadcastQueue queue;
17699 if (app == TOP_APP) {
17700 // The last app on the list is the foreground app.
17701 adj = ProcessList.FOREGROUND_APP_ADJ;
17702 schedGroup = Process.THREAD_GROUP_DEFAULT;
17703 app.adjType = "top-activity";
17704 foregroundActivities = true;
17705 procState = PROCESS_STATE_TOP;
17706 } else if (app.instrumentationClass != null) {
17707 // Don't want to kill running instrumentation.
17708 adj = ProcessList.FOREGROUND_APP_ADJ;
17709 schedGroup = Process.THREAD_GROUP_DEFAULT;
17710 app.adjType = "instrumentation";
17711 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17712 } else if ((queue = isReceivingBroadcast(app)) != null) {
17713 // An app that is currently receiving a broadcast also
17714 // counts as being in the foreground for OOM killer purposes.
17715 // It's placed in a sched group based on the nature of the
17716 // broadcast as reflected by which queue it's active in.
17717 adj = ProcessList.FOREGROUND_APP_ADJ;
17718 schedGroup = (queue == mFgBroadcastQueue)
17719 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17720 app.adjType = "broadcast";
17721 procState = ActivityManager.PROCESS_STATE_RECEIVER;
17722 } else if (app.executingServices.size() > 0) {
17723 // An app that is currently executing a service callback also
17724 // counts as being in the foreground.
17725 adj = ProcessList.FOREGROUND_APP_ADJ;
17726 schedGroup = app.execServicesFg ?
17727 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17728 app.adjType = "exec-service";
17729 procState = ActivityManager.PROCESS_STATE_SERVICE;
17730 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17732 // As far as we know the process is empty. We may change our mind later.
17733 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17734 // At this point we don't actually know the adjustment. Use the cached adj
17735 // value that the caller wants us to.
17737 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17740 app.adjType = "cch-empty";
17743 // Examine all activities if not already foreground.
17744 if (!foregroundActivities && activitiesSize > 0) {
17745 for (int j = 0; j < activitiesSize; j++) {
17746 final ActivityRecord r = app.activities.get(j);
17747 if (r.app != app) {
17748 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17749 + app + "?!? Using " + r.app + " instead.");
17753 // App has a visible activity; only upgrade adjustment.
17754 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17755 adj = ProcessList.VISIBLE_APP_ADJ;
17756 app.adjType = "visible";
17758 if (procState > PROCESS_STATE_TOP) {
17759 procState = PROCESS_STATE_TOP;
17761 schedGroup = Process.THREAD_GROUP_DEFAULT;
17762 app.cached = false;
17764 foregroundActivities = true;
17766 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17767 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17768 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17769 app.adjType = "pausing";
17771 if (procState > PROCESS_STATE_TOP) {
17772 procState = PROCESS_STATE_TOP;
17774 schedGroup = Process.THREAD_GROUP_DEFAULT;
17775 app.cached = false;
17777 foregroundActivities = true;
17778 } else if (r.state == ActivityState.STOPPING) {
17779 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17780 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17781 app.adjType = "stopping";
17783 // For the process state, we will at this point consider the
17784 // process to be cached. It will be cached either as an activity
17785 // or empty depending on whether the activity is finishing. We do
17786 // this so that we can treat the process as cached for purposes of
17787 // memory trimming (determing current memory level, trim command to
17788 // send to process) since there can be an arbitrary number of stopping
17789 // processes and they should soon all go into the cached state.
17790 if (!r.finishing) {
17791 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17792 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17795 app.cached = false;
17797 foregroundActivities = true;
17799 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17800 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17801 app.adjType = "cch-act";
17807 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17808 if (app.foregroundServices) {
17809 // The user is aware of this app, so make it visible.
17810 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17811 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17812 app.cached = false;
17813 app.adjType = "fg-service";
17814 schedGroup = Process.THREAD_GROUP_DEFAULT;
17815 } else if (app.forcingToForeground != null) {
17816 // The user is aware of this app, so make it visible.
17817 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17818 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17819 app.cached = false;
17820 app.adjType = "force-fg";
17821 app.adjSource = app.forcingToForeground;
17822 schedGroup = Process.THREAD_GROUP_DEFAULT;
17826 if (app == mHeavyWeightProcess) {
17827 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17828 // We don't want to kill the current heavy-weight process.
17829 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17830 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17831 app.cached = false;
17832 app.adjType = "heavy";
17834 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17835 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17839 if (app == mHomeProcess) {
17840 if (adj > ProcessList.HOME_APP_ADJ) {
17841 // This process is hosting what we currently consider to be the
17842 // home app, so we don't want to let it go into the background.
17843 adj = ProcessList.HOME_APP_ADJ;
17844 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17845 app.cached = false;
17846 app.adjType = "home";
17848 if (procState > ActivityManager.PROCESS_STATE_HOME) {
17849 procState = ActivityManager.PROCESS_STATE_HOME;
17853 if (app == mPreviousProcess && app.activities.size() > 0) {
17854 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17855 // This was the previous process that showed UI to the user.
17856 // We want to try to keep it around more aggressively, to give
17857 // a good experience around switching between two apps.
17858 adj = ProcessList.PREVIOUS_APP_ADJ;
17859 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17860 app.cached = false;
17861 app.adjType = "previous";
17863 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17864 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17868 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17869 + " reason=" + app.adjType);
17871 // By default, we use the computed adjustment. It may be changed if
17872 // there are applications dependent on our services or providers, but
17873 // this gives us a baseline and makes sure we don't get into an
17874 // infinite recursion.
17875 app.adjSeq = mAdjSeq;
17876 app.curRawAdj = adj;
17877 app.hasStartedServices = false;
17879 if (mBackupTarget != null && app == mBackupTarget.app) {
17880 // If possible we want to avoid killing apps while they're being backed up
17881 if (adj > ProcessList.BACKUP_APP_ADJ) {
17882 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17883 adj = ProcessList.BACKUP_APP_ADJ;
17884 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17885 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17887 app.adjType = "backup";
17888 app.cached = false;
17890 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
17891 procState = ActivityManager.PROCESS_STATE_BACKUP;
17895 boolean mayBeTop = false;
17897 for (int is = app.services.size()-1;
17898 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17899 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17900 || procState > ActivityManager.PROCESS_STATE_TOP);
17902 ServiceRecord s = app.services.valueAt(is);
17903 if (s.startRequested) {
17904 app.hasStartedServices = true;
17905 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
17906 procState = ActivityManager.PROCESS_STATE_SERVICE;
17908 if (app.hasShownUi && app != mHomeProcess) {
17909 // If this process has shown some UI, let it immediately
17910 // go to the LRU list because it may be pretty heavy with
17911 // UI stuff. We'll tag it with a label just to help
17912 // debug and understand what is going on.
17913 if (adj > ProcessList.SERVICE_ADJ) {
17914 app.adjType = "cch-started-ui-services";
17917 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17918 // This service has seen some activity within
17919 // recent memory, so we will keep its process ahead
17920 // of the background processes.
17921 if (adj > ProcessList.SERVICE_ADJ) {
17922 adj = ProcessList.SERVICE_ADJ;
17923 app.adjType = "started-services";
17924 app.cached = false;
17927 // If we have let the service slide into the background
17928 // state, still have some text describing what it is doing
17929 // even though the service no longer has an impact.
17930 if (adj > ProcessList.SERVICE_ADJ) {
17931 app.adjType = "cch-started-services";
17935 for (int conni = s.connections.size()-1;
17936 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
17937 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17938 || procState > ActivityManager.PROCESS_STATE_TOP);
17940 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
17942 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
17943 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
17944 || procState > ActivityManager.PROCESS_STATE_TOP);
17946 // XXX should compute this based on the max of
17947 // all connected clients.
17948 ConnectionRecord cr = clist.get(i);
17949 if (cr.binding.client == app) {
17950 // Binding to ourself is not interesting.
17953 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
17954 ProcessRecord client = cr.binding.client;
17955 int clientAdj = computeOomAdjLocked(client, cachedAdj,
17956 TOP_APP, doingAll, now);
17957 int clientProcState = client.curProcState;
17958 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17959 // If the other app is cached for any reason, for purposes here
17960 // we are going to consider it empty. The specific cached state
17961 // doesn't propagate except under certain conditions.
17962 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17964 String adjType = null;
17965 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
17966 // Not doing bind OOM management, so treat
17967 // this guy more like a started service.
17968 if (app.hasShownUi && app != mHomeProcess) {
17969 // If this process has shown some UI, let it immediately
17970 // go to the LRU list because it may be pretty heavy with
17971 // UI stuff. We'll tag it with a label just to help
17972 // debug and understand what is going on.
17973 if (adj > clientAdj) {
17974 adjType = "cch-bound-ui-services";
17976 app.cached = false;
17978 clientProcState = procState;
17980 if (now >= (s.lastActivity
17981 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
17982 // This service has not seen activity within
17983 // recent memory, so allow it to drop to the
17984 // LRU list if there is no other reason to keep
17985 // it around. We'll also tag it with a label just
17986 // to help debug and undertand what is going on.
17987 if (adj > clientAdj) {
17988 adjType = "cch-bound-services";
17994 if (adj > clientAdj) {
17995 // If this process has recently shown UI, and
17996 // the process that is binding to it is less
17997 // important than being visible, then we don't
17998 // care about the binding as much as we care
17999 // about letting this process get into the LRU
18000 // list to be killed and restarted if needed for
18002 if (app.hasShownUi && app != mHomeProcess
18003 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18004 adjType = "cch-bound-ui-services";
18006 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18007 |Context.BIND_IMPORTANT)) != 0) {
18008 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18009 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18010 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18011 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18012 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18013 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18014 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
18017 if (adj > ProcessList.VISIBLE_APP_ADJ) {
18018 adj = ProcessList.VISIBLE_APP_ADJ;
18021 if (!client.cached) {
18022 app.cached = false;
18024 adjType = "service";
18027 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18028 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18029 schedGroup = Process.THREAD_GROUP_DEFAULT;
18031 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18032 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18033 // Special handling of clients who are in the top state.
18034 // We *may* want to consider this process to be in the
18035 // top state as well, but only if there is not another
18036 // reason for it to be running. Being on the top is a
18037 // special state, meaning you are specifically running
18038 // for the current top app. If the process is already
18039 // running in the background for some other reason, it
18040 // is more important to continue considering it to be
18041 // in the background state.
18043 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18045 // Special handling for above-top states (persistent
18046 // processes). These should not bring the current process
18047 // into the top state, since they are not on top. Instead
18048 // give them the best state after that.
18049 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18051 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18052 } else if (mWakefulness
18053 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18054 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18057 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18060 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18065 if (clientProcState <
18066 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18068 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18071 if (procState > clientProcState) {
18072 procState = clientProcState;
18074 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18075 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18076 app.pendingUiClean = true;
18078 if (adjType != null) {
18079 app.adjType = adjType;
18080 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18081 .REASON_SERVICE_IN_USE;
18082 app.adjSource = cr.binding.client;
18083 app.adjSourceProcState = clientProcState;
18084 app.adjTarget = s.name;
18087 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18088 app.treatLikeActivity = true;
18090 final ActivityRecord a = cr.activity;
18091 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18092 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18093 (a.visible || a.state == ActivityState.RESUMED
18094 || a.state == ActivityState.PAUSING)) {
18095 adj = ProcessList.FOREGROUND_APP_ADJ;
18096 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18097 schedGroup = Process.THREAD_GROUP_DEFAULT;
18099 app.cached = false;
18100 app.adjType = "service";
18101 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18102 .REASON_SERVICE_IN_USE;
18104 app.adjSourceProcState = procState;
18105 app.adjTarget = s.name;
18112 for (int provi = app.pubProviders.size()-1;
18113 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18114 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18115 || procState > ActivityManager.PROCESS_STATE_TOP);
18117 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18118 for (int i = cpr.connections.size()-1;
18119 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18120 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18121 || procState > ActivityManager.PROCESS_STATE_TOP);
18123 ContentProviderConnection conn = cpr.connections.get(i);
18124 ProcessRecord client = conn.client;
18125 if (client == app) {
18126 // Being our own client is not interesting.
18129 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18130 int clientProcState = client.curProcState;
18131 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18132 // If the other app is cached for any reason, for purposes here
18133 // we are going to consider it empty.
18134 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18136 if (adj > clientAdj) {
18137 if (app.hasShownUi && app != mHomeProcess
18138 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18139 app.adjType = "cch-ui-provider";
18141 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18142 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18143 app.adjType = "provider";
18145 app.cached &= client.cached;
18146 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18147 .REASON_PROVIDER_IN_USE;
18148 app.adjSource = client;
18149 app.adjSourceProcState = clientProcState;
18150 app.adjTarget = cpr.name;
18152 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18153 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18154 // Special handling of clients who are in the top state.
18155 // We *may* want to consider this process to be in the
18156 // top state as well, but only if there is not another
18157 // reason for it to be running. Being on the top is a
18158 // special state, meaning you are specifically running
18159 // for the current top app. If the process is already
18160 // running in the background for some other reason, it
18161 // is more important to continue considering it to be
18162 // in the background state.
18164 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18166 // Special handling for above-top states (persistent
18167 // processes). These should not bring the current process
18168 // into the top state, since they are not on top. Instead
18169 // give them the best state after that.
18171 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18174 if (procState > clientProcState) {
18175 procState = clientProcState;
18177 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18178 schedGroup = Process.THREAD_GROUP_DEFAULT;
18181 // If the provider has external (non-framework) process
18182 // dependencies, ensure that its adjustment is at least
18183 // FOREGROUND_APP_ADJ.
18184 if (cpr.hasExternalProcessHandles()) {
18185 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18186 adj = ProcessList.FOREGROUND_APP_ADJ;
18187 schedGroup = Process.THREAD_GROUP_DEFAULT;
18188 app.cached = false;
18189 app.adjType = "provider";
18190 app.adjTarget = cpr.name;
18192 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18193 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18198 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18199 // A client of one of our services or providers is in the top state. We
18200 // *may* want to be in the top state, but not if we are already running in
18201 // the background for some other reason. For the decision here, we are going
18202 // to pick out a few specific states that we want to remain in when a client
18203 // is top (states that tend to be longer-term) and otherwise allow it to go
18204 // to the top state.
18205 switch (procState) {
18206 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18207 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18208 case ActivityManager.PROCESS_STATE_SERVICE:
18209 // These all are longer-term states, so pull them up to the top
18210 // of the background states, but not all the way to the top state.
18211 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18214 // Otherwise, top is a better choice, so take it.
18215 procState = ActivityManager.PROCESS_STATE_TOP;
18220 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18221 if (app.hasClientActivities) {
18222 // This is a cached process, but with client activities. Mark it so.
18223 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18224 app.adjType = "cch-client-act";
18225 } else if (app.treatLikeActivity) {
18226 // This is a cached process, but somebody wants us to treat it like it has
18227 // an activity, okay!
18228 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18229 app.adjType = "cch-as-act";
18233 if (adj == ProcessList.SERVICE_ADJ) {
18235 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18236 mNewNumServiceProcs++;
18237 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18238 if (!app.serviceb) {
18239 // This service isn't far enough down on the LRU list to
18240 // normally be a B service, but if we are low on RAM and it
18241 // is large we want to force it down since we would prefer to
18242 // keep launcher over it.
18243 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18244 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18245 app.serviceHighRam = true;
18246 app.serviceb = true;
18247 //Slog.i(TAG, "ADJ " + app + " high ram!");
18249 mNewNumAServiceProcs++;
18250 //Slog.i(TAG, "ADJ " + app + " not high ram!");
18253 app.serviceHighRam = false;
18256 if (app.serviceb) {
18257 adj = ProcessList.SERVICE_B_ADJ;
18261 app.curRawAdj = adj;
18263 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18264 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18265 if (adj > app.maxAdj) {
18267 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18268 schedGroup = Process.THREAD_GROUP_DEFAULT;
18272 // Do final modification to adj. Everything we do between here and applying
18273 // the final setAdj must be done in this function, because we will also use
18274 // it when computing the final cached adj later. Note that we don't need to
18275 // worry about this for max adj above, since max adj will always be used to
18276 // keep it out of the cached vaues.
18277 app.curAdj = app.modifyRawOomAdj(adj);
18278 app.curSchedGroup = schedGroup;
18279 app.curProcState = procState;
18280 app.foregroundActivities = foregroundActivities;
18282 return app.curRawAdj;
18286 * Record new PSS sample for a process.
18288 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18289 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18290 proc.lastPssTime = now;
18291 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18292 if (DEBUG_PSS) Slog.d(TAG_PSS,
18293 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18294 + " state=" + ProcessList.makeProcStateString(procState));
18295 if (proc.initialIdlePss == 0) {
18296 proc.initialIdlePss = pss;
18298 proc.lastPss = pss;
18299 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18300 proc.lastCachedPss = pss;
18303 final SparseArray<Pair<Long, String>> watchUids
18304 = mMemWatchProcesses.getMap().get(proc.processName);
18306 if (watchUids != null) {
18307 Pair<Long, String> val = watchUids.get(proc.uid);
18309 val = watchUids.get(0);
18315 if (check != null) {
18316 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18317 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18318 if (!isDebuggable) {
18319 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18320 isDebuggable = true;
18323 if (isDebuggable) {
18324 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18325 final ProcessRecord myProc = proc;
18326 final File heapdumpFile = DumpHeapProvider.getJavaFile();
18327 mMemWatchDumpProcName = proc.processName;
18328 mMemWatchDumpFile = heapdumpFile.toString();
18329 mMemWatchDumpPid = proc.pid;
18330 mMemWatchDumpUid = proc.uid;
18331 BackgroundThread.getHandler().post(new Runnable() {
18333 public void run() {
18334 revokeUriPermission(ActivityThread.currentActivityThread()
18335 .getApplicationThread(),
18336 DumpHeapActivity.JAVA_URI,
18337 Intent.FLAG_GRANT_READ_URI_PERMISSION
18338 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18339 UserHandle.myUserId());
18340 ParcelFileDescriptor fd = null;
18342 heapdumpFile.delete();
18343 fd = ParcelFileDescriptor.open(heapdumpFile,
18344 ParcelFileDescriptor.MODE_CREATE |
18345 ParcelFileDescriptor.MODE_TRUNCATE |
18346 ParcelFileDescriptor.MODE_WRITE_ONLY |
18347 ParcelFileDescriptor.MODE_APPEND);
18348 IApplicationThread thread = myProc.thread;
18349 if (thread != null) {
18351 if (DEBUG_PSS) Slog.d(TAG_PSS,
18352 "Requesting dump heap from "
18353 + myProc + " to " + heapdumpFile);
18354 thread.dumpHeap(true, heapdumpFile.toString(), fd);
18355 } catch (RemoteException e) {
18358 } catch (FileNotFoundException e) {
18359 e.printStackTrace();
18364 } catch (IOException e) {
18371 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18372 + ", but debugging not enabled");
18379 * Schedule PSS collection of a process.
18381 void requestPssLocked(ProcessRecord proc, int procState) {
18382 if (mPendingPssProcesses.contains(proc)) {
18385 if (mPendingPssProcesses.size() == 0) {
18386 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18388 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18389 proc.pssProcState = procState;
18390 mPendingPssProcesses.add(proc);
18394 * Schedule PSS collection of all processes.
18396 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18398 if (now < (mLastFullPssTime +
18399 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18403 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
18404 mLastFullPssTime = now;
18405 mFullPssPending = true;
18406 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18407 mPendingPssProcesses.clear();
18408 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18409 ProcessRecord app = mLruProcesses.get(i);
18410 if (app.thread == null
18411 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18414 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18415 app.pssProcState = app.setProcState;
18416 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18417 mTestPssMode, isSleeping(), now);
18418 mPendingPssProcesses.add(app);
18421 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18424 public void setTestPssMode(boolean enabled) {
18425 synchronized (this) {
18426 mTestPssMode = enabled;
18428 // Whenever we enable the mode, we want to take a snapshot all of current
18429 // process mem use.
18430 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18436 * Ask a given process to GC right now.
18438 final void performAppGcLocked(ProcessRecord app) {
18440 app.lastRequestedGc = SystemClock.uptimeMillis();
18441 if (app.thread != null) {
18442 if (app.reportLowMemory) {
18443 app.reportLowMemory = false;
18444 app.thread.scheduleLowMemory();
18446 app.thread.processInBackground();
18449 } catch (Exception e) {
18455 * Returns true if things are idle enough to perform GCs.
18457 private final boolean canGcNowLocked() {
18458 boolean processingBroadcasts = false;
18459 for (BroadcastQueue q : mBroadcastQueues) {
18460 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18461 processingBroadcasts = true;
18464 return !processingBroadcasts
18465 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18469 * Perform GCs on all processes that are waiting for it, but only
18470 * if things are idle.
18472 final void performAppGcsLocked() {
18473 final int N = mProcessesToGc.size();
18477 if (canGcNowLocked()) {
18478 while (mProcessesToGc.size() > 0) {
18479 ProcessRecord proc = mProcessesToGc.remove(0);
18480 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18481 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18482 <= SystemClock.uptimeMillis()) {
18483 // To avoid spamming the system, we will GC processes one
18484 // at a time, waiting a few seconds between each.
18485 performAppGcLocked(proc);
18486 scheduleAppGcsLocked();
18489 // It hasn't been long enough since we last GCed this
18490 // process... put it in the list to wait for its time.
18491 addProcessToGcListLocked(proc);
18497 scheduleAppGcsLocked();
18502 * If all looks good, perform GCs on all processes waiting for them.
18504 final void performAppGcsIfAppropriateLocked() {
18505 if (canGcNowLocked()) {
18506 performAppGcsLocked();
18509 // Still not idle, wait some more.
18510 scheduleAppGcsLocked();
18514 * Schedule the execution of all pending app GCs.
18516 final void scheduleAppGcsLocked() {
18517 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18519 if (mProcessesToGc.size() > 0) {
18520 // Schedule a GC for the time to the next process.
18521 ProcessRecord proc = mProcessesToGc.get(0);
18522 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18524 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18525 long now = SystemClock.uptimeMillis();
18526 if (when < (now+GC_TIMEOUT)) {
18527 when = now + GC_TIMEOUT;
18529 mHandler.sendMessageAtTime(msg, when);
18534 * Add a process to the array of processes waiting to be GCed. Keeps the
18535 * list in sorted order by the last GC time. The process can't already be
18538 final void addProcessToGcListLocked(ProcessRecord proc) {
18539 boolean added = false;
18540 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18541 if (mProcessesToGc.get(i).lastRequestedGc <
18542 proc.lastRequestedGc) {
18544 mProcessesToGc.add(i+1, proc);
18549 mProcessesToGc.add(0, proc);
18554 * Set up to ask a process to GC itself. This will either do it
18555 * immediately, or put it on the list of processes to gc the next
18556 * time things are idle.
18558 final void scheduleAppGcLocked(ProcessRecord app) {
18559 long now = SystemClock.uptimeMillis();
18560 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18563 if (!mProcessesToGc.contains(app)) {
18564 addProcessToGcListLocked(app);
18565 scheduleAppGcsLocked();
18569 final void checkExcessivePowerUsageLocked(boolean doKills) {
18570 updateCpuStatsNow();
18572 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18573 boolean doWakeKills = doKills;
18574 boolean doCpuKills = doKills;
18575 if (mLastPowerCheckRealtime == 0) {
18576 doWakeKills = false;
18578 if (mLastPowerCheckUptime == 0) {
18579 doCpuKills = false;
18581 if (stats.isScreenOn()) {
18582 doWakeKills = false;
18584 final long curRealtime = SystemClock.elapsedRealtime();
18585 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18586 final long curUptime = SystemClock.uptimeMillis();
18587 final long uptimeSince = curUptime - mLastPowerCheckUptime;
18588 mLastPowerCheckRealtime = curRealtime;
18589 mLastPowerCheckUptime = curUptime;
18590 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18591 doWakeKills = false;
18593 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18594 doCpuKills = false;
18596 int i = mLruProcesses.size();
18599 ProcessRecord app = mLruProcesses.get(i);
18600 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18602 synchronized (stats) {
18603 wtime = stats.getProcessWakeTime(app.info.uid,
18604 app.pid, curRealtime);
18606 long wtimeUsed = wtime - app.lastWakeTime;
18607 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18609 StringBuilder sb = new StringBuilder(128);
18610 sb.append("Wake for ");
18611 app.toShortString(sb);
18612 sb.append(": over ");
18613 TimeUtils.formatDuration(realtimeSince, sb);
18614 sb.append(" used ");
18615 TimeUtils.formatDuration(wtimeUsed, sb);
18617 sb.append((wtimeUsed*100)/realtimeSince);
18619 Slog.i(TAG_POWER, sb.toString());
18621 sb.append("CPU for ");
18622 app.toShortString(sb);
18623 sb.append(": over ");
18624 TimeUtils.formatDuration(uptimeSince, sb);
18625 sb.append(" used ");
18626 TimeUtils.formatDuration(cputimeUsed, sb);
18628 sb.append((cputimeUsed*100)/uptimeSince);
18630 Slog.i(TAG_POWER, sb.toString());
18632 // If a process has held a wake lock for more
18633 // than 50% of the time during this period,
18634 // that sounds bad. Kill!
18635 if (doWakeKills && realtimeSince > 0
18636 && ((wtimeUsed*100)/realtimeSince) >= 50) {
18637 synchronized (stats) {
18638 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18639 realtimeSince, wtimeUsed);
18641 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18642 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18643 } else if (doCpuKills && uptimeSince > 0
18644 && ((cputimeUsed*100)/uptimeSince) >= 25) {
18645 synchronized (stats) {
18646 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18647 uptimeSince, cputimeUsed);
18649 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18650 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18652 app.lastWakeTime = wtime;
18653 app.lastCpuTime = app.curCpuTime;
18659 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now) {
18660 boolean success = true;
18662 if (app.curRawAdj != app.setRawAdj) {
18663 app.setRawAdj = app.curRawAdj;
18668 if (app.curAdj != app.setAdj) {
18669 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18670 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18671 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18673 app.setAdj = app.curAdj;
18676 if (app.setSchedGroup != app.curSchedGroup) {
18677 app.setSchedGroup = app.curSchedGroup;
18678 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18679 "Setting process group of " + app.processName
18680 + " to " + app.curSchedGroup);
18681 if (app.waitingToKill != null && app.curReceiver == null
18682 && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18683 app.kill(app.waitingToKill, true);
18687 long oldId = Binder.clearCallingIdentity();
18689 Process.setProcessGroup(app.pid, app.curSchedGroup);
18690 } catch (Exception e) {
18691 Slog.w(TAG, "Failed setting process group of " + app.pid
18692 + " to " + app.curSchedGroup);
18693 e.printStackTrace();
18695 Binder.restoreCallingIdentity(oldId);
18698 if (app.thread != null) {
18700 app.thread.setSchedulingGroup(app.curSchedGroup);
18701 } catch (RemoteException e) {
18705 Process.setSwappiness(app.pid,
18706 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18709 if (app.repForegroundActivities != app.foregroundActivities) {
18710 app.repForegroundActivities = app.foregroundActivities;
18711 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18713 if (app.repProcState != app.curProcState) {
18714 app.repProcState = app.curProcState;
18715 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18716 if (app.thread != null) {
18719 //RuntimeException h = new RuntimeException("here");
18720 Slog.i(TAG, "Sending new process state " + app.repProcState
18721 + " to " + app /*, h*/);
18723 app.thread.setProcessState(app.repProcState);
18724 } catch (RemoteException e) {
18728 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18729 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18730 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18731 // Experimental code to more aggressively collect pss while
18732 // running test... the problem is that this tends to collect
18733 // the data right when a process is transitioning between process
18734 // states, which well tend to give noisy data.
18735 long start = SystemClock.uptimeMillis();
18736 long pss = Debug.getPss(app.pid, mTmpLong, null);
18737 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18738 mPendingPssProcesses.remove(app);
18739 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18740 + " to " + app.curProcState + ": "
18741 + (SystemClock.uptimeMillis()-start) + "ms");
18743 app.lastStateTime = now;
18744 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18745 mTestPssMode, isSleeping(), now);
18746 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18747 + ProcessList.makeProcStateString(app.setProcState) + " to "
18748 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18749 + (app.nextPssTime-now) + ": " + app);
18751 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18752 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18754 requestPssLocked(app, app.setProcState);
18755 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18756 mTestPssMode, isSleeping(), now);
18757 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18758 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18760 if (app.setProcState != app.curProcState) {
18761 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18762 "Proc state change of " + app.processName
18763 + " to " + app.curProcState);
18764 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18765 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18766 if (setImportant && !curImportant) {
18767 // This app is no longer something we consider important enough to allow to
18768 // use arbitrary amounts of battery power. Note
18769 // its current wake lock time to later know to kill it if
18770 // it is not behaving well.
18771 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18772 synchronized (stats) {
18773 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18774 app.pid, SystemClock.elapsedRealtime());
18776 app.lastCpuTime = app.curCpuTime;
18779 // Inform UsageStats of important process state change
18780 // Must be called before updating setProcState
18781 maybeUpdateUsageStatsLocked(app);
18783 app.setProcState = app.curProcState;
18784 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18785 app.notCachedSinceIdle = false;
18788 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18790 app.procStateChanged = true;
18794 if (changes != 0) {
18795 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18796 "Changes in " + app + ": " + changes);
18797 int i = mPendingProcessChanges.size()-1;
18798 ProcessChangeItem item = null;
18800 item = mPendingProcessChanges.get(i);
18801 if (item.pid == app.pid) {
18802 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18803 "Re-using existing item: " + item);
18809 // No existing item in pending changes; need a new one.
18810 final int NA = mAvailProcessChanges.size();
18812 item = mAvailProcessChanges.remove(NA-1);
18813 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18814 "Retrieving available item: " + item);
18816 item = new ProcessChangeItem();
18817 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18818 "Allocating new item: " + item);
18821 item.pid = app.pid;
18822 item.uid = app.info.uid;
18823 if (mPendingProcessChanges.size() == 0) {
18824 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18825 "*** Enqueueing dispatch processes changed!");
18826 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18828 mPendingProcessChanges.add(item);
18830 item.changes |= changes;
18831 item.processState = app.repProcState;
18832 item.foregroundActivities = app.repForegroundActivities;
18833 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18834 "Item " + Integer.toHexString(System.identityHashCode(item))
18835 + " " + app.toShortString() + ": changes=" + item.changes
18836 + " procState=" + item.processState
18837 + " foreground=" + item.foregroundActivities
18838 + " type=" + app.adjType + " source=" + app.adjSource
18839 + " target=" + app.adjTarget);
18845 private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18846 if (uidRec.pendingChange == null) {
18847 if (mPendingUidChanges.size() == 0) {
18848 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18849 "*** Enqueueing dispatch uid changed!");
18850 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18852 final int NA = mAvailUidChanges.size();
18854 uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18855 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18856 "Retrieving available item: " + uidRec.pendingChange);
18858 uidRec.pendingChange = new UidRecord.ChangeItem();
18859 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18860 "Allocating new item: " + uidRec.pendingChange);
18862 uidRec.pendingChange.uidRecord = uidRec;
18863 uidRec.pendingChange.uid = uidRec.uid;
18864 mPendingUidChanges.add(uidRec.pendingChange);
18866 uidRec.pendingChange.gone = gone;
18867 uidRec.pendingChange.processState = uidRec.setProcState;
18870 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18871 String authority) {
18872 if (app == null) return;
18873 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18874 UserState userState = mStartedUsers.get(app.userId);
18875 if (userState == null) return;
18876 final long now = SystemClock.elapsedRealtime();
18877 Long lastReported = userState.mProviderLastReportedFg.get(authority);
18878 if (lastReported == null || lastReported < now - 60 * 1000L) {
18879 mUsageStatsService.reportContentProviderUsage(
18880 authority, providerPkgName, app.userId);
18881 userState.mProviderLastReportedFg.put(authority, now);
18886 private void maybeUpdateUsageStatsLocked(ProcessRecord app) {
18887 if (DEBUG_USAGE_STATS) {
18888 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
18889 + "] state changes: old = " + app.setProcState + ", new = "
18890 + app.curProcState);
18892 if (mUsageStatsService == null) {
18895 boolean isInteraction;
18896 // To avoid some abuse patterns, we are going to be careful about what we consider
18897 // to be an app interaction. Being the top activity doesn't count while the display
18898 // is sleeping, nor do short foreground services.
18899 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
18900 isInteraction = true;
18901 app.fgInteractionTime = 0;
18902 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
18903 final long now = SystemClock.elapsedRealtime();
18904 if (app.fgInteractionTime == 0) {
18905 app.fgInteractionTime = now;
18906 isInteraction = false;
18908 isInteraction = now > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
18911 isInteraction = app.curProcState
18912 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18913 app.fgInteractionTime = 0;
18915 if (isInteraction && !app.reportedInteraction) {
18916 String[] packages = app.getPackageList();
18917 if (packages != null) {
18918 for (int i = 0; i < packages.length; i++) {
18919 mUsageStatsService.reportEvent(packages[i], app.userId,
18920 UsageEvents.Event.SYSTEM_INTERACTION);
18924 app.reportedInteraction = isInteraction;
18927 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
18928 if (proc.thread != null) {
18929 if (proc.baseProcessTracker != null) {
18930 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
18932 if (proc.repProcState >= 0) {
18933 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
18934 proc.repProcState);
18939 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
18940 ProcessRecord TOP_APP, boolean doingAll, long now) {
18941 if (app.thread == null) {
18945 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
18947 return applyOomAdjLocked(app, doingAll, now);
18950 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
18952 if (isForeground != proc.foregroundServices) {
18953 proc.foregroundServices = isForeground;
18954 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
18956 if (isForeground) {
18957 if (curProcs == null) {
18958 curProcs = new ArrayList<ProcessRecord>();
18959 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
18961 if (!curProcs.contains(proc)) {
18962 curProcs.add(proc);
18963 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
18964 proc.info.packageName, proc.info.uid);
18967 if (curProcs != null) {
18968 if (curProcs.remove(proc)) {
18969 mBatteryStatsService.noteEvent(
18970 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
18971 proc.info.packageName, proc.info.uid);
18972 if (curProcs.size() <= 0) {
18973 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
18979 updateOomAdjLocked();
18984 private final ActivityRecord resumedAppLocked() {
18985 ActivityRecord act = mStackSupervisor.resumedAppLocked();
18989 pkg = act.packageName;
18990 uid = act.info.applicationInfo.uid;
18995 // Has the UID or resumed package name changed?
18996 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
18997 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
18998 if (mCurResumedPackage != null) {
18999 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19000 mCurResumedPackage, mCurResumedUid);
19002 mCurResumedPackage = pkg;
19003 mCurResumedUid = uid;
19004 if (mCurResumedPackage != null) {
19005 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19006 mCurResumedPackage, mCurResumedUid);
19012 final boolean updateOomAdjLocked(ProcessRecord app) {
19013 final ActivityRecord TOP_ACT = resumedAppLocked();
19014 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19015 final boolean wasCached = app.cached;
19019 // This is the desired cached adjusment we want to tell it to use.
19020 // If our app is currently cached, we know it, and that is it. Otherwise,
19021 // we don't know it yet, and it needs to now be cached we will then
19022 // need to do a complete oom adj.
19023 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19024 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19025 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19026 SystemClock.uptimeMillis());
19027 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19028 // Changed to/from cached state, so apps after it in the LRU
19029 // list may also be changed.
19030 updateOomAdjLocked();
19035 final void updateOomAdjLocked() {
19036 final ActivityRecord TOP_ACT = resumedAppLocked();
19037 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19038 final long now = SystemClock.uptimeMillis();
19039 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19040 final int N = mLruProcesses.size();
19043 RuntimeException e = new RuntimeException();
19044 e.fillInStackTrace();
19045 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19048 // Reset state in all uid records.
19049 for (int i=mActiveUids.size()-1; i>=0; i--) {
19050 final UidRecord uidRec = mActiveUids.valueAt(i);
19051 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19052 "Starting update of " + uidRec);
19057 mNewNumServiceProcs = 0;
19058 mNewNumAServiceProcs = 0;
19060 final int emptyProcessLimit;
19061 final int cachedProcessLimit;
19062 if (mProcessLimit <= 0) {
19063 emptyProcessLimit = cachedProcessLimit = 0;
19064 } else if (mProcessLimit == 1) {
19065 emptyProcessLimit = 1;
19066 cachedProcessLimit = 0;
19068 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19069 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19072 // Let's determine how many processes we have running vs.
19073 // how many slots we have for background processes; we may want
19074 // to put multiple processes in a slot of there are enough of
19076 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19077 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19078 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19079 if (numEmptyProcs > cachedProcessLimit) {
19080 // If there are more empty processes than our limit on cached
19081 // processes, then use the cached process limit for the factor.
19082 // This ensures that the really old empty processes get pushed
19083 // down to the bottom, so if we are running low on memory we will
19084 // have a better chance at keeping around more cached processes
19085 // instead of a gazillion empty processes.
19086 numEmptyProcs = cachedProcessLimit;
19088 int emptyFactor = numEmptyProcs/numSlots;
19089 if (emptyFactor < 1) emptyFactor = 1;
19090 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19091 if (cachedFactor < 1) cachedFactor = 1;
19092 int stepCached = 0;
19096 int numTrimming = 0;
19098 mNumNonCachedProcs = 0;
19099 mNumCachedHiddenProcs = 0;
19101 // First update the OOM adjustment for each of the
19102 // application processes based on their current state.
19103 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19104 int nextCachedAdj = curCachedAdj+1;
19105 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19106 int nextEmptyAdj = curEmptyAdj+2;
19107 for (int i=N-1; i>=0; i--) {
19108 ProcessRecord app = mLruProcesses.get(i);
19109 if (!app.killedByAm && app.thread != null) {
19110 app.procStateChanged = false;
19111 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19113 // If we haven't yet assigned the final cached adj
19114 // to the process, do that now.
19115 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19116 switch (app.curProcState) {
19117 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19118 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19119 // This process is a cached process holding activities...
19120 // assign it the next cached value for that type, and then
19121 // step that cached level.
19122 app.curRawAdj = curCachedAdj;
19123 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19124 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19125 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19127 if (curCachedAdj != nextCachedAdj) {
19129 if (stepCached >= cachedFactor) {
19131 curCachedAdj = nextCachedAdj;
19132 nextCachedAdj += 2;
19133 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19134 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19140 // For everything else, assign next empty cached process
19141 // level and bump that up. Note that this means that
19142 // long-running services that have dropped down to the
19143 // cached level will be treated as empty (since their process
19144 // state is still as a service), which is what we want.
19145 app.curRawAdj = curEmptyAdj;
19146 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19147 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19148 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19150 if (curEmptyAdj != nextEmptyAdj) {
19152 if (stepEmpty >= emptyFactor) {
19154 curEmptyAdj = nextEmptyAdj;
19156 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19157 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19165 applyOomAdjLocked(app, true, now);
19167 // Count the number of process types.
19168 switch (app.curProcState) {
19169 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19170 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19171 mNumCachedHiddenProcs++;
19173 if (numCached > cachedProcessLimit) {
19174 app.kill("cached #" + numCached, true);
19177 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19178 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19179 && app.lastActivityTime < oldTime) {
19180 app.kill("empty for "
19181 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19182 / 1000) + "s", true);
19185 if (numEmpty > emptyProcessLimit) {
19186 app.kill("empty #" + numEmpty, true);
19191 mNumNonCachedProcs++;
19195 if (app.isolated && app.services.size() <= 0) {
19196 // If this is an isolated process, and there are no
19197 // services running in it, then the process is no longer
19198 // needed. We agressively kill these because we can by
19199 // definition not re-use the same process again, and it is
19200 // good to avoid having whatever code was running in them
19201 // left sitting around after no longer needed.
19202 app.kill("isolated not needed", true);
19204 // Keeping this process, update its uid.
19205 final UidRecord uidRec = app.uidRecord;
19206 if (uidRec != null && uidRec.curProcState > app.curProcState) {
19207 uidRec.curProcState = app.curProcState;
19211 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19212 && !app.killedByAm) {
19218 mNumServiceProcs = mNewNumServiceProcs;
19220 // Now determine the memory trimming level of background processes.
19221 // Unfortunately we need to start at the back of the list to do this
19222 // properly. We only do this if the number of background apps we
19223 // are managing to keep around is less than half the maximum we desire;
19224 // if we are keeping a good number around, we'll let them use whatever
19225 // memory they want.
19226 final int numCachedAndEmpty = numCached + numEmpty;
19228 if (numCached <= ProcessList.TRIM_CACHED_APPS
19229 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19230 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19231 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19232 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19233 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19235 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19238 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19240 // We always allow the memory level to go up (better). We only allow it to go
19241 // down if we are in a state where that is allowed, *and* the total number of processes
19242 // has gone down since last time.
19243 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19244 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19245 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19246 if (memFactor > mLastMemoryLevel) {
19247 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19248 memFactor = mLastMemoryLevel;
19249 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19252 mLastMemoryLevel = memFactor;
19253 mLastNumProcesses = mLruProcesses.size();
19254 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19255 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19256 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19257 if (mLowRamStartTime == 0) {
19258 mLowRamStartTime = now;
19262 switch (memFactor) {
19263 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19264 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19266 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19267 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19270 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19273 int factor = numTrimming/3;
19275 if (mHomeProcess != null) minFactor++;
19276 if (mPreviousProcess != null) minFactor++;
19277 if (factor < minFactor) factor = minFactor;
19278 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19279 for (int i=N-1; i>=0; i--) {
19280 ProcessRecord app = mLruProcesses.get(i);
19281 if (allChanged || app.procStateChanged) {
19282 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19283 app.procStateChanged = false;
19285 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19286 && !app.killedByAm) {
19287 if (app.trimMemoryLevel < curLevel && app.thread != null) {
19289 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19290 "Trimming memory of " + app.processName + " to " + curLevel);
19291 app.thread.scheduleTrimMemory(curLevel);
19292 } catch (RemoteException e) {
19295 // For now we won't do this; our memory trimming seems
19296 // to be good enough at this point that destroying
19297 // activities causes more harm than good.
19298 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19299 && app != mHomeProcess && app != mPreviousProcess) {
19300 // Need to do this on its own message because the stack may not
19301 // be in a consistent state at this point.
19302 // For these apps we will also finish their activities
19303 // to help them free memory.
19304 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19308 app.trimMemoryLevel = curLevel;
19310 if (step >= factor) {
19312 switch (curLevel) {
19313 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19314 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19316 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19317 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19321 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19322 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19323 && app.thread != null) {
19325 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19326 "Trimming memory of heavy-weight " + app.processName
19327 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19328 app.thread.scheduleTrimMemory(
19329 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19330 } catch (RemoteException e) {
19333 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19335 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19336 || app.systemNoUi) && app.pendingUiClean) {
19337 // If this application is now in the background and it
19338 // had done UI, then give it the special trim level to
19339 // have it free UI resources.
19340 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19341 if (app.trimMemoryLevel < level && app.thread != null) {
19343 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19344 "Trimming memory of bg-ui " + app.processName
19346 app.thread.scheduleTrimMemory(level);
19347 } catch (RemoteException e) {
19350 app.pendingUiClean = false;
19352 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19354 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19355 "Trimming memory of fg " + app.processName
19356 + " to " + fgTrimLevel);
19357 app.thread.scheduleTrimMemory(fgTrimLevel);
19358 } catch (RemoteException e) {
19361 app.trimMemoryLevel = fgTrimLevel;
19365 if (mLowRamStartTime != 0) {
19366 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19367 mLowRamStartTime = 0;
19369 for (int i=N-1; i>=0; i--) {
19370 ProcessRecord app = mLruProcesses.get(i);
19371 if (allChanged || app.procStateChanged) {
19372 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19373 app.procStateChanged = false;
19375 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19376 || app.systemNoUi) && app.pendingUiClean) {
19377 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19378 && app.thread != null) {
19380 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19381 "Trimming memory of ui hidden " + app.processName
19382 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19383 app.thread.scheduleTrimMemory(
19384 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19385 } catch (RemoteException e) {
19388 app.pendingUiClean = false;
19390 app.trimMemoryLevel = 0;
19394 if (mAlwaysFinishActivities) {
19395 // Need to do this on its own message because the stack may not
19396 // be in a consistent state at this point.
19397 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19401 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19404 // Update from any uid changes.
19405 for (int i=mActiveUids.size()-1; i>=0; i--) {
19406 final UidRecord uidRec = mActiveUids.valueAt(i);
19407 if (uidRec.setProcState != uidRec.curProcState) {
19408 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19409 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19410 + " to " + uidRec.curProcState);
19411 uidRec.setProcState = uidRec.curProcState;
19412 enqueueUidChangeLocked(uidRec, false);
19416 if (mProcessStats.shouldWriteNowLocked(now)) {
19417 mHandler.post(new Runnable() {
19418 @Override public void run() {
19419 synchronized (ActivityManagerService.this) {
19420 mProcessStats.writeStateAsyncLocked();
19426 if (DEBUG_OOM_ADJ) {
19427 final long duration = SystemClock.uptimeMillis() - now;
19429 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19430 new RuntimeException("here").fillInStackTrace());
19432 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19437 final void trimApplications() {
19438 synchronized (this) {
19441 // First remove any unused application processes whose package
19442 // has been removed.
19443 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19444 final ProcessRecord app = mRemovedProcesses.get(i);
19445 if (app.activities.size() == 0
19446 && app.curReceiver == null && app.services.size() == 0) {
19448 TAG, "Exiting empty application process "
19449 + app.processName + " ("
19450 + (app.thread != null ? app.thread.asBinder() : null)
19452 if (app.pid > 0 && app.pid != MY_PID) {
19453 app.kill("empty", false);
19456 app.thread.scheduleExit();
19457 } catch (Exception e) {
19458 // Ignore exceptions.
19461 cleanUpApplicationRecordLocked(app, false, true, -1);
19462 mRemovedProcesses.remove(i);
19464 if (app.persistent) {
19465 addAppLocked(app.info, false, null /* ABI override */);
19470 // Now update the oom adj for all processes.
19471 updateOomAdjLocked();
19475 /** This method sends the specified signal to each of the persistent apps */
19476 public void signalPersistentProcesses(int sig) throws RemoteException {
19477 if (sig != Process.SIGNAL_USR1) {
19478 throw new SecurityException("Only SIGNAL_USR1 is allowed");
19481 synchronized (this) {
19482 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19483 != PackageManager.PERMISSION_GRANTED) {
19484 throw new SecurityException("Requires permission "
19485 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19488 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19489 ProcessRecord r = mLruProcesses.get(i);
19490 if (r.thread != null && r.persistent) {
19491 Process.sendSignal(r.pid, sig);
19497 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19498 if (proc == null || proc == mProfileProc) {
19499 proc = mProfileProc;
19500 profileType = mProfileType;
19501 clearProfilerLocked();
19503 if (proc == null) {
19507 proc.thread.profilerControl(false, null, profileType);
19508 } catch (RemoteException e) {
19509 throw new IllegalStateException("Process disappeared");
19513 private void clearProfilerLocked() {
19514 if (mProfileFd != null) {
19516 mProfileFd.close();
19517 } catch (IOException e) {
19520 mProfileApp = null;
19521 mProfileProc = null;
19522 mProfileFile = null;
19524 mAutoStopProfiler = false;
19525 mSamplingInterval = 0;
19528 public boolean profileControl(String process, int userId, boolean start,
19529 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19532 synchronized (this) {
19533 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19534 // its own permission.
19535 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19536 != PackageManager.PERMISSION_GRANTED) {
19537 throw new SecurityException("Requires permission "
19538 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19541 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19542 throw new IllegalArgumentException("null profile info or fd");
19545 ProcessRecord proc = null;
19546 if (process != null) {
19547 proc = findProcessLocked(process, userId, "profileControl");
19550 if (start && (proc == null || proc.thread == null)) {
19551 throw new IllegalArgumentException("Unknown process: " + process);
19555 stopProfilerLocked(null, 0);
19556 setProfileApp(proc.info, proc.processName, profilerInfo);
19557 mProfileProc = proc;
19558 mProfileType = profileType;
19559 ParcelFileDescriptor fd = profilerInfo.profileFd;
19562 } catch (IOException e) {
19565 profilerInfo.profileFd = fd;
19566 proc.thread.profilerControl(start, profilerInfo, profileType);
19570 stopProfilerLocked(proc, profileType);
19571 if (profilerInfo != null && profilerInfo.profileFd != null) {
19573 profilerInfo.profileFd.close();
19574 } catch (IOException e) {
19581 } catch (RemoteException e) {
19582 throw new IllegalStateException("Process disappeared");
19584 if (profilerInfo != null && profilerInfo.profileFd != null) {
19586 profilerInfo.profileFd.close();
19587 } catch (IOException e) {
19593 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19594 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19595 userId, true, ALLOW_FULL_ONLY, callName, null);
19596 ProcessRecord proc = null;
19598 int pid = Integer.parseInt(process);
19599 synchronized (mPidsSelfLocked) {
19600 proc = mPidsSelfLocked.get(pid);
19602 } catch (NumberFormatException e) {
19605 if (proc == null) {
19606 ArrayMap<String, SparseArray<ProcessRecord>> all
19607 = mProcessNames.getMap();
19608 SparseArray<ProcessRecord> procs = all.get(process);
19609 if (procs != null && procs.size() > 0) {
19610 proc = procs.valueAt(0);
19611 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19612 for (int i=1; i<procs.size(); i++) {
19613 ProcessRecord thisProc = procs.valueAt(i);
19614 if (thisProc.userId == userId) {
19626 public boolean dumpHeap(String process, int userId, boolean managed,
19627 String path, ParcelFileDescriptor fd) throws RemoteException {
19630 synchronized (this) {
19631 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19632 // its own permission (same as profileControl).
19633 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19634 != PackageManager.PERMISSION_GRANTED) {
19635 throw new SecurityException("Requires permission "
19636 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19640 throw new IllegalArgumentException("null fd");
19643 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19644 if (proc == null || proc.thread == null) {
19645 throw new IllegalArgumentException("Unknown process: " + process);
19648 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19649 if (!isDebuggable) {
19650 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19651 throw new SecurityException("Process not debuggable: " + proc);
19655 proc.thread.dumpHeap(managed, path, fd);
19659 } catch (RemoteException e) {
19660 throw new IllegalStateException("Process disappeared");
19665 } catch (IOException e) {
19672 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19673 String reportPackage) {
19674 if (processName != null) {
19675 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19676 "setDumpHeapDebugLimit()");
19678 synchronized (mPidsSelfLocked) {
19679 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19680 if (proc == null) {
19681 throw new SecurityException("No process found for calling pid "
19682 + Binder.getCallingPid());
19684 if (!Build.IS_DEBUGGABLE
19685 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19686 throw new SecurityException("Not running a debuggable build");
19688 processName = proc.processName;
19690 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19691 throw new SecurityException("Package " + reportPackage + " is not running in "
19696 synchronized (this) {
19697 if (maxMemSize > 0) {
19698 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19701 mMemWatchProcesses.remove(processName, uid);
19703 mMemWatchProcesses.getMap().remove(processName);
19710 public void dumpHeapFinished(String path) {
19711 synchronized (this) {
19712 if (Binder.getCallingPid() != mMemWatchDumpPid) {
19713 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19714 + " does not match last pid " + mMemWatchDumpPid);
19717 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19718 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19719 + " does not match last path " + mMemWatchDumpFile);
19722 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19723 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19727 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19728 public void monitor() {
19729 synchronized (this) { }
19732 void onCoreSettingsChange(Bundle settings) {
19733 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19734 ProcessRecord processRecord = mLruProcesses.get(i);
19736 if (processRecord.thread != null) {
19737 processRecord.thread.setCoreSettings(settings);
19739 } catch (RemoteException re) {
19745 // Multi-user methods
19748 * Start user, if its not already running, but don't bring it to foreground.
19751 public boolean startUserInBackground(final int userId) {
19752 return startUser(userId, /* foreground */ false);
19756 * Start user, if its not already running, and bring it to foreground.
19758 boolean startUserInForeground(final int userId, Dialog dlg) {
19759 boolean result = startUser(userId, /* foreground */ true);
19765 * Refreshes the list of users related to the current user when either a
19766 * user switch happens or when a new related user is started in the
19769 private void updateCurrentProfileIdsLocked() {
19770 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19771 mCurrentUserId, false /* enabledOnly */);
19772 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19773 for (int i = 0; i < currentProfileIds.length; i++) {
19774 currentProfileIds[i] = profiles.get(i).id;
19776 mCurrentProfileIds = currentProfileIds;
19778 synchronized (mUserProfileGroupIdsSelfLocked) {
19779 mUserProfileGroupIdsSelfLocked.clear();
19780 final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19781 for (int i = 0; i < users.size(); i++) {
19782 UserInfo user = users.get(i);
19783 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19784 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19790 private Set<Integer> getProfileIdsLocked(int userId) {
19791 Set<Integer> userIds = new HashSet<Integer>();
19792 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19793 userId, false /* enabledOnly */);
19794 for (UserInfo user : profiles) {
19795 userIds.add(Integer.valueOf(user.id));
19801 public boolean switchUser(final int userId) {
19802 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19804 synchronized (this) {
19805 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19806 if (userInfo == null) {
19807 Slog.w(TAG, "No user info for user #" + userId);
19810 if (userInfo.isManagedProfile()) {
19811 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19814 userName = userInfo.name;
19815 mTargetUserId = userId;
19817 mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19818 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19822 private void showUserSwitchDialog(int userId, String userName) {
19823 // The dialog will show and then initiate the user switch by calling startUserInForeground
19824 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19825 true /* above system */);
19829 private boolean startUser(final int userId, final boolean foreground) {
19830 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19831 != PackageManager.PERMISSION_GRANTED) {
19832 String msg = "Permission Denial: switchUser() from pid="
19833 + Binder.getCallingPid()
19834 + ", uid=" + Binder.getCallingUid()
19835 + " requires " + INTERACT_ACROSS_USERS_FULL;
19837 throw new SecurityException(msg);
19840 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19842 final long ident = Binder.clearCallingIdentity();
19844 synchronized (this) {
19845 final int oldUserId = mCurrentUserId;
19846 if (oldUserId == userId) {
19850 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19851 "startUser", false);
19853 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19854 if (userInfo == null) {
19855 Slog.w(TAG, "No user info for user #" + userId);
19858 if (foreground && userInfo.isManagedProfile()) {
19859 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19864 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19865 R.anim.screen_user_enter);
19868 boolean needStart = false;
19870 // If the user we are switching to is not currently started, then
19871 // we need to start it now.
19872 if (mStartedUsers.get(userId) == null) {
19873 mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
19874 updateStartedUserArrayLocked();
19878 final Integer userIdInt = Integer.valueOf(userId);
19879 mUserLru.remove(userIdInt);
19880 mUserLru.add(userIdInt);
19883 mCurrentUserId = userId;
19884 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
19885 updateCurrentProfileIdsLocked();
19886 mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
19887 // Once the internal notion of the active user has switched, we lock the device
19888 // with the option to show the user switcher on the keyguard.
19889 mWindowManager.lockNow(null);
19891 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
19892 updateCurrentProfileIdsLocked();
19893 mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
19894 mUserLru.remove(currentUserIdInt);
19895 mUserLru.add(currentUserIdInt);
19898 final UserState uss = mStartedUsers.get(userId);
19900 // Make sure user is in the started state. If it is currently
19901 // stopping, we need to knock that off.
19902 if (uss.mState == UserState.STATE_STOPPING) {
19903 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
19904 // so we can just fairly silently bring the user back from
19905 // the almost-dead.
19906 uss.mState = UserState.STATE_RUNNING;
19907 updateStartedUserArrayLocked();
19909 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
19910 // This means ACTION_SHUTDOWN has been sent, so we will
19911 // need to treat this as a new boot of the user.
19912 uss.mState = UserState.STATE_BOOTING;
19913 updateStartedUserArrayLocked();
19917 if (uss.mState == UserState.STATE_BOOTING) {
19918 // Booting up a new user, need to tell system services about it.
19919 // Note that this is on the same handler as scheduling of broadcasts,
19920 // which is important because it needs to go first.
19921 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
19925 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
19927 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
19928 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
19929 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
19930 oldUserId, userId, uss));
19931 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
19932 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
19936 // Send USER_STARTED broadcast
19937 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
19938 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19939 | Intent.FLAG_RECEIVER_FOREGROUND);
19940 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19941 broadcastIntentLocked(null, null, intent,
19942 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19943 null, false, false, MY_PID, Process.SYSTEM_UID, userId);
19946 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
19947 if (userId != UserHandle.USER_OWNER) {
19948 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
19949 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19950 broadcastIntentLocked(null, null, intent, null,
19951 new IIntentReceiver.Stub() {
19952 public void performReceive(Intent intent, int resultCode,
19953 String data, Bundle extras, boolean ordered,
19954 boolean sticky, int sendingUser) {
19955 onUserInitialized(uss, foreground, oldUserId, userId);
19957 }, 0, null, null, null, AppOpsManager.OP_NONE,
19958 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
19959 uss.initializing = true;
19961 getUserManagerLocked().makeInitialized(userInfo.id);
19966 if (!uss.initializing) {
19967 moveUserToForeground(uss, oldUserId, userId);
19970 mStackSupervisor.startBackgroundUserLocked(userId, uss);
19974 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
19975 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19976 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
19977 broadcastIntentLocked(null, null, intent,
19978 null, new IIntentReceiver.Stub() {
19980 public void performReceive(Intent intent, int resultCode,
19981 String data, Bundle extras, boolean ordered, boolean sticky,
19982 int sendingUser) throws RemoteException {
19985 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
19986 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19990 Binder.restoreCallingIdentity(ident);
19996 void dispatchForegroundProfileChanged(int userId) {
19997 final int N = mUserSwitchObservers.beginBroadcast();
19998 for (int i = 0; i < N; i++) {
20000 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
20001 } catch (RemoteException e) {
20005 mUserSwitchObservers.finishBroadcast();
20008 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
20009 long ident = Binder.clearCallingIdentity();
20012 if (oldUserId >= 0) {
20013 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
20014 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
20015 int count = profiles.size();
20016 for (int i = 0; i < count; i++) {
20017 int profileUserId = profiles.get(i).id;
20018 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
20019 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20020 | Intent.FLAG_RECEIVER_FOREGROUND);
20021 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20022 broadcastIntentLocked(null, null, intent,
20023 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20024 null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20027 if (newUserId >= 0) {
20028 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
20029 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, 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_FOREGROUND);
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);
20041 intent = new Intent(Intent.ACTION_USER_SWITCHED);
20042 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20043 | Intent.FLAG_RECEIVER_FOREGROUND);
20044 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
20045 broadcastIntentLocked(null, null, intent,
20046 null, null, 0, null, null,
20047 new String[] {android.Manifest.permission.MANAGE_USERS},
20048 AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20049 UserHandle.USER_ALL);
20052 Binder.restoreCallingIdentity(ident);
20056 void dispatchUserSwitch(final UserState uss, final int oldUserId,
20057 final int newUserId) {
20058 final int N = mUserSwitchObservers.beginBroadcast();
20060 final IRemoteCallback callback = new IRemoteCallback.Stub() {
20063 public void sendResult(Bundle data) throws RemoteException {
20064 synchronized (ActivityManagerService.this) {
20065 if (mCurUserSwitchCallback == this) {
20068 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20074 synchronized (this) {
20075 uss.switching = true;
20076 mCurUserSwitchCallback = callback;
20078 for (int i=0; i<N; i++) {
20080 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20081 newUserId, callback);
20082 } catch (RemoteException e) {
20086 synchronized (this) {
20087 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20090 mUserSwitchObservers.finishBroadcast();
20093 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20094 synchronized (this) {
20095 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20096 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20100 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20101 mCurUserSwitchCallback = null;
20102 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20103 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20104 oldUserId, newUserId, uss));
20107 void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20108 synchronized (this) {
20110 moveUserToForeground(uss, oldUserId, newUserId);
20114 completeSwitchAndInitialize(uss, newUserId, true, false);
20117 void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20118 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20120 startHomeActivityLocked(newUserId, "moveUserToFroreground");
20122 mStackSupervisor.resumeTopActivitiesLocked();
20124 EventLogTags.writeAmSwitchUser(newUserId);
20125 getUserManagerLocked().onUserForeground(newUserId);
20126 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20129 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20130 completeSwitchAndInitialize(uss, newUserId, false, true);
20133 void completeSwitchAndInitialize(UserState uss, int newUserId,
20134 boolean clearInitializing, boolean clearSwitching) {
20135 boolean unfrozen = false;
20136 synchronized (this) {
20137 if (clearInitializing) {
20138 uss.initializing = false;
20139 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20141 if (clearSwitching) {
20142 uss.switching = false;
20144 if (!uss.switching && !uss.initializing) {
20145 mWindowManager.stopFreezingScreen();
20150 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20151 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20154 stopGuestUserIfBackground();
20157 /** Called on handler thread */
20158 void dispatchUserSwitchComplete(int userId) {
20159 final int observerCount = mUserSwitchObservers.beginBroadcast();
20160 for (int i = 0; i < observerCount; i++) {
20162 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20163 } catch (RemoteException e) {
20166 mUserSwitchObservers.finishBroadcast();
20170 * Stops the guest user if it has gone to the background.
20172 private void stopGuestUserIfBackground() {
20173 synchronized (this) {
20174 final int num = mUserLru.size();
20175 for (int i = 0; i < num; i++) {
20176 Integer oldUserId = mUserLru.get(i);
20177 UserState oldUss = mStartedUsers.get(oldUserId);
20178 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20179 || oldUss.mState == UserState.STATE_STOPPING
20180 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20183 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20184 if (userInfo.isGuest()) {
20185 // This is a user to be stopped.
20186 stopUserLocked(oldUserId, null);
20193 void scheduleStartProfilesLocked() {
20194 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20195 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20196 DateUtils.SECOND_IN_MILLIS);
20200 void startProfilesLocked() {
20201 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20202 List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20203 mCurrentUserId, false /* enabledOnly */);
20204 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20205 for (UserInfo user : profiles) {
20206 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20207 && user.id != mCurrentUserId) {
20211 final int n = toStart.size();
20213 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20214 startUserInBackground(toStart.get(i).id);
20217 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20221 void finishUserBoot(UserState uss) {
20222 synchronized (this) {
20223 if (uss.mState == UserState.STATE_BOOTING
20224 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20225 uss.mState = UserState.STATE_RUNNING;
20226 final int userId = uss.mHandle.getIdentifier();
20227 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20228 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20229 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20230 broadcastIntentLocked(null, null, intent,
20231 null, null, 0, null, null,
20232 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20233 AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20239 void finishUserSwitch(UserState uss) {
20240 synchronized (this) {
20241 finishUserBoot(uss);
20243 startProfilesLocked();
20245 int num = mUserLru.size();
20247 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20248 Integer oldUserId = mUserLru.get(i);
20249 UserState oldUss = mStartedUsers.get(oldUserId);
20250 if (oldUss == null) {
20251 // Shouldn't happen, but be sane if it does.
20252 mUserLru.remove(i);
20256 if (oldUss.mState == UserState.STATE_STOPPING
20257 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20258 // This user is already stopping, doesn't count.
20263 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20264 // Owner and current can't be stopped, but count as running.
20268 // This is a user to be stopped.
20269 stopUserLocked(oldUserId, null);
20277 public int stopUser(final int userId, final IStopUserCallback callback) {
20278 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20279 != PackageManager.PERMISSION_GRANTED) {
20280 String msg = "Permission Denial: switchUser() from pid="
20281 + Binder.getCallingPid()
20282 + ", uid=" + Binder.getCallingUid()
20283 + " requires " + INTERACT_ACROSS_USERS_FULL;
20285 throw new SecurityException(msg);
20287 if (userId < 0 || userId == UserHandle.USER_OWNER) {
20288 throw new IllegalArgumentException("Can't stop primary user " + userId);
20290 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20291 synchronized (this) {
20292 return stopUserLocked(userId, callback);
20296 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20297 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20298 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20299 return ActivityManager.USER_OP_IS_CURRENT;
20302 final UserState uss = mStartedUsers.get(userId);
20304 // User is not started, nothing to do... but we do need to
20305 // callback if requested.
20306 if (callback != null) {
20307 mHandler.post(new Runnable() {
20309 public void run() {
20311 callback.userStopped(userId);
20312 } catch (RemoteException e) {
20317 return ActivityManager.USER_OP_SUCCESS;
20320 if (callback != null) {
20321 uss.mStopCallbacks.add(callback);
20324 if (uss.mState != UserState.STATE_STOPPING
20325 && uss.mState != UserState.STATE_SHUTDOWN) {
20326 uss.mState = UserState.STATE_STOPPING;
20327 updateStartedUserArrayLocked();
20329 long ident = Binder.clearCallingIdentity();
20331 // We are going to broadcast ACTION_USER_STOPPING and then
20332 // once that is done send a final ACTION_SHUTDOWN and then
20334 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20335 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20336 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20337 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20338 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20339 // This is the result receiver for the final shutdown broadcast.
20340 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20342 public void performReceive(Intent intent, int resultCode, String data,
20343 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20344 finishUserStop(uss);
20347 // This is the result receiver for the initial stopping broadcast.
20348 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20350 public void performReceive(Intent intent, int resultCode, String data,
20351 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20353 synchronized (ActivityManagerService.this) {
20354 if (uss.mState != UserState.STATE_STOPPING) {
20355 // Whoops, we are being started back up. Abort, abort!
20358 uss.mState = UserState.STATE_SHUTDOWN;
20360 mBatteryStatsService.noteEvent(
20361 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20362 Integer.toString(userId), userId);
20363 mSystemServiceManager.stopUser(userId);
20364 broadcastIntentLocked(null, null, shutdownIntent,
20365 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20366 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20369 // Kick things off.
20370 broadcastIntentLocked(null, null, stoppingIntent,
20371 null, stoppingReceiver, 0, null, null,
20372 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20373 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20375 Binder.restoreCallingIdentity(ident);
20379 return ActivityManager.USER_OP_SUCCESS;
20382 void finishUserStop(UserState uss) {
20383 final int userId = uss.mHandle.getIdentifier();
20385 ArrayList<IStopUserCallback> callbacks;
20386 synchronized (this) {
20387 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20388 if (mStartedUsers.get(userId) != uss) {
20390 } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20394 // User can no longer run.
20395 mStartedUsers.remove(userId);
20396 mUserLru.remove(Integer.valueOf(userId));
20397 updateStartedUserArrayLocked();
20399 // Clean up all state and processes associated with the user.
20400 // Kill all the processes for the user.
20401 forceStopUserLocked(userId, "finish user");
20404 // Explicitly remove the old information in mRecentTasks.
20405 mRecentTasks.removeTasksForUserLocked(userId);
20408 for (int i=0; i<callbacks.size(); i++) {
20410 if (stopped) callbacks.get(i).userStopped(userId);
20411 else callbacks.get(i).userStopAborted(userId);
20412 } catch (RemoteException e) {
20417 mSystemServiceManager.cleanupUser(userId);
20418 synchronized (this) {
20419 mStackSupervisor.removeUserLocked(userId);
20425 public UserInfo getCurrentUser() {
20426 if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20427 != PackageManager.PERMISSION_GRANTED) && (
20428 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20429 != PackageManager.PERMISSION_GRANTED)) {
20430 String msg = "Permission Denial: getCurrentUser() from pid="
20431 + Binder.getCallingPid()
20432 + ", uid=" + Binder.getCallingUid()
20433 + " requires " + INTERACT_ACROSS_USERS;
20435 throw new SecurityException(msg);
20437 synchronized (this) {
20438 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20439 return getUserManagerLocked().getUserInfo(userId);
20443 int getCurrentUserIdLocked() {
20444 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20448 public boolean isUserRunning(int userId, boolean orStopped) {
20449 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20450 != PackageManager.PERMISSION_GRANTED) {
20451 String msg = "Permission Denial: isUserRunning() from pid="
20452 + Binder.getCallingPid()
20453 + ", uid=" + Binder.getCallingUid()
20454 + " requires " + INTERACT_ACROSS_USERS;
20456 throw new SecurityException(msg);
20458 synchronized (this) {
20459 return isUserRunningLocked(userId, orStopped);
20463 boolean isUserRunningLocked(int userId, boolean orStopped) {
20464 UserState state = mStartedUsers.get(userId);
20465 if (state == null) {
20471 return state.mState != UserState.STATE_STOPPING
20472 && state.mState != UserState.STATE_SHUTDOWN;
20476 public int[] getRunningUserIds() {
20477 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20478 != PackageManager.PERMISSION_GRANTED) {
20479 String msg = "Permission Denial: isUserRunning() from pid="
20480 + Binder.getCallingPid()
20481 + ", uid=" + Binder.getCallingUid()
20482 + " requires " + INTERACT_ACROSS_USERS;
20484 throw new SecurityException(msg);
20486 synchronized (this) {
20487 return mStartedUserArray;
20491 private void updateStartedUserArrayLocked() {
20493 for (int i=0; i<mStartedUsers.size(); i++) {
20494 UserState uss = mStartedUsers.valueAt(i);
20495 // This list does not include stopping users.
20496 if (uss.mState != UserState.STATE_STOPPING
20497 && uss.mState != UserState.STATE_SHUTDOWN) {
20501 mStartedUserArray = new int[num];
20503 for (int i=0; i<mStartedUsers.size(); i++) {
20504 UserState uss = mStartedUsers.valueAt(i);
20505 if (uss.mState != UserState.STATE_STOPPING
20506 && uss.mState != UserState.STATE_SHUTDOWN) {
20507 mStartedUserArray[num] = mStartedUsers.keyAt(i);
20514 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20515 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20516 != PackageManager.PERMISSION_GRANTED) {
20517 String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20518 + Binder.getCallingPid()
20519 + ", uid=" + Binder.getCallingUid()
20520 + " requires " + INTERACT_ACROSS_USERS_FULL;
20522 throw new SecurityException(msg);
20525 mUserSwitchObservers.register(observer);
20529 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20530 mUserSwitchObservers.unregister(observer);
20533 int[] getUsersLocked() {
20534 UserManagerService ums = getUserManagerLocked();
20535 return ums != null ? ums.getUserIds() : new int[] { 0 };
20538 UserManagerService getUserManagerLocked() {
20539 if (mUserManager == null) {
20540 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20541 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20543 return mUserManager;
20546 private int applyUserId(int uid, int userId) {
20547 return UserHandle.getUid(userId, uid);
20550 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20551 if (info == null) return null;
20552 ApplicationInfo newInfo = new ApplicationInfo(info);
20553 newInfo.uid = applyUserId(info.uid, userId);
20554 newInfo.dataDir = Environment
20555 .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20556 .getAbsolutePath();
20560 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20562 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20566 ActivityInfo info = new ActivityInfo(aInfo);
20567 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20571 private final class LocalService extends ActivityManagerInternal {
20573 public void onWakefulnessChanged(int wakefulness) {
20574 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20578 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20579 String processName, String abiOverride, int uid, Runnable crashHandler) {
20580 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20581 processName, abiOverride, uid, crashHandler);
20585 public SleepToken acquireSleepToken(String tag) {
20586 Preconditions.checkNotNull(tag);
20588 synchronized (ActivityManagerService.this) {
20589 SleepTokenImpl token = new SleepTokenImpl(tag);
20590 mSleepTokens.add(token);
20591 updateSleepIfNeededLocked();
20597 public ComponentName getHomeActivityForUser(int userId) {
20598 synchronized (ActivityManagerService.this) {
20599 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20600 return homeActivity == null ? null : homeActivity.realActivity;
20605 private final class SleepTokenImpl extends SleepToken {
20606 private final String mTag;
20607 private final long mAcquireTime;
20609 public SleepTokenImpl(String tag) {
20611 mAcquireTime = SystemClock.uptimeMillis();
20615 public void release() {
20616 synchronized (ActivityManagerService.this) {
20617 if (mSleepTokens.remove(this)) {
20618 updateSleepIfNeededLocked();
20624 public String toString() {
20625 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20630 * An implementation of IAppTask, that allows an app to manage its own tasks via
20631 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
20632 * only the process that calls getAppTasks() can call the AppTask methods.
20634 class AppTaskImpl extends IAppTask.Stub {
20635 private int mTaskId;
20636 private int mCallingUid;
20638 public AppTaskImpl(int taskId, int callingUid) {
20640 mCallingUid = callingUid;
20643 private void checkCaller() {
20644 if (mCallingUid != Binder.getCallingUid()) {
20645 throw new SecurityException("Caller " + mCallingUid
20646 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20651 public void finishAndRemoveTask() {
20654 synchronized (ActivityManagerService.this) {
20655 long origId = Binder.clearCallingIdentity();
20657 if (!removeTaskByIdLocked(mTaskId, false)) {
20658 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20661 Binder.restoreCallingIdentity(origId);
20667 public ActivityManager.RecentTaskInfo getTaskInfo() {
20670 synchronized (ActivityManagerService.this) {
20671 long origId = Binder.clearCallingIdentity();
20673 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20675 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20677 return createRecentTaskInfoFromTaskRecord(tr);
20679 Binder.restoreCallingIdentity(origId);
20685 public void moveToFront() {
20687 // Will bring task to front if it already has a root activity.
20688 startActivityFromRecentsInner(mTaskId, null);
20692 public int startActivity(IBinder whoThread, String callingPackage,
20693 Intent intent, String resolvedType, Bundle options) {
20696 int callingUser = UserHandle.getCallingUserId();
20698 IApplicationThread appThread;
20699 synchronized (ActivityManagerService.this) {
20700 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20702 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20704 appThread = ApplicationThreadNative.asInterface(whoThread);
20705 if (appThread == null) {
20706 throw new IllegalArgumentException("Bad app thread " + appThread);
20709 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20710 resolvedType, null, null, null, null, 0, 0, null, null,
20711 null, options, false, callingUser, null, tr);
20715 public void setExcludeFromRecents(boolean exclude) {
20718 synchronized (ActivityManagerService.this) {
20719 long origId = Binder.clearCallingIdentity();
20721 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20723 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20725 Intent intent = tr.getBaseIntent();
20727 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20729 intent.setFlags(intent.getFlags()
20730 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20733 Binder.restoreCallingIdentity(origId);