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.Downloads;
216 import android.provider.Settings;
217 import android.telecom.TelecomManager;
218 import android.text.format.DateUtils;
219 import android.text.format.Time;
220 import android.util.AtomicFile;
221 import android.util.EventLog;
222 import android.util.Log;
223 import android.util.Pair;
224 import android.util.PrintWriterPrinter;
225 import android.util.Slog;
226 import android.util.SparseArray;
227 import android.util.TimeUtils;
228 import android.util.Xml;
229 import android.view.Gravity;
230 import android.view.LayoutInflater;
231 import android.view.View;
232 import android.view.WindowManager;
234 import dalvik.system.VMRuntime;
236 import java.io.BufferedInputStream;
237 import java.io.BufferedOutputStream;
238 import java.io.DataInputStream;
239 import java.io.DataOutputStream;
241 import java.io.FileDescriptor;
242 import java.io.FileInputStream;
243 import java.io.FileNotFoundException;
244 import java.io.FileOutputStream;
245 import java.io.IOException;
246 import java.io.InputStreamReader;
247 import java.io.PrintWriter;
248 import java.io.StringWriter;
249 import java.lang.ref.WeakReference;
250 import java.nio.charset.StandardCharsets;
251 import java.util.ArrayList;
252 import java.util.Arrays;
253 import java.util.Collections;
254 import java.util.Comparator;
255 import java.util.HashMap;
256 import java.util.HashSet;
257 import java.util.Iterator;
258 import java.util.List;
259 import java.util.Locale;
260 import java.util.Map;
261 import java.util.Set;
262 import java.util.concurrent.atomic.AtomicBoolean;
263 import java.util.concurrent.atomic.AtomicLong;
265 public final class ActivityManagerService extends ActivityManagerNative
266 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
268 // File that stores last updated system version and called preboot receivers
269 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
271 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
272 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
273 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
274 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
275 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
276 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
277 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
278 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
279 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
280 private static final String TAG_LRU = TAG + POSTFIX_LRU;
281 private static final String TAG_MU = TAG + POSTFIX_MU;
282 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
283 private static final String TAG_POWER = TAG + POSTFIX_POWER;
284 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
285 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
286 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
287 private static final String TAG_PSS = TAG + POSTFIX_PSS;
288 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
289 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
290 private static final String TAG_STACK = TAG + POSTFIX_STACK;
291 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
292 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
293 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
294 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
295 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
297 /** Control over CPU and battery monitoring */
298 // write battery stats every 30 minutes.
299 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
300 static final boolean MONITOR_CPU_USAGE = true;
301 // don't sample cpu less than every 5 seconds.
302 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
303 // wait possibly forever for next cpu sample.
304 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
305 static final boolean MONITOR_THREAD_CPU_USAGE = false;
307 // The flags that are set for all calls we make to the package manager.
308 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
310 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
312 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
314 // Amount of time after a call to stopAppSwitches() during which we will
315 // prevent further untrusted switches from happening.
316 static final long APP_SWITCH_DELAY_TIME = 5*1000;
318 // How long we wait for a launched process to attach to the activity manager
319 // before we decide it's never going to come up for real.
320 static final int PROC_START_TIMEOUT = 10*1000;
321 // How long we wait for an attached process to publish its content providers
322 // before we decide it must be hung.
323 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
325 // How long we will retain processes hosting content providers in the "last activity"
326 // state before allowing them to drop down to the regular cached LRU list. This is
327 // to avoid thrashing of provider processes under low memory situations.
328 static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
330 // How long we wait for a launched process to attach to the activity manager
331 // before we decide it's never going to come up for real, when the process was
332 // started with a wrapper for instrumentation (such as Valgrind) because it
333 // could take much longer than usual.
334 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
336 // How long to wait after going idle before forcing apps to GC.
337 static final int GC_TIMEOUT = 5*1000;
339 // The minimum amount of time between successive GC requests for a process.
340 static final int GC_MIN_INTERVAL = 60*1000;
342 // The minimum amount of time between successive PSS requests for a process.
343 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
345 // The minimum amount of time between successive PSS requests for a process
346 // when the request is due to the memory state being lowered.
347 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
349 // The rate at which we check for apps using excessive power -- 15 mins.
350 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
352 // The minimum sample duration we will allow before deciding we have
353 // enough data on wake locks to start killing things.
354 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
356 // The minimum sample duration we will allow before deciding we have
357 // enough data on CPU usage to start killing things.
358 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
360 // How long we allow a receiver to run before giving up on it.
361 static final int BROADCAST_FG_TIMEOUT = 10*1000;
362 static final int BROADCAST_BG_TIMEOUT = 60*1000;
364 // How long we wait until we timeout on key dispatching.
365 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
367 // How long we wait until we timeout on key dispatching during instrumentation.
368 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
370 // Amount of time we wait for observers to handle a user switch before
371 // giving up on them and unfreezing the screen.
372 static final int USER_SWITCH_TIMEOUT = 2*1000;
374 // This is the amount of time an app needs to be running a foreground service before
375 // we will consider it to be doing interaction for usage stats.
376 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
378 // Maximum amount of time we will allow to elapse before re-reporting usage stats
379 // interaction with foreground processes.
380 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
382 // Maximum number of users we allow to be running at a time.
383 static final int MAX_RUNNING_USERS = 3;
385 // How long to wait in getAssistContextExtras for the activity and foreground services
386 // to respond with the result.
387 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
389 // How long top wait when going through the modern assist (which doesn't need to block
390 // on getting this result before starting to launch its UI).
391 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
393 // Maximum number of persisted Uri grants a package is allowed
394 static final int MAX_PERSISTED_URI_GRANTS = 128;
396 static final int MY_PID = Process.myPid();
398 static final String[] EMPTY_STRING_ARRAY = new String[0];
400 // How many bytes to write into the dropbox log before truncating
401 static final int DROPBOX_MAX_SIZE = 256 * 1024;
403 // Access modes for handleIncomingUser.
404 static final int ALLOW_NON_FULL = 0;
405 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
406 static final int ALLOW_FULL_ONLY = 2;
408 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
410 // Delay in notifying task stack change listeners (in millis)
411 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 1000;
413 // Necessary ApplicationInfo flags to mark an app as persistent
414 private static final int PERSISTENT_MASK =
415 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
418 // Delay to disable app launch boost
419 static final int APP_BOOST_MESSAGE_DELAY = 3000;
420 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
421 static final int APP_BOOST_TIMEOUT = 2500;
423 private static native int nativeMigrateToBoost();
424 private static native int nativeMigrateFromBoost();
425 private boolean mIsBoosted = false;
426 private long mBoostStartTime = 0;
428 /** All system services */
429 SystemServiceManager mSystemServiceManager;
431 private Installer mInstaller;
433 /** Run all ActivityStacks through this */
434 ActivityStackSupervisor mStackSupervisor;
436 /** Task stack change listeners. */
437 private RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
438 new RemoteCallbackList<ITaskStackListener>();
440 public IntentFirewall mIntentFirewall;
442 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
443 // default actuion automatically. Important for devices without direct input
445 private boolean mShowDialogs = true;
447 BroadcastQueue mFgBroadcastQueue;
448 BroadcastQueue mBgBroadcastQueue;
449 // Convenient for easy iteration over the queues. Foreground is first
450 // so that dispatch of foreground broadcasts gets precedence.
451 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
453 BroadcastQueue broadcastQueueForIntent(Intent intent) {
454 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
455 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
456 "Broadcast intent " + intent + " on "
457 + (isFg ? "foreground" : "background") + " queue");
458 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
462 * Activity we have told the window manager to have key focus.
464 ActivityRecord mFocusedActivity = null;
467 * User id of the last activity mFocusedActivity was set to.
469 private int mLastFocusedUserId;
472 * If non-null, we are tracking the time the user spends in the currently focused app.
474 private AppTimeTracker mCurAppTimeTracker;
477 * List of intents that were used to start the most recent tasks.
479 private final RecentTasks mRecentTasks;
482 * For addAppTask: cached of the last activity component that was added.
484 ComponentName mLastAddedTaskComponent;
487 * For addAppTask: cached of the last activity uid that was added.
489 int mLastAddedTaskUid;
492 * For addAppTask: cached of the last ActivityInfo that was added.
494 ActivityInfo mLastAddedTaskActivity;
497 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
499 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
502 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
504 String mDeviceOwnerName;
506 public class PendingAssistExtras extends Binder implements Runnable {
507 public final ActivityRecord activity;
508 public final Bundle extras;
509 public final Intent intent;
510 public final String hint;
511 public final IResultReceiver receiver;
512 public final int userHandle;
513 public boolean haveResult = false;
514 public Bundle result = null;
515 public AssistStructure structure = null;
516 public AssistContent content = null;
517 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
518 String _hint, IResultReceiver _receiver, int _userHandle) {
519 activity = _activity;
523 receiver = _receiver;
524 userHandle = _userHandle;
528 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
529 synchronized (this) {
533 pendingAssistExtrasTimedOut(this);
537 final ArrayList<PendingAssistExtras> mPendingAssistExtras
538 = new ArrayList<PendingAssistExtras>();
541 * Process management.
543 final ProcessList mProcessList = new ProcessList();
546 * All of the applications we currently have running organized by name.
547 * The keys are strings of the application package name (as
548 * returned by the package manager), and the keys are ApplicationRecord
551 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
554 * Tracking long-term execution of processes to look for abuse and other
557 final ProcessStatsService mProcessStats;
560 * The currently running isolated processes.
562 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
565 * Counter for assigning isolated process uids, to avoid frequently reusing the
568 int mNextIsolatedProcessUid = 0;
571 * The currently running heavy-weight process, if any.
573 ProcessRecord mHeavyWeightProcess = null;
576 * The last time that various processes have crashed.
578 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
581 * Information about a process that is currently marked as bad.
583 static final class BadProcessInfo {
584 BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
586 this.shortMsg = shortMsg;
587 this.longMsg = longMsg;
592 final String shortMsg;
593 final String longMsg;
598 * Set of applications that we consider to be bad, and will reject
599 * incoming broadcasts from (which the user has no control over).
600 * Processes are added to this set when they have crashed twice within
601 * a minimum amount of time; they are removed from it when they are
602 * later restarted (hopefully due to some user action). The value is the
603 * time it was added to the list.
605 final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
608 * All of the processes we currently have running organized by pid.
609 * The keys are the pid running the application.
611 * <p>NOTE: This object is protected by its own lock, NOT the global
612 * activity manager lock!
614 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
617 * All of the processes that have been forced to be foreground. The key
618 * is the pid of the caller who requested it (we hold a death
621 abstract class ForegroundToken implements IBinder.DeathRecipient {
625 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
628 * List of records for processes that someone had tried to start before the
629 * system was ready. We don't start them at that point, but ensure they
630 * are started by the time booting is complete.
632 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
635 * List of persistent applications that are in the process
638 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
641 * Processes that are being forcibly torn down.
643 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
646 * List of running applications, sorted by recent usage.
647 * The first entry in the list is the least recently used.
649 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
652 * Where in mLruProcesses that the processes hosting activities start.
654 int mLruProcessActivityStart = 0;
657 * Where in mLruProcesses that the processes hosting services start.
658 * This is after (lower index) than mLruProcessesActivityStart.
660 int mLruProcessServiceStart = 0;
663 * List of processes that should gc as soon as things are idle.
665 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
668 * Processes we want to collect PSS data from.
670 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
673 * Last time we requested PSS data of all processes.
675 long mLastFullPssTime = SystemClock.uptimeMillis();
678 * If set, the next time we collect PSS data we should do a full collection
679 * with data from native processes and the kernel.
681 boolean mFullPssPending = false;
684 * This is the process holding what we currently consider to be
685 * the "home" activity.
687 ProcessRecord mHomeProcess;
690 * This is the process holding the activity the user last visited that
691 * is in a different process from the one they are currently in.
693 ProcessRecord mPreviousProcess;
696 * The time at which the previous process was last visible.
698 long mPreviousProcessVisibleTime;
701 * Track all uids that have actively running processes.
703 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
706 * Which users have been started, so are allowed to run code.
708 final SparseArray<UserState> mStartedUsers = new SparseArray<>();
711 * LRU list of history of current users. Most recently current is at the end.
713 final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
716 * Constant array of the users that are currently started.
718 int[] mStartedUserArray = new int[] { 0 };
721 * Registered observers of the user switching mechanics.
723 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
724 = new RemoteCallbackList<IUserSwitchObserver>();
727 * Currently active user switch.
729 Object mCurUserSwitchCallback;
732 * Packages that the user has asked to have run in screen size
733 * compatibility mode instead of filling the screen.
735 final CompatModePackages mCompatModePackages;
738 * Set of IntentSenderRecord objects that are currently active.
740 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
741 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
744 * Fingerprints (hashCode()) of stack traces that we've
745 * already logged DropBox entries for. Guarded by itself. If
746 * something (rogue user app) forces this over
747 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
749 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
750 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
753 * Strict Mode background batched logging state.
755 * The string buffer is guarded by itself, and its lock is also
756 * used to determine if another batched write is already
759 private final StringBuilder mStrictModeBuffer = new StringBuilder();
762 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
763 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
765 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
768 * Resolver for broadcast intents to registered receivers.
769 * Holds BroadcastFilter (subclass of IntentFilter).
771 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
772 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
774 protected boolean allowFilterResult(
775 BroadcastFilter filter, List<BroadcastFilter> dest) {
776 IBinder target = filter.receiverList.receiver.asBinder();
777 for (int i = dest.size() - 1; i >= 0; i--) {
778 if (dest.get(i).receiverList.receiver.asBinder() == target) {
786 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
787 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
788 || userId == filter.owningUserId) {
789 return super.newResult(filter, match, userId);
795 protected BroadcastFilter[] newArray(int size) {
796 return new BroadcastFilter[size];
800 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
801 return packageName.equals(filter.packageName);
806 * State of all active sticky broadcasts per user. Keys are the action of the
807 * sticky Intent, values are an ArrayList of all broadcasted intents with
808 * that action (which should usually be one). The SparseArray is keyed
809 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
810 * for stickies that are sent to all users.
812 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
813 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
815 final ActiveServices mServices;
817 final static class Association {
818 final int mSourceUid;
819 final String mSourceProcess;
820 final int mTargetUid;
821 final ComponentName mTargetComponent;
822 final String mTargetProcess;
830 Association(int sourceUid, String sourceProcess, int targetUid,
831 ComponentName targetComponent, String targetProcess) {
832 mSourceUid = sourceUid;
833 mSourceProcess = sourceProcess;
834 mTargetUid = targetUid;
835 mTargetComponent = targetComponent;
836 mTargetProcess = targetProcess;
841 * When service association tracking is enabled, this is all of the associations we
842 * have seen. Mapping is target uid -> target component -> source uid -> source process name
843 * -> association data.
845 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
846 mAssociations = new SparseArray<>();
847 boolean mTrackingAssociations;
850 * Backup/restore process management
852 String mBackupAppName = null;
853 BackupRecord mBackupTarget = null;
855 final ProviderMap mProviderMap;
858 * List of content providers who have clients waiting for them. The
859 * application is currently being launched and the provider will be
860 * removed from this list once it is published.
862 final ArrayList<ContentProviderRecord> mLaunchingProviders
863 = new ArrayList<ContentProviderRecord>();
866 * File storing persisted {@link #mGrantedUriPermissions}.
868 private final AtomicFile mGrantFile;
870 /** XML constants used in {@link #mGrantFile} */
871 private static final String TAG_URI_GRANTS = "uri-grants";
872 private static final String TAG_URI_GRANT = "uri-grant";
873 private static final String ATTR_USER_HANDLE = "userHandle";
874 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
875 private static final String ATTR_TARGET_USER_ID = "targetUserId";
876 private static final String ATTR_SOURCE_PKG = "sourcePkg";
877 private static final String ATTR_TARGET_PKG = "targetPkg";
878 private static final String ATTR_URI = "uri";
879 private static final String ATTR_MODE_FLAGS = "modeFlags";
880 private static final String ATTR_CREATED_TIME = "createdTime";
881 private static final String ATTR_PREFIX = "prefix";
884 * Global set of specific {@link Uri} permissions that have been granted.
885 * This optimized lookup structure maps from {@link UriPermission#targetUid}
886 * to {@link UriPermission#uri} to {@link UriPermission}.
889 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
890 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
892 public static class GrantUri {
893 public final int sourceUserId;
894 public final Uri uri;
895 public boolean prefix;
897 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
898 this.sourceUserId = sourceUserId;
900 this.prefix = prefix;
904 public int hashCode() {
906 hashCode = 31 * hashCode + sourceUserId;
907 hashCode = 31 * hashCode + uri.hashCode();
908 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
913 public boolean equals(Object o) {
914 if (o instanceof GrantUri) {
915 GrantUri other = (GrantUri) o;
916 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
917 && prefix == other.prefix;
923 public String toString() {
924 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
925 if (prefix) result += " [prefix]";
929 public String toSafeString() {
930 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
931 if (prefix) result += " [prefix]";
935 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
936 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
937 ContentProvider.getUriWithoutUserId(uri), false);
941 CoreSettingsObserver mCoreSettingsObserver;
944 * Thread-local storage used to carry caller permissions over through
945 * indirect content-provider access.
947 private class Identity {
948 public final IBinder token;
949 public final int pid;
950 public final int uid;
952 Identity(IBinder _token, int _pid, int _uid) {
959 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
962 * All information we have collected about the runtime performance of
963 * any user id that can impact battery performance.
965 final BatteryStatsService mBatteryStatsService;
968 * Information about component usage
970 UsageStatsManagerInternal mUsageStatsService;
973 * Access to DeviceIdleController service.
975 DeviceIdleController.LocalService mLocalDeviceIdleController;
978 * Information about and control over application operations
980 final AppOpsService mAppOpsService;
983 * Save recent tasks information across reboots.
985 final TaskPersister mTaskPersister;
988 * Current configuration information. HistoryRecord objects are given
989 * a reference to this object to indicate which configuration they are
990 * currently running in, so this object must be kept immutable.
992 Configuration mConfiguration = new Configuration();
995 * Current sequencing integer of the configuration, for skipping old
998 int mConfigurationSeq = 0;
1001 * Hardware-reported OpenGLES version.
1003 final int GL_ES_VERSION;
1006 * List of initialization arguments to pass to all processes when binding applications to them.
1007 * For example, references to the commonly used services.
1009 HashMap<String, IBinder> mAppBindArgs;
1010 HashMap<String, IBinder> mIsolatedAppBindArgs;
1013 * Temporary to avoid allocations. Protected by main lock.
1015 final StringBuilder mStringBuilder = new StringBuilder(256);
1018 * Used to control how we initialize the service.
1020 ComponentName mTopComponent;
1021 String mTopAction = Intent.ACTION_MAIN;
1023 boolean mProcessesReady = false;
1024 boolean mSystemReady = false;
1025 boolean mBooting = false;
1026 boolean mCallFinishBooting = false;
1027 boolean mBootAnimationComplete = false;
1028 boolean mWaitingUpdate = false;
1029 boolean mDidUpdate = false;
1030 boolean mOnBattery = false;
1031 boolean mLaunchWarningShown = false;
1037 boolean mCheckedForSetup;
1040 * The time at which we will allow normal application switches again,
1041 * after a call to {@link #stopAppSwitches()}.
1043 long mAppSwitchesAllowedTime;
1046 * This is set to true after the first switch after mAppSwitchesAllowedTime
1047 * is set; any switches after that will clear the time.
1049 boolean mDidAppSwitch;
1052 * Last time (in realtime) at which we checked for power usage.
1054 long mLastPowerCheckRealtime;
1057 * Last time (in uptime) at which we checked for power usage.
1059 long mLastPowerCheckUptime;
1062 * Set while we are wanting to sleep, to prevent any
1063 * activities from being started/resumed.
1065 private boolean mSleeping = false;
1068 * The process state used for processes that are running the top activities.
1069 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1071 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1074 * Set while we are running a voice interaction. This overrides
1075 * sleeping while it is active.
1077 private IVoiceInteractionSession mRunningVoice;
1080 * For some direct access we need to power manager.
1082 PowerManagerInternal mLocalPowerManager;
1085 * We want to hold a wake lock while running a voice interaction session, since
1086 * this may happen with the screen off and we need to keep the CPU running to
1087 * be able to continue to interact with the user.
1089 PowerManager.WakeLock mVoiceWakeLock;
1092 * State of external calls telling us if the device is awake or asleep.
1094 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1097 * A list of tokens that cause the top activity to be put to sleep.
1098 * They are used by components that may hide and block interaction with underlying
1101 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1103 static final int LOCK_SCREEN_HIDDEN = 0;
1104 static final int LOCK_SCREEN_LEAVING = 1;
1105 static final int LOCK_SCREEN_SHOWN = 2;
1107 * State of external call telling us if the lock screen is shown.
1109 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1112 * Set if we are shutting down the system, similar to sleeping.
1114 boolean mShuttingDown = false;
1117 * Current sequence id for oom_adj computation traversal.
1122 * Current sequence id for process LRU updating.
1127 * Keep track of the non-cached/empty process we last found, to help
1128 * determine how to distribute cached/empty processes next time.
1130 int mNumNonCachedProcs = 0;
1133 * Keep track of the number of cached hidden procs, to balance oom adj
1134 * distribution between those and empty procs.
1136 int mNumCachedHiddenProcs = 0;
1139 * Keep track of the number of service processes we last found, to
1140 * determine on the next iteration which should be B services.
1142 int mNumServiceProcs = 0;
1143 int mNewNumAServiceProcs = 0;
1144 int mNewNumServiceProcs = 0;
1147 * Allow the current computed overall memory level of the system to go down?
1148 * This is set to false when we are killing processes for reasons other than
1149 * memory management, so that the now smaller process list will not be taken as
1150 * an indication that memory is tighter.
1152 boolean mAllowLowerMemLevel = false;
1155 * The last computed memory level, for holding when we are in a state that
1156 * processes are going away for other reasons.
1158 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1161 * The last total number of process we have, to determine if changes actually look
1162 * like a shrinking number of process due to lower RAM.
1164 int mLastNumProcesses;
1167 * The uptime of the last time we performed idle maintenance.
1169 long mLastIdleTime = SystemClock.uptimeMillis();
1172 * Total time spent with RAM that has been added in the past since the last idle time.
1174 long mLowRamTimeSinceLastIdle = 0;
1177 * If RAM is currently low, when that horrible situation started.
1179 long mLowRamStartTime = 0;
1182 * For reporting to battery stats the current top application.
1184 private String mCurResumedPackage = null;
1185 private int mCurResumedUid = -1;
1188 * For reporting to battery stats the apps currently running foreground
1189 * service. The ProcessMap is package/uid tuples; each of these contain
1190 * an array of the currently foreground processes.
1192 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1193 = new ProcessMap<ArrayList<ProcessRecord>>();
1196 * This is set if we had to do a delayed dexopt of an app before launching
1197 * it, to increase the ANR timeouts in that case.
1202 * Set if the systemServer made a call to enterSafeMode.
1207 * If true, we are running under a test environment so will sample PSS from processes
1208 * much more rapidly to try to collect better data when the tests are rapidly
1209 * running through apps.
1211 boolean mTestPssMode = false;
1213 String mDebugApp = null;
1214 boolean mWaitForDebugger = false;
1215 boolean mDebugTransient = false;
1216 String mOrigDebugApp = null;
1217 boolean mOrigWaitForDebugger = false;
1218 boolean mAlwaysFinishActivities = false;
1219 IActivityController mController = null;
1220 String mProfileApp = null;
1221 ProcessRecord mProfileProc = null;
1222 String mProfileFile;
1223 ParcelFileDescriptor mProfileFd;
1224 int mSamplingInterval = 0;
1225 boolean mAutoStopProfiler = false;
1226 int mProfileType = 0;
1227 String mOpenGlTraceApp = null;
1228 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1229 String mMemWatchDumpProcName;
1230 String mMemWatchDumpFile;
1231 int mMemWatchDumpPid;
1232 int mMemWatchDumpUid;
1234 final long[] mTmpLong = new long[1];
1236 static final class ProcessChangeItem {
1237 static final int CHANGE_ACTIVITIES = 1<<0;
1238 static final int CHANGE_PROCESS_STATE = 1<<1;
1243 boolean foregroundActivities;
1246 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1247 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1249 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1250 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1252 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1253 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1255 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1256 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1259 * Runtime CPU use collection thread. This object's lock is used to
1260 * perform synchronization with the thread (notifying it to run).
1262 final Thread mProcessCpuThread;
1265 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1266 * Must acquire this object's lock when accessing it.
1267 * NOTE: this lock will be held while doing long operations (trawling
1268 * through all processes in /proc), so it should never be acquired by
1269 * any critical paths such as when holding the main activity manager lock.
1271 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1272 MONITOR_THREAD_CPU_USAGE);
1273 final AtomicLong mLastCpuTime = new AtomicLong(0);
1274 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1276 long mLastWriteTime = 0;
1279 * Used to retain an update lock when the foreground activity is in
1282 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1285 * Set to true after the system has finished booting.
1287 boolean mBooted = false;
1289 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1290 int mProcessLimitOverride = -1;
1292 WindowManagerService mWindowManager;
1294 final ActivityThread mSystemThread;
1296 // Holds the current foreground user's id
1297 int mCurrentUserId = 0;
1298 // Holds the target user's id during a user switch
1299 int mTargetUserId = UserHandle.USER_NULL;
1300 // If there are multiple profiles for the current user, their ids are here
1301 // Currently only the primary user can have managed profiles
1302 int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1305 * Mapping from each known user ID to the profile group ID it is associated with.
1307 SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1309 private UserManagerService mUserManager;
1311 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1312 final ProcessRecord mApp;
1314 final IApplicationThread mAppThread;
1316 AppDeathRecipient(ProcessRecord app, int pid,
1317 IApplicationThread thread) {
1318 if (DEBUG_ALL) Slog.v(
1319 TAG, "New death recipient " + this
1320 + " for thread " + thread.asBinder());
1323 mAppThread = thread;
1327 public void binderDied() {
1328 if (DEBUG_ALL) Slog.v(
1329 TAG, "Death received in " + this
1330 + " for thread " + mAppThread.asBinder());
1331 synchronized(ActivityManagerService.this) {
1332 appDiedLocked(mApp, mPid, mAppThread, true);
1337 static final int SHOW_ERROR_MSG = 1;
1338 static final int SHOW_NOT_RESPONDING_MSG = 2;
1339 static final int SHOW_FACTORY_ERROR_MSG = 3;
1340 static final int UPDATE_CONFIGURATION_MSG = 4;
1341 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1342 static final int WAIT_FOR_DEBUGGER_MSG = 6;
1343 static final int SERVICE_TIMEOUT_MSG = 12;
1344 static final int UPDATE_TIME_ZONE = 13;
1345 static final int SHOW_UID_ERROR_MSG = 14;
1346 static final int SHOW_FINGERPRINT_ERROR_MSG = 15;
1347 static final int PROC_START_TIMEOUT_MSG = 20;
1348 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1349 static final int KILL_APPLICATION_MSG = 22;
1350 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1351 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1352 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1353 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1354 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1355 static final int CLEAR_DNS_CACHE_MSG = 28;
1356 static final int UPDATE_HTTP_PROXY_MSG = 29;
1357 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1358 static final int DISPATCH_PROCESSES_CHANGED = 31;
1359 static final int DISPATCH_PROCESS_DIED = 32;
1360 static final int REPORT_MEM_USAGE_MSG = 33;
1361 static final int REPORT_USER_SWITCH_MSG = 34;
1362 static final int CONTINUE_USER_SWITCH_MSG = 35;
1363 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1364 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1365 static final int PERSIST_URI_GRANTS_MSG = 38;
1366 static final int REQUEST_ALL_PSS_MSG = 39;
1367 static final int START_PROFILES_MSG = 40;
1368 static final int UPDATE_TIME = 41;
1369 static final int SYSTEM_USER_START_MSG = 42;
1370 static final int SYSTEM_USER_CURRENT_MSG = 43;
1371 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1372 static final int FINISH_BOOTING_MSG = 45;
1373 static final int START_USER_SWITCH_MSG = 46;
1374 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1375 static final int DISMISS_DIALOG_MSG = 48;
1376 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1377 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1378 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1379 static final int DELETE_DUMPHEAP_MSG = 52;
1380 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1381 static final int DISPATCH_UIDS_CHANGED_MSG = 54;
1382 static final int REPORT_TIME_TRACKER_MSG = 55;
1383 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1384 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1385 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1386 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1388 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1389 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1390 static final int FIRST_COMPAT_MODE_MSG = 300;
1391 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1393 CompatModeDialog mCompatModeDialog;
1394 long mLastMemUsageReportTime = 0;
1397 * Flag whether the current user is a "monkey", i.e. whether
1398 * the UI is driven by a UI automation tool.
1400 private boolean mUserIsMonkey;
1402 /** Flag whether the device has a Recents UI */
1403 boolean mHasRecents;
1405 /** The dimensions of the thumbnails in the Recents UI. */
1406 int mThumbnailWidth;
1407 int mThumbnailHeight;
1409 final ServiceThread mHandlerThread;
1410 final MainHandler mHandler;
1411 final UiHandler mUiHandler;
1413 final class UiHandler extends Handler {
1414 public UiHandler() {
1415 super(com.android.server.UiThread.get().getLooper(), null, true);
1419 public void handleMessage(Message msg) {
1421 case SHOW_ERROR_MSG: {
1422 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1423 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1424 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1425 synchronized (ActivityManagerService.this) {
1426 ProcessRecord proc = (ProcessRecord)data.get("app");
1427 AppErrorResult res = (AppErrorResult) data.get("result");
1428 if (proc != null && proc.crashDialog != null) {
1429 Slog.e(TAG, "App already has crash dialog: " + proc);
1435 boolean isBackground = (UserHandle.getAppId(proc.uid)
1436 >= Process.FIRST_APPLICATION_UID
1437 && proc.pid != MY_PID);
1438 for (int userId : mCurrentProfileIds) {
1439 isBackground &= (proc.userId != userId);
1441 if (isBackground && !showBackground) {
1442 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1448 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1449 Dialog d = new AppErrorDialog(mContext,
1450 ActivityManagerService.this, res, proc);
1452 proc.crashDialog = d;
1454 // The device is asleep, so just pretend that the user
1455 // saw a crash dialog and hit "force quit".
1462 ensureBootCompleted();
1464 case SHOW_NOT_RESPONDING_MSG: {
1465 synchronized (ActivityManagerService.this) {
1466 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1467 ProcessRecord proc = (ProcessRecord)data.get("app");
1468 if (proc != null && proc.anrDialog != null) {
1469 Slog.e(TAG, "App already has anr dialog: " + proc);
1473 Intent intent = new Intent("android.intent.action.ANR");
1474 if (!mProcessesReady) {
1475 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1476 | Intent.FLAG_RECEIVER_FOREGROUND);
1478 broadcastIntentLocked(null, null, intent,
1479 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1480 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1483 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1484 mContext, proc, (ActivityRecord)data.get("activity"),
1489 // Just kill the app if there is no dialog to be shown.
1490 killAppAtUsersRequest(proc, null);
1494 ensureBootCompleted();
1496 case SHOW_STRICT_MODE_VIOLATION_MSG: {
1497 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1498 synchronized (ActivityManagerService.this) {
1499 ProcessRecord proc = (ProcessRecord) data.get("app");
1501 Slog.e(TAG, "App not found when showing strict mode dialog.");
1504 if (proc.crashDialog != null) {
1505 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1508 AppErrorResult res = (AppErrorResult) data.get("result");
1509 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1510 Dialog d = new StrictModeViolationDialog(mContext,
1511 ActivityManagerService.this, res, proc);
1513 proc.crashDialog = d;
1515 // The device is asleep, so just pretend that the user
1516 // saw a crash dialog and hit "force quit".
1520 ensureBootCompleted();
1522 case SHOW_FACTORY_ERROR_MSG: {
1523 Dialog d = new FactoryErrorDialog(
1524 mContext, msg.getData().getCharSequence("msg"));
1526 ensureBootCompleted();
1528 case WAIT_FOR_DEBUGGER_MSG: {
1529 synchronized (ActivityManagerService.this) {
1530 ProcessRecord app = (ProcessRecord)msg.obj;
1531 if (msg.arg1 != 0) {
1532 if (!app.waitedForDebugger) {
1533 Dialog d = new AppWaitingForDebuggerDialog(
1534 ActivityManagerService.this,
1537 app.waitedForDebugger = true;
1541 if (app.waitDialog != null) {
1542 app.waitDialog.dismiss();
1543 app.waitDialog = null;
1548 case SHOW_UID_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_wipe_data));
1555 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1556 obtainMessage(DISMISS_DIALOG_MSG, d));
1560 case SHOW_FINGERPRINT_ERROR_MSG: {
1562 AlertDialog d = new BaseErrorDialog(mContext);
1563 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1564 d.setCancelable(false);
1565 d.setTitle(mContext.getText(R.string.android_system_label));
1566 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1567 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1568 obtainMessage(DISMISS_DIALOG_MSG, d));
1572 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1573 synchronized (ActivityManagerService.this) {
1574 ActivityRecord ar = (ActivityRecord) msg.obj;
1575 if (mCompatModeDialog != null) {
1576 if (mCompatModeDialog.mAppInfo.packageName.equals(
1577 ar.info.applicationInfo.packageName)) {
1580 mCompatModeDialog.dismiss();
1581 mCompatModeDialog = null;
1583 if (ar != null && false) {
1584 if (mCompatModePackages.getPackageAskCompatModeLocked(
1586 int mode = mCompatModePackages.computeCompatModeLocked(
1587 ar.info.applicationInfo);
1588 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1589 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1590 mCompatModeDialog = new CompatModeDialog(
1591 ActivityManagerService.this, mContext,
1592 ar.info.applicationInfo);
1593 mCompatModeDialog.show();
1600 case START_USER_SWITCH_MSG: {
1601 showUserSwitchDialog(msg.arg1, (String) msg.obj);
1604 case DISMISS_DIALOG_MSG: {
1605 final Dialog d = (Dialog) msg.obj;
1609 case DISPATCH_PROCESSES_CHANGED: {
1610 dispatchProcessesChanged();
1613 case DISPATCH_PROCESS_DIED: {
1614 final int pid = msg.arg1;
1615 final int uid = msg.arg2;
1616 dispatchProcessDied(pid, uid);
1619 case DISPATCH_UIDS_CHANGED_MSG: {
1620 dispatchUidsChanged();
1626 final class MainHandler extends Handler {
1627 public MainHandler(Looper looper) {
1628 super(looper, null, true);
1632 public void handleMessage(Message msg) {
1634 case UPDATE_CONFIGURATION_MSG: {
1635 final ContentResolver resolver = mContext.getContentResolver();
1636 Settings.System.putConfiguration(resolver, (Configuration) msg.obj);
1638 case GC_BACKGROUND_PROCESSES_MSG: {
1639 synchronized (ActivityManagerService.this) {
1640 performAppGcsIfAppropriateLocked();
1643 case SERVICE_TIMEOUT_MSG: {
1646 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1648 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1651 mServices.serviceTimeout((ProcessRecord)msg.obj);
1653 case UPDATE_TIME_ZONE: {
1654 synchronized (ActivityManagerService.this) {
1655 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1656 ProcessRecord r = mLruProcesses.get(i);
1657 if (r.thread != null) {
1659 r.thread.updateTimeZone();
1660 } catch (RemoteException ex) {
1661 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1667 case CLEAR_DNS_CACHE_MSG: {
1668 synchronized (ActivityManagerService.this) {
1669 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1670 ProcessRecord r = mLruProcesses.get(i);
1671 if (r.thread != null) {
1673 r.thread.clearDnsCache();
1674 } catch (RemoteException ex) {
1675 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1681 case UPDATE_HTTP_PROXY_MSG: {
1682 ProxyInfo proxy = (ProxyInfo)msg.obj;
1685 String exclList = "";
1686 Uri pacFileUrl = Uri.EMPTY;
1687 if (proxy != null) {
1688 host = proxy.getHost();
1689 port = Integer.toString(proxy.getPort());
1690 exclList = proxy.getExclusionListAsString();
1691 pacFileUrl = proxy.getPacFileUrl();
1693 synchronized (ActivityManagerService.this) {
1694 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1695 ProcessRecord r = mLruProcesses.get(i);
1696 if (r.thread != null) {
1698 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1699 } catch (RemoteException ex) {
1700 Slog.w(TAG, "Failed to update http proxy for: " +
1701 r.info.processName);
1707 case PROC_START_TIMEOUT_MSG: {
1710 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1712 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1715 ProcessRecord app = (ProcessRecord)msg.obj;
1716 synchronized (ActivityManagerService.this) {
1717 processStartTimedOutLocked(app);
1720 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1721 ProcessRecord app = (ProcessRecord)msg.obj;
1722 synchronized (ActivityManagerService.this) {
1723 processContentProviderPublishTimedOutLocked(app);
1726 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1727 synchronized (ActivityManagerService.this) {
1728 mStackSupervisor.doPendingActivityLaunchesLocked(true);
1731 case KILL_APPLICATION_MSG: {
1732 synchronized (ActivityManagerService.this) {
1733 int appid = msg.arg1;
1734 boolean restart = (msg.arg2 == 1);
1735 Bundle bundle = (Bundle)msg.obj;
1736 String pkg = bundle.getString("pkg");
1737 String reason = bundle.getString("reason");
1738 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1739 false, UserHandle.USER_ALL, reason);
1742 case FINALIZE_PENDING_INTENT_MSG: {
1743 ((PendingIntentRecord)msg.obj).completeFinalize();
1745 case POST_HEAVY_NOTIFICATION_MSG: {
1746 INotificationManager inm = NotificationManager.getService();
1751 ActivityRecord root = (ActivityRecord)msg.obj;
1752 ProcessRecord process = root.app;
1753 if (process == null) {
1758 Context context = mContext.createPackageContext(process.info.packageName, 0);
1759 String text = mContext.getString(R.string.heavy_weight_notification,
1760 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1761 Notification notification = new Notification.Builder(context)
1762 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1766 .setColor(mContext.getColor(
1767 com.android.internal.R.color.system_notification_accent_color))
1768 .setContentTitle(text)
1770 mContext.getText(R.string.heavy_weight_notification_detail))
1771 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1772 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1773 new UserHandle(root.userId)))
1776 int[] outId = new int[1];
1777 inm.enqueueNotificationWithTag("android", "android", null,
1778 R.string.heavy_weight_notification,
1779 notification, outId, root.userId);
1780 } catch (RuntimeException e) {
1781 Slog.w(ActivityManagerService.TAG,
1782 "Error showing notification for heavy-weight app", e);
1783 } catch (RemoteException e) {
1785 } catch (NameNotFoundException e) {
1786 Slog.w(TAG, "Unable to create context for heavy notification", e);
1789 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1790 INotificationManager inm = NotificationManager.getService();
1795 inm.cancelNotificationWithTag("android", null,
1796 R.string.heavy_weight_notification, msg.arg1);
1797 } catch (RuntimeException e) {
1798 Slog.w(ActivityManagerService.TAG,
1799 "Error canceling notification for service", e);
1800 } catch (RemoteException e) {
1803 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1804 synchronized (ActivityManagerService.this) {
1805 checkExcessivePowerUsageLocked(true);
1806 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1807 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1808 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1811 case REPORT_MEM_USAGE_MSG: {
1812 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1813 Thread thread = new Thread() {
1814 @Override public void run() {
1815 reportMemUsage(memInfos);
1821 case REPORT_USER_SWITCH_MSG: {
1822 dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1825 case CONTINUE_USER_SWITCH_MSG: {
1826 continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1829 case USER_SWITCH_TIMEOUT_MSG: {
1830 timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1833 case IMMERSIVE_MODE_LOCK_MSG: {
1834 final boolean nextState = (msg.arg1 != 0);
1835 if (mUpdateLock.isHeld() != nextState) {
1836 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1837 "Applying new update lock state '" + nextState
1838 + "' for " + (ActivityRecord)msg.obj);
1840 mUpdateLock.acquire();
1842 mUpdateLock.release();
1847 case PERSIST_URI_GRANTS_MSG: {
1848 writeGrantedUriPermissions();
1851 case REQUEST_ALL_PSS_MSG: {
1852 synchronized (ActivityManagerService.this) {
1853 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1857 case START_PROFILES_MSG: {
1858 synchronized (ActivityManagerService.this) {
1859 startProfilesLocked();
1864 synchronized (ActivityManagerService.this) {
1865 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1866 ProcessRecord r = mLruProcesses.get(i);
1867 if (r.thread != null) {
1869 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1870 } catch (RemoteException ex) {
1871 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1878 case SYSTEM_USER_START_MSG: {
1879 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1880 Integer.toString(msg.arg1), msg.arg1);
1881 mSystemServiceManager.startUser(msg.arg1);
1884 case SYSTEM_USER_CURRENT_MSG: {
1885 mBatteryStatsService.noteEvent(
1886 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1887 Integer.toString(msg.arg2), msg.arg2);
1888 mBatteryStatsService.noteEvent(
1889 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1890 Integer.toString(msg.arg1), msg.arg1);
1891 mSystemServiceManager.switchUser(msg.arg1);
1894 case ENTER_ANIMATION_COMPLETE_MSG: {
1895 synchronized (ActivityManagerService.this) {
1896 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1897 if (r != null && r.app != null && r.app.thread != null) {
1899 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1900 } catch (RemoteException e) {
1906 case FINISH_BOOTING_MSG: {
1907 if (msg.arg1 != 0) {
1910 if (msg.arg2 != 0) {
1911 enableScreenAfterBoot();
1915 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1917 Locale l = (Locale) msg.obj;
1918 IBinder service = ServiceManager.getService("mount");
1919 IMountService mountService = IMountService.Stub.asInterface(service);
1920 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1921 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1922 } catch (RemoteException e) {
1923 Log.e(TAG, "Error storing locale for decryption UI", e);
1927 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1928 synchronized (ActivityManagerService.this) {
1929 int i = mTaskStackListeners.beginBroadcast();
1933 // Make a one-way callback to the listener
1934 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1935 } catch (RemoteException e){
1936 // Handled by the RemoteCallbackList
1939 mTaskStackListeners.finishBroadcast();
1943 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
1944 final int uid = msg.arg1;
1945 final byte[] firstPacket = (byte[]) msg.obj;
1947 synchronized (mPidsSelfLocked) {
1948 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
1949 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
1952 p.thread.notifyCleartextNetwork(firstPacket);
1953 } catch (RemoteException ignored) {
1960 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
1961 final String procName;
1963 final long memLimit;
1964 final String reportPackage;
1965 synchronized (ActivityManagerService.this) {
1966 procName = mMemWatchDumpProcName;
1967 uid = mMemWatchDumpUid;
1968 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
1970 val = mMemWatchProcesses.get(procName, 0);
1973 memLimit = val.first;
1974 reportPackage = val.second;
1977 reportPackage = null;
1980 if (procName == null) {
1984 if (DEBUG_PSS) Slog.d(TAG_PSS,
1985 "Showing dump heap notification from " + procName + "/" + uid);
1987 INotificationManager inm = NotificationManager.getService();
1992 String text = mContext.getString(R.string.dump_heap_notification, procName);
1995 Intent deleteIntent = new Intent();
1996 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
1997 Intent intent = new Intent();
1998 intent.setClassName("android", DumpHeapActivity.class.getName());
1999 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2000 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2001 if (reportPackage != null) {
2002 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2004 int userId = UserHandle.getUserId(uid);
2005 Notification notification = new Notification.Builder(mContext)
2006 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2009 .setAutoCancel(true)
2011 .setColor(mContext.getColor(
2012 com.android.internal.R.color.system_notification_accent_color))
2013 .setContentTitle(text)
2015 mContext.getText(R.string.dump_heap_notification_detail))
2016 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2017 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2018 new UserHandle(userId)))
2019 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2020 deleteIntent, 0, UserHandle.OWNER))
2024 int[] outId = new int[1];
2025 inm.enqueueNotificationWithTag("android", "android", null,
2026 R.string.dump_heap_notification,
2027 notification, outId, userId);
2028 } catch (RuntimeException e) {
2029 Slog.w(ActivityManagerService.TAG,
2030 "Error showing notification for dump heap", e);
2031 } catch (RemoteException e) {
2034 case DELETE_DUMPHEAP_MSG: {
2035 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2036 DumpHeapActivity.JAVA_URI,
2037 Intent.FLAG_GRANT_READ_URI_PERMISSION
2038 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2039 UserHandle.myUserId());
2040 synchronized (ActivityManagerService.this) {
2041 mMemWatchDumpFile = null;
2042 mMemWatchDumpProcName = null;
2043 mMemWatchDumpPid = -1;
2044 mMemWatchDumpUid = -1;
2047 case FOREGROUND_PROFILE_CHANGED_MSG: {
2048 dispatchForegroundProfileChanged(msg.arg1);
2050 case REPORT_TIME_TRACKER_MSG: {
2051 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2052 tracker.deliverResult(mContext);
2054 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2055 dispatchUserSwitchComplete(msg.arg1);
2057 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2058 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2060 connection.shutdown();
2061 } catch (RemoteException e) {
2062 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2064 // Only a UiAutomation can set this flag and now that
2065 // it is finished we make sure it is reset to its default.
2066 mUserIsMonkey = false;
2068 case APP_BOOST_DEACTIVATE_MSG : {
2069 synchronized(ActivityManagerService.this) {
2071 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2072 nativeMigrateFromBoost();
2074 mBoostStartTime = 0;
2076 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2077 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2086 static final int COLLECT_PSS_BG_MSG = 1;
2088 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2090 public void handleMessage(Message msg) {
2092 case COLLECT_PSS_BG_MSG: {
2093 long start = SystemClock.uptimeMillis();
2094 MemInfoReader memInfo = null;
2095 synchronized (ActivityManagerService.this) {
2096 if (mFullPssPending) {
2097 mFullPssPending = false;
2098 memInfo = new MemInfoReader();
2101 if (memInfo != null) {
2102 updateCpuStatsNow();
2103 long nativeTotalPss = 0;
2104 synchronized (mProcessCpuTracker) {
2105 final int N = mProcessCpuTracker.countStats();
2106 for (int j=0; j<N; j++) {
2107 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2108 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2109 // This is definitely an application process; skip it.
2112 synchronized (mPidsSelfLocked) {
2113 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2114 // This is one of our own processes; skip it.
2118 nativeTotalPss += Debug.getPss(st.pid, null, null);
2121 memInfo.readMemInfo();
2122 synchronized (ActivityManagerService.this) {
2123 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2124 + (SystemClock.uptimeMillis()-start) + "ms");
2125 final long cachedKb = memInfo.getCachedSizeKb();
2126 final long freeKb = memInfo.getFreeSizeKb();
2127 final long zramKb = memInfo.getZramTotalSizeKb();
2128 final long kernelKb = memInfo.getKernelUsedSizeKb();
2129 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2130 kernelKb*1024, nativeTotalPss*1024);
2131 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2137 long[] tmp = new long[1];
2143 synchronized (ActivityManagerService.this) {
2144 if (mPendingPssProcesses.size() <= 0) {
2145 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2146 "Collected PSS of " + num + " processes in "
2147 + (SystemClock.uptimeMillis() - start) + "ms");
2148 mPendingPssProcesses.clear();
2151 proc = mPendingPssProcesses.remove(0);
2152 procState = proc.pssProcState;
2153 lastPssTime = proc.lastPssTime;
2154 if (proc.thread != null && procState == proc.setProcState
2155 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2156 < SystemClock.uptimeMillis()) {
2164 long pss = Debug.getPss(pid, tmp, null);
2165 synchronized (ActivityManagerService.this) {
2166 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2167 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2169 recordPssSampleLocked(proc, procState, pss, tmp[0],
2170 SystemClock.uptimeMillis());
2180 public void setSystemProcess() {
2182 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2183 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2184 ServiceManager.addService("meminfo", new MemBinder(this));
2185 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2186 ServiceManager.addService("dbinfo", new DbBinder(this));
2187 if (MONITOR_CPU_USAGE) {
2188 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2190 ServiceManager.addService("permission", new PermissionController(this));
2191 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2193 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2194 "android", STOCK_PM_FLAGS);
2195 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2197 synchronized (this) {
2198 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2199 app.persistent = true;
2201 app.maxAdj = ProcessList.SYSTEM_ADJ;
2202 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2203 synchronized (mPidsSelfLocked) {
2204 mPidsSelfLocked.put(app.pid, app);
2206 updateLruProcessLocked(app, false, null);
2207 updateOomAdjLocked();
2209 } catch (PackageManager.NameNotFoundException e) {
2210 throw new RuntimeException(
2211 "Unable to find android system package", e);
2215 public void setWindowManager(WindowManagerService wm) {
2216 mWindowManager = wm;
2217 mStackSupervisor.setWindowManager(wm);
2220 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2221 mUsageStatsService = usageStatsManager;
2224 public void startObservingNativeCrashes() {
2225 final NativeCrashListener ncl = new NativeCrashListener(this);
2229 public IAppOpsService getAppOpsService() {
2230 return mAppOpsService;
2233 static class MemBinder extends Binder {
2234 ActivityManagerService mActivityManagerService;
2235 MemBinder(ActivityManagerService activityManagerService) {
2236 mActivityManagerService = activityManagerService;
2240 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2241 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2242 != PackageManager.PERMISSION_GRANTED) {
2243 pw.println("Permission Denial: can't dump meminfo from from pid="
2244 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2245 + " without permission " + android.Manifest.permission.DUMP);
2249 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2253 static class GraphicsBinder extends Binder {
2254 ActivityManagerService mActivityManagerService;
2255 GraphicsBinder(ActivityManagerService activityManagerService) {
2256 mActivityManagerService = activityManagerService;
2260 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2261 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2262 != PackageManager.PERMISSION_GRANTED) {
2263 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2264 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2265 + " without permission " + android.Manifest.permission.DUMP);
2269 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2273 static class DbBinder extends Binder {
2274 ActivityManagerService mActivityManagerService;
2275 DbBinder(ActivityManagerService activityManagerService) {
2276 mActivityManagerService = activityManagerService;
2280 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2281 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2282 != PackageManager.PERMISSION_GRANTED) {
2283 pw.println("Permission Denial: can't dump dbinfo from from pid="
2284 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2285 + " without permission " + android.Manifest.permission.DUMP);
2289 mActivityManagerService.dumpDbInfo(fd, pw, args);
2293 static class CpuBinder extends Binder {
2294 ActivityManagerService mActivityManagerService;
2295 CpuBinder(ActivityManagerService activityManagerService) {
2296 mActivityManagerService = activityManagerService;
2300 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2301 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2302 != PackageManager.PERMISSION_GRANTED) {
2303 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2304 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2305 + " without permission " + android.Manifest.permission.DUMP);
2309 synchronized (mActivityManagerService.mProcessCpuTracker) {
2310 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2311 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2312 SystemClock.uptimeMillis()));
2317 public static final class Lifecycle extends SystemService {
2318 private final ActivityManagerService mService;
2320 public Lifecycle(Context context) {
2322 mService = new ActivityManagerService(context);
2326 public void onStart() {
2330 public ActivityManagerService getService() {
2335 // Note: This method is invoked on the main thread but may need to attach various
2336 // handlers to other threads. So take care to be explicit about the looper.
2337 public ActivityManagerService(Context systemContext) {
2338 mContext = systemContext;
2339 mFactoryTest = FactoryTest.getMode();
2340 mSystemThread = ActivityThread.currentActivityThread();
2342 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2344 mHandlerThread = new ServiceThread(TAG,
2345 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2346 mHandlerThread.start();
2347 mHandler = new MainHandler(mHandlerThread.getLooper());
2348 mUiHandler = new UiHandler();
2350 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2351 "foreground", BROADCAST_FG_TIMEOUT, false);
2352 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2353 "background", BROADCAST_BG_TIMEOUT, true);
2354 mBroadcastQueues[0] = mFgBroadcastQueue;
2355 mBroadcastQueues[1] = mBgBroadcastQueue;
2357 mServices = new ActiveServices(this);
2358 mProviderMap = new ProviderMap(this);
2360 // TODO: Move creation of battery stats service outside of activity manager service.
2361 File dataDir = Environment.getDataDirectory();
2362 File systemDir = new File(dataDir, "system");
2364 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2365 mBatteryStatsService.getActiveStatistics().readLocked();
2366 mBatteryStatsService.scheduleWriteToDisk();
2367 mOnBattery = DEBUG_POWER ? true
2368 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2369 mBatteryStatsService.getActiveStatistics().setCallback(this);
2371 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2373 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2375 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2377 // User 0 is the first and only user that runs at boot.
2378 mStartedUsers.put(UserHandle.USER_OWNER, new UserState(UserHandle.OWNER, true));
2379 mUserLru.add(UserHandle.USER_OWNER);
2380 updateStartedUserArrayLocked();
2382 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2383 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2385 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2387 mConfiguration.setToDefaults();
2388 mConfiguration.setLocale(Locale.getDefault());
2390 mConfigurationSeq = mConfiguration.seq = 1;
2391 mProcessCpuTracker.init();
2393 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2394 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2395 mRecentTasks = new RecentTasks(this);
2396 mStackSupervisor = new ActivityStackSupervisor(this, mRecentTasks);
2397 mTaskPersister = new TaskPersister(systemDir, mStackSupervisor, mRecentTasks);
2399 mProcessCpuThread = new Thread("CpuTracker") {
2405 synchronized(this) {
2406 final long now = SystemClock.uptimeMillis();
2407 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2408 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2409 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2410 // + ", write delay=" + nextWriteDelay);
2411 if (nextWriteDelay < nextCpuDelay) {
2412 nextCpuDelay = nextWriteDelay;
2414 if (nextCpuDelay > 0) {
2415 mProcessCpuMutexFree.set(true);
2416 this.wait(nextCpuDelay);
2419 } catch (InterruptedException e) {
2421 updateCpuStatsNow();
2422 } catch (Exception e) {
2423 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2429 Watchdog.getInstance().addMonitor(this);
2430 Watchdog.getInstance().addThread(mHandler);
2433 public void setSystemServiceManager(SystemServiceManager mgr) {
2434 mSystemServiceManager = mgr;
2437 public void setInstaller(Installer installer) {
2438 mInstaller = installer;
2441 private void start() {
2442 Process.removeAllProcessGroups();
2443 mProcessCpuThread.start();
2445 mBatteryStatsService.publish(mContext);
2446 mAppOpsService.publish(mContext);
2447 Slog.d("AppOps", "AppOpsService published");
2448 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2451 public void initPowerManagement() {
2452 mStackSupervisor.initPowerManagement();
2453 mBatteryStatsService.initPowerManagement();
2454 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2455 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2456 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2457 mVoiceWakeLock.setReferenceCounted(false);
2461 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2462 throws RemoteException {
2463 if (code == SYSPROPS_TRANSACTION) {
2464 // We need to tell all apps about the system property change.
2465 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2466 synchronized(this) {
2467 final int NP = mProcessNames.getMap().size();
2468 for (int ip=0; ip<NP; ip++) {
2469 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2470 final int NA = apps.size();
2471 for (int ia=0; ia<NA; ia++) {
2472 ProcessRecord app = apps.valueAt(ia);
2473 if (app.thread != null) {
2474 procs.add(app.thread.asBinder());
2480 int N = procs.size();
2481 for (int i=0; i<N; i++) {
2482 Parcel data2 = Parcel.obtain();
2484 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2485 } catch (RemoteException e) {
2491 return super.onTransact(code, data, reply, flags);
2492 } catch (RuntimeException e) {
2493 // The activity manager only throws security exceptions, so let's
2495 if (!(e instanceof SecurityException)) {
2496 Slog.wtf(TAG, "Activity Manager Crash", e);
2502 void updateCpuStats() {
2503 final long now = SystemClock.uptimeMillis();
2504 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2507 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2508 synchronized (mProcessCpuThread) {
2509 mProcessCpuThread.notify();
2514 void updateCpuStatsNow() {
2515 synchronized (mProcessCpuTracker) {
2516 mProcessCpuMutexFree.set(false);
2517 final long now = SystemClock.uptimeMillis();
2518 boolean haveNewCpuStats = false;
2520 if (MONITOR_CPU_USAGE &&
2521 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2522 mLastCpuTime.set(now);
2523 mProcessCpuTracker.update();
2524 if (mProcessCpuTracker.hasGoodLastStats()) {
2525 haveNewCpuStats = true;
2526 //Slog.i(TAG, mProcessCpu.printCurrentState());
2527 //Slog.i(TAG, "Total CPU usage: "
2528 // + mProcessCpu.getTotalCpuPercent() + "%");
2530 // Slog the cpu usage if the property is set.
2531 if ("true".equals(SystemProperties.get("events.cpu"))) {
2532 int user = mProcessCpuTracker.getLastUserTime();
2533 int system = mProcessCpuTracker.getLastSystemTime();
2534 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2535 int irq = mProcessCpuTracker.getLastIrqTime();
2536 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2537 int idle = mProcessCpuTracker.getLastIdleTime();
2539 int total = user + system + iowait + irq + softIrq + idle;
2540 if (total == 0) total = 1;
2542 EventLog.writeEvent(EventLogTags.CPU,
2543 ((user+system+iowait+irq+softIrq) * 100) / total,
2544 (user * 100) / total,
2545 (system * 100) / total,
2546 (iowait * 100) / total,
2547 (irq * 100) / total,
2548 (softIrq * 100) / total);
2553 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2554 synchronized(bstats) {
2555 synchronized(mPidsSelfLocked) {
2556 if (haveNewCpuStats) {
2557 if (bstats.startAddingCpuLocked()) {
2560 final int N = mProcessCpuTracker.countStats();
2561 for (int i=0; i<N; i++) {
2562 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2566 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2567 totalUTime += st.rel_utime;
2568 totalSTime += st.rel_stime;
2570 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2571 if (ps == null || !ps.isActive()) {
2572 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2573 pr.info.uid, pr.processName);
2575 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2576 pr.curCpuTime += st.rel_utime + st.rel_stime;
2578 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2579 if (ps == null || !ps.isActive()) {
2580 st.batteryStats = ps = bstats.getProcessStatsLocked(
2581 bstats.mapUid(st.uid), st.name);
2583 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2586 final int userTime = mProcessCpuTracker.getLastUserTime();
2587 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2588 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2589 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2590 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2591 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2592 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2593 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2598 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2599 mLastWriteTime = now;
2600 mBatteryStatsService.scheduleWriteToDisk();
2607 public void batteryNeedsCpuUpdate() {
2608 updateCpuStatsNow();
2612 public void batteryPowerChanged(boolean onBattery) {
2613 // When plugging in, update the CPU stats first before changing
2615 updateCpuStatsNow();
2616 synchronized (this) {
2617 synchronized(mPidsSelfLocked) {
2618 mOnBattery = DEBUG_POWER ? true : onBattery;
2624 public void batterySendBroadcast(Intent intent) {
2625 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2626 AppOpsManager.OP_NONE, null, false, false,
2627 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2631 * Initialize the application bind args. These are passed to each
2632 * process when the bindApplication() IPC is sent to the process. They're
2633 * lazily setup to make sure the services are running when they're asked for.
2635 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2636 // Isolated processes won't get this optimization, so that we don't
2637 // violate the rules about which services they have access to.
2639 if (mIsolatedAppBindArgs == null) {
2640 mIsolatedAppBindArgs = new HashMap<>();
2641 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2643 return mIsolatedAppBindArgs;
2646 if (mAppBindArgs == null) {
2647 mAppBindArgs = new HashMap<>();
2649 // Setup the application init args
2650 mAppBindArgs.put("package", ServiceManager.getService("package"));
2651 mAppBindArgs.put("window", ServiceManager.getService("window"));
2652 mAppBindArgs.put(Context.ALARM_SERVICE,
2653 ServiceManager.getService(Context.ALARM_SERVICE));
2655 return mAppBindArgs;
2658 final void setFocusedActivityLocked(ActivityRecord r, String reason) {
2659 if (r != null && mFocusedActivity != r) {
2660 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2661 ActivityRecord last = mFocusedActivity;
2662 mFocusedActivity = r;
2663 if (r.task.taskType != ActivityRecord.HOME_ACTIVITY_TYPE
2664 && r.task.taskType != ActivityRecord.RECENTS_ACTIVITY_TYPE) {
2665 if (mCurAppTimeTracker != r.appTimeTracker) {
2666 // We are switching app tracking. Complete the current one.
2667 if (mCurAppTimeTracker != null) {
2668 mCurAppTimeTracker.stop();
2669 mHandler.obtainMessage(REPORT_TIME_TRACKER_MSG,
2670 mCurAppTimeTracker).sendToTarget();
2671 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2672 mCurAppTimeTracker = null;
2674 if (r.appTimeTracker != null) {
2675 mCurAppTimeTracker = r.appTimeTracker;
2676 startTimeTrackingFocusedActivityLocked();
2679 startTimeTrackingFocusedActivityLocked();
2682 r.appTimeTracker = null;
2684 if (r.task != null && r.task.voiceInteractor != null) {
2685 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2687 finishRunningVoiceLocked();
2688 if (last != null && last.task.voiceSession != null) {
2689 // We had been in a voice interaction session, but now focused has
2690 // move to something different. Just finish the session, we can't
2691 // return to it and retain the proper state and synchronization with
2692 // the voice interaction service.
2693 finishVoiceTask(last.task.voiceSession);
2696 if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
2697 mWindowManager.setFocusedApp(r.appToken, true);
2699 applyUpdateLockStateLocked(r);
2700 if (mFocusedActivity.userId != mLastFocusedUserId) {
2701 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2702 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2703 mFocusedActivity.userId, 0));
2704 mLastFocusedUserId = mFocusedActivity.userId;
2707 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY,
2708 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2709 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName);
2712 final void clearFocusedActivity(ActivityRecord r) {
2713 if (mFocusedActivity == r) {
2714 ActivityStack stack = mStackSupervisor.getFocusedStack();
2715 if (stack != null) {
2716 ActivityRecord top = stack.topActivity();
2717 if (top != null && top.userId != mLastFocusedUserId) {
2718 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2719 mHandler.sendMessage(mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG,
2721 mLastFocusedUserId = top.userId;
2724 mFocusedActivity = null;
2725 EventLog.writeEvent(EventLogTags.AM_FOCUSED_ACTIVITY, -1, "NULL");
2730 public void setFocusedStack(int stackId) {
2731 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2732 synchronized (ActivityManagerService.this) {
2733 ActivityStack stack = mStackSupervisor.getStack(stackId);
2734 if (stack != null) {
2735 ActivityRecord r = stack.topRunningActivityLocked(null);
2737 setFocusedActivityLocked(r, "setFocusedStack");
2738 mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
2744 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2746 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2747 synchronized (ActivityManagerService.this) {
2748 if (listener != null) {
2749 mTaskStackListeners.register(listener);
2755 public void notifyActivityDrawn(IBinder token) {
2756 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2757 synchronized (this) {
2758 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2760 r.task.stack.notifyActivityDrawnLocked(r);
2765 final void applyUpdateLockStateLocked(ActivityRecord r) {
2766 // Modifications to the UpdateLock state are done on our handler, outside
2767 // the activity manager's locks. The new state is determined based on the
2768 // state *now* of the relevant activity record. The object is passed to
2769 // the handler solely for logging detail, not to be consulted/modified.
2770 final boolean nextState = r != null && r.immersive;
2771 mHandler.sendMessage(
2772 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2775 final void showAskCompatModeDialogLocked(ActivityRecord r) {
2776 Message msg = Message.obtain();
2777 msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2778 msg.obj = r.task.askedCompatMode ? null : r;
2779 mUiHandler.sendMessage(msg);
2782 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2783 String what, Object obj, ProcessRecord srcApp) {
2784 app.lastActivityTime = now;
2786 if (app.activities.size() > 0) {
2787 // Don't want to touch dependent processes that are hosting activities.
2791 int lrui = mLruProcesses.lastIndexOf(app);
2793 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2794 + what + " " + obj + " from " + srcApp);
2798 if (lrui >= index) {
2799 // Don't want to cause this to move dependent processes *back* in the
2800 // list as if they were less frequently used.
2804 if (lrui >= mLruProcessActivityStart) {
2805 // Don't want to touch dependent processes that are hosting activities.
2809 mLruProcesses.remove(lrui);
2813 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2814 + " in LRU list: " + app);
2815 mLruProcesses.add(index, app);
2819 private static void killProcessGroup(int uid, int pid) {
2820 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
2821 Process.killProcessGroup(uid, pid);
2822 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2825 final void removeLruProcessLocked(ProcessRecord app) {
2826 int lrui = mLruProcesses.lastIndexOf(app);
2829 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
2830 Process.killProcessQuiet(app.pid);
2831 killProcessGroup(app.uid, app.pid);
2833 if (lrui <= mLruProcessActivityStart) {
2834 mLruProcessActivityStart--;
2836 if (lrui <= mLruProcessServiceStart) {
2837 mLruProcessServiceStart--;
2839 mLruProcesses.remove(lrui);
2843 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2844 ProcessRecord client) {
2845 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2846 || app.treatLikeActivity;
2847 final boolean hasService = false; // not impl yet. app.services.size() > 0;
2848 if (!activityChange && hasActivity) {
2849 // The process has activities, so we are only allowing activity-based adjustments
2850 // to move it. It should be kept in the front of the list with other
2851 // processes that have activities, and we don't want those to change their
2852 // order except due to activity operations.
2857 final long now = SystemClock.uptimeMillis();
2858 app.lastActivityTime = now;
2860 // First a quick reject: if the app is already at the position we will
2861 // put it, then there is nothing to do.
2863 final int N = mLruProcesses.size();
2864 if (N > 0 && mLruProcesses.get(N-1) == app) {
2865 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
2869 if (mLruProcessServiceStart > 0
2870 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2871 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
2876 int lrui = mLruProcesses.lastIndexOf(app);
2878 if (app.persistent && lrui >= 0) {
2879 // We don't care about the position of persistent processes, as long as
2880 // they are in the list.
2881 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
2885 /* In progress: compute new position first, so we can avoid doing work
2886 if the process is not actually going to move. Not yet working.
2889 boolean inActivity = false, inService = false;
2891 // Process has activities, put it at the very tipsy-top.
2892 addIndex = mLruProcesses.size();
2893 nextIndex = mLruProcessServiceStart;
2895 } else if (hasService) {
2896 // Process has services, put it at the top of the service list.
2897 addIndex = mLruProcessActivityStart;
2898 nextIndex = mLruProcessServiceStart;
2902 // Process not otherwise of interest, it goes to the top of the non-service area.
2903 addIndex = mLruProcessServiceStart;
2904 if (client != null) {
2905 int clientIndex = mLruProcesses.lastIndexOf(client);
2906 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2908 if (clientIndex >= 0 && addIndex > clientIndex) {
2909 addIndex = clientIndex;
2912 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2915 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2916 + mLruProcessActivityStart + "): " + app);
2920 if (lrui < mLruProcessActivityStart) {
2921 mLruProcessActivityStart--;
2923 if (lrui < mLruProcessServiceStart) {
2924 mLruProcessServiceStart--;
2927 if (addIndex > lrui) {
2930 if (nextIndex > lrui) {
2934 mLruProcesses.remove(lrui);
2938 mLruProcesses.add(addIndex, app);
2940 mLruProcessActivityStart++;
2943 mLruProcessActivityStart++;
2949 final int N = mLruProcesses.size();
2950 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
2951 // Process doesn't have activities, but has clients with
2952 // activities... move it up, but one below the top (the top
2953 // should always have a real activity).
2954 if (DEBUG_LRU) Slog.d(TAG_LRU,
2955 "Adding to second-top of LRU activity list: " + app);
2956 mLruProcesses.add(N - 1, app);
2957 // To keep it from spamming the LRU list (by making a bunch of clients),
2958 // we will push down any other entries owned by the app.
2959 final int uid = app.info.uid;
2960 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
2961 ProcessRecord subProc = mLruProcesses.get(i);
2962 if (subProc.info.uid == uid) {
2963 // We want to push this one down the list. If the process after
2964 // it is for the same uid, however, don't do so, because we don't
2965 // want them internally to be re-ordered.
2966 if (mLruProcesses.get(i - 1).info.uid != uid) {
2967 if (DEBUG_LRU) Slog.d(TAG_LRU,
2968 "Pushing uid " + uid + " swapping at " + i + ": "
2969 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
2970 ProcessRecord tmp = mLruProcesses.get(i);
2971 mLruProcesses.set(i, mLruProcesses.get(i - 1));
2972 mLruProcesses.set(i - 1, tmp);
2976 // A gap, we can stop here.
2981 // Process has activities, put it at the very tipsy-top.
2982 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
2983 mLruProcesses.add(app);
2985 nextIndex = mLruProcessServiceStart;
2986 } else if (hasService) {
2987 // Process has services, put it at the top of the service list.
2988 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
2989 mLruProcesses.add(mLruProcessActivityStart, app);
2990 nextIndex = mLruProcessServiceStart;
2991 mLruProcessActivityStart++;
2993 // Process not otherwise of interest, it goes to the top of the non-service area.
2994 int index = mLruProcessServiceStart;
2995 if (client != null) {
2996 // If there is a client, don't allow the process to be moved up higher
2997 // in the list than that client.
2998 int clientIndex = mLruProcesses.lastIndexOf(client);
2999 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3000 + " when updating " + app);
3001 if (clientIndex <= lrui) {
3002 // Don't allow the client index restriction to push it down farther in the
3003 // list than it already is.
3006 if (clientIndex >= 0 && index > clientIndex) {
3007 index = clientIndex;
3010 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3011 mLruProcesses.add(index, app);
3012 nextIndex = index-1;
3013 mLruProcessActivityStart++;
3014 mLruProcessServiceStart++;
3017 // If the app is currently using a content provider or service,
3018 // bump those processes as well.
3019 for (int j=app.connections.size()-1; j>=0; j--) {
3020 ConnectionRecord cr = app.connections.valueAt(j);
3021 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3022 && cr.binding.service.app != null
3023 && cr.binding.service.app.lruSeq != mLruSeq
3024 && !cr.binding.service.app.persistent) {
3025 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3026 "service connection", cr, app);
3029 for (int j=app.conProviders.size()-1; j>=0; j--) {
3030 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3031 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3032 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3033 "provider reference", cpr, app);
3038 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3039 if (uid == Process.SYSTEM_UID) {
3040 // The system gets to run in any process. If there are multiple
3041 // processes with the same uid, just pick the first (this
3042 // should never happen).
3043 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3044 if (procs == null) return null;
3045 final int procCount = procs.size();
3046 for (int i = 0; i < procCount; i++) {
3047 final int procUid = procs.keyAt(i);
3048 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3049 // Don't use an app process or different user process for system component.
3052 return procs.valueAt(i);
3055 ProcessRecord proc = mProcessNames.get(processName, uid);
3056 if (false && proc != null && !keepIfLarge
3057 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3058 && proc.lastCachedPss >= 4000) {
3059 // Turn this condition on to cause killing to happen regularly, for testing.
3060 if (proc.baseProcessTracker != null) {
3061 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3063 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3064 } else if (proc != null && !keepIfLarge
3065 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3066 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3067 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3068 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3069 if (proc.baseProcessTracker != null) {
3070 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3072 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3078 void ensurePackageDexOpt(String packageName) {
3079 IPackageManager pm = AppGlobals.getPackageManager();
3081 if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
3084 } catch (RemoteException e) {
3088 boolean isNextTransitionForward() {
3089 int transit = mWindowManager.getPendingAppTransition();
3090 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
3091 || transit == AppTransition.TRANSIT_TASK_OPEN
3092 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
3095 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3096 String processName, String abiOverride, int uid, Runnable crashHandler) {
3097 synchronized(this) {
3098 ApplicationInfo info = new ApplicationInfo();
3099 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3100 // For isolated processes, the former contains the parent's uid and the latter the
3101 // actual uid of the isolated process.
3102 // In the special case introduced by this method (which is, starting an isolated
3103 // process directly from the SystemServer without an actual parent app process) the
3104 // closest thing to a parent's uid is SYSTEM_UID.
3105 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3106 // the |isolated| logic in the ProcessRecord constructor.
3107 info.uid = Process.SYSTEM_UID;
3108 info.processName = processName;
3109 info.className = entryPoint;
3110 info.packageName = "android";
3111 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3112 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3113 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3114 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3116 return proc != null ? proc.pid : 0;
3120 final ProcessRecord startProcessLocked(String processName,
3121 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3122 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3123 boolean isolated, boolean keepIfLarge) {
3124 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3125 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3126 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3127 null /* crashHandler */);
3130 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3131 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3132 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3133 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3134 long startTime = SystemClock.elapsedRealtime();
3137 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3138 checkTime(startTime, "startProcess: after getProcessRecord");
3140 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3141 // If we are in the background, then check to see if this process
3142 // is bad. If so, we will just silently fail.
3143 if (mBadProcesses.get(info.processName, info.uid) != null) {
3144 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3145 + "/" + info.processName);
3149 // When the user is explicitly starting a process, then clear its
3150 // crash count so that we won't make it bad until they see at
3151 // least one crash dialog again, and make the process good again
3152 // if it had been bad.
3153 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3154 + "/" + info.processName);
3155 mProcessCrashTimes.remove(info.processName, info.uid);
3156 if (mBadProcesses.get(info.processName, info.uid) != null) {
3157 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3158 UserHandle.getUserId(info.uid), info.uid,
3160 mBadProcesses.remove(info.processName, info.uid);
3167 // If this is an isolated process, it can't re-use an existing process.
3171 // app launch boost for big.little configurations
3172 // use cpusets to migrate freshly launched tasks to big cores
3173 synchronized(ActivityManagerService.this) {
3174 nativeMigrateToBoost();
3176 mBoostStartTime = SystemClock.uptimeMillis();
3177 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3178 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3181 // We don't have to do anything more if:
3182 // (1) There is an existing application record; and
3183 // (2) The caller doesn't think it is dead, OR there is no thread
3184 // object attached to it so we know it couldn't have crashed; and
3185 // (3) There is a pid assigned to it, so it is either starting or
3187 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3188 + " app=" + app + " knownToBeDead=" + knownToBeDead
3189 + " thread=" + (app != null ? app.thread : null)
3190 + " pid=" + (app != null ? app.pid : -1));
3191 if (app != null && app.pid > 0) {
3192 if (!knownToBeDead || app.thread == null) {
3193 // We already have the app running, or are waiting for it to
3194 // come up (we have a pid but not yet its thread), so keep it.
3195 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3196 // If this is a new package in the process, add the package to the list
3197 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3198 checkTime(startTime, "startProcess: done, added package to proc");
3202 // An application record is attached to a previous process,
3204 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3205 checkTime(startTime, "startProcess: bad proc running, killing");
3206 killProcessGroup(app.uid, app.pid);
3207 handleAppDiedLocked(app, true, true);
3208 checkTime(startTime, "startProcess: done killing old proc");
3211 String hostingNameStr = hostingName != null
3212 ? hostingName.flattenToShortString() : null;
3215 checkTime(startTime, "startProcess: creating new process record");
3216 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3218 Slog.w(TAG, "Failed making new process record for "
3219 + processName + "/" + info.uid + " isolated=" + isolated);
3222 app.crashHandler = crashHandler;
3223 checkTime(startTime, "startProcess: done creating new process record");
3225 // If this is a new package in the process, add the package to the list
3226 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3227 checkTime(startTime, "startProcess: added package to existing proc");
3230 // If the system is not ready yet, then hold off on starting this
3231 // process until it is.
3232 if (!mProcessesReady
3233 && !isAllowedWhileBooting(info)
3234 && !allowWhileBooting) {
3235 if (!mProcessesOnHold.contains(app)) {
3236 mProcessesOnHold.add(app);
3238 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3239 "System not ready, putting on hold: " + app);
3240 checkTime(startTime, "startProcess: returning with proc on hold");
3244 checkTime(startTime, "startProcess: stepping in to startProcess");
3246 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3247 checkTime(startTime, "startProcess: done starting proc!");
3248 return (app.pid != 0) ? app : null;
3251 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3252 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3255 private final void startProcessLocked(ProcessRecord app,
3256 String hostingType, String hostingNameStr) {
3257 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3258 null /* entryPoint */, null /* entryPointArgs */);
3261 private final void startProcessLocked(ProcessRecord app, String hostingType,
3262 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3263 long startTime = SystemClock.elapsedRealtime();
3264 if (app.pid > 0 && app.pid != MY_PID) {
3265 checkTime(startTime, "startProcess: removing from pids map");
3266 synchronized (mPidsSelfLocked) {
3267 mPidsSelfLocked.remove(app.pid);
3268 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3270 checkTime(startTime, "startProcess: done removing from pids map");
3274 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3275 "startProcessLocked removing on hold: " + app);
3276 mProcessesOnHold.remove(app);
3278 checkTime(startTime, "startProcess: starting to update cpu stats");
3280 checkTime(startTime, "startProcess: done updating cpu stats");
3284 if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) {
3285 // This is caught below as if we had failed to fork zygote
3286 throw new RuntimeException("Package " + app.info.packageName + " is frozen!");
3288 } catch (RemoteException e) {
3289 throw e.rethrowAsRuntimeException();
3294 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3295 if (!app.isolated) {
3296 int[] permGids = null;
3298 checkTime(startTime, "startProcess: getting gids from package manager");
3299 final IPackageManager pm = AppGlobals.getPackageManager();
3300 permGids = pm.getPackageGids(app.info.packageName, app.userId);
3301 MountServiceInternal mountServiceInternal = LocalServices.getService(
3302 MountServiceInternal.class);
3303 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3304 app.info.packageName);
3305 } catch (RemoteException e) {
3306 throw e.rethrowAsRuntimeException();
3310 * Add shared application and profile GIDs so applications can share some
3311 * resources like shared libraries and access user-wide resources
3313 if (ArrayUtils.isEmpty(permGids)) {
3316 gids = new int[permGids.length + 2];
3317 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3319 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3320 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3322 checkTime(startTime, "startProcess: building args");
3323 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3324 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3325 && mTopComponent != null
3326 && app.processName.equals(mTopComponent.getPackageName())) {
3329 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3330 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3335 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3336 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3337 // Also turn on CheckJNI for debuggable apps. It's quite
3338 // awkward to turn on otherwise.
3339 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3341 // Run the app in safe mode if its manifest requests so or the
3342 // system is booted in safe mode.
3343 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3344 mSafeMode == true) {
3345 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3347 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3348 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3350 String jitDebugProperty = SystemProperties.get("debug.usejit");
3351 if ("true".equals(jitDebugProperty)) {
3352 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3353 } else if (!"false".equals(jitDebugProperty)) {
3354 // If we didn't force disable by setting false, defer to the dalvik vm options.
3355 if ("true".equals(SystemProperties.get("dalvik.vm.usejit"))) {
3356 debugFlags |= Zygote.DEBUG_ENABLE_JIT;
3359 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3360 if ("true".equals(genDebugInfoProperty)) {
3361 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3363 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3364 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3366 if ("1".equals(SystemProperties.get("debug.assert"))) {
3367 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3370 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3371 if (requiredAbi == null) {
3372 requiredAbi = Build.SUPPORTED_ABIS[0];
3375 String instructionSet = null;
3376 if (app.info.primaryCpuAbi != null) {
3377 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3381 app.requiredAbi = requiredAbi;
3382 app.instructionSet = instructionSet;
3384 // Start the process. It will either succeed and return a result containing
3385 // the PID of the new process, or else throw a RuntimeException.
3386 boolean isActivityProcess = (entryPoint == null);
3387 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3388 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3390 checkTime(startTime, "startProcess: asking zygote to start proc");
3391 Process.ProcessStartResult startResult = Process.start(entryPoint,
3392 app.processName, uid, uid, gids, debugFlags, mountExternal,
3393 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3394 app.info.dataDir, entryPointArgs);
3395 checkTime(startTime, "startProcess: returned from zygote!");
3396 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3399 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3401 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3402 checkTime(startTime, "startProcess: done updating battery stats");
3404 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3405 UserHandle.getUserId(uid), startResult.pid, uid,
3406 app.processName, hostingType,
3407 hostingNameStr != null ? hostingNameStr : "");
3409 if (app.persistent) {
3410 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3413 checkTime(startTime, "startProcess: building log message");
3414 StringBuilder buf = mStringBuilder;
3416 buf.append("Start proc ");
3417 buf.append(startResult.pid);
3419 buf.append(app.processName);
3421 UserHandle.formatUid(buf, uid);
3422 if (!isActivityProcess) {
3424 buf.append(entryPoint);
3427 buf.append(" for ");
3428 buf.append(hostingType);
3429 if (hostingNameStr != null) {
3431 buf.append(hostingNameStr);
3433 Slog.i(TAG, buf.toString());
3434 app.setPid(startResult.pid);
3435 app.usingWrapper = startResult.usingWrapper;
3436 app.removed = false;
3438 app.killedByAm = false;
3439 checkTime(startTime, "startProcess: starting to update pids map");
3440 ProcessRecord oldApp;
3441 synchronized (mPidsSelfLocked) {
3442 oldApp = mPidsSelfLocked.get(startResult.pid);
3444 // If there is already an app occupying that pid that hasn't been cleaned up
3445 if (oldApp != null && !app.isolated) {
3446 // Clean up anything relating to this pid first
3447 Slog.w(TAG, "Reusing pid " + startResult.pid
3448 + " while app is still mapped to it");
3449 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3450 true /*replacingPid*/);
3452 synchronized (mPidsSelfLocked) {
3453 this.mPidsSelfLocked.put(startResult.pid, app);
3454 if (isActivityProcess) {
3455 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3457 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3458 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3461 checkTime(startTime, "startProcess: done updating pids map");
3462 } catch (RuntimeException e) {
3463 // XXX do better error recovery.
3465 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3467 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3469 Slog.e(TAG, "Failure starting process " + app.processName, e);
3473 void updateUsageStats(ActivityRecord component, boolean resumed) {
3474 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3475 "updateUsageStats: comp=" + component + "res=" + resumed);
3476 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3478 if (mUsageStatsService != null) {
3479 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3480 UsageEvents.Event.MOVE_TO_FOREGROUND);
3482 synchronized (stats) {
3483 stats.noteActivityResumedLocked(component.app.uid);
3486 if (mUsageStatsService != null) {
3487 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3488 UsageEvents.Event.MOVE_TO_BACKGROUND);
3490 synchronized (stats) {
3491 stats.noteActivityPausedLocked(component.app.uid);
3496 Intent getHomeIntent() {
3497 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3498 intent.setComponent(mTopComponent);
3499 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3500 intent.addCategory(Intent.CATEGORY_HOME);
3505 boolean startHomeActivityLocked(int userId, String reason) {
3506 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3507 && mTopAction == null) {
3508 // We are running in factory test mode, but unable to find
3509 // the factory test app, so just sit around displaying the
3510 // error message and don't try to start anything.
3513 Intent intent = getHomeIntent();
3514 ActivityInfo aInfo =
3515 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3516 if (aInfo != null) {
3517 intent.setComponent(new ComponentName(
3518 aInfo.applicationInfo.packageName, aInfo.name));
3519 // Don't do this if the home app is currently being
3521 aInfo = new ActivityInfo(aInfo);
3522 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3523 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3524 aInfo.applicationInfo.uid, true);
3525 if (app == null || app.instrumentationClass == null) {
3526 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3527 mStackSupervisor.startHomeActivity(intent, aInfo, reason);
3534 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3535 ActivityInfo ai = null;
3536 ComponentName comp = intent.getComponent();
3540 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3542 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3544 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3548 ai = info.activityInfo;
3551 } catch (RemoteException e) {
3559 * Starts the "new version setup screen" if appropriate.
3561 void startSetupActivityLocked() {
3562 // Only do this once per boot.
3563 if (mCheckedForSetup) {
3567 // We will show this screen if the current one is a different
3568 // version than the last one shown, and we are not running in
3569 // low-level factory test mode.
3570 final ContentResolver resolver = mContext.getContentResolver();
3571 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3572 Settings.Global.getInt(resolver,
3573 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3574 mCheckedForSetup = true;
3576 // See if we should be showing the platform update setup UI.
3577 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3578 List<ResolveInfo> ris = mContext.getPackageManager()
3579 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3581 // We don't allow third party apps to replace this.
3582 ResolveInfo ri = null;
3583 for (int i=0; ris != null && i<ris.size(); i++) {
3584 if ((ris.get(i).activityInfo.applicationInfo.flags
3585 & ApplicationInfo.FLAG_SYSTEM) != 0) {
3592 String vers = ri.activityInfo.metaData != null
3593 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3595 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3596 vers = ri.activityInfo.applicationInfo.metaData.getString(
3597 Intent.METADATA_SETUP_VERSION);
3599 String lastVers = Settings.Secure.getString(
3600 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3601 if (vers != null && !vers.equals(lastVers)) {
3602 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3603 intent.setComponent(new ComponentName(
3604 ri.activityInfo.packageName, ri.activityInfo.name));
3605 mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3606 null, null, null, null, 0, 0, 0, null, 0, 0, 0, null, false, false,
3613 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3614 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3617 void enforceNotIsolatedCaller(String caller) {
3618 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3619 throw new SecurityException("Isolated process not allowed to call " + caller);
3623 void enforceShellRestriction(String restriction, int userHandle) {
3624 if (Binder.getCallingUid() == Process.SHELL_UID) {
3626 || mUserManager.hasUserRestriction(restriction, userHandle)) {
3627 throw new SecurityException("Shell does not have permission to access user "
3634 public int getFrontActivityScreenCompatMode() {
3635 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3636 synchronized (this) {
3637 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3642 public void setFrontActivityScreenCompatMode(int mode) {
3643 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3644 "setFrontActivityScreenCompatMode");
3645 synchronized (this) {
3646 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3651 public int getPackageScreenCompatMode(String packageName) {
3652 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3653 synchronized (this) {
3654 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3659 public void setPackageScreenCompatMode(String packageName, int mode) {
3660 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3661 "setPackageScreenCompatMode");
3662 synchronized (this) {
3663 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3668 public boolean getPackageAskScreenCompat(String packageName) {
3669 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3670 synchronized (this) {
3671 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3676 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3677 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3678 "setPackageAskScreenCompat");
3679 synchronized (this) {
3680 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3684 private boolean hasUsageStatsPermission(String callingPackage) {
3685 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3686 Binder.getCallingUid(), callingPackage);
3687 if (mode == AppOpsManager.MODE_DEFAULT) {
3688 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3689 == PackageManager.PERMISSION_GRANTED;
3691 return mode == AppOpsManager.MODE_ALLOWED;
3695 public int getPackageProcessState(String packageName, String callingPackage) {
3696 if (!hasUsageStatsPermission(callingPackage)) {
3697 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3698 "getPackageProcessState");
3701 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3702 synchronized (this) {
3703 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3704 final ProcessRecord proc = mLruProcesses.get(i);
3705 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3706 || procState > proc.setProcState) {
3707 boolean found = false;
3708 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3709 if (proc.pkgList.keyAt(j).equals(packageName)) {
3710 procState = proc.setProcState;
3714 if (proc.pkgDeps != null && !found) {
3715 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3716 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3717 procState = proc.setProcState;
3729 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3730 synchronized (this) {
3731 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3735 if (app.trimMemoryLevel < level && app.thread != null &&
3736 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3737 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3739 app.thread.scheduleTrimMemory(level);
3740 app.trimMemoryLevel = level;
3742 } catch (RemoteException e) {
3743 // Fallthrough to failure case.
3750 private void dispatchProcessesChanged() {
3752 synchronized (this) {
3753 N = mPendingProcessChanges.size();
3754 if (mActiveProcessChanges.length < N) {
3755 mActiveProcessChanges = new ProcessChangeItem[N];
3757 mPendingProcessChanges.toArray(mActiveProcessChanges);
3758 mPendingProcessChanges.clear();
3759 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3760 "*** Delivering " + N + " process changes");
3763 int i = mProcessObservers.beginBroadcast();
3766 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3767 if (observer != null) {
3769 for (int j=0; j<N; j++) {
3770 ProcessChangeItem item = mActiveProcessChanges[j];
3771 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3772 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3773 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3774 + item.uid + ": " + item.foregroundActivities);
3775 observer.onForegroundActivitiesChanged(item.pid, item.uid,
3776 item.foregroundActivities);
3778 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3779 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3780 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3781 + ": " + item.processState);
3782 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3785 } catch (RemoteException e) {
3789 mProcessObservers.finishBroadcast();
3791 synchronized (this) {
3792 for (int j=0; j<N; j++) {
3793 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3798 private void dispatchProcessDied(int pid, int uid) {
3799 int i = mProcessObservers.beginBroadcast();
3802 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3803 if (observer != null) {
3805 observer.onProcessDied(pid, uid);
3806 } catch (RemoteException e) {
3810 mProcessObservers.finishBroadcast();
3813 private void dispatchUidsChanged() {
3815 synchronized (this) {
3816 N = mPendingUidChanges.size();
3817 if (mActiveUidChanges.length < N) {
3818 mActiveUidChanges = new UidRecord.ChangeItem[N];
3820 for (int i=0; i<N; i++) {
3821 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3822 mActiveUidChanges[i] = change;
3823 change.uidRecord.pendingChange = null;
3824 change.uidRecord = null;
3826 mPendingUidChanges.clear();
3827 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3828 "*** Delivering " + N + " uid changes");
3831 if (mLocalPowerManager != null) {
3832 for (int j=0; j<N; j++) {
3833 UidRecord.ChangeItem item = mActiveUidChanges[j];
3835 mLocalPowerManager.uidGone(item.uid);
3837 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
3842 int i = mUidObservers.beginBroadcast();
3845 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
3846 if (observer != null) {
3848 for (int j=0; j<N; j++) {
3849 UidRecord.ChangeItem item = mActiveUidChanges[j];
3851 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3852 "UID gone uid=" + item.uid);
3853 observer.onUidGone(item.uid);
3855 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3856 "UID CHANGED uid=" + item.uid
3857 + ": " + item.processState);
3858 observer.onUidStateChanged(item.uid, item.processState);
3861 } catch (RemoteException e) {
3865 mUidObservers.finishBroadcast();
3867 synchronized (this) {
3868 for (int j=0; j<N; j++) {
3869 mAvailUidChanges.add(mActiveUidChanges[j]);
3875 public final int startActivity(IApplicationThread caller, String callingPackage,
3876 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3877 int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3878 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3879 resultWho, requestCode, startFlags, profilerInfo, options,
3880 UserHandle.getCallingUserId());
3884 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3885 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3886 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3887 enforceNotIsolatedCaller("startActivity");
3888 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3889 false, ALLOW_FULL_ONLY, "startActivity", null);
3890 // TODO: Switch to user app stacks here.
3891 return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3892 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3893 profilerInfo, null, null, options, false, userId, null, null);
3897 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3898 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3899 int startFlags, ProfilerInfo profilerInfo, Bundle options, boolean ignoreTargetSecurity,
3902 // This is very dangerous -- it allows you to perform a start activity (including
3903 // permission grants) as any app that may launch one of your own activities. So
3904 // we will only allow this to be done from activities that are part of the core framework,
3905 // and then only when they are running as the system.
3906 final ActivityRecord sourceRecord;
3907 final int targetUid;
3908 final String targetPackage;
3909 synchronized (this) {
3910 if (resultTo == null) {
3911 throw new SecurityException("Must be called from an activity");
3913 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3914 if (sourceRecord == null) {
3915 throw new SecurityException("Called with bad activity token: " + resultTo);
3917 if (!sourceRecord.info.packageName.equals("android")) {
3918 throw new SecurityException(
3919 "Must be called from an activity that is declared in the android package");
3921 if (sourceRecord.app == null) {
3922 throw new SecurityException("Called without a process attached to activity");
3924 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3925 // This is still okay, as long as this activity is running under the
3926 // uid of the original calling activity.
3927 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3928 throw new SecurityException(
3929 "Calling activity in uid " + sourceRecord.app.uid
3930 + " must be system uid or original calling uid "
3931 + sourceRecord.launchedFromUid);
3934 if (ignoreTargetSecurity) {
3935 if (intent.getComponent() == null) {
3936 throw new SecurityException(
3937 "Component must be specified with ignoreTargetSecurity");
3939 if (intent.getSelector() != null) {
3940 throw new SecurityException(
3941 "Selector not allowed with ignoreTargetSecurity");
3944 targetUid = sourceRecord.launchedFromUid;
3945 targetPackage = sourceRecord.launchedFromPackage;
3948 if (userId == UserHandle.USER_NULL) {
3949 userId = UserHandle.getUserId(sourceRecord.app.uid);
3952 // TODO: Switch to user app stacks here.
3954 int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3955 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3956 null, null, options, ignoreTargetSecurity, userId, null, null);
3958 } catch (SecurityException e) {
3959 // XXX need to figure out how to propagate to original app.
3960 // A SecurityException here is generally actually a fault of the original
3961 // calling activity (such as a fairly granting permissions), so propagate it
3964 StringBuilder msg = new StringBuilder();
3965 msg.append("While launching");
3966 msg.append(intent.toString());
3968 msg.append(e.getMessage());
3975 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3976 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3977 int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3978 enforceNotIsolatedCaller("startActivityAndWait");
3979 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3980 false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3981 WaitResult res = new WaitResult();
3982 // TODO: Switch to user app stacks here.
3983 mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3984 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3985 options, false, userId, null, null);
3990 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3991 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3992 int startFlags, Configuration config, Bundle options, int userId) {
3993 enforceNotIsolatedCaller("startActivityWithConfig");
3994 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3995 false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3996 // TODO: Switch to user app stacks here.
3997 int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3998 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3999 null, null, config, options, false, userId, null, null);
4004 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4005 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4006 int requestCode, int flagsMask, int flagsValues, Bundle options)
4007 throws TransactionTooLargeException {
4008 enforceNotIsolatedCaller("startActivityIntentSender");
4009 // Refuse possible leaked file descriptors
4010 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4011 throw new IllegalArgumentException("File descriptors passed in Intent");
4014 IIntentSender sender = intent.getTarget();
4015 if (!(sender instanceof PendingIntentRecord)) {
4016 throw new IllegalArgumentException("Bad PendingIntent object");
4019 PendingIntentRecord pir = (PendingIntentRecord)sender;
4021 synchronized (this) {
4022 // If this is coming from the currently resumed activity, it is
4023 // effectively saying that app switches are allowed at this point.
4024 final ActivityStack stack = getFocusedStack();
4025 if (stack.mResumedActivity != null &&
4026 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4027 mAppSwitchesAllowedTime = 0;
4030 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4031 resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
4036 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4037 Intent intent, String resolvedType, IVoiceInteractionSession session,
4038 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4039 Bundle options, int userId) {
4040 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4041 != PackageManager.PERMISSION_GRANTED) {
4042 String msg = "Permission Denial: startVoiceActivity() from pid="
4043 + Binder.getCallingPid()
4044 + ", uid=" + Binder.getCallingUid()
4045 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4047 throw new SecurityException(msg);
4049 if (session == null || interactor == null) {
4050 throw new NullPointerException("null session or interactor");
4052 userId = handleIncomingUser(callingPid, callingUid, userId,
4053 false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
4054 // TODO: Switch to user app stacks here.
4055 return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
4056 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4057 null, options, false, userId, null, null);
4061 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4062 synchronized (this) {
4063 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4065 mVoiceWakeLock.acquire();
4067 mVoiceWakeLock.release();
4074 public boolean startNextMatchingActivity(IBinder callingActivity,
4075 Intent intent, Bundle options) {
4076 // Refuse possible leaked file descriptors
4077 if (intent != null && intent.hasFileDescriptors() == true) {
4078 throw new IllegalArgumentException("File descriptors passed in Intent");
4081 synchronized (this) {
4082 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4084 ActivityOptions.abort(options);
4087 if (r.app == null || r.app.thread == null) {
4088 // The caller is not running... d'oh!
4089 ActivityOptions.abort(options);
4092 intent = new Intent(intent);
4093 // The caller is not allowed to change the data.
4094 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4095 // And we are resetting to find the next component...
4096 intent.setComponent(null);
4098 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4100 ActivityInfo aInfo = null;
4102 List<ResolveInfo> resolves =
4103 AppGlobals.getPackageManager().queryIntentActivities(
4104 intent, r.resolvedType,
4105 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4106 UserHandle.getCallingUserId());
4108 // Look for the original activity in the list...
4109 final int N = resolves != null ? resolves.size() : 0;
4110 for (int i=0; i<N; i++) {
4111 ResolveInfo rInfo = resolves.get(i);
4112 if (rInfo.activityInfo.packageName.equals(r.packageName)
4113 && rInfo.activityInfo.name.equals(r.info.name)) {
4114 // We found the current one... the next matching is
4118 aInfo = resolves.get(i).activityInfo;
4121 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4122 + "/" + r.info.name);
4123 Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
4124 + "/" + aInfo.name);
4129 } catch (RemoteException e) {
4132 if (aInfo == null) {
4133 // Nobody who is next!
4134 ActivityOptions.abort(options);
4135 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4139 intent.setComponent(new ComponentName(
4140 aInfo.applicationInfo.packageName, aInfo.name));
4141 intent.setFlags(intent.getFlags()&~(
4142 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4143 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4144 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4145 Intent.FLAG_ACTIVITY_NEW_TASK));
4147 // Okay now we need to start the new activity, replacing the
4148 // currently running activity. This is a little tricky because
4149 // we want to start the new one as if the current one is finished,
4150 // but not finish the current one first so that there is no flicker.
4152 final boolean wasFinishing = r.finishing;
4155 // Propagate reply information over to the new activity.
4156 final ActivityRecord resultTo = r.resultTo;
4157 final String resultWho = r.resultWho;
4158 final int requestCode = r.requestCode;
4160 if (resultTo != null) {
4161 resultTo.removeResultsLocked(r, resultWho, requestCode);
4164 final long origId = Binder.clearCallingIdentity();
4165 int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
4166 r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
4167 resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage,
4168 -1, r.launchedFromUid, 0, options, false, false, null, null, null);
4169 Binder.restoreCallingIdentity(origId);
4171 r.finishing = wasFinishing;
4172 if (res != ActivityManager.START_SUCCESS) {
4180 public final int startActivityFromRecents(int taskId, Bundle options) {
4181 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4182 String msg = "Permission Denial: startActivityFromRecents called without " +
4183 START_TASKS_FROM_RECENTS;
4185 throw new SecurityException(msg);
4187 return startActivityFromRecentsInner(taskId, options);
4190 final int startActivityFromRecentsInner(int taskId, Bundle options) {
4191 final TaskRecord task;
4192 final int callingUid;
4193 final String callingPackage;
4194 final Intent intent;
4196 synchronized (this) {
4197 task = mStackSupervisor.anyTaskForIdLocked(taskId);
4199 throw new IllegalArgumentException("Task " + taskId + " not found.");
4201 if (task.getRootActivity() != null) {
4202 moveTaskToFrontLocked(task.taskId, 0, null);
4203 return ActivityManager.START_TASK_TO_FRONT;
4205 callingUid = task.mCallingUid;
4206 callingPackage = task.mCallingPackage;
4207 intent = task.intent;
4208 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4209 userId = task.userId;
4211 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4212 options, userId, null, task);
4215 final int startActivityInPackage(int uid, String callingPackage,
4216 Intent intent, String resolvedType, IBinder resultTo,
4217 String resultWho, int requestCode, int startFlags, Bundle options, int userId,
4218 IActivityContainer container, TaskRecord inTask) {
4220 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4221 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4223 // TODO: Switch to user app stacks here.
4224 int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
4225 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4226 null, null, null, options, false, userId, container, inTask);
4231 public final int startActivities(IApplicationThread caller, String callingPackage,
4232 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
4234 enforceNotIsolatedCaller("startActivities");
4235 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4236 false, ALLOW_FULL_ONLY, "startActivity", null);
4237 // TODO: Switch to user app stacks here.
4238 int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
4239 resolvedTypes, resultTo, options, userId);
4243 final int startActivitiesInPackage(int uid, String callingPackage,
4244 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4245 Bundle options, int userId) {
4247 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
4248 false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4249 // TODO: Switch to user app stacks here.
4250 int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4251 resultTo, options, userId);
4256 public void reportActivityFullyDrawn(IBinder token) {
4257 synchronized (this) {
4258 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4262 r.reportFullyDrawnLocked();
4267 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4268 synchronized (this) {
4269 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4273 if (r.task != null && r.task.mResizeable) {
4274 // Fixed screen orientation isn't supported with resizeable activities.
4277 final long origId = Binder.clearCallingIdentity();
4278 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4279 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4280 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4281 if (config != null) {
4282 r.frozenBeforeDestroy = true;
4283 if (!updateConfigurationLocked(config, r, false, false)) {
4284 mStackSupervisor.resumeTopActivitiesLocked();
4287 Binder.restoreCallingIdentity(origId);
4292 public int getRequestedOrientation(IBinder token) {
4293 synchronized (this) {
4294 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4296 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4298 return mWindowManager.getAppOrientation(r.appToken);
4303 * This is the internal entry point for handling Activity.finish().
4305 * @param token The Binder token referencing the Activity we want to finish.
4306 * @param resultCode Result code, if any, from this Activity.
4307 * @param resultData Result data (Intent), if any, from this Activity.
4308 * @param finishTask Whether to finish the task associated with this Activity. Only applies to
4309 * the root Activity in the task.
4311 * @return Returns true if the activity successfully finished, or false if it is still running.
4314 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4315 boolean finishTask) {
4316 // Refuse possible leaked file descriptors
4317 if (resultData != null && resultData.hasFileDescriptors() == true) {
4318 throw new IllegalArgumentException("File descriptors passed in Intent");
4321 synchronized(this) {
4322 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4326 // Keep track of the root activity of the task before we finish it
4327 TaskRecord tr = r.task;
4328 ActivityRecord rootR = tr.getRootActivity();
4329 if (rootR == null) {
4330 Slog.w(TAG, "Finishing task with all activities already finished");
4332 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4334 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4335 mStackSupervisor.isLastLockedTask(tr)) {
4336 Slog.i(TAG, "Not finishing task in lock task mode");
4337 mStackSupervisor.showLockTaskToast();
4340 if (mController != null) {
4341 // Find the first activity that is not finishing.
4342 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4344 // ask watcher if this is allowed
4345 boolean resumeOK = true;
4347 resumeOK = mController.activityResuming(next.packageName);
4348 } catch (RemoteException e) {
4350 Watchdog.getInstance().setActivityController(null);
4354 Slog.i(TAG, "Not finishing activity because controller resumed");
4359 final long origId = Binder.clearCallingIdentity();
4362 if (finishTask && r == rootR) {
4363 // If requested, remove the task that is associated to this activity only if it
4364 // was the root activity in the task. The result code and data is ignored
4365 // because we don't support returning them across task boundaries.
4366 res = removeTaskByIdLocked(tr.taskId, false);
4368 Slog.i(TAG, "Removing task failed to finish activity");
4371 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4372 resultData, "app-request", true);
4374 Slog.i(TAG, "Failed to finish by app-request");
4379 Binder.restoreCallingIdentity(origId);
4385 public final void finishHeavyWeightApp() {
4386 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4387 != PackageManager.PERMISSION_GRANTED) {
4388 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4389 + Binder.getCallingPid()
4390 + ", uid=" + Binder.getCallingUid()
4391 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4393 throw new SecurityException(msg);
4396 synchronized(this) {
4397 if (mHeavyWeightProcess == null) {
4401 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4402 for (int i = 0; i < activities.size(); i++) {
4403 ActivityRecord r = activities.get(i);
4404 if (!r.finishing && r.isInStackLocked()) {
4405 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4406 null, "finish-heavy", true);
4410 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4411 mHeavyWeightProcess.userId, 0));
4412 mHeavyWeightProcess = null;
4417 public void crashApplication(int uid, int initialPid, String packageName,
4419 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4420 != PackageManager.PERMISSION_GRANTED) {
4421 String msg = "Permission Denial: crashApplication() from pid="
4422 + Binder.getCallingPid()
4423 + ", uid=" + Binder.getCallingUid()
4424 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4426 throw new SecurityException(msg);
4429 synchronized(this) {
4430 ProcessRecord proc = null;
4432 // Figure out which process to kill. We don't trust that initialPid
4433 // still has any relation to current pids, so must scan through the
4435 synchronized (mPidsSelfLocked) {
4436 for (int i=0; i<mPidsSelfLocked.size(); i++) {
4437 ProcessRecord p = mPidsSelfLocked.valueAt(i);
4441 if (p.pid == initialPid) {
4445 if (p.pkgList.containsKey(packageName)) {
4452 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4453 + " initialPid=" + initialPid
4454 + " packageName=" + packageName);
4458 if (proc.thread != null) {
4459 if (proc.pid == Process.myPid()) {
4460 Log.w(TAG, "crashApplication: trying to crash self!");
4463 long ident = Binder.clearCallingIdentity();
4465 proc.thread.scheduleCrash(message);
4466 } catch (RemoteException e) {
4468 Binder.restoreCallingIdentity(ident);
4474 public final void finishSubActivity(IBinder token, String resultWho,
4476 synchronized(this) {
4477 final long origId = Binder.clearCallingIdentity();
4478 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4480 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4482 Binder.restoreCallingIdentity(origId);
4487 public boolean finishActivityAffinity(IBinder token) {
4488 synchronized(this) {
4489 final long origId = Binder.clearCallingIdentity();
4491 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4496 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4498 final TaskRecord task = r.task;
4499 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4500 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4501 mStackSupervisor.showLockTaskToast();
4504 return task.stack.finishActivityAffinityLocked(r);
4506 Binder.restoreCallingIdentity(origId);
4512 public void finishVoiceTask(IVoiceInteractionSession session) {
4513 synchronized(this) {
4514 final long origId = Binder.clearCallingIdentity();
4516 mStackSupervisor.finishVoiceTask(session);
4518 Binder.restoreCallingIdentity(origId);
4525 public boolean releaseActivityInstance(IBinder token) {
4526 synchronized(this) {
4527 final long origId = Binder.clearCallingIdentity();
4529 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4533 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4535 Binder.restoreCallingIdentity(origId);
4541 public void releaseSomeActivities(IApplicationThread appInt) {
4542 synchronized(this) {
4543 final long origId = Binder.clearCallingIdentity();
4545 ProcessRecord app = getRecordForAppLocked(appInt);
4546 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4548 Binder.restoreCallingIdentity(origId);
4554 public boolean willActivityBeVisible(IBinder token) {
4555 synchronized(this) {
4556 ActivityStack stack = ActivityRecord.getStackLocked(token);
4557 if (stack != null) {
4558 return stack.willActivityBeVisibleLocked(token);
4565 public void overridePendingTransition(IBinder token, String packageName,
4566 int enterAnim, int exitAnim) {
4567 synchronized(this) {
4568 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4573 final long origId = Binder.clearCallingIdentity();
4575 if (self.state == ActivityState.RESUMED
4576 || self.state == ActivityState.PAUSING) {
4577 mWindowManager.overridePendingAppTransition(packageName,
4578 enterAnim, exitAnim, null);
4581 Binder.restoreCallingIdentity(origId);
4586 * Main function for removing an existing process from the activity manager
4587 * as a result of that process going away. Clears out all connections
4590 private final void handleAppDiedLocked(ProcessRecord app,
4591 boolean restarting, boolean allowRestart) {
4593 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
4594 false /*replacingPid*/);
4595 if (!kept && !restarting) {
4596 removeLruProcessLocked(app);
4598 ProcessList.remove(pid);
4602 if (mProfileProc == app) {
4603 clearProfilerLocked();
4606 // Remove this application's activities from active lists.
4607 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4609 app.activities.clear();
4611 if (app.instrumentationClass != null) {
4612 Slog.w(TAG, "Crash of app " + app.processName
4613 + " running instrumentation " + app.instrumentationClass);
4614 Bundle info = new Bundle();
4615 info.putString("shortMsg", "Process crashed.");
4616 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4619 if (!restarting && hasVisibleActivities && !mStackSupervisor.resumeTopActivitiesLocked()) {
4620 // If there was nothing to resume, and we are not already
4621 // restarting this process, but there is a visible activity that
4622 // is hosted by the process... then make sure all visible
4623 // activities are running, taking care of restarting this
4625 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4629 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4630 IBinder threadBinder = thread.asBinder();
4631 // Find the application record.
4632 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4633 ProcessRecord rec = mLruProcesses.get(i);
4634 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4641 final ProcessRecord getRecordForAppLocked(
4642 IApplicationThread thread) {
4643 if (thread == null) {
4647 int appIndex = getLRURecordIndexForAppLocked(thread);
4648 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4651 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4652 // If there are no longer any background processes running,
4653 // and the app that died was not running instrumentation,
4654 // then tell everyone we are now low on memory.
4655 boolean haveBg = false;
4656 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4657 ProcessRecord rec = mLruProcesses.get(i);
4658 if (rec.thread != null
4659 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4666 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4668 long now = SystemClock.uptimeMillis();
4669 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4672 mLastMemUsageReportTime = now;
4675 final ArrayList<ProcessMemInfo> memInfos
4676 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4677 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4678 long now = SystemClock.uptimeMillis();
4679 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4680 ProcessRecord rec = mLruProcesses.get(i);
4681 if (rec == dyingProc || rec.thread == null) {
4685 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4686 rec.setProcState, rec.adjType, rec.makeAdjReason()));
4688 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4689 // The low memory report is overriding any current
4690 // state for a GC request. Make sure to do
4691 // heavy/important/visible/foreground processes first.
4692 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4693 rec.lastRequestedGc = 0;
4695 rec.lastRequestedGc = rec.lastLowMemory;
4697 rec.reportLowMemory = true;
4698 rec.lastLowMemory = now;
4699 mProcessesToGc.remove(rec);
4700 addProcessToGcListLocked(rec);
4704 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4705 mHandler.sendMessage(msg);
4707 scheduleAppGcsLocked();
4711 final void appDiedLocked(ProcessRecord app) {
4712 appDiedLocked(app, app.pid, app.thread, false);
4715 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
4716 boolean fromBinderDied) {
4717 // First check if this ProcessRecord is actually active for the pid.
4718 synchronized (mPidsSelfLocked) {
4719 ProcessRecord curProc = mPidsSelfLocked.get(pid);
4720 if (curProc != app) {
4721 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
4726 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4727 synchronized (stats) {
4728 stats.noteProcessDiedLocked(app.info.uid, pid);
4732 if (!fromBinderDied) {
4733 Process.killProcessQuiet(pid);
4735 killProcessGroup(app.uid, pid);
4739 // Clean up already done if the process has been re-started.
4740 if (app.pid == pid && app.thread != null &&
4741 app.thread.asBinder() == thread.asBinder()) {
4742 boolean doLowMem = app.instrumentationClass == null;
4743 boolean doOomAdj = doLowMem;
4744 if (!app.killedByAm) {
4745 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4747 mAllowLowerMemLevel = true;
4749 // Note that we always want to do oom adj to update our state with the
4750 // new number of procs.
4751 mAllowLowerMemLevel = false;
4754 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4755 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
4756 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
4757 handleAppDiedLocked(app, false, true);
4760 updateOomAdjLocked();
4763 doLowMemReportIfNeededLocked(app);
4765 } else if (app.pid != pid) {
4766 // A new process has already been started.
4767 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4768 + ") has died and restarted (pid " + app.pid + ").");
4769 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4770 } else if (DEBUG_PROCESSES) {
4771 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
4772 + thread.asBinder());
4777 * If a stack trace dump file is configured, dump process stack traces.
4778 * @param clearTraces causes the dump file to be erased prior to the new
4779 * traces being written, if true; when false, the new traces will be
4780 * appended to any existing file content.
4781 * @param firstPids of dalvik VM processes to dump stack traces for first
4782 * @param lastPids of dalvik VM processes to dump stack traces for last
4783 * @param nativeProcs optional list of native process names to dump stack crawls
4784 * @return file containing stack traces, or null if no dump file is configured
4786 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4787 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4788 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4789 if (tracesPath == null || tracesPath.length() == 0) {
4793 File tracesFile = new File(tracesPath);
4795 File tracesDir = tracesFile.getParentFile();
4796 if (!tracesDir.exists()) {
4798 if (!SELinux.restorecon(tracesDir)) {
4802 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4804 if (clearTraces && tracesFile.exists()) tracesFile.delete();
4805 tracesFile.createNewFile();
4806 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4807 } catch (IOException e) {
4808 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4812 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4816 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4817 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4818 // Use a FileObserver to detect when traces finish writing.
4819 // The order of traces is considered important to maintain for legibility.
4820 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4822 public synchronized void onEvent(int event, String path) { notify(); }
4826 observer.startWatching();
4828 // First collect all of the stacks of the most important pids.
4829 if (firstPids != null) {
4831 int num = firstPids.size();
4832 for (int i = 0; i < num; i++) {
4833 synchronized (observer) {
4834 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4835 observer.wait(200); // Wait for write-close, give up after 200msec
4838 } catch (InterruptedException e) {
4843 // Next collect the stacks of the native pids
4844 if (nativeProcs != null) {
4845 int[] pids = Process.getPidsForCommands(nativeProcs);
4847 for (int pid : pids) {
4848 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4853 // Lastly, measure CPU usage.
4854 if (processCpuTracker != null) {
4855 processCpuTracker.init();
4857 processCpuTracker.update();
4859 synchronized (processCpuTracker) {
4860 processCpuTracker.wait(500); // measure over 1/2 second.
4862 } catch (InterruptedException e) {
4864 processCpuTracker.update();
4866 // We'll take the stack crawls of just the top apps using CPU.
4867 final int N = processCpuTracker.countWorkingStats();
4869 for (int i=0; i<N && numProcs<5; i++) {
4870 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4871 if (lastPids.indexOfKey(stats.pid) >= 0) {
4874 synchronized (observer) {
4875 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4876 observer.wait(200); // Wait for write-close, give up after 200msec
4878 } catch (InterruptedException e) {
4886 observer.stopWatching();
4890 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4891 if (true || IS_USER_BUILD) {
4894 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4895 if (tracesPath == null || tracesPath.length() == 0) {
4899 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4900 StrictMode.allowThreadDiskWrites();
4902 final File tracesFile = new File(tracesPath);
4903 final File tracesDir = tracesFile.getParentFile();
4904 final File tracesTmp = new File(tracesDir, "__tmp__");
4906 if (!tracesDir.exists()) {
4908 if (!SELinux.restorecon(tracesDir.getPath())) {
4912 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
4914 if (tracesFile.exists()) {
4916 tracesFile.renameTo(tracesTmp);
4918 StringBuilder sb = new StringBuilder();
4919 Time tobj = new Time();
4920 tobj.set(System.currentTimeMillis());
4921 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4923 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4924 sb.append(" since ");
4926 FileOutputStream fos = new FileOutputStream(tracesFile);
4927 fos.write(sb.toString().getBytes());
4929 fos.write("\n*** No application process!".getBytes());
4932 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4933 } catch (IOException e) {
4934 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4939 ArrayList<Integer> firstPids = new ArrayList<Integer>();
4940 firstPids.add(app.pid);
4941 dumpStackTraces(tracesPath, firstPids, null, null, null);
4944 File lastTracesFile = null;
4945 File curTracesFile = null;
4946 for (int i=9; i>=0; i--) {
4947 String name = String.format(Locale.US, "slow%02d.txt", i);
4948 curTracesFile = new File(tracesDir, name);
4949 if (curTracesFile.exists()) {
4950 if (lastTracesFile != null) {
4951 curTracesFile.renameTo(lastTracesFile);
4953 curTracesFile.delete();
4956 lastTracesFile = curTracesFile;
4958 tracesFile.renameTo(curTracesFile);
4959 if (tracesTmp.exists()) {
4960 tracesTmp.renameTo(tracesFile);
4963 StrictMode.setThreadPolicy(oldPolicy);
4967 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4968 ActivityRecord parent, boolean aboveSystem, final String annotation) {
4969 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4970 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4972 if (mController != null) {
4974 // 0 == continue, -1 = kill process immediately
4975 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4976 if (res < 0 && app.pid != MY_PID) {
4977 app.kill("anr", true);
4979 } catch (RemoteException e) {
4981 Watchdog.getInstance().setActivityController(null);
4985 long anrTime = SystemClock.uptimeMillis();
4986 if (MONITOR_CPU_USAGE) {
4987 updateCpuStatsNow();
4990 synchronized (this) {
4991 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4992 if (mShuttingDown) {
4993 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4995 } else if (app.notResponding) {
4996 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4998 } else if (app.crashing) {
4999 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5003 // In case we come through here for the same app before completing
5004 // this one, mark as anring now so we will bail out.
5005 app.notResponding = true;
5007 // Log the ANR to the event log.
5008 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5009 app.processName, app.info.flags, annotation);
5011 // Dump thread traces as quickly as we can, starting with "interesting" processes.
5012 firstPids.add(app.pid);
5014 int parentPid = app.pid;
5015 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5016 if (parentPid != app.pid) firstPids.add(parentPid);
5018 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5020 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5021 ProcessRecord r = mLruProcesses.get(i);
5022 if (r != null && r.thread != null) {
5024 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5028 lastPids.put(pid, Boolean.TRUE);
5035 // Log the ANR to the main log.
5036 StringBuilder info = new StringBuilder();
5038 info.append("ANR in ").append(app.processName);
5039 if (activity != null && activity.shortComponentName != null) {
5040 info.append(" (").append(activity.shortComponentName).append(")");
5043 info.append("PID: ").append(app.pid).append("\n");
5044 if (annotation != null) {
5045 info.append("Reason: ").append(annotation).append("\n");
5047 if (parent != null && parent != activity) {
5048 info.append("Parent: ").append(parent.shortComponentName).append("\n");
5051 final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5053 File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5054 NATIVE_STACKS_OF_INTEREST);
5056 String cpuInfo = null;
5057 if (MONITOR_CPU_USAGE) {
5058 updateCpuStatsNow();
5059 synchronized (mProcessCpuTracker) {
5060 cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5062 info.append(processCpuTracker.printCurrentLoad());
5063 info.append(cpuInfo);
5066 info.append(processCpuTracker.printCurrentState(anrTime));
5068 Slog.e(TAG, info.toString());
5069 if (tracesFile == null) {
5070 // There is no trace file, so dump (only) the alleged culprit's threads to the log
5071 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5074 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5075 cpuInfo, tracesFile, null);
5077 if (mController != null) {
5079 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5080 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5082 if (res < 0 && app.pid != MY_PID) {
5083 app.kill("anr", true);
5085 synchronized (this) {
5086 mServices.scheduleServiceTimeoutLocked(app);
5091 } catch (RemoteException e) {
5093 Watchdog.getInstance().setActivityController(null);
5097 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5098 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5099 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5101 synchronized (this) {
5102 mBatteryStatsService.noteProcessAnr(app.processName, app.uid);
5104 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5105 app.kill("bg anr", true);
5109 // Set the app's notResponding state, and look up the errorReportReceiver
5110 makeAppNotRespondingLocked(app,
5111 activity != null ? activity.shortComponentName : null,
5112 annotation != null ? "ANR " + annotation : "ANR",
5115 // Bring up the infamous App Not Responding dialog
5116 Message msg = Message.obtain();
5117 HashMap<String, Object> map = new HashMap<String, Object>();
5118 msg.what = SHOW_NOT_RESPONDING_MSG;
5120 msg.arg1 = aboveSystem ? 1 : 0;
5121 map.put("app", app);
5122 if (activity != null) {
5123 map.put("activity", activity);
5126 mUiHandler.sendMessage(msg);
5130 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5131 if (!mLaunchWarningShown) {
5132 mLaunchWarningShown = true;
5133 mUiHandler.post(new Runnable() {
5136 synchronized (ActivityManagerService.this) {
5137 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5139 mUiHandler.postDelayed(new Runnable() {
5142 synchronized (ActivityManagerService.this) {
5144 mLaunchWarningShown = false;
5155 public boolean clearApplicationUserData(final String packageName,
5156 final IPackageDataObserver observer, int userId) {
5157 enforceNotIsolatedCaller("clearApplicationUserData");
5158 if (packageName != null && packageName.equals(mDeviceOwnerName)) {
5159 throw new SecurityException("Clearing DeviceOwner data is forbidden.");
5161 int uid = Binder.getCallingUid();
5162 int pid = Binder.getCallingPid();
5163 userId = handleIncomingUser(pid, uid,
5164 userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5165 long callingId = Binder.clearCallingIdentity();
5167 IPackageManager pm = AppGlobals.getPackageManager();
5169 synchronized(this) {
5171 pkgUid = pm.getPackageUid(packageName, userId);
5172 } catch (RemoteException e) {
5175 Slog.w(TAG, "Invalid packageName: " + packageName);
5176 if (observer != null) {
5178 observer.onRemoveCompleted(packageName, false);
5179 } catch (RemoteException e) {
5180 Slog.i(TAG, "Observer no longer exists.");
5185 if (uid == pkgUid || checkComponentPermission(
5186 android.Manifest.permission.CLEAR_APP_USER_DATA,
5188 == PackageManager.PERMISSION_GRANTED) {
5189 forceStopPackageLocked(packageName, pkgUid, "clear data");
5191 throw new SecurityException("PID " + pid + " does not have permission "
5192 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5193 + " of package " + packageName);
5196 // Remove all tasks match the cleared application package and user
5197 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5198 final TaskRecord tr = mRecentTasks.get(i);
5199 final String taskPackageName =
5200 tr.getBaseIntent().getComponent().getPackageName();
5201 if (tr.userId != userId) continue;
5202 if (!taskPackageName.equals(packageName)) continue;
5203 removeTaskByIdLocked(tr.taskId, false);
5208 // Clear application user data
5209 pm.clearApplicationUserData(packageName, observer, userId);
5211 synchronized(this) {
5212 // Remove all permissions granted from/to this package
5213 removeUriPermissionsForPackageLocked(packageName, userId, true);
5216 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5217 Uri.fromParts("package", packageName, null));
5218 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5219 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5220 null, null, 0, null, null, null, null, false, false, userId);
5221 } catch (RemoteException e) {
5224 Binder.restoreCallingIdentity(callingId);
5230 public void killBackgroundProcesses(final String packageName, int userId) {
5231 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5232 != PackageManager.PERMISSION_GRANTED &&
5233 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5234 != PackageManager.PERMISSION_GRANTED) {
5235 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5236 + Binder.getCallingPid()
5237 + ", uid=" + Binder.getCallingUid()
5238 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5240 throw new SecurityException(msg);
5243 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5244 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5245 long callingId = Binder.clearCallingIdentity();
5247 IPackageManager pm = AppGlobals.getPackageManager();
5248 synchronized(this) {
5251 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5252 } catch (RemoteException e) {
5255 Slog.w(TAG, "Invalid packageName: " + packageName);
5258 killPackageProcessesLocked(packageName, appId, userId,
5259 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5262 Binder.restoreCallingIdentity(callingId);
5267 public void killAllBackgroundProcesses() {
5268 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5269 != PackageManager.PERMISSION_GRANTED) {
5270 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5271 + Binder.getCallingPid()
5272 + ", uid=" + Binder.getCallingUid()
5273 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5275 throw new SecurityException(msg);
5278 long callingId = Binder.clearCallingIdentity();
5280 synchronized(this) {
5281 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5282 final int NP = mProcessNames.getMap().size();
5283 for (int ip=0; ip<NP; ip++) {
5284 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5285 final int NA = apps.size();
5286 for (int ia=0; ia<NA; ia++) {
5287 ProcessRecord app = apps.valueAt(ia);
5288 if (app.persistent) {
5289 // we don't kill persistent processes
5294 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5301 int N = procs.size();
5302 for (int i=0; i<N; i++) {
5303 removeProcessLocked(procs.get(i), false, true, "kill all background");
5305 mAllowLowerMemLevel = true;
5306 updateOomAdjLocked();
5307 doLowMemReportIfNeededLocked(null);
5310 Binder.restoreCallingIdentity(callingId);
5315 public void forceStopPackage(final String packageName, int userId) {
5316 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5317 != PackageManager.PERMISSION_GRANTED) {
5318 String msg = "Permission Denial: forceStopPackage() from pid="
5319 + Binder.getCallingPid()
5320 + ", uid=" + Binder.getCallingUid()
5321 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5323 throw new SecurityException(msg);
5325 final int callingPid = Binder.getCallingPid();
5326 userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5327 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5328 long callingId = Binder.clearCallingIdentity();
5330 IPackageManager pm = AppGlobals.getPackageManager();
5331 synchronized(this) {
5332 int[] users = userId == UserHandle.USER_ALL
5333 ? getUsersLocked() : new int[] { userId };
5334 for (int user : users) {
5337 pkgUid = pm.getPackageUid(packageName, user);
5338 } catch (RemoteException e) {
5341 Slog.w(TAG, "Invalid packageName: " + packageName);
5345 pm.setPackageStoppedState(packageName, true, user);
5346 } catch (RemoteException e) {
5347 } catch (IllegalArgumentException e) {
5348 Slog.w(TAG, "Failed trying to unstop package "
5349 + packageName + ": " + e);
5351 if (isUserRunningLocked(user, false)) {
5352 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5357 Binder.restoreCallingIdentity(callingId);
5362 public void addPackageDependency(String packageName) {
5363 synchronized (this) {
5364 int callingPid = Binder.getCallingPid();
5365 if (callingPid == Process.myPid()) {
5370 synchronized (mPidsSelfLocked) {
5371 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5374 if (proc.pkgDeps == null) {
5375 proc.pkgDeps = new ArraySet<String>(1);
5377 proc.pkgDeps.add(packageName);
5383 * The pkg name and app id have to be specified.
5386 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5390 // Make sure the uid is valid.
5392 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5395 int callerUid = Binder.getCallingUid();
5396 // Only the system server can kill an application
5397 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5398 // Post an aysnc message to kill the application
5399 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5402 Bundle bundle = new Bundle();
5403 bundle.putString("pkg", pkg);
5404 bundle.putString("reason", reason);
5406 mHandler.sendMessage(msg);
5408 throw new SecurityException(callerUid + " cannot kill pkg: " +
5414 public void closeSystemDialogs(String reason) {
5415 enforceNotIsolatedCaller("closeSystemDialogs");
5417 final int pid = Binder.getCallingPid();
5418 final int uid = Binder.getCallingUid();
5419 final long origId = Binder.clearCallingIdentity();
5421 synchronized (this) {
5422 // Only allow this from foreground processes, so that background
5423 // applications can't abuse it to prevent system UI from being shown.
5424 if (uid >= Process.FIRST_APPLICATION_UID) {
5426 synchronized (mPidsSelfLocked) {
5427 proc = mPidsSelfLocked.get(pid);
5429 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5430 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5431 + " from background process " + proc);
5435 closeSystemDialogsLocked(reason);
5438 Binder.restoreCallingIdentity(origId);
5442 void closeSystemDialogsLocked(String reason) {
5443 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5444 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5445 | Intent.FLAG_RECEIVER_FOREGROUND);
5446 if (reason != null) {
5447 intent.putExtra("reason", reason);
5449 mWindowManager.closeSystemDialogs(reason);
5451 mStackSupervisor.closeSystemDialogsLocked();
5453 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5454 AppOpsManager.OP_NONE, null, false, false,
5455 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5459 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5460 enforceNotIsolatedCaller("getProcessMemoryInfo");
5461 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5462 for (int i=pids.length-1; i>=0; i--) {
5465 synchronized (this) {
5466 synchronized (mPidsSelfLocked) {
5467 proc = mPidsSelfLocked.get(pids[i]);
5468 oomAdj = proc != null ? proc.setAdj : 0;
5471 infos[i] = new Debug.MemoryInfo();
5472 Debug.getMemoryInfo(pids[i], infos[i]);
5474 synchronized (this) {
5475 if (proc.thread != null && proc.setAdj == oomAdj) {
5476 // Record this for posterity if the process has been stable.
5477 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5478 infos[i].getTotalUss(), false, proc.pkgList);
5487 public long[] getProcessPss(int[] pids) {
5488 enforceNotIsolatedCaller("getProcessPss");
5489 long[] pss = new long[pids.length];
5490 for (int i=pids.length-1; i>=0; i--) {
5493 synchronized (this) {
5494 synchronized (mPidsSelfLocked) {
5495 proc = mPidsSelfLocked.get(pids[i]);
5496 oomAdj = proc != null ? proc.setAdj : 0;
5499 long[] tmpUss = new long[1];
5500 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5502 synchronized (this) {
5503 if (proc.thread != null && proc.setAdj == oomAdj) {
5504 // Record this for posterity if the process has been stable.
5505 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5514 public void killApplicationProcess(String processName, int uid) {
5515 if (processName == null) {
5519 int callerUid = Binder.getCallingUid();
5520 // Only the system server can kill an application
5521 if (callerUid == Process.SYSTEM_UID) {
5522 synchronized (this) {
5523 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5524 if (app != null && app.thread != null) {
5526 app.thread.scheduleSuicide();
5527 } catch (RemoteException e) {
5528 // If the other end already died, then our work here is done.
5531 Slog.w(TAG, "Process/uid not found attempting kill of "
5532 + processName + " / " + uid);
5536 throw new SecurityException(callerUid + " cannot kill app process: " +
5541 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5542 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5543 false, true, false, false, UserHandle.getUserId(uid), reason);
5544 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5545 Uri.fromParts("package", packageName, null));
5546 if (!mProcessesReady) {
5547 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5548 | Intent.FLAG_RECEIVER_FOREGROUND);
5550 intent.putExtra(Intent.EXTRA_UID, uid);
5551 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5552 broadcastIntentLocked(null, null, intent,
5553 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5554 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5557 private void forceStopUserLocked(int userId, String reason) {
5558 forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5559 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5560 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5561 | Intent.FLAG_RECEIVER_FOREGROUND);
5562 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5563 broadcastIntentLocked(null, null, intent,
5564 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5565 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5568 private final boolean killPackageProcessesLocked(String packageName, int appId,
5569 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5570 boolean doit, boolean evenPersistent, String reason) {
5571 ArrayList<ProcessRecord> procs = new ArrayList<>();
5573 // Remove all processes this package may have touched: all with the
5574 // same UID (except for the system or root user), and all whose name
5575 // matches the package name.
5576 final int NP = mProcessNames.getMap().size();
5577 for (int ip=0; ip<NP; ip++) {
5578 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5579 final int NA = apps.size();
5580 for (int ia=0; ia<NA; ia++) {
5581 ProcessRecord app = apps.valueAt(ia);
5582 if (app.persistent && !evenPersistent) {
5583 // we don't kill persistent processes
5593 // Skip process if it doesn't meet our oom adj requirement.
5594 if (app.setAdj < minOomAdj) {
5598 // If no package is specified, we call all processes under the
5600 if (packageName == null) {
5601 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5604 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5607 // Package has been specified, we want to hit all processes
5608 // that match it. We need to qualify this by the processes
5609 // that are running under the specified app and user ID.
5611 final boolean isDep = app.pkgDeps != null
5612 && app.pkgDeps.contains(packageName);
5613 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5616 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5619 if (!app.pkgList.containsKey(packageName) && !isDep) {
5624 // Process has passed all conditions, kill it!
5633 int N = procs.size();
5634 for (int i=0; i<N; i++) {
5635 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5637 updateOomAdjLocked();
5641 private void cleanupDisabledPackageComponentsLocked(
5642 String packageName, int userId, boolean killProcess, String[] changedClasses) {
5644 Set<String> disabledClasses = null;
5645 boolean packageDisabled = false;
5646 IPackageManager pm = AppGlobals.getPackageManager();
5648 if (changedClasses == null) {
5649 // Nothing changed...
5653 // Determine enable/disable state of the package and its components.
5654 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5655 for (int i = changedClasses.length - 1; i >= 0; i--) {
5656 final String changedClass = changedClasses[i];
5658 if (changedClass.equals(packageName)) {
5660 // Entire package setting changed
5661 enabled = pm.getApplicationEnabledSetting(packageName,
5662 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5663 } catch (Exception e) {
5664 // No such package/component; probably racing with uninstall. In any
5665 // event it means we have nothing further to do here.
5668 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5669 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5670 if (packageDisabled) {
5671 // Entire package is disabled.
5672 // No need to continue to check component states.
5673 disabledClasses = null;
5678 enabled = pm.getComponentEnabledSetting(
5679 new ComponentName(packageName, changedClass),
5680 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_OWNER);
5681 } catch (Exception e) {
5682 // As above, probably racing with uninstall.
5685 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5686 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5687 if (disabledClasses == null) {
5688 disabledClasses = new ArraySet<>(changedClasses.length);
5690 disabledClasses.add(changedClass);
5695 if (!packageDisabled && disabledClasses == null) {
5696 // Nothing to do here...
5700 // Clean-up disabled activities.
5701 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5702 packageName, disabledClasses, true, false, userId) && mBooted) {
5703 mStackSupervisor.resumeTopActivitiesLocked();
5704 mStackSupervisor.scheduleIdleLocked();
5707 // Clean-up disabled tasks
5708 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5710 // Clean-up disabled services.
5711 mServices.bringDownDisabledPackageServicesLocked(
5712 packageName, disabledClasses, userId, false, killProcess, true);
5714 // Clean-up disabled providers.
5715 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5716 mProviderMap.collectPackageProvidersLocked(
5717 packageName, disabledClasses, true, false, userId, providers);
5718 for (int i = providers.size() - 1; i >= 0; i--) {
5719 removeDyingProviderLocked(null, providers.get(i), true);
5722 // Clean-up disabled broadcast receivers.
5723 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5724 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5725 packageName, disabledClasses, userId, true);
5730 private final boolean forceStopPackageLocked(String packageName, int appId,
5731 boolean callerWillRestart, boolean purgeCache, boolean doit,
5732 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5735 if (userId == UserHandle.USER_ALL && packageName == null) {
5736 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5739 if (appId < 0 && packageName != null) {
5741 appId = UserHandle.getAppId(
5742 AppGlobals.getPackageManager().getPackageUid(packageName, 0));
5743 } catch (RemoteException e) {
5748 if (packageName != null) {
5749 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5750 + " user=" + userId + ": " + reason);
5752 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5755 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5756 for (int ip = pmap.size() - 1; ip >= 0; ip--) {
5757 SparseArray<Long> ba = pmap.valueAt(ip);
5758 for (i = ba.size() - 1; i >= 0; i--) {
5759 boolean remove = false;
5760 final int entUid = ba.keyAt(i);
5761 if (packageName != null) {
5762 if (userId == UserHandle.USER_ALL) {
5763 if (UserHandle.getAppId(entUid) == appId) {
5767 if (entUid == UserHandle.getUid(userId, appId)) {
5771 } else if (UserHandle.getUserId(entUid) == userId) {
5778 if (ba.size() == 0) {
5784 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5785 -100, callerWillRestart, true, doit, evenPersistent,
5786 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5788 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5789 packageName, null, doit, evenPersistent, userId)) {
5793 didSomething = true;
5796 if (mServices.bringDownDisabledPackageServicesLocked(
5797 packageName, null, userId, evenPersistent, true, doit)) {
5801 didSomething = true;
5804 if (packageName == null) {
5805 // Remove all sticky broadcasts from this user.
5806 mStickyBroadcasts.remove(userId);
5809 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5810 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5811 userId, providers)) {
5815 didSomething = true;
5817 for (i = providers.size() - 1; i >= 0; i--) {
5818 removeDyingProviderLocked(null, providers.get(i), true);
5821 // Remove transient permissions granted from/to this package/user
5822 removeUriPermissionsForPackageLocked(packageName, userId, false);
5825 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5826 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5827 packageName, null, userId, doit);
5831 if (packageName == null || uninstalling) {
5832 // Remove pending intents. For now we only do this when force
5833 // stopping users, because we have some problems when doing this
5834 // for packages -- app widgets are not currently cleaned up for
5835 // such packages, so they can be left with bad pending intents.
5836 if (mIntentSenderRecords.size() > 0) {
5837 Iterator<WeakReference<PendingIntentRecord>> it
5838 = mIntentSenderRecords.values().iterator();
5839 while (it.hasNext()) {
5840 WeakReference<PendingIntentRecord> wpir = it.next();
5845 PendingIntentRecord pir = wpir.get();
5850 if (packageName == null) {
5851 // Stopping user, remove all objects for the user.
5852 if (pir.key.userId != userId) {
5853 // Not the same user, skip it.
5857 if (UserHandle.getAppId(pir.uid) != appId) {
5858 // Different app id, skip it.
5861 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5862 // Different user, skip it.
5865 if (!pir.key.packageName.equals(packageName)) {
5866 // Different package, skip it.
5873 didSomething = true;
5875 pir.canceled = true;
5876 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
5877 pir.key.activity.pendingResults.remove(pir.ref);
5884 if (purgeCache && packageName != null) {
5885 AttributeCache ac = AttributeCache.instance();
5887 ac.removePackage(packageName);
5891 mStackSupervisor.resumeTopActivitiesLocked();
5892 mStackSupervisor.scheduleIdleLocked();
5896 return didSomething;
5899 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
5900 ProcessRecord old = mProcessNames.remove(name, uid);
5902 old.uidRecord.numProcs--;
5903 if (old.uidRecord.numProcs == 0) {
5904 // No more processes using this uid, tell clients it is gone.
5905 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5906 "No more processes in " + old.uidRecord);
5907 enqueueUidChangeLocked(old.uidRecord, true);
5908 mActiveUids.remove(uid);
5910 old.uidRecord = null;
5912 mIsolatedProcesses.remove(uid);
5916 private final void addProcessNameLocked(ProcessRecord proc) {
5917 // We shouldn't already have a process under this name, but just in case we
5918 // need to clean up whatever may be there now.
5919 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
5920 if (old == proc && proc.persistent) {
5921 // We are re-adding a persistent process. Whatevs! Just leave it there.
5922 Slog.w(TAG, "Re-adding persistent process " + proc);
5923 } else if (old != null) {
5924 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
5926 UidRecord uidRec = mActiveUids.get(proc.uid);
5927 if (uidRec == null) {
5928 uidRec = new UidRecord(proc.uid);
5929 // This is the first appearance of the uid, report it now!
5930 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
5931 "Creating new process uid: " + uidRec);
5932 mActiveUids.put(proc.uid, uidRec);
5933 enqueueUidChangeLocked(uidRec, false);
5935 proc.uidRecord = uidRec;
5937 mProcessNames.put(proc.processName, proc.uid, proc);
5938 if (proc.isolated) {
5939 mIsolatedProcesses.put(proc.uid, proc);
5943 private final boolean removeProcessLocked(ProcessRecord app,
5944 boolean callerWillRestart, boolean allowRestart, String reason) {
5945 final String name = app.processName;
5946 final int uid = app.uid;
5947 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
5948 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
5950 removeProcessNameLocked(name, uid);
5951 if (mHeavyWeightProcess == app) {
5952 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5953 mHeavyWeightProcess.userId, 0));
5954 mHeavyWeightProcess = null;
5956 boolean needRestart = false;
5957 if (app.pid > 0 && app.pid != MY_PID) {
5959 synchronized (mPidsSelfLocked) {
5960 mPidsSelfLocked.remove(pid);
5961 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5963 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5965 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5967 boolean willRestart = false;
5968 if (app.persistent && !app.isolated) {
5969 if (!callerWillRestart) {
5975 app.kill(reason, true);
5976 handleAppDiedLocked(app, willRestart, allowRestart);
5978 removeLruProcessLocked(app);
5979 addAppLocked(app.info, false, null /* ABI override */);
5982 mRemovedProcesses.add(app);
5988 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
5989 cleanupAppInLaunchingProvidersLocked(app, true);
5990 removeProcessLocked(app, false, true, "timeout publishing content providers");
5993 private final void processStartTimedOutLocked(ProcessRecord app) {
5994 final int pid = app.pid;
5995 boolean gone = false;
5996 synchronized (mPidsSelfLocked) {
5997 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5998 if (knownApp != null && knownApp.thread == null) {
5999 mPidsSelfLocked.remove(pid);
6005 Slog.w(TAG, "Process " + app + " failed to attach");
6006 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6007 pid, app.uid, app.processName);
6008 removeProcessNameLocked(app.processName, app.uid);
6009 if (mHeavyWeightProcess == app) {
6010 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6011 mHeavyWeightProcess.userId, 0));
6012 mHeavyWeightProcess = null;
6014 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6016 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6018 // Take care of any launching providers waiting for this process.
6019 cleanupAppInLaunchingProvidersLocked(app, true);
6020 // Take care of any services that are waiting for the process.
6021 mServices.processStartTimedOutLocked(app);
6022 app.kill("start timeout", true);
6023 removeLruProcessLocked(app);
6024 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6025 Slog.w(TAG, "Unattached app died before backup, skipping");
6027 IBackupManager bm = IBackupManager.Stub.asInterface(
6028 ServiceManager.getService(Context.BACKUP_SERVICE));
6029 bm.agentDisconnected(app.info.packageName);
6030 } catch (RemoteException e) {
6031 // Can't happen; the backup manager is local
6034 if (isPendingBroadcastProcessLocked(pid)) {
6035 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6036 skipPendingBroadcastLocked(pid);
6039 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6043 private final boolean attachApplicationLocked(IApplicationThread thread,
6046 // Find the application record that is being attached... either via
6047 // the pid if we are running in multiple processes, or just pull the
6048 // next app record if we are emulating process with anonymous threads.
6050 if (pid != MY_PID && pid >= 0) {
6051 synchronized (mPidsSelfLocked) {
6052 app = mPidsSelfLocked.get(pid);
6059 Slog.w(TAG, "No pending application record for pid " + pid
6060 + " (IApplicationThread " + thread + "); dropping process");
6061 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6062 if (pid > 0 && pid != MY_PID) {
6063 Process.killProcessQuiet(pid);
6064 //TODO: killProcessGroup(app.info.uid, pid);
6067 thread.scheduleExit();
6068 } catch (Exception e) {
6069 // Ignore exceptions.
6075 // If this application record is still attached to a previous
6076 // process, clean it up now.
6077 if (app.thread != null) {
6078 handleAppDiedLocked(app, true, true);
6081 // Tell the process all about itself.
6083 if (DEBUG_ALL) Slog.v(
6084 TAG, "Binding process pid " + pid + " to record " + app);
6086 final String processName = app.processName;
6088 AppDeathRecipient adr = new AppDeathRecipient(
6090 thread.asBinder().linkToDeath(adr, 0);
6091 app.deathRecipient = adr;
6092 } catch (RemoteException e) {
6093 app.resetPackageList(mProcessStats);
6094 startProcessLocked(app, "link fail", processName);
6098 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6100 app.makeActive(thread, mProcessStats);
6101 app.curAdj = app.setAdj = -100;
6102 app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
6103 app.forcingToForeground = null;
6104 updateProcessForegroundLocked(app, false, false);
6105 app.hasShownUi = false;
6106 app.debugging = false;
6108 app.killedByAm = false;
6110 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6112 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6113 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6115 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6116 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6118 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6122 Slog.i(TAG, "Launching preboot mode app: " + app);
6125 if (DEBUG_ALL) Slog.v(
6126 TAG, "New app record " + app
6127 + " thread=" + thread.asBinder() + " pid=" + pid);
6129 int testMode = IApplicationThread.DEBUG_OFF;
6130 if (mDebugApp != null && mDebugApp.equals(processName)) {
6131 testMode = mWaitForDebugger
6132 ? IApplicationThread.DEBUG_WAIT
6133 : IApplicationThread.DEBUG_ON;
6134 app.debugging = true;
6135 if (mDebugTransient) {
6136 mDebugApp = mOrigDebugApp;
6137 mWaitForDebugger = mOrigWaitForDebugger;
6140 String profileFile = app.instrumentationProfileFile;
6141 ParcelFileDescriptor profileFd = null;
6142 int samplingInterval = 0;
6143 boolean profileAutoStop = false;
6144 if (mProfileApp != null && mProfileApp.equals(processName)) {
6146 profileFile = mProfileFile;
6147 profileFd = mProfileFd;
6148 samplingInterval = mSamplingInterval;
6149 profileAutoStop = mAutoStopProfiler;
6151 boolean enableOpenGlTrace = false;
6152 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6153 enableOpenGlTrace = true;
6154 mOpenGlTraceApp = null;
6157 // If the app is being launched for restore or full backup, set it up specially
6158 boolean isRestrictedBackupMode = false;
6159 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6160 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6161 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6162 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6165 ensurePackageDexOpt(app.instrumentationInfo != null
6166 ? app.instrumentationInfo.packageName
6167 : app.info.packageName);
6168 if (app.instrumentationClass != null) {
6169 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6171 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6172 + processName + " with config " + mConfiguration);
6173 ApplicationInfo appInfo = app.instrumentationInfo != null
6174 ? app.instrumentationInfo : app.info;
6175 app.compat = compatibilityInfoForPackageLocked(appInfo);
6176 if (profileFd != null) {
6177 profileFd = profileFd.dup();
6179 ProfilerInfo profilerInfo = profileFile == null ? null
6180 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6181 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6182 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6183 app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6184 isRestrictedBackupMode || !normalMode, app.persistent,
6185 new Configuration(mConfiguration), app.compat,
6186 getCommonServicesLocked(app.isolated),
6187 mCoreSettingsObserver.getCoreSettingsLocked());
6188 updateLruProcessLocked(app, false, null);
6189 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6190 } catch (Exception e) {
6191 // todo: Yikes! What should we do? For now we will try to
6192 // start another process, but that could easily get us in
6193 // an infinite loop of restarting processes...
6194 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6196 app.resetPackageList(mProcessStats);
6197 app.unlinkDeathRecipient();
6198 startProcessLocked(app, "bind fail", processName);
6202 // Remove this record from the list of starting applications.
6203 mPersistentStartingProcesses.remove(app);
6204 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6205 "Attach application locked removing on hold: " + app);
6206 mProcessesOnHold.remove(app);
6208 boolean badApp = false;
6209 boolean didSomething = false;
6211 // See if the top visible activity is waiting to run in this process...
6214 if (mStackSupervisor.attachApplicationLocked(app)) {
6215 didSomething = true;
6217 } catch (Exception e) {
6218 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6223 // Find any services that should be running in this process...
6226 didSomething |= mServices.attachApplicationLocked(app, processName);
6227 } catch (Exception e) {
6228 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6233 // Check if a next-broadcast receiver is in this process...
6234 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6236 didSomething |= sendPendingBroadcastsLocked(app);
6237 } catch (Exception e) {
6238 // If the app died trying to launch the receiver we declare it 'bad'
6239 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6244 // Check whether the next backup agent is in this process...
6245 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6246 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6247 "New app is backup target, launching agent for " + app);
6248 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6250 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6251 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6252 mBackupTarget.backupMode);
6253 } catch (Exception e) {
6254 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6260 app.kill("error during init", true);
6261 handleAppDiedLocked(app, false, true);
6265 if (!didSomething) {
6266 updateOomAdjLocked();
6273 public final void attachApplication(IApplicationThread thread) {
6274 synchronized (this) {
6275 int callingPid = Binder.getCallingPid();
6276 final long origId = Binder.clearCallingIdentity();
6277 attachApplicationLocked(thread, callingPid);
6278 Binder.restoreCallingIdentity(origId);
6283 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6284 final long origId = Binder.clearCallingIdentity();
6285 synchronized (this) {
6286 ActivityStack stack = ActivityRecord.getStackLocked(token);
6287 if (stack != null) {
6289 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6290 if (stopProfiling) {
6291 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6294 } catch (IOException e) {
6296 clearProfilerLocked();
6301 Binder.restoreCallingIdentity(origId);
6304 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6305 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6306 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6309 void enableScreenAfterBoot() {
6310 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6311 SystemClock.uptimeMillis());
6312 mWindowManager.enableScreenAfterBoot();
6314 synchronized (this) {
6315 updateEventDispatchingLocked();
6320 public void showBootMessage(final CharSequence msg, final boolean always) {
6321 if (Binder.getCallingUid() != Process.myUid()) {
6322 // These days only the core system can call this, so apps can't get in
6323 // the way of what we show about running them.
6325 mWindowManager.showBootMessage(msg, always);
6329 public void keyguardWaitingForActivityDrawn() {
6330 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6331 final long token = Binder.clearCallingIdentity();
6333 synchronized (this) {
6334 if (DEBUG_LOCKSCREEN) logLockScreen("");
6335 mWindowManager.keyguardWaitingForActivityDrawn();
6336 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6337 mLockScreenShown = LOCK_SCREEN_LEAVING;
6338 updateSleepIfNeededLocked();
6342 Binder.restoreCallingIdentity(token);
6347 public void keyguardGoingAway(boolean disableWindowAnimations,
6348 boolean keyguardGoingToNotificationShade) {
6349 enforceNotIsolatedCaller("keyguardGoingAway");
6350 final long token = Binder.clearCallingIdentity();
6352 synchronized (this) {
6353 if (DEBUG_LOCKSCREEN) logLockScreen("");
6354 mWindowManager.keyguardGoingAway(disableWindowAnimations,
6355 keyguardGoingToNotificationShade);
6356 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6357 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6358 updateSleepIfNeededLocked();
6362 Binder.restoreCallingIdentity(token);
6366 final void finishBooting() {
6367 synchronized (this) {
6368 if (!mBootAnimationComplete) {
6369 mCallFinishBooting = true;
6372 mCallFinishBooting = false;
6375 ArraySet<String> completedIsas = new ArraySet<String>();
6376 for (String abi : Build.SUPPORTED_ABIS) {
6377 Process.establishZygoteConnectionForAbi(abi);
6378 final String instructionSet = VMRuntime.getInstructionSet(abi);
6379 if (!completedIsas.contains(instructionSet)) {
6380 if (mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi)) != 0) {
6381 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi);
6383 completedIsas.add(instructionSet);
6387 IntentFilter pkgFilter = new IntentFilter();
6388 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6389 pkgFilter.addDataScheme("package");
6390 mContext.registerReceiver(new BroadcastReceiver() {
6392 public void onReceive(Context context, Intent intent) {
6393 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6395 for (String pkg : pkgs) {
6396 synchronized (ActivityManagerService.this) {
6397 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6398 0, "query restart")) {
6399 setResultCode(Activity.RESULT_OK);
6408 IntentFilter dumpheapFilter = new IntentFilter();
6409 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6410 mContext.registerReceiver(new BroadcastReceiver() {
6412 public void onReceive(Context context, Intent intent) {
6413 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6414 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6416 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6421 // Let system services know.
6422 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6424 synchronized (this) {
6425 // Ensure that any processes we had put on hold are now started
6427 final int NP = mProcessesOnHold.size();
6429 ArrayList<ProcessRecord> procs =
6430 new ArrayList<ProcessRecord>(mProcessesOnHold);
6431 for (int ip=0; ip<NP; ip++) {
6432 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6434 startProcessLocked(procs.get(ip), "on-hold", null);
6438 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6439 // Start looking for apps that are abusing wake locks.
6440 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6441 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6442 // Tell anyone interested that we are done booting!
6443 SystemProperties.set("sys.boot_completed", "1");
6445 // And trigger dev.bootcomplete if we are not showing encryption progress
6446 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6447 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6448 SystemProperties.set("dev.bootcomplete", "1");
6450 for (int i=0; i<mStartedUsers.size(); i++) {
6451 UserState uss = mStartedUsers.valueAt(i);
6452 if (uss.mState == UserState.STATE_BOOTING) {
6453 uss.mState = UserState.STATE_RUNNING;
6454 final int userId = mStartedUsers.keyAt(i);
6455 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6456 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6457 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6458 broadcastIntentLocked(null, null, intent, null,
6459 new IIntentReceiver.Stub() {
6461 public void performReceive(Intent intent, int resultCode,
6462 String data, Bundle extras, boolean ordered,
6463 boolean sticky, int sendingUser) {
6464 synchronized (ActivityManagerService.this) {
6465 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6471 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
6472 AppOpsManager.OP_NONE, null, true, false,
6473 MY_PID, Process.SYSTEM_UID, userId);
6476 scheduleStartProfilesLocked();
6482 public void bootAnimationComplete() {
6483 final boolean callFinishBooting;
6484 synchronized (this) {
6485 callFinishBooting = mCallFinishBooting;
6486 mBootAnimationComplete = true;
6488 if (callFinishBooting) {
6493 final void ensureBootCompleted() {
6495 boolean enableScreen;
6496 synchronized (this) {
6499 enableScreen = !mBooted;
6508 enableScreenAfterBoot();
6513 public final void activityResumed(IBinder token) {
6514 final long origId = Binder.clearCallingIdentity();
6515 synchronized(this) {
6516 ActivityStack stack = ActivityRecord.getStackLocked(token);
6517 if (stack != null) {
6518 ActivityRecord.activityResumedLocked(token);
6521 Binder.restoreCallingIdentity(origId);
6525 public final void activityPaused(IBinder token) {
6526 final long origId = Binder.clearCallingIdentity();
6527 synchronized(this) {
6528 ActivityStack stack = ActivityRecord.getStackLocked(token);
6529 if (stack != null) {
6530 stack.activityPausedLocked(token, false);
6533 Binder.restoreCallingIdentity(origId);
6537 public final void activityStopped(IBinder token, Bundle icicle,
6538 PersistableBundle persistentState, CharSequence description) {
6539 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6541 // Refuse possible leaked file descriptors
6542 if (icicle != null && icicle.hasFileDescriptors()) {
6543 throw new IllegalArgumentException("File descriptors passed in Bundle");
6546 final long origId = Binder.clearCallingIdentity();
6548 synchronized (this) {
6549 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6551 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6557 Binder.restoreCallingIdentity(origId);
6561 public final void activityDestroyed(IBinder token) {
6562 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6563 synchronized (this) {
6564 ActivityStack stack = ActivityRecord.getStackLocked(token);
6565 if (stack != null) {
6566 stack.activityDestroyedLocked(token, "activityDestroyed");
6572 public final void backgroundResourcesReleased(IBinder token) {
6573 final long origId = Binder.clearCallingIdentity();
6575 synchronized (this) {
6576 ActivityStack stack = ActivityRecord.getStackLocked(token);
6577 if (stack != null) {
6578 stack.backgroundResourcesReleased();
6582 Binder.restoreCallingIdentity(origId);
6587 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6588 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6592 public final void notifyEnterAnimationComplete(IBinder token) {
6593 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6597 public String getCallingPackage(IBinder token) {
6598 synchronized (this) {
6599 ActivityRecord r = getCallingRecordLocked(token);
6600 return r != null ? r.info.packageName : null;
6605 public ComponentName getCallingActivity(IBinder token) {
6606 synchronized (this) {
6607 ActivityRecord r = getCallingRecordLocked(token);
6608 return r != null ? r.intent.getComponent() : null;
6612 private ActivityRecord getCallingRecordLocked(IBinder token) {
6613 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6621 public ComponentName getActivityClassForToken(IBinder token) {
6622 synchronized(this) {
6623 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6627 return r.intent.getComponent();
6632 public String getPackageForToken(IBinder token) {
6633 synchronized(this) {
6634 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6638 return r.packageName;
6643 public boolean isRootVoiceInteraction(IBinder token) {
6644 synchronized(this) {
6645 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6649 return r.rootVoiceInteraction;
6654 public IIntentSender getIntentSender(int type,
6655 String packageName, IBinder token, String resultWho,
6656 int requestCode, Intent[] intents, String[] resolvedTypes,
6657 int flags, Bundle options, int userId) {
6658 enforceNotIsolatedCaller("getIntentSender");
6659 // Refuse possible leaked file descriptors
6660 if (intents != null) {
6661 if (intents.length < 1) {
6662 throw new IllegalArgumentException("Intents array length must be >= 1");
6664 for (int i=0; i<intents.length; i++) {
6665 Intent intent = intents[i];
6666 if (intent != null) {
6667 if (intent.hasFileDescriptors()) {
6668 throw new IllegalArgumentException("File descriptors passed in Intent");
6670 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6671 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6672 throw new IllegalArgumentException(
6673 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6675 intents[i] = new Intent(intent);
6678 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6679 throw new IllegalArgumentException(
6680 "Intent array length does not match resolvedTypes length");
6683 if (options != null) {
6684 if (options.hasFileDescriptors()) {
6685 throw new IllegalArgumentException("File descriptors passed in options");
6689 synchronized(this) {
6690 int callingUid = Binder.getCallingUid();
6691 int origUserId = userId;
6692 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6693 type == ActivityManager.INTENT_SENDER_BROADCAST,
6694 ALLOW_NON_FULL, "getIntentSender", null);
6695 if (origUserId == UserHandle.USER_CURRENT) {
6696 // We don't want to evaluate this until the pending intent is
6697 // actually executed. However, we do want to always do the
6698 // security checking for it above.
6699 userId = UserHandle.USER_CURRENT;
6702 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6703 int uid = AppGlobals.getPackageManager()
6704 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6705 if (!UserHandle.isSameApp(callingUid, uid)) {
6706 String msg = "Permission Denial: getIntentSender() from pid="
6707 + Binder.getCallingPid()
6708 + ", uid=" + Binder.getCallingUid()
6709 + ", (need uid=" + uid + ")"
6710 + " is not allowed to send as package " + packageName;
6712 throw new SecurityException(msg);
6716 return getIntentSenderLocked(type, packageName, callingUid, userId,
6717 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6719 } catch (RemoteException e) {
6720 throw new SecurityException(e);
6725 IIntentSender getIntentSenderLocked(int type, String packageName,
6726 int callingUid, int userId, IBinder token, String resultWho,
6727 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6729 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6730 ActivityRecord activity = null;
6731 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6732 activity = ActivityRecord.isInStackLocked(token);
6733 if (activity == null) {
6736 if (activity.finishing) {
6741 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6742 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6743 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6744 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6745 |PendingIntent.FLAG_UPDATE_CURRENT);
6747 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6748 type, packageName, activity, resultWho,
6749 requestCode, intents, resolvedTypes, flags, options, userId);
6750 WeakReference<PendingIntentRecord> ref;
6751 ref = mIntentSenderRecords.get(key);
6752 PendingIntentRecord rec = ref != null ? ref.get() : null;
6754 if (!cancelCurrent) {
6755 if (updateCurrent) {
6756 if (rec.key.requestIntent != null) {
6757 rec.key.requestIntent.replaceExtras(intents != null ?
6758 intents[intents.length - 1] : null);
6760 if (intents != null) {
6761 intents[intents.length-1] = rec.key.requestIntent;
6762 rec.key.allIntents = intents;
6763 rec.key.allResolvedTypes = resolvedTypes;
6765 rec.key.allIntents = null;
6766 rec.key.allResolvedTypes = null;
6771 rec.canceled = true;
6772 mIntentSenderRecords.remove(key);
6777 rec = new PendingIntentRecord(this, key, callingUid);
6778 mIntentSenderRecords.put(key, rec.ref);
6779 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6780 if (activity.pendingResults == null) {
6781 activity.pendingResults
6782 = new HashSet<WeakReference<PendingIntentRecord>>();
6784 activity.pendingResults.add(rec.ref);
6790 public void cancelIntentSender(IIntentSender sender) {
6791 if (!(sender instanceof PendingIntentRecord)) {
6794 synchronized(this) {
6795 PendingIntentRecord rec = (PendingIntentRecord)sender;
6797 int uid = AppGlobals.getPackageManager()
6798 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6799 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6800 String msg = "Permission Denial: cancelIntentSender() from pid="
6801 + Binder.getCallingPid()
6802 + ", uid=" + Binder.getCallingUid()
6803 + " is not allowed to cancel packges "
6804 + rec.key.packageName;
6806 throw new SecurityException(msg);
6808 } catch (RemoteException e) {
6809 throw new SecurityException(e);
6811 cancelIntentSenderLocked(rec, true);
6815 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6816 rec.canceled = true;
6817 mIntentSenderRecords.remove(rec.key);
6818 if (cleanActivity && rec.key.activity != null) {
6819 rec.key.activity.pendingResults.remove(rec.ref);
6824 public String getPackageForIntentSender(IIntentSender pendingResult) {
6825 if (!(pendingResult instanceof PendingIntentRecord)) {
6829 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6830 return res.key.packageName;
6831 } catch (ClassCastException e) {
6837 public int getUidForIntentSender(IIntentSender sender) {
6838 if (sender instanceof PendingIntentRecord) {
6840 PendingIntentRecord res = (PendingIntentRecord)sender;
6842 } catch (ClassCastException e) {
6849 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6850 if (!(pendingResult instanceof PendingIntentRecord)) {
6854 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6855 if (res.key.allIntents == null) {
6858 for (int i=0; i<res.key.allIntents.length; i++) {
6859 Intent intent = res.key.allIntents[i];
6860 if (intent.getPackage() != null && intent.getComponent() != null) {
6865 } catch (ClassCastException e) {
6871 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6872 if (!(pendingResult instanceof PendingIntentRecord)) {
6876 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6877 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6881 } catch (ClassCastException e) {
6887 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6888 if (!(pendingResult instanceof PendingIntentRecord)) {
6892 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6893 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6894 } catch (ClassCastException e) {
6900 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6901 if (!(pendingResult instanceof PendingIntentRecord)) {
6905 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6906 synchronized (this) {
6907 return getTagForIntentSenderLocked(res, prefix);
6909 } catch (ClassCastException e) {
6914 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
6915 final Intent intent = res.key.requestIntent;
6916 if (intent != null) {
6917 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6918 || res.lastTagPrefix.equals(prefix))) {
6921 res.lastTagPrefix = prefix;
6922 final StringBuilder sb = new StringBuilder(128);
6923 if (prefix != null) {
6926 if (intent.getAction() != null) {
6927 sb.append(intent.getAction());
6928 } else if (intent.getComponent() != null) {
6929 intent.getComponent().appendShortString(sb);
6933 return res.lastTag = sb.toString();
6939 public void setProcessLimit(int max) {
6940 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6941 "setProcessLimit()");
6942 synchronized (this) {
6943 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6944 mProcessLimitOverride = max;
6950 public int getProcessLimit() {
6951 synchronized (this) {
6952 return mProcessLimitOverride;
6956 void foregroundTokenDied(ForegroundToken token) {
6957 synchronized (ActivityManagerService.this) {
6958 synchronized (mPidsSelfLocked) {
6960 = mForegroundProcesses.get(token.pid);
6964 mForegroundProcesses.remove(token.pid);
6965 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6969 pr.forcingToForeground = null;
6970 updateProcessForegroundLocked(pr, false, false);
6972 updateOomAdjLocked();
6977 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6978 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6979 "setProcessForeground()");
6980 synchronized(this) {
6981 boolean changed = false;
6983 synchronized (mPidsSelfLocked) {
6984 ProcessRecord pr = mPidsSelfLocked.get(pid);
6985 if (pr == null && isForeground) {
6986 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6989 ForegroundToken oldToken = mForegroundProcesses.get(pid);
6990 if (oldToken != null) {
6991 oldToken.token.unlinkToDeath(oldToken, 0);
6992 mForegroundProcesses.remove(pid);
6994 pr.forcingToForeground = null;
6998 if (isForeground && token != null) {
6999 ForegroundToken newToken = new ForegroundToken() {
7001 public void binderDied() {
7002 foregroundTokenDied(this);
7006 newToken.token = token;
7008 token.linkToDeath(newToken, 0);
7009 mForegroundProcesses.put(pid, newToken);
7010 pr.forcingToForeground = token;
7012 } catch (RemoteException e) {
7013 // If the process died while doing this, we will later
7014 // do the cleanup with the process death link.
7020 updateOomAdjLocked();
7025 // =========================================================
7027 // =========================================================
7029 static class ProcessInfoService extends IProcessInfoService.Stub {
7030 final ActivityManagerService mActivityManagerService;
7031 ProcessInfoService(ActivityManagerService activityManagerService) {
7032 mActivityManagerService = activityManagerService;
7036 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7037 mActivityManagerService.getProcessStatesForPIDs(/*in*/ pids, /*out*/ states);
7042 * For each PID in the given input array, write the current process state
7043 * for that process into the output array, or -1 to indicate that no
7044 * process with the given PID exists.
7046 public void getProcessStatesForPIDs(/*in*/ int[] pids, /*out*/ int[] states) {
7048 throw new NullPointerException("pids");
7049 } else if (states == null) {
7050 throw new NullPointerException("states");
7051 } else if (pids.length != states.length) {
7052 throw new IllegalArgumentException("input and output arrays have different lengths!");
7055 synchronized (mPidsSelfLocked) {
7056 for (int i = 0; i < pids.length; i++) {
7057 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7058 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7064 // =========================================================
7066 // =========================================================
7068 static class PermissionController extends IPermissionController.Stub {
7069 ActivityManagerService mActivityManagerService;
7070 PermissionController(ActivityManagerService activityManagerService) {
7071 mActivityManagerService = activityManagerService;
7075 public boolean checkPermission(String permission, int pid, int uid) {
7076 return mActivityManagerService.checkPermission(permission, pid,
7077 uid) == PackageManager.PERMISSION_GRANTED;
7081 public String[] getPackagesForUid(int uid) {
7082 return mActivityManagerService.mContext.getPackageManager()
7083 .getPackagesForUid(uid);
7087 public boolean isRuntimePermission(String permission) {
7089 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7090 .getPermissionInfo(permission, 0);
7091 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7092 } catch (NameNotFoundException nnfe) {
7093 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7099 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7101 public int checkComponentPermission(String permission, int pid, int uid,
7102 int owningUid, boolean exported) {
7103 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7104 owningUid, exported);
7108 public Object getAMSLock() {
7109 return ActivityManagerService.this;
7114 * This can be called with or without the global lock held.
7116 int checkComponentPermission(String permission, int pid, int uid,
7117 int owningUid, boolean exported) {
7118 if (pid == MY_PID) {
7119 return PackageManager.PERMISSION_GRANTED;
7121 return ActivityManager.checkComponentPermission(permission, uid,
7122 owningUid, exported);
7126 * As the only public entry point for permissions checking, this method
7127 * can enforce the semantic that requesting a check on a null global
7128 * permission is automatically denied. (Internally a null permission
7129 * string is used when calling {@link #checkComponentPermission} in cases
7130 * when only uid-based security is needed.)
7132 * This can be called with or without the global lock held.
7135 public int checkPermission(String permission, int pid, int uid) {
7136 if (permission == null) {
7137 return PackageManager.PERMISSION_DENIED;
7139 return checkComponentPermission(permission, pid, uid, -1, true);
7143 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7144 if (permission == null) {
7145 return PackageManager.PERMISSION_DENIED;
7148 // We might be performing an operation on behalf of an indirect binder
7149 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7150 // client identity accordingly before proceeding.
7151 Identity tlsIdentity = sCallerIdentity.get();
7152 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7153 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7154 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7155 uid = tlsIdentity.uid;
7156 pid = tlsIdentity.pid;
7159 return checkComponentPermission(permission, pid, uid, -1, true);
7163 * Binder IPC calls go through the public entry point.
7164 * This can be called with or without the global lock held.
7166 int checkCallingPermission(String permission) {
7167 return checkPermission(permission,
7168 Binder.getCallingPid(),
7169 UserHandle.getAppId(Binder.getCallingUid()));
7173 * This can be called with or without the global lock held.
7175 void enforceCallingPermission(String permission, String func) {
7176 if (checkCallingPermission(permission)
7177 == PackageManager.PERMISSION_GRANTED) {
7181 String msg = "Permission Denial: " + func + " from pid="
7182 + Binder.getCallingPid()
7183 + ", uid=" + Binder.getCallingUid()
7184 + " requires " + permission;
7186 throw new SecurityException(msg);
7190 * Determine if UID is holding permissions required to access {@link Uri} in
7191 * the given {@link ProviderInfo}. Final permission checking is always done
7192 * in {@link ContentProvider}.
7194 private final boolean checkHoldingPermissionsLocked(
7195 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7196 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7197 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7198 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7199 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7200 != PERMISSION_GRANTED) {
7204 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7207 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7208 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7209 if (pi.applicationInfo.uid == uid) {
7211 } else if (!pi.exported) {
7215 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7216 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7218 // check if target holds top-level <provider> permissions
7219 if (!readMet && pi.readPermission != null && considerUidPermissions
7220 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7223 if (!writeMet && pi.writePermission != null && considerUidPermissions
7224 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7228 // track if unprotected read/write is allowed; any denied
7229 // <path-permission> below removes this ability
7230 boolean allowDefaultRead = pi.readPermission == null;
7231 boolean allowDefaultWrite = pi.writePermission == null;
7233 // check if target holds any <path-permission> that match uri
7234 final PathPermission[] pps = pi.pathPermissions;
7236 final String path = grantUri.uri.getPath();
7238 while (i > 0 && (!readMet || !writeMet)) {
7240 PathPermission pp = pps[i];
7241 if (pp.match(path)) {
7243 final String pprperm = pp.getReadPermission();
7244 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7245 "Checking read perm for " + pprperm + " for " + pp.getPath()
7246 + ": match=" + pp.match(path)
7247 + " check=" + pm.checkUidPermission(pprperm, uid));
7248 if (pprperm != null) {
7249 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7250 == PERMISSION_GRANTED) {
7253 allowDefaultRead = false;
7258 final String ppwperm = pp.getWritePermission();
7259 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7260 "Checking write perm " + ppwperm + " for " + pp.getPath()
7261 + ": match=" + pp.match(path)
7262 + " check=" + pm.checkUidPermission(ppwperm, uid));
7263 if (ppwperm != null) {
7264 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7265 == PERMISSION_GRANTED) {
7268 allowDefaultWrite = false;
7276 // grant unprotected <provider> read/write, if not blocked by
7277 // <path-permission> above
7278 if (allowDefaultRead) readMet = true;
7279 if (allowDefaultWrite) writeMet = true;
7281 } catch (RemoteException e) {
7285 return readMet && writeMet;
7288 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7289 ProviderInfo pi = null;
7290 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7295 pi = AppGlobals.getPackageManager().resolveContentProvider(
7296 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7297 } catch (RemoteException ex) {
7303 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7304 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7305 if (targetUris != null) {
7306 return targetUris.get(grantUri);
7311 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7312 String targetPkg, int targetUid, GrantUri grantUri) {
7313 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7314 if (targetUris == null) {
7315 targetUris = Maps.newArrayMap();
7316 mGrantedUriPermissions.put(targetUid, targetUris);
7319 UriPermission perm = targetUris.get(grantUri);
7321 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7322 targetUris.put(grantUri, perm);
7328 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7329 final int modeFlags) {
7330 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7331 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7332 : UriPermission.STRENGTH_OWNED;
7334 // Root gets to do everything.
7339 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7340 if (perms == null) return false;
7342 // First look for exact match
7343 final UriPermission exactPerm = perms.get(grantUri);
7344 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7348 // No exact match, look for prefixes
7349 final int N = perms.size();
7350 for (int i = 0; i < N; i++) {
7351 final UriPermission perm = perms.valueAt(i);
7352 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7353 && perm.getStrength(modeFlags) >= minStrength) {
7362 * @param uri This uri must NOT contain an embedded userId.
7363 * @param userId The userId in which the uri is to be resolved.
7366 public int checkUriPermission(Uri uri, int pid, int uid,
7367 final int modeFlags, int userId, IBinder callerToken) {
7368 enforceNotIsolatedCaller("checkUriPermission");
7370 // Another redirected-binder-call permissions check as in
7371 // {@link checkPermissionWithToken}.
7372 Identity tlsIdentity = sCallerIdentity.get();
7373 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7374 uid = tlsIdentity.uid;
7375 pid = tlsIdentity.pid;
7378 // Our own process gets to do everything.
7379 if (pid == MY_PID) {
7380 return PackageManager.PERMISSION_GRANTED;
7382 synchronized (this) {
7383 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7384 ? PackageManager.PERMISSION_GRANTED
7385 : PackageManager.PERMISSION_DENIED;
7390 * Check if the targetPkg can be granted permission to access uri by
7391 * the callingUid using the given modeFlags. Throws a security exception
7392 * if callingUid is not allowed to do this. Returns the uid of the target
7393 * if the URI permission grant should be performed; returns -1 if it is not
7394 * needed (for example targetPkg already has permission to access the URI).
7395 * If you already know the uid of the target, you can supply it in
7396 * lastTargetUid else set that to -1.
7398 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7399 final int modeFlags, int lastTargetUid) {
7400 if (!Intent.isAccessUriMode(modeFlags)) {
7404 if (targetPkg != null) {
7405 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7406 "Checking grant " + targetPkg + " permission to " + grantUri);
7409 final IPackageManager pm = AppGlobals.getPackageManager();
7411 // If this is not a content: uri, we can't do anything with it.
7412 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7413 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7414 "Can't grant URI permission for non-content URI: " + grantUri);
7418 final String authority = grantUri.uri.getAuthority();
7419 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7421 Slog.w(TAG, "No content provider found for permission check: " +
7422 grantUri.uri.toSafeString());
7426 int targetUid = lastTargetUid;
7427 if (targetUid < 0 && targetPkg != null) {
7429 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7430 if (targetUid < 0) {
7431 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7432 "Can't grant URI permission no uid for: " + targetPkg);
7435 } catch (RemoteException ex) {
7440 if (targetUid >= 0) {
7441 // First... does the target actually need this permission?
7442 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7443 // No need to grant the target this permission.
7444 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7445 "Target " + targetPkg + " already has full permission to " + grantUri);
7449 // First... there is no target package, so can anyone access it?
7450 boolean allowed = pi.exported;
7451 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7452 if (pi.readPermission != null) {
7456 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7457 if (pi.writePermission != null) {
7466 /* There is a special cross user grant if:
7467 * - The target is on another user.
7468 * - Apps on the current user can access the uri without any uid permissions.
7469 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7470 * grant uri permissions.
7472 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7473 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7474 modeFlags, false /*without considering the uid permissions*/);
7476 // Second... is the provider allowing granting of URI permissions?
7477 if (!specialCrossUserGrant) {
7478 if (!pi.grantUriPermissions) {
7479 throw new SecurityException("Provider " + pi.packageName
7481 + " does not allow granting of Uri permissions (uri "
7484 if (pi.uriPermissionPatterns != null) {
7485 final int N = pi.uriPermissionPatterns.length;
7486 boolean allowed = false;
7487 for (int i=0; i<N; i++) {
7488 if (pi.uriPermissionPatterns[i] != null
7489 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7495 throw new SecurityException("Provider " + pi.packageName
7497 + " does not allow granting of permission to path of Uri "
7503 // Third... does the caller itself have permission to access
7505 final int callingAppId = UserHandle.getAppId(callingUid);
7506 if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
7507 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
7508 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
7511 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7512 // Require they hold a strong enough Uri permission
7513 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7514 throw new SecurityException("Uid " + callingUid
7515 + " does not have permission to uri " + grantUri);
7523 * @param uri This uri must NOT contain an embedded userId.
7524 * @param userId The userId in which the uri is to be resolved.
7527 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7528 final int modeFlags, int userId) {
7529 enforceNotIsolatedCaller("checkGrantUriPermission");
7530 synchronized(this) {
7531 return checkGrantUriPermissionLocked(callingUid, targetPkg,
7532 new GrantUri(userId, uri, false), modeFlags, -1);
7536 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7537 final int modeFlags, UriPermissionOwner owner) {
7538 if (!Intent.isAccessUriMode(modeFlags)) {
7542 // So here we are: the caller has the assumed permission
7543 // to the uri, and the target doesn't. Let's now give this to
7546 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7547 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7549 final String authority = grantUri.uri.getAuthority();
7550 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7552 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7556 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7557 grantUri.prefix = true;
7559 final UriPermission perm = findOrCreateUriPermissionLocked(
7560 pi.packageName, targetPkg, targetUid, grantUri);
7561 perm.grantModes(modeFlags, owner);
7564 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7565 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7566 if (targetPkg == null) {
7567 throw new NullPointerException("targetPkg");
7570 final IPackageManager pm = AppGlobals.getPackageManager();
7572 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7573 } catch (RemoteException ex) {
7577 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7579 if (targetUid < 0) {
7583 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7587 static class NeededUriGrants extends ArrayList<GrantUri> {
7588 final String targetPkg;
7589 final int targetUid;
7592 NeededUriGrants(String targetPkg, int targetUid, int flags) {
7593 this.targetPkg = targetPkg;
7594 this.targetUid = targetUid;
7600 * Like checkGrantUriPermissionLocked, but takes an Intent.
7602 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7603 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7604 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7605 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7606 + " clip=" + (intent != null ? intent.getClipData() : null)
7607 + " from " + intent + "; flags=0x"
7608 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7610 if (targetPkg == null) {
7611 throw new NullPointerException("targetPkg");
7614 if (intent == null) {
7617 Uri data = intent.getData();
7618 ClipData clip = intent.getClipData();
7619 if (data == null && clip == null) {
7622 // Default userId for uris in the intent (if they don't specify it themselves)
7623 int contentUserHint = intent.getContentUserHint();
7624 if (contentUserHint == UserHandle.USER_CURRENT) {
7625 contentUserHint = UserHandle.getUserId(callingUid);
7627 final IPackageManager pm = AppGlobals.getPackageManager();
7629 if (needed != null) {
7630 targetUid = needed.targetUid;
7633 targetUid = pm.getPackageUid(targetPkg, targetUserId);
7634 } catch (RemoteException ex) {
7637 if (targetUid < 0) {
7638 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7639 "Can't grant URI permission no uid for: " + targetPkg
7640 + " on user " + targetUserId);
7645 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7646 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7648 if (targetUid > 0) {
7649 if (needed == null) {
7650 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7652 needed.add(grantUri);
7656 for (int i=0; i<clip.getItemCount(); i++) {
7657 Uri uri = clip.getItemAt(i).getUri();
7659 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7660 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7662 if (targetUid > 0) {
7663 if (needed == null) {
7664 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7666 needed.add(grantUri);
7669 Intent clipIntent = clip.getItemAt(i).getIntent();
7670 if (clipIntent != null) {
7671 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7672 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7673 if (newNeeded != null) {
7685 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7687 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7688 UriPermissionOwner owner) {
7689 if (needed != null) {
7690 for (int i=0; i<needed.size(); i++) {
7691 GrantUri grantUri = needed.get(i);
7692 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7693 grantUri, needed.flags, owner);
7698 void grantUriPermissionFromIntentLocked(int callingUid,
7699 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7700 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7701 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7702 if (needed == null) {
7706 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7710 * @param uri This uri must NOT contain an embedded userId.
7711 * @param userId The userId in which the uri is to be resolved.
7714 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7715 final int modeFlags, int userId) {
7716 enforceNotIsolatedCaller("grantUriPermission");
7717 GrantUri grantUri = new GrantUri(userId, uri, false);
7718 synchronized(this) {
7719 final ProcessRecord r = getRecordForAppLocked(caller);
7721 throw new SecurityException("Unable to find app for caller "
7723 + " when granting permission to uri " + grantUri);
7725 if (targetPkg == null) {
7726 throw new IllegalArgumentException("null target");
7728 if (grantUri == null) {
7729 throw new IllegalArgumentException("null uri");
7732 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7733 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7734 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7735 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7737 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7738 UserHandle.getUserId(r.uid));
7742 void removeUriPermissionIfNeededLocked(UriPermission perm) {
7743 if (perm.modeFlags == 0) {
7744 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7746 if (perms != null) {
7747 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7748 "Removing " + perm.targetUid + " permission to " + perm.uri);
7750 perms.remove(perm.uri);
7751 if (perms.isEmpty()) {
7752 mGrantedUriPermissions.remove(perm.targetUid);
7758 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7759 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7760 "Revoking all granted permissions to " + grantUri);
7762 final IPackageManager pm = AppGlobals.getPackageManager();
7763 final String authority = grantUri.uri.getAuthority();
7764 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7766 Slog.w(TAG, "No content provider found for permission revoke: "
7767 + grantUri.toSafeString());
7771 // Does the caller have this permission on the URI?
7772 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7773 // If they don't have direct access to the URI, then revoke any
7774 // ownerless URI permissions that have been granted to them.
7775 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7776 if (perms != null) {
7777 boolean persistChanged = false;
7778 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7779 final UriPermission perm = it.next();
7780 if (perm.uri.sourceUserId == grantUri.sourceUserId
7781 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7782 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7783 "Revoking non-owned " + perm.targetUid
7784 + " permission to " + perm.uri);
7785 persistChanged |= perm.revokeModes(
7786 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
7787 if (perm.modeFlags == 0) {
7792 if (perms.isEmpty()) {
7793 mGrantedUriPermissions.remove(callingUid);
7795 if (persistChanged) {
7796 schedulePersistUriGrants();
7802 boolean persistChanged = false;
7804 // Go through all of the permissions and remove any that match.
7805 int N = mGrantedUriPermissions.size();
7806 for (int i = 0; i < N; i++) {
7807 final int targetUid = mGrantedUriPermissions.keyAt(i);
7808 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7810 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7811 final UriPermission perm = it.next();
7812 if (perm.uri.sourceUserId == grantUri.sourceUserId
7813 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7814 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7815 "Revoking " + perm.targetUid + " permission to " + perm.uri);
7816 persistChanged |= perm.revokeModes(
7817 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7818 if (perm.modeFlags == 0) {
7824 if (perms.isEmpty()) {
7825 mGrantedUriPermissions.remove(targetUid);
7831 if (persistChanged) {
7832 schedulePersistUriGrants();
7837 * @param uri This uri must NOT contain an embedded userId.
7838 * @param userId The userId in which the uri is to be resolved.
7841 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7843 enforceNotIsolatedCaller("revokeUriPermission");
7844 synchronized(this) {
7845 final ProcessRecord r = getRecordForAppLocked(caller);
7847 throw new SecurityException("Unable to find app for caller "
7849 + " when revoking permission to uri " + uri);
7852 Slog.w(TAG, "revokeUriPermission: null uri");
7856 if (!Intent.isAccessUriMode(modeFlags)) {
7860 final String authority = uri.getAuthority();
7861 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7863 Slog.w(TAG, "No content provider found for permission revoke: "
7864 + uri.toSafeString());
7868 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7873 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7876 * @param packageName Package name to match, or {@code null} to apply to all
7878 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7880 * @param persistable If persistable grants should be removed.
7882 private void removeUriPermissionsForPackageLocked(
7883 String packageName, int userHandle, boolean persistable) {
7884 if (userHandle == UserHandle.USER_ALL && packageName == null) {
7885 throw new IllegalArgumentException("Must narrow by either package or user");
7888 boolean persistChanged = false;
7890 int N = mGrantedUriPermissions.size();
7891 for (int i = 0; i < N; i++) {
7892 final int targetUid = mGrantedUriPermissions.keyAt(i);
7893 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7895 // Only inspect grants matching user
7896 if (userHandle == UserHandle.USER_ALL
7897 || userHandle == UserHandle.getUserId(targetUid)) {
7898 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7899 final UriPermission perm = it.next();
7901 // Only inspect grants matching package
7902 if (packageName == null || perm.sourcePkg.equals(packageName)
7903 || perm.targetPkg.equals(packageName)) {
7904 // Hacky solution as part of fixing a security bug; ignore
7905 // grants associated with DownloadManager so we don't have
7906 // to immediately launch it to regrant the permissions
7907 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
7908 && !persistable) continue;
7910 persistChanged |= perm.revokeModes(persistable
7911 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
7913 // Only remove when no modes remain; any persisted grants
7914 // will keep this alive.
7915 if (perm.modeFlags == 0) {
7921 if (perms.isEmpty()) {
7922 mGrantedUriPermissions.remove(targetUid);
7929 if (persistChanged) {
7930 schedulePersistUriGrants();
7935 public IBinder newUriPermissionOwner(String name) {
7936 enforceNotIsolatedCaller("newUriPermissionOwner");
7937 synchronized(this) {
7938 UriPermissionOwner owner = new UriPermissionOwner(this, name);
7939 return owner.getExternalTokenLocked();
7944 * @param uri This uri must NOT contain an embedded userId.
7945 * @param sourceUserId The userId in which the uri is to be resolved.
7946 * @param targetUserId The userId of the app that receives the grant.
7949 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7950 final int modeFlags, int sourceUserId, int targetUserId) {
7951 targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7952 targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7953 synchronized(this) {
7954 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7955 if (owner == null) {
7956 throw new IllegalArgumentException("Unknown owner: " + token);
7958 if (fromUid != Binder.getCallingUid()) {
7959 if (Binder.getCallingUid() != Process.myUid()) {
7960 // Only system code can grant URI permissions on behalf
7962 throw new SecurityException("nice try");
7965 if (targetPkg == null) {
7966 throw new IllegalArgumentException("null target");
7969 throw new IllegalArgumentException("null uri");
7972 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7973 modeFlags, owner, targetUserId);
7978 * @param uri This uri must NOT contain an embedded userId.
7979 * @param userId The userId in which the uri is to be resolved.
7982 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7983 synchronized(this) {
7984 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7985 if (owner == null) {
7986 throw new IllegalArgumentException("Unknown owner: " + token);
7990 owner.removeUriPermissionsLocked(mode);
7992 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7997 private void schedulePersistUriGrants() {
7998 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7999 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8000 10 * DateUtils.SECOND_IN_MILLIS);
8004 private void writeGrantedUriPermissions() {
8005 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8007 // Snapshot permissions so we can persist without lock
8008 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8009 synchronized (this) {
8010 final int size = mGrantedUriPermissions.size();
8011 for (int i = 0; i < size; i++) {
8012 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8013 for (UriPermission perm : perms.values()) {
8014 if (perm.persistedModeFlags != 0) {
8015 persist.add(perm.snapshot());
8021 FileOutputStream fos = null;
8023 fos = mGrantFile.startWrite();
8025 XmlSerializer out = new FastXmlSerializer();
8026 out.setOutput(fos, StandardCharsets.UTF_8.name());
8027 out.startDocument(null, true);
8028 out.startTag(null, TAG_URI_GRANTS);
8029 for (UriPermission.Snapshot perm : persist) {
8030 out.startTag(null, TAG_URI_GRANT);
8031 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8032 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8033 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8034 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8035 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8036 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8037 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8038 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8039 out.endTag(null, TAG_URI_GRANT);
8041 out.endTag(null, TAG_URI_GRANTS);
8044 mGrantFile.finishWrite(fos);
8045 } catch (IOException e) {
8047 mGrantFile.failWrite(fos);
8052 private void readGrantedUriPermissionsLocked() {
8053 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8055 final long now = System.currentTimeMillis();
8057 FileInputStream fis = null;
8059 fis = mGrantFile.openRead();
8060 final XmlPullParser in = Xml.newPullParser();
8061 in.setInput(fis, StandardCharsets.UTF_8.name());
8064 while ((type = in.next()) != END_DOCUMENT) {
8065 final String tag = in.getName();
8066 if (type == START_TAG) {
8067 if (TAG_URI_GRANT.equals(tag)) {
8068 final int sourceUserId;
8069 final int targetUserId;
8070 final int userHandle = readIntAttribute(in,
8071 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8072 if (userHandle != UserHandle.USER_NULL) {
8073 // For backwards compatibility.
8074 sourceUserId = userHandle;
8075 targetUserId = userHandle;
8077 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8078 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8080 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8081 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8082 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8083 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8084 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8085 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8087 // Sanity check that provider still belongs to source package
8088 final ProviderInfo pi = getProviderInfoLocked(
8089 uri.getAuthority(), sourceUserId);
8090 if (pi != null && sourcePkg.equals(pi.packageName)) {
8093 targetUid = AppGlobals.getPackageManager()
8094 .getPackageUid(targetPkg, targetUserId);
8095 } catch (RemoteException e) {
8097 if (targetUid != -1) {
8098 final UriPermission perm = findOrCreateUriPermissionLocked(
8099 sourcePkg, targetPkg, targetUid,
8100 new GrantUri(sourceUserId, uri, prefix));
8101 perm.initPersistedModes(modeFlags, createdTime);
8104 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8105 + " but instead found " + pi);
8110 } catch (FileNotFoundException e) {
8111 // Missing grants is okay
8112 } catch (IOException e) {
8113 Slog.wtf(TAG, "Failed reading Uri grants", e);
8114 } catch (XmlPullParserException e) {
8115 Slog.wtf(TAG, "Failed reading Uri grants", e);
8117 IoUtils.closeQuietly(fis);
8122 * @param uri This uri must NOT contain an embedded userId.
8123 * @param userId The userId in which the uri is to be resolved.
8126 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8127 enforceNotIsolatedCaller("takePersistableUriPermission");
8129 Preconditions.checkFlagsArgument(modeFlags,
8130 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8132 synchronized (this) {
8133 final int callingUid = Binder.getCallingUid();
8134 boolean persistChanged = false;
8135 GrantUri grantUri = new GrantUri(userId, uri, false);
8137 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8138 new GrantUri(userId, uri, false));
8139 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8140 new GrantUri(userId, uri, true));
8142 final boolean exactValid = (exactPerm != null)
8143 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8144 final boolean prefixValid = (prefixPerm != null)
8145 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8147 if (!(exactValid || prefixValid)) {
8148 throw new SecurityException("No persistable permission grants found for UID "
8149 + callingUid + " and Uri " + grantUri.toSafeString());
8153 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8156 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8159 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8161 if (persistChanged) {
8162 schedulePersistUriGrants();
8168 * @param uri This uri must NOT contain an embedded userId.
8169 * @param userId The userId in which the uri is to be resolved.
8172 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8173 enforceNotIsolatedCaller("releasePersistableUriPermission");
8175 Preconditions.checkFlagsArgument(modeFlags,
8176 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8178 synchronized (this) {
8179 final int callingUid = Binder.getCallingUid();
8180 boolean persistChanged = false;
8182 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8183 new GrantUri(userId, uri, false));
8184 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8185 new GrantUri(userId, uri, true));
8186 if (exactPerm == null && prefixPerm == null) {
8187 throw new SecurityException("No permission grants found for UID " + callingUid
8188 + " and Uri " + uri.toSafeString());
8191 if (exactPerm != null) {
8192 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8193 removeUriPermissionIfNeededLocked(exactPerm);
8195 if (prefixPerm != null) {
8196 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8197 removeUriPermissionIfNeededLocked(prefixPerm);
8200 if (persistChanged) {
8201 schedulePersistUriGrants();
8207 * Prune any older {@link UriPermission} for the given UID until outstanding
8208 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8210 * @return if any mutations occured that require persisting.
8212 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8213 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8214 if (perms == null) return false;
8215 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8217 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8218 for (UriPermission perm : perms.values()) {
8219 if (perm.persistedModeFlags != 0) {
8220 persisted.add(perm);
8224 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8225 if (trimCount <= 0) return false;
8227 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8228 for (int i = 0; i < trimCount; i++) {
8229 final UriPermission perm = persisted.get(i);
8231 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8232 "Trimming grant created at " + perm.persistedCreateTime);
8234 perm.releasePersistableModes(~0);
8235 removeUriPermissionIfNeededLocked(perm);
8242 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8243 String packageName, boolean incoming) {
8244 enforceNotIsolatedCaller("getPersistedUriPermissions");
8245 Preconditions.checkNotNull(packageName, "packageName");
8247 final int callingUid = Binder.getCallingUid();
8248 final IPackageManager pm = AppGlobals.getPackageManager();
8250 final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
8251 if (packageUid != callingUid) {
8252 throw new SecurityException(
8253 "Package " + packageName + " does not belong to calling UID " + callingUid);
8255 } catch (RemoteException e) {
8256 throw new SecurityException("Failed to verify package name ownership");
8259 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8260 synchronized (this) {
8262 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8264 if (perms == null) {
8265 Slog.w(TAG, "No permission grants found for " + packageName);
8267 for (UriPermission perm : perms.values()) {
8268 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8269 result.add(perm.buildPersistedPublicApiObject());
8274 final int size = mGrantedUriPermissions.size();
8275 for (int i = 0; i < size; i++) {
8276 final ArrayMap<GrantUri, UriPermission> perms =
8277 mGrantedUriPermissions.valueAt(i);
8278 for (UriPermission perm : perms.values()) {
8279 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8280 result.add(perm.buildPersistedPublicApiObject());
8286 return new ParceledListSlice<android.content.UriPermission>(result);
8290 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8291 synchronized (this) {
8293 who != null ? getRecordForAppLocked(who) : null;
8294 if (app == null) return;
8296 Message msg = Message.obtain();
8297 msg.what = WAIT_FOR_DEBUGGER_MSG;
8299 msg.arg1 = waiting ? 1 : 0;
8300 mUiHandler.sendMessage(msg);
8305 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8306 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8307 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8308 outInfo.availMem = Process.getFreeMemory();
8309 outInfo.totalMem = Process.getTotalMemory();
8310 outInfo.threshold = homeAppMem;
8311 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8312 outInfo.hiddenAppThreshold = cachedAppMem;
8313 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8314 ProcessList.SERVICE_ADJ);
8315 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8316 ProcessList.VISIBLE_APP_ADJ);
8317 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8318 ProcessList.FOREGROUND_APP_ADJ);
8321 // =========================================================
8323 // =========================================================
8326 public List<IAppTask> getAppTasks(String callingPackage) {
8327 int callingUid = Binder.getCallingUid();
8328 long ident = Binder.clearCallingIdentity();
8330 synchronized(this) {
8331 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8333 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8335 final int N = mRecentTasks.size();
8336 for (int i = 0; i < N; i++) {
8337 TaskRecord tr = mRecentTasks.get(i);
8338 // Skip tasks that do not match the caller. We don't need to verify
8339 // callingPackage, because we are also limiting to callingUid and know
8340 // that will limit to the correct security sandbox.
8341 if (tr.effectiveUid != callingUid) {
8344 Intent intent = tr.getBaseIntent();
8345 if (intent == null ||
8346 !callingPackage.equals(intent.getComponent().getPackageName())) {
8349 ActivityManager.RecentTaskInfo taskInfo =
8350 createRecentTaskInfoFromTaskRecord(tr);
8351 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8355 Binder.restoreCallingIdentity(ident);
8362 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8363 final int callingUid = Binder.getCallingUid();
8364 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8366 synchronized(this) {
8367 if (DEBUG_ALL) Slog.v(
8368 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8370 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8373 // TODO: Improve with MRU list from all ActivityStacks.
8374 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8381 * Creates a new RecentTaskInfo from a TaskRecord.
8383 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8384 // Update the task description to reflect any changes in the task stack
8385 tr.updateTaskDescription();
8387 // Compose the recent task info
8388 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8389 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8390 rti.persistentId = tr.taskId;
8391 rti.baseIntent = new Intent(tr.getBaseIntent());
8392 rti.origActivity = tr.origActivity;
8393 rti.description = tr.lastDescription;
8394 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8395 rti.userId = tr.userId;
8396 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8397 rti.firstActiveTime = tr.firstActiveTime;
8398 rti.lastActiveTime = tr.lastActiveTime;
8399 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8400 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8401 rti.numActivities = 0;
8403 ActivityRecord base = null;
8404 ActivityRecord top = null;
8407 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8408 tmp = tr.mActivities.get(i);
8409 if (tmp.finishing) {
8413 if (top == null || (top.state == ActivityState.INITIALIZING)) {
8416 rti.numActivities++;
8419 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8420 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8425 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8426 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8427 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8429 if (checkPermission(android.Manifest.permission.GET_TASKS,
8430 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8431 // Temporary compatibility: some existing apps on the system image may
8432 // still be requesting the old permission and not switched to the new
8433 // one; if so, we'll still allow them full access. This means we need
8434 // to see if they are holding the old permission and are a system app.
8436 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8438 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8439 + " is using old GET_TASKS but privileged; allowing");
8441 } catch (RemoteException e) {
8446 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8447 + " does not hold REAL_GET_TASKS; limiting output");
8453 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8454 final int callingUid = Binder.getCallingUid();
8455 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8456 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8458 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8459 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8460 synchronized (this) {
8461 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8463 final boolean detailed = checkCallingPermission(
8464 android.Manifest.permission.GET_DETAILED_TASKS)
8465 == PackageManager.PERMISSION_GRANTED;
8467 final int recentsCount = mRecentTasks.size();
8468 ArrayList<ActivityManager.RecentTaskInfo> res =
8469 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8471 final Set<Integer> includedUsers;
8472 if (includeProfiles) {
8473 includedUsers = getProfileIdsLocked(userId);
8475 includedUsers = new HashSet<>();
8477 includedUsers.add(Integer.valueOf(userId));
8479 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8480 TaskRecord tr = mRecentTasks.get(i);
8481 // Only add calling user or related users recent tasks
8482 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8483 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8487 // Return the entry if desired by the caller. We always return
8488 // the first entry, because callers always expect this to be the
8489 // foreground app. We may filter others if the caller has
8490 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8491 // we should exclude the entry.
8495 || (tr.intent == null)
8496 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8499 // If the caller doesn't have the GET_TASKS permission, then only
8500 // allow them to see a small subset of tasks -- their own and home.
8501 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8502 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8506 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8507 if (tr.stack != null && tr.stack.isHomeStack()) {
8508 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8509 "Skipping, home stack task: " + tr);
8513 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8514 // Don't include auto remove tasks that are finished or finishing.
8515 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8516 "Skipping, auto-remove without activity: " + tr);
8519 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8520 && !tr.isAvailable) {
8521 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8522 "Skipping, unavail real act: " + tr);
8526 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8528 rti.baseIntent.replaceExtras((Bundle)null);
8540 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8541 synchronized (this) {
8542 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8543 "getTaskThumbnail()");
8544 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(id, false);
8546 return tr.getTaskThumbnailLocked();
8553 public int addAppTask(IBinder activityToken, Intent intent,
8554 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8555 final int callingUid = Binder.getCallingUid();
8556 final long callingIdent = Binder.clearCallingIdentity();
8559 synchronized (this) {
8560 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8562 throw new IllegalArgumentException("Activity does not exist; token="
8565 ComponentName comp = intent.getComponent();
8567 throw new IllegalArgumentException("Intent " + intent
8568 + " must specify explicit component");
8570 if (thumbnail.getWidth() != mThumbnailWidth
8571 || thumbnail.getHeight() != mThumbnailHeight) {
8572 throw new IllegalArgumentException("Bad thumbnail size: got "
8573 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8574 + mThumbnailWidth + "x" + mThumbnailHeight);
8576 if (intent.getSelector() != null) {
8577 intent.setSelector(null);
8579 if (intent.getSourceBounds() != null) {
8580 intent.setSourceBounds(null);
8582 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8583 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8584 // The caller has added this as an auto-remove task... that makes no
8585 // sense, so turn off auto-remove.
8586 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8588 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8589 // Must be a new task.
8590 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8592 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8593 mLastAddedTaskActivity = null;
8595 ActivityInfo ainfo = mLastAddedTaskActivity;
8596 if (ainfo == null) {
8597 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8598 comp, 0, UserHandle.getUserId(callingUid));
8599 if (ainfo.applicationInfo.uid != callingUid) {
8600 throw new SecurityException(
8601 "Can't add task for another application: target uid="
8602 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8606 TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8607 intent, description);
8609 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
8611 // If this would have caused a trim, then we'll abort because that
8612 // means it would be added at the end of the list but then just removed.
8613 return INVALID_TASK_ID;
8616 final int N = mRecentTasks.size();
8617 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8618 final TaskRecord tr = mRecentTasks.remove(N - 1);
8619 tr.removedFromRecents();
8622 task.inRecents = true;
8623 mRecentTasks.add(task);
8624 r.task.stack.addTask(task, false, false);
8626 task.setLastThumbnail(thumbnail);
8627 task.freeLastThumbnail();
8632 Binder.restoreCallingIdentity(callingIdent);
8637 public Point getAppTaskThumbnailSize() {
8638 synchronized (this) {
8639 return new Point(mThumbnailWidth, mThumbnailHeight);
8644 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8645 synchronized (this) {
8646 ActivityRecord r = ActivityRecord.isInStackLocked(token);
8648 r.setTaskDescription(td);
8649 r.task.updateTaskDescription();
8655 public void setTaskResizeable(int taskId, boolean resizeable) {
8656 synchronized (this) {
8657 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8659 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
8662 if (task.mResizeable != resizeable) {
8663 task.mResizeable = resizeable;
8664 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
8665 mStackSupervisor.resumeTopActivitiesLocked();
8671 public void resizeTask(int taskId, Rect bounds) {
8672 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8674 long ident = Binder.clearCallingIdentity();
8676 synchronized (this) {
8677 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8679 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
8682 mStackSupervisor.resizeTaskLocked(task, bounds);
8685 Binder.restoreCallingIdentity(ident);
8690 public Bitmap getTaskDescriptionIcon(String filename) {
8691 if (!FileUtils.isValidExtFilename(filename)
8692 || !filename.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
8693 throw new IllegalArgumentException("Bad filename: " + filename);
8695 return mTaskPersister.getTaskDescriptionIcon(filename);
8699 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
8700 throws RemoteException {
8701 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
8702 opts.getCustomInPlaceResId() == 0) {
8703 throw new IllegalArgumentException("Expected in-place ActivityOption " +
8704 "with valid animation");
8706 mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false);
8707 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
8708 opts.getCustomInPlaceResId());
8709 mWindowManager.executeAppTransition();
8712 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess) {
8713 mRecentTasks.remove(tr);
8714 tr.removedFromRecents();
8715 ComponentName component = tr.getBaseIntent().getComponent();
8716 if (component == null) {
8717 Slog.w(TAG, "No component for base intent of task: " + tr);
8721 // Find any running services associated with this app and stop if needed.
8722 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
8728 // Determine if the process(es) for this task should be killed.
8729 final String pkg = component.getPackageName();
8730 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
8731 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8732 for (int i = 0; i < pmap.size(); i++) {
8734 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8735 for (int j = 0; j < uids.size(); j++) {
8736 ProcessRecord proc = uids.valueAt(j);
8737 if (proc.userId != tr.userId) {
8738 // Don't kill process for a different user.
8741 if (proc == mHomeProcess) {
8742 // Don't kill the home process along with tasks from the same package.
8745 if (!proc.pkgList.containsKey(pkg)) {
8746 // Don't kill process that is not associated with this task.
8750 for (int k = 0; k < proc.activities.size(); k++) {
8751 TaskRecord otherTask = proc.activities.get(k).task;
8752 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
8753 // Don't kill process(es) that has an activity in a different task that is
8759 if (proc.foregroundServices) {
8760 // Don't kill process(es) with foreground service.
8764 // Add process to kill list.
8765 procsToKill.add(proc);
8769 // Kill the running processes.
8770 for (int i = 0; i < procsToKill.size(); i++) {
8771 ProcessRecord pr = procsToKill.get(i);
8772 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
8773 && pr.curReceiver == null) {
8774 pr.kill("remove task", true);
8776 // We delay killing processes that are not in the background or running a receiver.
8777 pr.waitingToKill = "remove task";
8782 private void removeTasksByPackageNameLocked(String packageName, int userId) {
8783 // Remove all tasks with activities in the specified package from the list of recent tasks
8784 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8785 TaskRecord tr = mRecentTasks.get(i);
8786 if (tr.userId != userId) continue;
8788 ComponentName cn = tr.intent.getComponent();
8789 if (cn != null && cn.getPackageName().equals(packageName)) {
8790 // If the package name matches, remove the task.
8791 removeTaskByIdLocked(tr.taskId, true);
8796 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
8799 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
8800 TaskRecord tr = mRecentTasks.get(i);
8801 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
8805 ComponentName cn = tr.intent.getComponent();
8806 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
8807 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
8808 if (sameComponent) {
8809 removeTaskByIdLocked(tr.taskId, false);
8815 * Removes the task with the specified task id.
8817 * @param taskId Identifier of the task to be removed.
8818 * @param killProcess Kill any process associated with the task if possible.
8819 * @return Returns true if the given task was found and removed.
8821 private boolean removeTaskByIdLocked(int taskId, boolean killProcess) {
8822 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
8824 tr.removeTaskActivitiesLocked();
8825 cleanUpRemovedTaskLocked(tr, killProcess);
8826 if (tr.isPersistable) {
8827 notifyTaskPersisterLocked(null, true);
8831 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
8836 public boolean removeTask(int taskId) {
8837 synchronized (this) {
8838 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8840 long ident = Binder.clearCallingIdentity();
8842 return removeTaskByIdLocked(taskId, true);
8844 Binder.restoreCallingIdentity(ident);
8850 * TODO: Add mController hook
8853 public void moveTaskToFront(int taskId, int flags, Bundle options) {
8854 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
8856 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
8857 synchronized(this) {
8858 moveTaskToFrontLocked(taskId, flags, options);
8862 void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8863 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8864 Binder.getCallingUid(), -1, -1, "Task to front")) {
8865 ActivityOptions.abort(options);
8868 final long origId = Binder.clearCallingIdentity();
8870 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8872 Slog.d(TAG, "Could not find task for id: "+ taskId);
8875 if (mStackSupervisor.isLockTaskModeViolation(task)) {
8876 mStackSupervisor.showLockTaskToast();
8877 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8880 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8881 if (prev != null && prev.isRecentsActivity()) {
8882 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8884 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
8886 Binder.restoreCallingIdentity(origId);
8888 ActivityOptions.abort(options);
8892 * Moves an activity, and all of the other activities within the same task, to the bottom
8893 * of the history stack. The activity's order within the task is unchanged.
8895 * @param token A reference to the activity we wish to move
8896 * @param nonRoot If false then this only works if the activity is the root
8897 * of a task; if true it will work for any activity in a task.
8898 * @return Returns true if the move completed, false if not.
8901 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8902 enforceNotIsolatedCaller("moveActivityTaskToBack");
8903 synchronized(this) {
8904 final long origId = Binder.clearCallingIdentity();
8906 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8907 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8909 if (mStackSupervisor.isLockedTask(task)) {
8910 mStackSupervisor.showLockTaskToast();
8913 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
8916 Binder.restoreCallingIdentity(origId);
8923 public void moveTaskBackwards(int task) {
8924 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8925 "moveTaskBackwards()");
8927 synchronized(this) {
8928 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8929 Binder.getCallingUid(), -1, -1, "Task backwards")) {
8932 final long origId = Binder.clearCallingIdentity();
8933 moveTaskBackwardsLocked(task);
8934 Binder.restoreCallingIdentity(origId);
8938 private final void moveTaskBackwardsLocked(int task) {
8939 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8943 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
8944 IActivityContainerCallback callback) throws RemoteException {
8945 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8946 "createActivityContainer()");
8947 synchronized (this) {
8948 if (parentActivityToken == null) {
8949 throw new IllegalArgumentException("parent token must not be null");
8951 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
8955 if (callback == null) {
8956 throw new IllegalArgumentException("callback must not be null");
8958 return mStackSupervisor.createVirtualActivityContainer(r, callback);
8963 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8964 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8965 "deleteActivityContainer()");
8966 synchronized (this) {
8967 mStackSupervisor.deleteActivityContainer(container);
8972 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
8973 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8974 "createStackOnDisplay()");
8975 synchronized (this) {
8976 final int stackId = mStackSupervisor.getNextStackId();
8977 final ActivityStack stack = mStackSupervisor.createStackOnDisplay(stackId, displayId);
8978 if (stack == null) {
8981 return stack.mActivityContainer;
8986 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
8987 synchronized (this) {
8988 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8989 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
8990 return stack.mActivityContainer.getDisplayId();
8992 return Display.DEFAULT_DISPLAY;
8997 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8998 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8999 "moveTaskToStack()");
9000 if (stackId == HOME_STACK_ID) {
9001 Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
9002 new RuntimeException("here").fillInStackTrace());
9004 synchronized (this) {
9005 long ident = Binder.clearCallingIdentity();
9007 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9008 + " to stackId=" + stackId + " toTop=" + toTop);
9009 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop);
9011 Binder.restoreCallingIdentity(ident);
9017 public void resizeStack(int stackId, Rect bounds) {
9018 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9020 long ident = Binder.clearCallingIdentity();
9022 synchronized (this) {
9023 mStackSupervisor.resizeStackLocked(stackId, bounds);
9026 Binder.restoreCallingIdentity(ident);
9031 public List<StackInfo> getAllStackInfos() {
9032 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9033 "getAllStackInfos()");
9034 long ident = Binder.clearCallingIdentity();
9036 synchronized (this) {
9037 return mStackSupervisor.getAllStackInfosLocked();
9040 Binder.restoreCallingIdentity(ident);
9045 public StackInfo getStackInfo(int stackId) {
9046 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9048 long ident = Binder.clearCallingIdentity();
9050 synchronized (this) {
9051 return mStackSupervisor.getStackInfoLocked(stackId);
9054 Binder.restoreCallingIdentity(ident);
9059 public boolean isInHomeStack(int taskId) {
9060 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9062 long ident = Binder.clearCallingIdentity();
9064 synchronized (this) {
9065 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(taskId, false);
9066 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9069 Binder.restoreCallingIdentity(ident);
9074 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9075 synchronized(this) {
9076 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9081 public void updateDeviceOwner(String packageName) {
9082 final int callingUid = Binder.getCallingUid();
9083 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9084 throw new SecurityException("updateDeviceOwner called from non-system process");
9086 synchronized (this) {
9087 mDeviceOwnerName = packageName;
9092 public void updateLockTaskPackages(int userId, String[] packages) {
9093 final int callingUid = Binder.getCallingUid();
9094 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9095 throw new SecurityException("updateLockTaskPackage called from non-system process");
9097 synchronized (this) {
9098 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9099 Arrays.toString(packages));
9100 mLockTaskPackages.put(userId, packages);
9101 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9106 void startLockTaskModeLocked(TaskRecord task) {
9107 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9108 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9112 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9113 // is initiated by system after the pinning request was shown and locked mode is initiated
9114 // by an authorized app directly
9115 final int callingUid = Binder.getCallingUid();
9116 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9117 long ident = Binder.clearCallingIdentity();
9119 final ActivityStack stack = mStackSupervisor.getFocusedStack();
9120 if (!isSystemInitiated) {
9121 task.mLockTaskUid = callingUid;
9122 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9123 // startLockTask() called by app and task mode is lockTaskModeDefault.
9124 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9125 StatusBarManagerInternal statusBarManager =
9126 LocalServices.getService(StatusBarManagerInternal.class);
9127 if (statusBarManager != null) {
9128 statusBarManager.showScreenPinningRequest();
9133 if (stack == null || task != stack.topTask()) {
9134 throw new IllegalArgumentException("Invalid task, not in foreground");
9137 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9139 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9140 ActivityManager.LOCK_TASK_MODE_PINNED :
9141 ActivityManager.LOCK_TASK_MODE_LOCKED,
9142 "startLockTask", true);
9144 Binder.restoreCallingIdentity(ident);
9149 public void startLockTaskMode(int taskId) {
9150 synchronized (this) {
9151 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9153 startLockTaskModeLocked(task);
9159 public void startLockTaskMode(IBinder token) {
9160 synchronized (this) {
9161 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9165 final TaskRecord task = r.task;
9167 startLockTaskModeLocked(task);
9173 public void startLockTaskModeOnCurrent() throws RemoteException {
9174 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9175 "startLockTaskModeOnCurrent");
9176 long ident = Binder.clearCallingIdentity();
9178 synchronized (this) {
9179 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9181 startLockTaskModeLocked(r.task);
9185 Binder.restoreCallingIdentity(ident);
9190 public void stopLockTaskMode() {
9191 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9192 if (lockTask == null) {
9193 // Our work here is done.
9197 final int callingUid = Binder.getCallingUid();
9198 final int lockTaskUid = lockTask.mLockTaskUid;
9199 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9200 // It is possible lockTaskMode was started by the system process because
9201 // android:lockTaskMode is set to a locking value in the application manifest instead of
9202 // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9203 // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9204 if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9205 callingUid != lockTaskUid
9206 && (lockTaskUid != 0
9207 || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9208 throw new SecurityException("Invalid uid, expected " + lockTaskUid
9209 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9212 long ident = Binder.clearCallingIdentity();
9214 Log.d(TAG, "stopLockTaskMode");
9216 synchronized (this) {
9217 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9218 "stopLockTask", true);
9220 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
9222 tm.showInCallScreen(false);
9225 Binder.restoreCallingIdentity(ident);
9230 public void stopLockTaskModeOnCurrent() throws RemoteException {
9231 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9232 "stopLockTaskModeOnCurrent");
9233 long ident = Binder.clearCallingIdentity();
9237 Binder.restoreCallingIdentity(ident);
9242 public boolean isInLockTaskMode() {
9243 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9247 public int getLockTaskModeState() {
9248 synchronized (this) {
9249 return mStackSupervisor.getLockTaskModeState();
9254 public void showLockTaskEscapeMessage(IBinder token) {
9255 synchronized (this) {
9256 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9260 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9264 // =========================================================
9265 // CONTENT PROVIDERS
9266 // =========================================================
9268 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9269 List<ProviderInfo> providers = null;
9271 ParceledListSlice<ProviderInfo> slice = AppGlobals.getPackageManager().
9272 queryContentProviders(app.processName, app.uid,
9273 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
9274 providers = slice != null ? slice.getList() : null;
9275 } catch (RemoteException ex) {
9277 if (DEBUG_MU) Slog.v(TAG_MU,
9278 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9279 int userId = app.userId;
9280 if (providers != null) {
9281 int N = providers.size();
9282 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9283 for (int i=0; i<N; i++) {
9285 (ProviderInfo)providers.get(i);
9286 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9287 cpi.name, cpi.flags);
9288 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_OWNER) {
9289 // This is a singleton provider, but a user besides the
9290 // default user is asking to initialize a process it runs
9291 // in... well, no, it doesn't actually run in this process,
9292 // it runs in the process of the default user. Get rid of it.
9293 providers.remove(i);
9299 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9300 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
9302 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
9303 mProviderMap.putProviderByClass(comp, cpr);
9305 if (DEBUG_MU) Slog.v(TAG_MU,
9306 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
9307 app.pubProviders.put(cpi.name, cpr);
9308 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
9309 // Don't add this if it is a platform component that is marked
9310 // to run in multiple processes, because this is actually
9311 // part of the framework so doesn't make sense to track as a
9312 // separate apk in the process.
9313 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
9316 ensurePackageDexOpt(cpi.applicationInfo.packageName);
9323 * Check if the calling UID has a possible chance at accessing the provider
9324 * at the given authority and user.
9326 public String checkContentProviderAccess(String authority, int userId) {
9327 if (userId == UserHandle.USER_ALL) {
9328 mContext.enforceCallingOrSelfPermission(
9329 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
9330 userId = UserHandle.getCallingUserId();
9333 ProviderInfo cpi = null;
9335 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
9336 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9337 } catch (RemoteException ignored) {
9340 // TODO: make this an outright failure in a future platform release;
9341 // until then anonymous content notifications are unprotected
9342 //return "Failed to find provider " + authority + " for user " + userId;
9346 ProcessRecord r = null;
9347 synchronized (mPidsSelfLocked) {
9348 r = mPidsSelfLocked.get(Binder.getCallingPid());
9351 return "Failed to find PID " + Binder.getCallingPid();
9354 synchronized (this) {
9355 return checkContentProviderPermissionLocked(cpi, r, userId, true);
9360 * Check if {@link ProcessRecord} has a possible chance at accessing the
9361 * given {@link ProviderInfo}. Final permission checking is always done
9362 * in {@link ContentProvider}.
9364 private final String checkContentProviderPermissionLocked(
9365 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
9366 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
9367 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
9368 boolean checkedGrants = false;
9370 // Looking for cross-user grants before enforcing the typical cross-users permissions
9371 int tmpTargetUserId = unsafeConvertIncomingUser(userId);
9372 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
9373 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
9376 checkedGrants = true;
9378 userId = handleIncomingUser(callingPid, callingUid, userId,
9379 false, ALLOW_NON_FULL,
9380 "checkContentProviderPermissionLocked " + cpi.authority, null);
9381 if (userId != tmpTargetUserId) {
9382 // When we actually went to determine the final targer user ID, this ended
9383 // up different than our initial check for the authority. This is because
9384 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
9385 // SELF. So we need to re-check the grants again.
9386 checkedGrants = false;
9389 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
9390 cpi.applicationInfo.uid, cpi.exported)
9391 == PackageManager.PERMISSION_GRANTED) {
9394 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
9395 cpi.applicationInfo.uid, cpi.exported)
9396 == PackageManager.PERMISSION_GRANTED) {
9400 PathPermission[] pps = cpi.pathPermissions;
9405 PathPermission pp = pps[i];
9406 String pprperm = pp.getReadPermission();
9407 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
9408 cpi.applicationInfo.uid, cpi.exported)
9409 == PackageManager.PERMISSION_GRANTED) {
9412 String ppwperm = pp.getWritePermission();
9413 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
9414 cpi.applicationInfo.uid, cpi.exported)
9415 == PackageManager.PERMISSION_GRANTED) {
9420 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
9425 if (!cpi.exported) {
9426 msg = "Permission Denial: opening provider " + cpi.name
9427 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9428 + ", uid=" + callingUid + ") that is not exported from uid "
9429 + cpi.applicationInfo.uid;
9431 msg = "Permission Denial: opening provider " + cpi.name
9432 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
9433 + ", uid=" + callingUid + ") requires "
9434 + cpi.readPermission + " or " + cpi.writePermission;
9441 * Returns if the ContentProvider has granted a uri to callingUid
9443 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
9444 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
9445 if (perms != null) {
9446 for (int i=perms.size()-1; i>=0; i--) {
9447 GrantUri grantUri = perms.keyAt(i);
9448 if (grantUri.sourceUserId == userId || !checkUser) {
9449 if (matchesProvider(grantUri.uri, cpi)) {
9459 * Returns true if the uri authority is one of the authorities specified in the provider.
9461 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
9462 String uriAuth = uri.getAuthority();
9463 String cpiAuth = cpi.authority;
9464 if (cpiAuth.indexOf(';') == -1) {
9465 return cpiAuth.equals(uriAuth);
9467 String[] cpiAuths = cpiAuth.split(";");
9468 int length = cpiAuths.length;
9469 for (int i = 0; i < length; i++) {
9470 if (cpiAuths[i].equals(uriAuth)) return true;
9475 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
9476 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9478 for (int i=0; i<r.conProviders.size(); i++) {
9479 ContentProviderConnection conn = r.conProviders.get(i);
9480 if (conn.provider == cpr) {
9481 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9482 "Adding provider requested by "
9483 + r.processName + " from process "
9484 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9485 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9488 conn.numStableIncs++;
9490 conn.unstableCount++;
9491 conn.numUnstableIncs++;
9496 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
9498 conn.stableCount = 1;
9499 conn.numStableIncs = 1;
9501 conn.unstableCount = 1;
9502 conn.numUnstableIncs = 1;
9504 cpr.connections.add(conn);
9505 r.conProviders.add(conn);
9506 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
9509 cpr.addExternalProcessHandleLocked(externalProcessToken);
9513 boolean decProviderCountLocked(ContentProviderConnection conn,
9514 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
9516 cpr = conn.provider;
9517 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
9518 "Removing provider requested by "
9519 + conn.client.processName + " from process "
9520 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
9521 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
9525 conn.unstableCount--;
9527 if (conn.stableCount == 0 && conn.unstableCount == 0) {
9528 cpr.connections.remove(conn);
9529 conn.client.conProviders.remove(conn);
9530 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
9531 // The client is more important than last activity -- note the time this
9532 // is happening, so we keep the old provider process around a bit as last
9533 // activity to avoid thrashing it.
9534 if (cpr.proc != null) {
9535 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
9538 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
9543 cpr.removeExternalProcessHandleLocked(externalProcessToken);
9547 private void checkTime(long startTime, String where) {
9548 long now = SystemClock.elapsedRealtime();
9549 if ((now-startTime) > 1000) {
9550 // If we are taking more than a second, log about it.
9551 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
9555 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9556 String name, IBinder token, boolean stable, int userId) {
9557 ContentProviderRecord cpr;
9558 ContentProviderConnection conn = null;
9559 ProviderInfo cpi = null;
9561 synchronized(this) {
9562 long startTime = SystemClock.elapsedRealtime();
9564 ProcessRecord r = null;
9565 if (caller != null) {
9566 r = getRecordForAppLocked(caller);
9568 throw new SecurityException(
9569 "Unable to find app for caller " + caller
9570 + " (pid=" + Binder.getCallingPid()
9571 + ") when getting content provider " + name);
9575 boolean checkCrossUser = true;
9577 checkTime(startTime, "getContentProviderImpl: getProviderByName");
9579 // First check if this content provider has been published...
9580 cpr = mProviderMap.getProviderByName(name, userId);
9581 // If that didn't work, check if it exists for user 0 and then
9582 // verify that it's a singleton provider before using it.
9583 if (cpr == null && userId != UserHandle.USER_OWNER) {
9584 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9587 if (isSingleton(cpi.processName, cpi.applicationInfo,
9588 cpi.name, cpi.flags)
9589 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9590 userId = UserHandle.USER_OWNER;
9591 checkCrossUser = false;
9599 boolean providerRunning = cpr != null;
9600 if (providerRunning) {
9603 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9604 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9606 throw new SecurityException(msg);
9608 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9610 if (r != null && cpr.canRunHere(r)) {
9611 // This provider has been published or is in the process
9612 // of being published... but it is also allowed to run
9613 // in the caller's process, so don't make a connection
9614 // and just let the caller instantiate its own instance.
9615 ContentProviderHolder holder = cpr.newHolder(null);
9616 // don't give caller the provider object, it needs
9618 holder.provider = null;
9622 final long origId = Binder.clearCallingIdentity();
9624 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9626 // In this case the provider instance already exists, so we can
9627 // return it right away.
9628 conn = incProviderCountLocked(r, cpr, token, stable);
9629 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9630 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9631 // If this is a perceptible app accessing the provider,
9632 // make sure to count it as being accessed and thus
9633 // back up on the LRU list. This is good because
9634 // content providers are often expensive to start.
9635 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9636 updateLruProcessLocked(cpr.proc, false, null);
9637 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9641 if (cpr.proc != null) {
9643 if (cpr.name.flattenToShortString().equals(
9644 "com.android.providers.calendar/.CalendarProvider2")) {
9645 Slog.v(TAG, "****************** KILLING "
9646 + cpr.name.flattenToShortString());
9647 Process.killProcess(cpr.proc.pid);
9650 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9651 boolean success = updateOomAdjLocked(cpr.proc);
9652 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
9653 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9654 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
9655 // NOTE: there is still a race here where a signal could be
9656 // pending on the process even though we managed to update its
9657 // adj level. Not sure what to do about this, but at least
9658 // the race is now smaller.
9660 // Uh oh... it looks like the provider's process
9661 // has been killed on us. We need to wait for a new
9662 // process to be started, and make sure its death
9663 // doesn't kill our process.
9664 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
9665 + " is crashing; detaching " + r);
9666 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9667 checkTime(startTime, "getContentProviderImpl: before appDied");
9668 appDiedLocked(cpr.proc);
9669 checkTime(startTime, "getContentProviderImpl: after appDied");
9671 // This wasn't the last ref our process had on
9672 // the provider... we have now been killed, bail.
9675 providerRunning = false;
9680 Binder.restoreCallingIdentity(origId);
9684 if (!providerRunning) {
9686 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9687 cpi = AppGlobals.getPackageManager().
9688 resolveContentProvider(name,
9689 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9690 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9691 } catch (RemoteException ex) {
9696 // If the provider is a singleton AND
9697 // (it's a call within the same user || the provider is a
9699 // Then allow connecting to the singleton provider
9700 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9701 cpi.name, cpi.flags)
9702 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9704 userId = UserHandle.USER_OWNER;
9706 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9707 checkTime(startTime, "getContentProviderImpl: got app info for user");
9710 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9711 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9713 throw new SecurityException(msg);
9715 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9717 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9718 && !cpi.processName.equals("system")) {
9719 // If this content provider does not run in the system
9720 // process, and the system is not yet ready to run other
9721 // processes, then fail fast instead of hanging.
9722 throw new IllegalArgumentException(
9723 "Attempt to launch content provider before system ready");
9726 // Make sure that the user who owns this provider is running. If not,
9727 // we don't want to allow it to run.
9728 if (!isUserRunningLocked(userId, false)) {
9729 Slog.w(TAG, "Unable to launch app "
9730 + cpi.applicationInfo.packageName + "/"
9731 + cpi.applicationInfo.uid + " for provider "
9732 + name + ": user " + userId + " is stopped");
9736 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9737 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9738 cpr = mProviderMap.getProviderByClass(comp, userId);
9739 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9740 final boolean firstClass = cpr == null;
9742 final long ident = Binder.clearCallingIdentity();
9744 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9745 ApplicationInfo ai =
9746 AppGlobals.getPackageManager().
9748 cpi.applicationInfo.packageName,
9749 STOCK_PM_FLAGS, userId);
9750 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9752 Slog.w(TAG, "No package info for content provider "
9756 ai = getAppInfoForUser(ai, userId);
9757 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9758 } catch (RemoteException ex) {
9759 // pm is in same process, this will never happen.
9761 Binder.restoreCallingIdentity(ident);
9765 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9767 if (r != null && cpr.canRunHere(r)) {
9768 // If this is a multiprocess provider, then just return its
9769 // info and allow the caller to instantiate it. Only do
9770 // this if the provider is the same user as the caller's
9771 // process, or can run as root (so can be in any process).
9772 return cpr.newHolder(null);
9775 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
9776 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
9777 + cpr.info.name + " callers=" + Debug.getCallers(6));
9779 // This is single process, and our app is now connecting to it.
9780 // See if we are already in the process of launching this
9782 final int N = mLaunchingProviders.size();
9784 for (i = 0; i < N; i++) {
9785 if (mLaunchingProviders.get(i) == cpr) {
9790 // If the provider is not already being launched, then get it
9793 final long origId = Binder.clearCallingIdentity();
9796 // Content provider is now in use, its package can't be stopped.
9798 checkTime(startTime, "getContentProviderImpl: before set stopped state");
9799 AppGlobals.getPackageManager().setPackageStoppedState(
9800 cpr.appInfo.packageName, false, userId);
9801 checkTime(startTime, "getContentProviderImpl: after set stopped state");
9802 } catch (RemoteException e) {
9803 } catch (IllegalArgumentException e) {
9804 Slog.w(TAG, "Failed trying to unstop package "
9805 + cpr.appInfo.packageName + ": " + e);
9808 // Use existing process if already started
9809 checkTime(startTime, "getContentProviderImpl: looking for process record");
9810 ProcessRecord proc = getProcessRecordLocked(
9811 cpi.processName, cpr.appInfo.uid, false);
9812 if (proc != null && proc.thread != null) {
9813 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
9814 "Installing in existing process " + proc);
9815 if (!proc.pubProviders.containsKey(cpi.name)) {
9816 checkTime(startTime, "getContentProviderImpl: scheduling install");
9817 proc.pubProviders.put(cpi.name, cpr);
9819 proc.thread.scheduleInstallProvider(cpi);
9820 } catch (RemoteException e) {
9824 checkTime(startTime, "getContentProviderImpl: before start process");
9825 proc = startProcessLocked(cpi.processName,
9826 cpr.appInfo, false, 0, "content provider",
9827 new ComponentName(cpi.applicationInfo.packageName,
9828 cpi.name), false, false, false);
9829 checkTime(startTime, "getContentProviderImpl: after start process");
9831 Slog.w(TAG, "Unable to launch app "
9832 + cpi.applicationInfo.packageName + "/"
9833 + cpi.applicationInfo.uid + " for provider "
9834 + name + ": process is bad");
9838 cpr.launchingApp = proc;
9839 mLaunchingProviders.add(cpr);
9841 Binder.restoreCallingIdentity(origId);
9845 checkTime(startTime, "getContentProviderImpl: updating data structures");
9847 // Make sure the provider is published (the same provider class
9848 // may be published under multiple names).
9850 mProviderMap.putProviderByClass(comp, cpr);
9853 mProviderMap.putProviderByName(name, cpr);
9854 conn = incProviderCountLocked(r, cpr, token, stable);
9856 conn.waiting = true;
9859 checkTime(startTime, "getContentProviderImpl: done!");
9862 // Wait for the provider to be published...
9863 synchronized (cpr) {
9864 while (cpr.provider == null) {
9865 if (cpr.launchingApp == null) {
9866 Slog.w(TAG, "Unable to launch app "
9867 + cpi.applicationInfo.packageName + "/"
9868 + cpi.applicationInfo.uid + " for provider "
9869 + name + ": launching app became null");
9870 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9871 UserHandle.getUserId(cpi.applicationInfo.uid),
9872 cpi.applicationInfo.packageName,
9873 cpi.applicationInfo.uid, name);
9877 if (DEBUG_MU) Slog.v(TAG_MU,
9878 "Waiting to start provider " + cpr
9879 + " launchingApp=" + cpr.launchingApp);
9881 conn.waiting = true;
9884 } catch (InterruptedException ex) {
9887 conn.waiting = false;
9892 return cpr != null ? cpr.newHolder(conn) : null;
9896 public final ContentProviderHolder getContentProvider(
9897 IApplicationThread caller, String name, int userId, boolean stable) {
9898 enforceNotIsolatedCaller("getContentProvider");
9899 if (caller == null) {
9900 String msg = "null IApplicationThread when getting content provider "
9903 throw new SecurityException(msg);
9905 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9906 // with cross-user grant.
9907 return getContentProviderImpl(caller, name, null, stable, userId);
9910 public ContentProviderHolder getContentProviderExternal(
9911 String name, int userId, IBinder token) {
9912 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9913 "Do not have permission in call getContentProviderExternal()");
9914 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9915 false, ALLOW_FULL_ONLY, "getContentProvider", null);
9916 return getContentProviderExternalUnchecked(name, token, userId);
9919 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9920 IBinder token, int userId) {
9921 return getContentProviderImpl(null, name, token, true, userId);
9925 * Drop a content provider from a ProcessRecord's bookkeeping
9927 public void removeContentProvider(IBinder connection, boolean stable) {
9928 enforceNotIsolatedCaller("removeContentProvider");
9929 long ident = Binder.clearCallingIdentity();
9931 synchronized (this) {
9932 ContentProviderConnection conn;
9934 conn = (ContentProviderConnection)connection;
9935 } catch (ClassCastException e) {
9936 String msg ="removeContentProvider: " + connection
9937 + " not a ContentProviderConnection";
9939 throw new IllegalArgumentException(msg);
9942 throw new NullPointerException("connection is null");
9944 if (decProviderCountLocked(conn, null, null, stable)) {
9945 updateOomAdjLocked();
9949 Binder.restoreCallingIdentity(ident);
9953 public void removeContentProviderExternal(String name, IBinder token) {
9954 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9955 "Do not have permission in call removeContentProviderExternal()");
9956 int userId = UserHandle.getCallingUserId();
9957 long ident = Binder.clearCallingIdentity();
9959 removeContentProviderExternalUnchecked(name, token, userId);
9961 Binder.restoreCallingIdentity(ident);
9965 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9966 synchronized (this) {
9967 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9969 //remove from mProvidersByClass
9970 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
9974 //update content provider record entry info
9975 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9976 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9977 if (localCpr.hasExternalProcessHandles()) {
9978 if (localCpr.removeExternalProcessHandleLocked(token)) {
9979 updateOomAdjLocked();
9981 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9982 + " with no external reference for token: "
9986 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9987 + " with no external references.");
9992 public final void publishContentProviders(IApplicationThread caller,
9993 List<ContentProviderHolder> providers) {
9994 if (providers == null) {
9998 enforceNotIsolatedCaller("publishContentProviders");
9999 synchronized (this) {
10000 final ProcessRecord r = getRecordForAppLocked(caller);
10001 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10003 throw new SecurityException(
10004 "Unable to find app for caller " + caller
10005 + " (pid=" + Binder.getCallingPid()
10006 + ") when publishing content providers");
10009 final long origId = Binder.clearCallingIdentity();
10011 final int N = providers.size();
10012 for (int i = 0; i < N; i++) {
10013 ContentProviderHolder src = providers.get(i);
10014 if (src == null || src.info == null || src.provider == null) {
10017 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10018 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10020 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10021 mProviderMap.putProviderByClass(comp, dst);
10022 String names[] = dst.info.authority.split(";");
10023 for (int j = 0; j < names.length; j++) {
10024 mProviderMap.putProviderByName(names[j], dst);
10027 int launchingCount = mLaunchingProviders.size();
10029 boolean wasInLaunchingProviders = false;
10030 for (j = 0; j < launchingCount; j++) {
10031 if (mLaunchingProviders.get(j) == dst) {
10032 mLaunchingProviders.remove(j);
10033 wasInLaunchingProviders = true;
10038 if (wasInLaunchingProviders) {
10039 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10041 synchronized (dst) {
10042 dst.provider = src.provider;
10046 updateOomAdjLocked(r);
10047 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10048 src.info.authority);
10052 Binder.restoreCallingIdentity(origId);
10056 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10057 ContentProviderConnection conn;
10059 conn = (ContentProviderConnection)connection;
10060 } catch (ClassCastException e) {
10061 String msg ="refContentProvider: " + connection
10062 + " not a ContentProviderConnection";
10064 throw new IllegalArgumentException(msg);
10066 if (conn == null) {
10067 throw new NullPointerException("connection is null");
10070 synchronized (this) {
10072 conn.numStableIncs += stable;
10074 stable = conn.stableCount + stable;
10076 throw new IllegalStateException("stableCount < 0: " + stable);
10079 if (unstable > 0) {
10080 conn.numUnstableIncs += unstable;
10082 unstable = conn.unstableCount + unstable;
10083 if (unstable < 0) {
10084 throw new IllegalStateException("unstableCount < 0: " + unstable);
10087 if ((stable+unstable) <= 0) {
10088 throw new IllegalStateException("ref counts can't go to zero here: stable="
10089 + stable + " unstable=" + unstable);
10091 conn.stableCount = stable;
10092 conn.unstableCount = unstable;
10097 public void unstableProviderDied(IBinder connection) {
10098 ContentProviderConnection conn;
10100 conn = (ContentProviderConnection)connection;
10101 } catch (ClassCastException e) {
10102 String msg ="refContentProvider: " + connection
10103 + " not a ContentProviderConnection";
10105 throw new IllegalArgumentException(msg);
10107 if (conn == null) {
10108 throw new NullPointerException("connection is null");
10111 // Safely retrieve the content provider associated with the connection.
10112 IContentProvider provider;
10113 synchronized (this) {
10114 provider = conn.provider.provider;
10117 if (provider == null) {
10118 // Um, yeah, we're way ahead of you.
10122 // Make sure the caller is being honest with us.
10123 if (provider.asBinder().pingBinder()) {
10124 // Er, no, still looks good to us.
10125 synchronized (this) {
10126 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10127 + " says " + conn + " died, but we don't agree");
10132 // Well look at that! It's dead!
10133 synchronized (this) {
10134 if (conn.provider.provider != provider) {
10135 // But something changed... good enough.
10139 ProcessRecord proc = conn.provider.proc;
10140 if (proc == null || proc.thread == null) {
10141 // Seems like the process is already cleaned up.
10145 // As far as we're concerned, this is just like receiving a
10146 // death notification... just a bit prematurely.
10147 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10148 + ") early provider death");
10149 final long ident = Binder.clearCallingIdentity();
10151 appDiedLocked(proc);
10153 Binder.restoreCallingIdentity(ident);
10159 public void appNotRespondingViaProvider(IBinder connection) {
10160 enforceCallingPermission(
10161 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10163 final ContentProviderConnection conn = (ContentProviderConnection) connection;
10164 if (conn == null) {
10165 Slog.w(TAG, "ContentProviderConnection is null");
10169 final ProcessRecord host = conn.provider.proc;
10170 if (host == null) {
10171 Slog.w(TAG, "Failed to find hosting ProcessRecord");
10175 final long token = Binder.clearCallingIdentity();
10177 appNotResponding(host, null, null, false, "ContentProvider not responding");
10179 Binder.restoreCallingIdentity(token);
10183 public final void installSystemProviders() {
10184 List<ProviderInfo> providers;
10185 synchronized (this) {
10186 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10187 providers = generateApplicationProvidersLocked(app);
10188 if (providers != null) {
10189 for (int i=providers.size()-1; i>=0; i--) {
10190 ProviderInfo pi = (ProviderInfo)providers.get(i);
10191 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10192 Slog.w(TAG, "Not installing system proc provider " + pi.name
10193 + ": not system .apk");
10194 providers.remove(i);
10199 if (providers != null) {
10200 mSystemThread.installSystemProviders(providers);
10203 mCoreSettingsObserver = new CoreSettingsObserver(this);
10205 //mUsageStatsService.monitorPackages();
10209 * Allows apps to retrieve the MIME type of a URI.
10210 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10211 * users, then it does not need permission to access the ContentProvider.
10212 * Either, it needs cross-user uri grants.
10214 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
10216 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
10217 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
10219 public String getProviderMimeType(Uri uri, int userId) {
10220 enforceNotIsolatedCaller("getProviderMimeType");
10221 final String name = uri.getAuthority();
10222 int callingUid = Binder.getCallingUid();
10223 int callingPid = Binder.getCallingPid();
10225 boolean clearedIdentity = false;
10226 userId = unsafeConvertIncomingUser(userId);
10227 if (canClearIdentity(callingPid, callingUid, userId)) {
10228 clearedIdentity = true;
10229 ident = Binder.clearCallingIdentity();
10231 ContentProviderHolder holder = null;
10233 holder = getContentProviderExternalUnchecked(name, null, userId);
10234 if (holder != null) {
10235 return holder.provider.getType(uri);
10237 } catch (RemoteException e) {
10238 Log.w(TAG, "Content provider dead retrieving " + uri, e);
10241 // We need to clear the identity to call removeContentProviderExternalUnchecked
10242 if (!clearedIdentity) {
10243 ident = Binder.clearCallingIdentity();
10246 if (holder != null) {
10247 removeContentProviderExternalUnchecked(name, null, userId);
10250 Binder.restoreCallingIdentity(ident);
10257 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
10258 if (UserHandle.getUserId(callingUid) == userId) {
10261 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
10262 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
10263 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
10264 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
10270 // =========================================================
10271 // GLOBAL MANAGEMENT
10272 // =========================================================
10274 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
10275 boolean isolated, int isolatedUid) {
10276 String proc = customProcess != null ? customProcess : info.processName;
10277 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10278 final int userId = UserHandle.getUserId(info.uid);
10279 int uid = info.uid;
10281 if (isolatedUid == 0) {
10282 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
10284 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
10285 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
10286 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
10288 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
10289 mNextIsolatedProcessUid++;
10290 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
10291 // No process for this uid, use it.
10295 if (stepsLeft <= 0) {
10300 // Special case for startIsolatedProcess (internal only), where
10301 // the uid of the isolated process is specified by the caller.
10305 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
10306 if (!mBooted && !mBooting
10307 && userId == UserHandle.USER_OWNER
10308 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10309 r.persistent = true;
10311 addProcessNameLocked(r);
10315 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
10316 String abiOverride) {
10319 app = getProcessRecordLocked(info.processName, info.uid, true);
10325 app = newProcessRecordLocked(info, null, isolated, 0);
10326 updateLruProcessLocked(app, false, null);
10327 updateOomAdjLocked();
10330 // This package really, really can not be stopped.
10332 AppGlobals.getPackageManager().setPackageStoppedState(
10333 info.packageName, false, UserHandle.getUserId(app.uid));
10334 } catch (RemoteException e) {
10335 } catch (IllegalArgumentException e) {
10336 Slog.w(TAG, "Failed trying to unstop package "
10337 + info.packageName + ": " + e);
10340 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
10341 app.persistent = true;
10342 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
10344 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
10345 mPersistentStartingProcesses.add(app);
10346 startProcessLocked(app, "added application", app.processName, abiOverride,
10347 null /* entryPoint */, null /* entryPointArgs */);
10353 public void unhandledBack() {
10354 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
10355 "unhandledBack()");
10357 synchronized(this) {
10358 final long origId = Binder.clearCallingIdentity();
10360 getFocusedStack().unhandledBackLocked();
10362 Binder.restoreCallingIdentity(origId);
10367 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
10368 enforceNotIsolatedCaller("openContentUri");
10369 final int userId = UserHandle.getCallingUserId();
10370 String name = uri.getAuthority();
10371 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
10372 ParcelFileDescriptor pfd = null;
10374 // We record the binder invoker's uid in thread-local storage before
10375 // going to the content provider to open the file. Later, in the code
10376 // that handles all permissions checks, we look for this uid and use
10377 // that rather than the Activity Manager's own uid. The effect is that
10378 // we do the check against the caller's permissions even though it looks
10379 // to the content provider like the Activity Manager itself is making
10381 Binder token = new Binder();
10382 sCallerIdentity.set(new Identity(
10383 token, Binder.getCallingPid(), Binder.getCallingUid()));
10385 pfd = cph.provider.openFile(null, uri, "r", null, token);
10386 } catch (FileNotFoundException e) {
10387 // do nothing; pfd will be returned null
10389 // Ensure that whatever happens, we clean up the identity state
10390 sCallerIdentity.remove();
10391 // Ensure we're done with the provider.
10392 removeContentProviderExternalUnchecked(name, null, userId);
10395 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
10400 // Actually is sleeping or shutting down or whatever else in the future
10401 // is an inactive state.
10402 public boolean isSleepingOrShuttingDown() {
10403 return isSleeping() || mShuttingDown;
10406 public boolean isSleeping() {
10410 void onWakefulnessChanged(int wakefulness) {
10411 synchronized(this) {
10412 mWakefulness = wakefulness;
10413 updateSleepIfNeededLocked();
10417 void finishRunningVoiceLocked() {
10418 if (mRunningVoice != null) {
10419 mRunningVoice = null;
10420 mVoiceWakeLock.release();
10421 updateSleepIfNeededLocked();
10425 void startTimeTrackingFocusedActivityLocked() {
10426 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
10427 mCurAppTimeTracker.start(mFocusedActivity.packageName);
10431 void updateSleepIfNeededLocked() {
10432 if (mSleeping && !shouldSleepLocked()) {
10434 startTimeTrackingFocusedActivityLocked();
10435 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
10436 mStackSupervisor.comeOutOfSleepIfNeededLocked();
10437 updateOomAdjLocked();
10438 } else if (!mSleeping && shouldSleepLocked()) {
10440 if (mCurAppTimeTracker != null) {
10441 mCurAppTimeTracker.stop();
10443 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
10444 mStackSupervisor.goingToSleepLocked();
10445 updateOomAdjLocked();
10447 // Initialize the wake times of all processes.
10448 checkExcessivePowerUsageLocked(false);
10449 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10450 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
10451 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
10455 private boolean shouldSleepLocked() {
10456 // Resume applications while running a voice interactor.
10457 if (mRunningVoice != null) {
10461 // TODO: Transform the lock screen state into a sleep token instead.
10462 switch (mWakefulness) {
10463 case PowerManagerInternal.WAKEFULNESS_AWAKE:
10464 case PowerManagerInternal.WAKEFULNESS_DREAMING:
10465 case PowerManagerInternal.WAKEFULNESS_DOZING:
10466 // Pause applications whenever the lock screen is shown or any sleep
10467 // tokens have been acquired.
10468 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
10469 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
10471 // If we're asleep then pause applications unconditionally.
10476 /** Pokes the task persister. */
10477 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
10478 if (task != null && task.stack != null && task.stack.isHomeStack()) {
10479 // Never persist the home stack.
10482 mTaskPersister.wakeup(task, flush);
10485 /** Notifies all listeners when the task stack has changed. */
10486 void notifyTaskStackChangedLocked() {
10487 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10488 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
10489 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
10493 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
10494 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
10498 public boolean shutdown(int timeout) {
10499 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
10500 != PackageManager.PERMISSION_GRANTED) {
10501 throw new SecurityException("Requires permission "
10502 + android.Manifest.permission.SHUTDOWN);
10505 boolean timedout = false;
10507 synchronized(this) {
10508 mShuttingDown = true;
10509 updateEventDispatchingLocked();
10510 timedout = mStackSupervisor.shutdownLocked(timeout);
10513 mAppOpsService.shutdown();
10514 if (mUsageStatsService != null) {
10515 mUsageStatsService.prepareShutdown();
10517 mBatteryStatsService.shutdown();
10518 synchronized (this) {
10519 mProcessStats.shutdownLocked();
10520 notifyTaskPersisterLocked(null, true);
10526 public final void activitySlept(IBinder token) {
10527 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
10529 final long origId = Binder.clearCallingIdentity();
10531 synchronized (this) {
10532 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10534 mStackSupervisor.activitySleptLocked(r);
10538 Binder.restoreCallingIdentity(origId);
10541 private String lockScreenShownToString() {
10542 switch (mLockScreenShown) {
10543 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
10544 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
10545 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
10546 default: return "Unknown=" + mLockScreenShown;
10550 void logLockScreen(String msg) {
10551 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
10552 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
10553 + PowerManagerInternal.wakefulnessToString(mWakefulness)
10554 + " mSleeping=" + mSleeping);
10557 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
10558 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
10559 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
10560 boolean wasRunningVoice = mRunningVoice != null;
10561 mRunningVoice = session;
10562 if (!wasRunningVoice) {
10563 mVoiceWakeLock.acquire();
10564 updateSleepIfNeededLocked();
10569 private void updateEventDispatchingLocked() {
10570 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
10573 public void setLockScreenShown(boolean shown) {
10574 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
10575 != PackageManager.PERMISSION_GRANTED) {
10576 throw new SecurityException("Requires permission "
10577 + android.Manifest.permission.DEVICE_POWER);
10580 synchronized(this) {
10581 long ident = Binder.clearCallingIdentity();
10583 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
10584 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
10585 updateSleepIfNeededLocked();
10587 Binder.restoreCallingIdentity(ident);
10593 public void stopAppSwitches() {
10594 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10595 != PackageManager.PERMISSION_GRANTED) {
10596 throw new SecurityException("Requires permission "
10597 + android.Manifest.permission.STOP_APP_SWITCHES);
10600 synchronized(this) {
10601 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
10602 + APP_SWITCH_DELAY_TIME;
10603 mDidAppSwitch = false;
10604 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10605 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
10606 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
10610 public void resumeAppSwitches() {
10611 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
10612 != PackageManager.PERMISSION_GRANTED) {
10613 throw new SecurityException("Requires permission "
10614 + android.Manifest.permission.STOP_APP_SWITCHES);
10617 synchronized(this) {
10618 // Note that we don't execute any pending app switches... we will
10619 // let those wait until either the timeout, or the next start
10620 // activity request.
10621 mAppSwitchesAllowedTime = 0;
10625 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
10626 int callingPid, int callingUid, String name) {
10627 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
10631 int perm = checkComponentPermission(
10632 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
10633 sourceUid, -1, true);
10634 if (perm == PackageManager.PERMISSION_GRANTED) {
10638 // If the actual IPC caller is different from the logical source, then
10639 // also see if they are allowed to control app switches.
10640 if (callingUid != -1 && callingUid != sourceUid) {
10641 perm = checkComponentPermission(
10642 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
10643 callingUid, -1, true);
10644 if (perm == PackageManager.PERMISSION_GRANTED) {
10649 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
10653 public void setDebugApp(String packageName, boolean waitForDebugger,
10654 boolean persistent) {
10655 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10658 long ident = Binder.clearCallingIdentity();
10660 // Note that this is not really thread safe if there are multiple
10661 // callers into it at the same time, but that's not a situation we
10664 final ContentResolver resolver = mContext.getContentResolver();
10665 Settings.Global.putString(
10666 resolver, Settings.Global.DEBUG_APP,
10668 Settings.Global.putInt(
10669 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10670 waitForDebugger ? 1 : 0);
10673 synchronized (this) {
10675 mOrigDebugApp = mDebugApp;
10676 mOrigWaitForDebugger = mWaitForDebugger;
10678 mDebugApp = packageName;
10679 mWaitForDebugger = waitForDebugger;
10680 mDebugTransient = !persistent;
10681 if (packageName != null) {
10682 forceStopPackageLocked(packageName, -1, false, false, true, true,
10683 false, UserHandle.USER_ALL, "set debug app");
10687 Binder.restoreCallingIdentity(ident);
10691 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10692 synchronized (this) {
10693 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10694 if (!isDebuggable) {
10695 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10696 throw new SecurityException("Process not debuggable: " + app.packageName);
10700 mOpenGlTraceApp = processName;
10704 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10705 synchronized (this) {
10706 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10707 if (!isDebuggable) {
10708 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10709 throw new SecurityException("Process not debuggable: " + app.packageName);
10712 mProfileApp = processName;
10713 mProfileFile = profilerInfo.profileFile;
10714 if (mProfileFd != null) {
10716 mProfileFd.close();
10717 } catch (IOException e) {
10721 mProfileFd = profilerInfo.profileFd;
10722 mSamplingInterval = profilerInfo.samplingInterval;
10723 mAutoStopProfiler = profilerInfo.autoStopProfiler;
10729 public void setAlwaysFinish(boolean enabled) {
10730 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10731 "setAlwaysFinish()");
10733 Settings.Global.putInt(
10734 mContext.getContentResolver(),
10735 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10737 synchronized (this) {
10738 mAlwaysFinishActivities = enabled;
10743 public void setActivityController(IActivityController controller) {
10744 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10745 "setActivityController()");
10746 synchronized (this) {
10747 mController = controller;
10748 Watchdog.getInstance().setActivityController(controller);
10753 public void setUserIsMonkey(boolean userIsMonkey) {
10754 synchronized (this) {
10755 synchronized (mPidsSelfLocked) {
10756 final int callingPid = Binder.getCallingPid();
10757 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10758 if (precessRecord == null) {
10759 throw new SecurityException("Unknown process: " + callingPid);
10761 if (precessRecord.instrumentationUiAutomationConnection == null) {
10762 throw new SecurityException("Only an instrumentation process "
10763 + "with a UiAutomation can call setUserIsMonkey");
10766 mUserIsMonkey = userIsMonkey;
10771 public boolean isUserAMonkey() {
10772 synchronized (this) {
10773 // If there is a controller also implies the user is a monkey.
10774 return (mUserIsMonkey || mController != null);
10778 public void requestBugReport() {
10779 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10780 SystemProperties.set("ctl.start", "bugreport");
10783 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10784 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10787 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10788 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10789 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10791 return KEY_DISPATCHING_TIMEOUT;
10795 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10796 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10797 != PackageManager.PERMISSION_GRANTED) {
10798 throw new SecurityException("Requires permission "
10799 + android.Manifest.permission.FILTER_EVENTS);
10801 ProcessRecord proc;
10803 synchronized (this) {
10804 synchronized (mPidsSelfLocked) {
10805 proc = mPidsSelfLocked.get(pid);
10807 timeout = getInputDispatchingTimeoutLocked(proc);
10810 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10818 * Handle input dispatching timeouts.
10819 * Returns whether input dispatching should be aborted or not.
10821 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10822 final ActivityRecord activity, final ActivityRecord parent,
10823 final boolean aboveSystem, String reason) {
10824 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10825 != PackageManager.PERMISSION_GRANTED) {
10826 throw new SecurityException("Requires permission "
10827 + android.Manifest.permission.FILTER_EVENTS);
10830 final String annotation;
10831 if (reason == null) {
10832 annotation = "Input dispatching timed out";
10834 annotation = "Input dispatching timed out (" + reason + ")";
10837 if (proc != null) {
10838 synchronized (this) {
10839 if (proc.debugging) {
10844 // Give more time since we were dexopting.
10845 mDidDexOpt = false;
10849 if (proc.instrumentationClass != null) {
10850 Bundle info = new Bundle();
10851 info.putString("shortMsg", "keyDispatchingTimedOut");
10852 info.putString("longMsg", annotation);
10853 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10857 mHandler.post(new Runnable() {
10859 public void run() {
10860 appNotResponding(proc, activity, parent, aboveSystem, annotation);
10869 public Bundle getAssistContextExtras(int requestType) {
10870 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
10871 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
10875 synchronized (pae) {
10876 while (!pae.haveResult) {
10879 } catch (InterruptedException e) {
10883 synchronized (this) {
10884 buildAssistBundleLocked(pae, pae.result);
10885 mPendingAssistExtras.remove(pae);
10886 mUiHandler.removeCallbacks(pae);
10892 public boolean isAssistDataAllowedOnCurrentActivity() {
10893 int userId = mCurrentUserId;
10894 synchronized (this) {
10895 ActivityRecord activity = getFocusedStack().topActivity();
10896 if (activity == null) {
10899 userId = activity.userId;
10901 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
10902 Context.DEVICE_POLICY_SERVICE);
10903 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
10907 public boolean showAssistFromActivity(IBinder token, Bundle args) {
10908 long ident = Binder.clearCallingIdentity();
10910 synchronized (this) {
10911 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
10912 ActivityRecord top = getFocusedStack().topActivity();
10913 if (top != caller) {
10914 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10915 + " is not current top " + top);
10918 if (!top.nowVisible) {
10919 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
10920 + " is not visible");
10924 AssistUtils utils = new AssistUtils(mContext);
10925 return utils.showSessionForActiveService(args,
10926 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
10928 Binder.restoreCallingIdentity(ident);
10933 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
10934 IBinder activityToken) {
10935 return enqueueAssistContext(requestType, null, null, receiver, activityToken,
10936 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
10939 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
10940 IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
10942 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10943 "enqueueAssistContext()");
10944 synchronized (this) {
10945 ActivityRecord activity = getFocusedStack().topActivity();
10946 if (activity == null) {
10947 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
10950 if (activity.app == null || activity.app.thread == null) {
10951 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10954 if (activityToken != null) {
10955 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
10956 if (activity != caller) {
10957 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
10958 + " is not current top " + activity);
10962 PendingAssistExtras pae;
10963 Bundle extras = new Bundle();
10964 if (args != null) {
10965 extras.putAll(args);
10967 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10968 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
10969 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
10971 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10973 mPendingAssistExtras.add(pae);
10974 mUiHandler.postDelayed(pae, timeout);
10975 } catch (RemoteException e) {
10976 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10983 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
10984 IResultReceiver receiver;
10985 synchronized (this) {
10986 mPendingAssistExtras.remove(pae);
10987 receiver = pae.receiver;
10989 if (receiver != null) {
10990 // Caller wants result sent back to them.
10992 pae.receiver.send(0, null);
10993 } catch (RemoteException e) {
10998 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
10999 if (result != null) {
11000 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11002 if (pae.hint != null) {
11003 pae.extras.putBoolean(pae.hint, true);
11007 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11008 AssistContent content, Uri referrer) {
11009 PendingAssistExtras pae = (PendingAssistExtras)token;
11010 synchronized (pae) {
11011 pae.result = extras;
11012 pae.structure = structure;
11013 pae.content = content;
11014 if (referrer != null) {
11015 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11017 pae.haveResult = true;
11019 if (pae.intent == null && pae.receiver == null) {
11020 // Caller is just waiting for the result.
11025 // We are now ready to launch the assist activity.
11026 IResultReceiver sendReceiver = null;
11027 Bundle sendBundle = null;
11028 synchronized (this) {
11029 buildAssistBundleLocked(pae, extras);
11030 boolean exists = mPendingAssistExtras.remove(pae);
11031 mUiHandler.removeCallbacks(pae);
11036 if ((sendReceiver=pae.receiver) != null) {
11037 // Caller wants result sent back to them.
11038 sendBundle = new Bundle();
11039 sendBundle.putBundle("data", pae.extras);
11040 sendBundle.putParcelable("structure", pae.structure);
11041 sendBundle.putParcelable("content", pae.content);
11044 if (sendReceiver != null) {
11046 sendReceiver.send(0, sendBundle);
11047 } catch (RemoteException e) {
11052 long ident = Binder.clearCallingIdentity();
11054 pae.intent.replaceExtras(pae.extras);
11055 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11056 | Intent.FLAG_ACTIVITY_SINGLE_TOP
11057 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11058 closeSystemDialogs("assist");
11060 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11061 } catch (ActivityNotFoundException e) {
11062 Slog.w(TAG, "No activity to handle assist action.", e);
11065 Binder.restoreCallingIdentity(ident);
11069 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11071 return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11072 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11075 public void registerProcessObserver(IProcessObserver observer) {
11076 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11077 "registerProcessObserver()");
11078 synchronized (this) {
11079 mProcessObservers.register(observer);
11084 public void unregisterProcessObserver(IProcessObserver observer) {
11085 synchronized (this) {
11086 mProcessObservers.unregister(observer);
11090 public void registerUidObserver(IUidObserver observer) {
11091 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11092 "registerUidObserver()");
11093 synchronized (this) {
11094 mUidObservers.register(observer);
11099 public void unregisterUidObserver(IUidObserver observer) {
11100 synchronized (this) {
11101 mUidObservers.unregister(observer);
11106 public boolean convertFromTranslucent(IBinder token) {
11107 final long origId = Binder.clearCallingIdentity();
11109 synchronized (this) {
11110 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11114 final boolean translucentChanged = r.changeWindowTranslucency(true);
11115 if (translucentChanged) {
11116 r.task.stack.releaseBackgroundResources(r);
11117 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11119 mWindowManager.setAppFullscreen(token, true);
11120 return translucentChanged;
11123 Binder.restoreCallingIdentity(origId);
11128 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
11129 final long origId = Binder.clearCallingIdentity();
11131 synchronized (this) {
11132 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11136 int index = r.task.mActivities.lastIndexOf(r);
11138 ActivityRecord under = r.task.mActivities.get(index - 1);
11139 under.returningOptions = options;
11141 final boolean translucentChanged = r.changeWindowTranslucency(false);
11142 if (translucentChanged) {
11143 r.task.stack.convertActivityToTranslucent(r);
11145 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
11146 mWindowManager.setAppFullscreen(token, false);
11147 return translucentChanged;
11150 Binder.restoreCallingIdentity(origId);
11155 public boolean requestVisibleBehind(IBinder token, boolean visible) {
11156 final long origId = Binder.clearCallingIdentity();
11158 synchronized (this) {
11159 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11161 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
11166 Binder.restoreCallingIdentity(origId);
11171 public boolean isBackgroundVisibleBehind(IBinder token) {
11172 final long origId = Binder.clearCallingIdentity();
11174 synchronized (this) {
11175 final ActivityStack stack = ActivityRecord.getStackLocked(token);
11176 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
11177 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
11178 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
11182 Binder.restoreCallingIdentity(origId);
11187 public ActivityOptions getActivityOptions(IBinder token) {
11188 final long origId = Binder.clearCallingIdentity();
11190 synchronized (this) {
11191 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11193 final ActivityOptions activityOptions = r.pendingOptions;
11194 r.pendingOptions = null;
11195 return activityOptions;
11200 Binder.restoreCallingIdentity(origId);
11205 public void setImmersive(IBinder token, boolean immersive) {
11206 synchronized(this) {
11207 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11209 throw new IllegalArgumentException();
11211 r.immersive = immersive;
11213 // update associated state if we're frontmost
11214 if (r == mFocusedActivity) {
11215 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
11216 applyUpdateLockStateLocked(r);
11222 public boolean isImmersive(IBinder token) {
11223 synchronized (this) {
11224 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11226 throw new IllegalArgumentException();
11228 return r.immersive;
11232 public boolean isTopActivityImmersive() {
11233 enforceNotIsolatedCaller("startActivity");
11234 synchronized (this) {
11235 ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
11236 return (r != null) ? r.immersive : false;
11241 public boolean isTopOfTask(IBinder token) {
11242 synchronized (this) {
11243 ActivityRecord r = ActivityRecord.isInStackLocked(token);
11245 throw new IllegalArgumentException();
11247 return r.task.getTopActivity() == r;
11251 public final void enterSafeMode() {
11252 synchronized(this) {
11253 // It only makes sense to do this before the system is ready
11254 // and started launching other packages.
11255 if (!mSystemReady) {
11257 AppGlobals.getPackageManager().enterSafeMode();
11258 } catch (RemoteException e) {
11266 public final void showSafeModeOverlay() {
11267 View v = LayoutInflater.from(mContext).inflate(
11268 com.android.internal.R.layout.safe_mode, null);
11269 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
11270 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
11271 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
11272 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
11273 lp.gravity = Gravity.BOTTOM | Gravity.START;
11274 lp.format = v.getBackground().getOpacity();
11275 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
11276 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
11277 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
11278 ((WindowManager)mContext.getSystemService(
11279 Context.WINDOW_SERVICE)).addView(v, lp);
11282 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
11283 if (!(sender instanceof PendingIntentRecord)) {
11286 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11287 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11288 synchronized (stats) {
11289 if (mBatteryStatsService.isOnBattery()) {
11290 mBatteryStatsService.enforceCallingPermission();
11291 int MY_UID = Binder.getCallingUid();
11292 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11293 BatteryStatsImpl.Uid.Pkg pkg =
11294 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
11295 sourcePkg != null ? sourcePkg : rec.key.packageName);
11296 pkg.noteWakeupAlarmLocked(tag);
11301 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
11302 if (!(sender instanceof PendingIntentRecord)) {
11305 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11306 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11307 synchronized (stats) {
11308 mBatteryStatsService.enforceCallingPermission();
11309 int MY_UID = Binder.getCallingUid();
11310 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11311 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
11315 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
11316 if (!(sender instanceof PendingIntentRecord)) {
11319 final PendingIntentRecord rec = (PendingIntentRecord)sender;
11320 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11321 synchronized (stats) {
11322 mBatteryStatsService.enforceCallingPermission();
11323 int MY_UID = Binder.getCallingUid();
11324 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
11325 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
11329 public boolean killPids(int[] pids, String pReason, boolean secure) {
11330 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11331 throw new SecurityException("killPids only available to the system");
11333 String reason = (pReason == null) ? "Unknown" : pReason;
11334 // XXX Note: don't acquire main activity lock here, because the window
11335 // manager calls in with its locks held.
11337 boolean killed = false;
11338 synchronized (mPidsSelfLocked) {
11339 int[] types = new int[pids.length];
11341 for (int i=0; i<pids.length; i++) {
11342 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11343 if (proc != null) {
11344 int type = proc.setAdj;
11346 if (type > worstType) {
11352 // If the worst oom_adj is somewhere in the cached proc LRU range,
11353 // then constrain it so we will kill all cached procs.
11354 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
11355 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
11356 worstType = ProcessList.CACHED_APP_MIN_ADJ;
11359 // If this is not a secure call, don't let it kill processes that
11361 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
11362 worstType = ProcessList.SERVICE_ADJ;
11365 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
11366 for (int i=0; i<pids.length; i++) {
11367 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
11368 if (proc == null) {
11371 int adj = proc.setAdj;
11372 if (adj >= worstType && !proc.killedByAm) {
11373 proc.kill(reason, true);
11382 public void killUid(int appId, int userId, String reason) {
11383 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
11384 synchronized (this) {
11385 final long identity = Binder.clearCallingIdentity();
11387 killPackageProcessesLocked(null, appId, userId,
11388 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
11389 reason != null ? reason : "kill uid");
11391 Binder.restoreCallingIdentity(identity);
11397 public boolean killProcessesBelowForeground(String reason) {
11398 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11399 throw new SecurityException("killProcessesBelowForeground() only available to system");
11402 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
11405 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
11406 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
11407 throw new SecurityException("killProcessesBelowAdj() only available to system");
11410 boolean killed = false;
11411 synchronized (mPidsSelfLocked) {
11412 final int size = mPidsSelfLocked.size();
11413 for (int i = 0; i < size; i++) {
11414 final int pid = mPidsSelfLocked.keyAt(i);
11415 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11416 if (proc == null) continue;
11418 final int adj = proc.setAdj;
11419 if (adj > belowAdj && !proc.killedByAm) {
11420 proc.kill(reason, true);
11429 public void hang(final IBinder who, boolean allowRestart) {
11430 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11431 != PackageManager.PERMISSION_GRANTED) {
11432 throw new SecurityException("Requires permission "
11433 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11436 final IBinder.DeathRecipient death = new DeathRecipient() {
11438 public void binderDied() {
11439 synchronized (this) {
11446 who.linkToDeath(death, 0);
11447 } catch (RemoteException e) {
11448 Slog.w(TAG, "hang: given caller IBinder is already dead.");
11452 synchronized (this) {
11453 Watchdog.getInstance().setAllowRestart(allowRestart);
11454 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
11455 synchronized (death) {
11456 while (who.isBinderAlive()) {
11459 } catch (InterruptedException e) {
11463 Watchdog.getInstance().setAllowRestart(true);
11468 public void restart() {
11469 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11470 != PackageManager.PERMISSION_GRANTED) {
11471 throw new SecurityException("Requires permission "
11472 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11475 Log.i(TAG, "Sending shutdown broadcast...");
11477 BroadcastReceiver br = new BroadcastReceiver() {
11478 @Override public void onReceive(Context context, Intent intent) {
11479 // Now the broadcast is done, finish up the low-level shutdown.
11480 Log.i(TAG, "Shutting down activity manager...");
11482 Log.i(TAG, "Shutdown complete, restarting!");
11483 Process.killProcess(Process.myPid());
11488 // First send the high-level shut down broadcast.
11489 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
11490 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
11491 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
11492 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
11493 mContext.sendOrderedBroadcastAsUser(intent,
11494 UserHandle.ALL, null, br, mHandler, 0, null, null);
11496 br.onReceive(mContext, intent);
11499 private long getLowRamTimeSinceIdle(long now) {
11500 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
11504 public void performIdleMaintenance() {
11505 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
11506 != PackageManager.PERMISSION_GRANTED) {
11507 throw new SecurityException("Requires permission "
11508 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
11511 synchronized (this) {
11512 final long now = SystemClock.uptimeMillis();
11513 final long timeSinceLastIdle = now - mLastIdleTime;
11514 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
11515 mLastIdleTime = now;
11516 mLowRamTimeSinceLastIdle = 0;
11517 if (mLowRamStartTime != 0) {
11518 mLowRamStartTime = now;
11521 StringBuilder sb = new StringBuilder(128);
11522 sb.append("Idle maintenance over ");
11523 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11524 sb.append(" low RAM for ");
11525 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11526 Slog.i(TAG, sb.toString());
11528 // If at least 1/3 of our time since the last idle period has been spent
11529 // with RAM low, then we want to kill processes.
11530 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
11532 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11533 ProcessRecord proc = mLruProcesses.get(i);
11534 if (proc.notCachedSinceIdle) {
11535 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
11536 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
11537 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
11538 if (doKilling && proc.initialIdlePss != 0
11539 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
11540 sb = new StringBuilder(128);
11542 sb.append(proc.processName);
11543 sb.append(" in idle maint: pss=");
11544 sb.append(proc.lastPss);
11545 sb.append(", initialPss=");
11546 sb.append(proc.initialIdlePss);
11547 sb.append(", period=");
11548 TimeUtils.formatDuration(timeSinceLastIdle, sb);
11549 sb.append(", lowRamPeriod=");
11550 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
11551 Slog.wtfQuiet(TAG, sb.toString());
11552 proc.kill("idle maint (pss " + proc.lastPss
11553 + " from " + proc.initialIdlePss + ")", true);
11556 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
11557 proc.notCachedSinceIdle = true;
11558 proc.initialIdlePss = 0;
11559 proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
11560 mTestPssMode, isSleeping(), now);
11564 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
11565 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
11569 private void retrieveSettings() {
11570 final ContentResolver resolver = mContext.getContentResolver();
11571 String debugApp = Settings.Global.getString(
11572 resolver, Settings.Global.DEBUG_APP);
11573 boolean waitForDebugger = Settings.Global.getInt(
11574 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
11575 boolean alwaysFinishActivities = Settings.Global.getInt(
11576 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
11577 boolean forceRtl = Settings.Global.getInt(
11578 resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
11579 // Transfer any global setting for forcing RTL layout, into a System Property
11580 SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
11582 Configuration configuration = new Configuration();
11583 Settings.System.getConfiguration(resolver, configuration);
11585 // This will take care of setting the correct layout direction flags
11586 configuration.setLayoutDirection(configuration.locale);
11589 synchronized (this) {
11590 mDebugApp = mOrigDebugApp = debugApp;
11591 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
11592 mAlwaysFinishActivities = alwaysFinishActivities;
11593 // This happens before any activities are started, so we can
11594 // change mConfiguration in-place.
11595 updateConfigurationLocked(configuration, null, false, true);
11596 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
11597 "Initial config: " + mConfiguration);
11601 /** Loads resources after the current configuration has been set. */
11602 private void loadResourcesOnSystemReady() {
11603 final Resources res = mContext.getResources();
11604 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
11605 mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
11606 mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
11609 public boolean testIsSystemReady() {
11610 // no need to synchronize(this) just to read & return the value
11611 return mSystemReady;
11614 private static File getCalledPreBootReceiversFile() {
11615 File dataDir = Environment.getDataDirectory();
11616 File systemDir = new File(dataDir, "system");
11617 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
11621 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
11622 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
11623 File file = getCalledPreBootReceiversFile();
11624 FileInputStream fis = null;
11626 fis = new FileInputStream(file);
11627 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
11628 int fvers = dis.readInt();
11629 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
11630 String vers = dis.readUTF();
11631 String codename = dis.readUTF();
11632 String build = dis.readUTF();
11633 if (android.os.Build.VERSION.RELEASE.equals(vers)
11634 && android.os.Build.VERSION.CODENAME.equals(codename)
11635 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
11636 int num = dis.readInt();
11639 String pkg = dis.readUTF();
11640 String cls = dis.readUTF();
11641 lastDoneReceivers.add(new ComponentName(pkg, cls));
11645 } catch (FileNotFoundException e) {
11646 } catch (IOException e) {
11647 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
11652 } catch (IOException e) {
11656 return lastDoneReceivers;
11659 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
11660 File file = getCalledPreBootReceiversFile();
11661 FileOutputStream fos = null;
11662 DataOutputStream dos = null;
11664 fos = new FileOutputStream(file);
11665 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
11666 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
11667 dos.writeUTF(android.os.Build.VERSION.RELEASE);
11668 dos.writeUTF(android.os.Build.VERSION.CODENAME);
11669 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
11670 dos.writeInt(list.size());
11671 for (int i=0; i<list.size(); i++) {
11672 dos.writeUTF(list.get(i).getPackageName());
11673 dos.writeUTF(list.get(i).getClassName());
11675 } catch (IOException e) {
11676 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
11679 FileUtils.sync(fos);
11683 } catch (IOException e) {
11684 // TODO Auto-generated catch block
11685 e.printStackTrace();
11691 final class PreBootContinuation extends IIntentReceiver.Stub {
11692 final Intent intent;
11693 final Runnable onFinishCallback;
11694 final ArrayList<ComponentName> doneReceivers;
11695 final List<ResolveInfo> ris;
11701 PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
11702 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
11704 onFinishCallback = _onFinishCallback;
11705 doneReceivers = _doneReceivers;
11711 if (lastRi != curRi) {
11712 ActivityInfo ai = ris.get(curRi).activityInfo;
11713 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11714 intent.setComponent(comp);
11715 doneReceivers.add(comp);
11717 CharSequence label = ai.loadLabel(mContext.getPackageManager());
11718 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
11720 Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
11721 + " for user " + users[curUser]);
11722 EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
11723 broadcastIntentLocked(null, null, intent, null, this,
11724 0, null, null, null, AppOpsManager.OP_NONE,
11725 null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
11728 public void performReceive(Intent intent, int resultCode,
11729 String data, Bundle extras, boolean ordered,
11730 boolean sticky, int sendingUser) {
11732 if (curUser >= users.length) {
11735 if (curRi >= ris.size()) {
11736 // All done sending broadcasts!
11737 if (onFinishCallback != null) {
11738 // The raw IIntentReceiver interface is called
11739 // with the AM lock held, so redispatch to
11740 // execute our code without the lock.
11741 mHandler.post(onFinishCallback);
11750 private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
11751 ArrayList<ComponentName> doneReceivers, int userId) {
11752 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
11753 List<ResolveInfo> ris = null;
11755 ris = AppGlobals.getPackageManager().queryIntentReceivers(
11756 intent, null, 0, userId);
11757 } catch (RemoteException e) {
11762 for (int i=ris.size()-1; i>=0; i--) {
11763 if ((ris.get(i).activityInfo.applicationInfo.flags
11764 &ApplicationInfo.FLAG_SYSTEM) == 0) {
11768 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
11770 // For User 0, load the version number. When delivering to a new user, deliver
11771 // to all receivers.
11772 if (userId == UserHandle.USER_OWNER) {
11773 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
11774 for (int i=0; i<ris.size(); i++) {
11775 ActivityInfo ai = ris.get(i).activityInfo;
11776 ComponentName comp = new ComponentName(ai.packageName, ai.name);
11777 if (lastDoneReceivers.contains(comp)) {
11778 // We already did the pre boot receiver for this app with the current
11779 // platform version, so don't do it again...
11782 // ...however, do keep it as one that has been done, so we don't
11783 // forget about it when rewriting the file of last done receivers.
11784 doneReceivers.add(comp);
11789 if (ris.size() <= 0) {
11793 // If primary user, send broadcast to all available users, else just to userId
11794 final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
11795 : new int[] { userId };
11796 if (users.length <= 0) {
11800 PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
11806 public void systemReady(final Runnable goingCallback) {
11807 synchronized(this) {
11808 if (mSystemReady) {
11809 // If we're done calling all the receivers, run the next "boot phase" passed in
11810 // by the SystemServer
11811 if (goingCallback != null) {
11812 goingCallback.run();
11817 mLocalDeviceIdleController
11818 = LocalServices.getService(DeviceIdleController.LocalService.class);
11820 // Make sure we have the current profile info, since it is needed for
11821 // security checks.
11822 updateCurrentProfileIdsLocked();
11824 mRecentTasks.clear();
11825 mRecentTasks.addAll(mTaskPersister.restoreTasksLocked());
11826 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
11827 mTaskPersister.startPersisting();
11829 // Check to see if there are any update receivers to run.
11831 if (mWaitingUpdate) {
11834 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
11835 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
11836 public void run() {
11837 synchronized (ActivityManagerService.this) {
11840 showBootMessage(mContext.getText(
11841 R.string.android_upgrading_complete),
11843 writeLastDonePreBootReceivers(doneReceivers);
11844 systemReady(goingCallback);
11846 }, doneReceivers, UserHandle.USER_OWNER);
11848 if (mWaitingUpdate) {
11854 mAppOpsService.systemReady();
11855 mSystemReady = true;
11858 ArrayList<ProcessRecord> procsToKill = null;
11859 synchronized(mPidsSelfLocked) {
11860 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
11861 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
11862 if (!isAllowedWhileBooting(proc.info)){
11863 if (procsToKill == null) {
11864 procsToKill = new ArrayList<ProcessRecord>();
11866 procsToKill.add(proc);
11871 synchronized(this) {
11872 if (procsToKill != null) {
11873 for (int i=procsToKill.size()-1; i>=0; i--) {
11874 ProcessRecord proc = procsToKill.get(i);
11875 Slog.i(TAG, "Removing system update proc: " + proc);
11876 removeProcessLocked(proc, true, false, "system update done");
11880 // Now that we have cleaned up any update processes, we
11881 // are ready to start launching real processes and know that
11882 // we won't trample on them any more.
11883 mProcessesReady = true;
11886 Slog.i(TAG, "System now ready");
11887 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
11888 SystemClock.uptimeMillis());
11890 synchronized(this) {
11891 // Make sure we have no pre-ready processes sitting around.
11893 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11894 ResolveInfo ri = mContext.getPackageManager()
11895 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11897 CharSequence errorMsg = null;
11899 ActivityInfo ai = ri.activityInfo;
11900 ApplicationInfo app = ai.applicationInfo;
11901 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11902 mTopAction = Intent.ACTION_FACTORY_TEST;
11904 mTopComponent = new ComponentName(app.packageName,
11907 errorMsg = mContext.getResources().getText(
11908 com.android.internal.R.string.factorytest_not_system);
11911 errorMsg = mContext.getResources().getText(
11912 com.android.internal.R.string.factorytest_no_action);
11914 if (errorMsg != null) {
11917 mTopComponent = null;
11918 Message msg = Message.obtain();
11919 msg.what = SHOW_FACTORY_ERROR_MSG;
11920 msg.getData().putCharSequence("msg", errorMsg);
11921 mUiHandler.sendMessage(msg);
11926 retrieveSettings();
11927 loadResourcesOnSystemReady();
11929 synchronized (this) {
11930 readGrantedUriPermissionsLocked();
11933 if (goingCallback != null) goingCallback.run();
11935 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11936 Integer.toString(mCurrentUserId), mCurrentUserId);
11937 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11938 Integer.toString(mCurrentUserId), mCurrentUserId);
11939 mSystemServiceManager.startUser(mCurrentUserId);
11941 synchronized (this) {
11942 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11944 List apps = AppGlobals.getPackageManager().
11945 getPersistentApplications(STOCK_PM_FLAGS);
11946 if (apps != null) {
11947 int N = apps.size();
11949 for (i=0; i<N; i++) {
11950 ApplicationInfo info
11951 = (ApplicationInfo)apps.get(i);
11952 if (info != null &&
11953 !info.packageName.equals("android")) {
11954 addAppLocked(info, false, null /* ABI override */);
11958 } catch (RemoteException ex) {
11959 // pm is in same process, this will never happen.
11963 // Start up initial activity.
11965 startHomeActivityLocked(mCurrentUserId, "systemReady");
11968 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11969 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
11970 + " data partition or your device will be unstable.");
11971 mUiHandler.obtainMessage(SHOW_UID_ERROR_MSG).sendToTarget();
11973 } catch (RemoteException e) {
11976 if (!Build.isBuildConsistent()) {
11977 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
11978 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_MSG).sendToTarget();
11981 long ident = Binder.clearCallingIdentity();
11983 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11984 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11985 | Intent.FLAG_RECEIVER_FOREGROUND);
11986 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11987 broadcastIntentLocked(null, null, intent,
11988 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11989 null, false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11990 intent = new Intent(Intent.ACTION_USER_STARTING);
11991 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11992 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11993 broadcastIntentLocked(null, null, intent,
11994 null, new IIntentReceiver.Stub() {
11996 public void performReceive(Intent intent, int resultCode, String data,
11997 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11998 throws RemoteException {
12001 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12002 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12003 } catch (Throwable t) {
12004 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12006 Binder.restoreCallingIdentity(ident);
12008 mStackSupervisor.resumeTopActivitiesLocked();
12009 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
12013 private boolean makeAppCrashingLocked(ProcessRecord app,
12014 String shortMsg, String longMsg, String stackTrace) {
12015 app.crashing = true;
12016 app.crashingReport = generateProcessError(app,
12017 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
12018 startAppProblemLocked(app);
12019 app.stopFreezingAllLocked();
12020 return handleAppCrashLocked(app, "force-crash" /*reason*/, shortMsg, longMsg, stackTrace);
12023 private void makeAppNotRespondingLocked(ProcessRecord app,
12024 String activity, String shortMsg, String longMsg) {
12025 app.notResponding = true;
12026 app.notRespondingReport = generateProcessError(app,
12027 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
12028 activity, shortMsg, longMsg, null);
12029 startAppProblemLocked(app);
12030 app.stopFreezingAllLocked();
12034 * Generate a process error record, suitable for attachment to a ProcessRecord.
12036 * @param app The ProcessRecord in which the error occurred.
12037 * @param condition Crashing, Application Not Responding, etc. Values are defined in
12038 * ActivityManager.AppErrorStateInfo
12039 * @param activity The activity associated with the crash, if known.
12040 * @param shortMsg Short message describing the crash.
12041 * @param longMsg Long message describing the crash.
12042 * @param stackTrace Full crash stack trace, may be null.
12044 * @return Returns a fully-formed AppErrorStateInfo record.
12046 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
12047 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
12048 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
12050 report.condition = condition;
12051 report.processName = app.processName;
12052 report.pid = app.pid;
12053 report.uid = app.info.uid;
12054 report.tag = activity;
12055 report.shortMsg = shortMsg;
12056 report.longMsg = longMsg;
12057 report.stackTrace = stackTrace;
12062 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12063 synchronized (this) {
12064 app.crashing = false;
12065 app.crashingReport = null;
12066 app.notResponding = false;
12067 app.notRespondingReport = null;
12068 if (app.anrDialog == fromDialog) {
12069 app.anrDialog = null;
12071 if (app.waitDialog == fromDialog) {
12072 app.waitDialog = null;
12074 if (app.pid > 0 && app.pid != MY_PID) {
12075 handleAppCrashLocked(app, "user-terminated" /*reason*/,
12076 null /*shortMsg*/, null /*longMsg*/, null /*stackTrace*/);
12077 app.kill("user request after error", true);
12082 private boolean handleAppCrashLocked(ProcessRecord app, String reason,
12083 String shortMsg, String longMsg, String stackTrace) {
12084 long now = SystemClock.uptimeMillis();
12087 if (!app.isolated) {
12088 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
12092 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
12093 // This process loses!
12094 Slog.w(TAG, "Process " + app.info.processName
12095 + " has crashed too many times: killing!");
12096 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
12097 app.userId, app.info.processName, app.uid);
12098 mStackSupervisor.handleAppCrashLocked(app);
12099 if (!app.persistent) {
12100 // We don't want to start this process again until the user
12101 // explicitly does so... but for persistent process, we really
12102 // need to keep it running. If a persistent process is actually
12103 // repeatedly crashing, then badness for everyone.
12104 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
12105 app.info.processName);
12106 if (!app.isolated) {
12107 // XXX We don't have a way to mark isolated processes
12108 // as bad, since they don't have a peristent identity.
12109 mBadProcesses.put(app.info.processName, app.uid,
12110 new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
12111 mProcessCrashTimes.remove(app.info.processName, app.uid);
12114 app.removed = true;
12115 // Don't let services in this process be restarted and potentially
12116 // annoy the user repeatedly. Unless it is persistent, since those
12117 // processes run critical code.
12118 removeProcessLocked(app, false, false, "crash");
12119 mStackSupervisor.resumeTopActivitiesLocked();
12122 mStackSupervisor.resumeTopActivitiesLocked();
12124 mStackSupervisor.finishTopRunningActivityLocked(app, reason);
12127 // Bump up the crash count of any services currently running in the proc.
12128 for (int i=app.services.size()-1; i>=0; i--) {
12129 // Any services running in the application need to be placed
12130 // back in the pending list.
12131 ServiceRecord sr = app.services.valueAt(i);
12135 // If the crashing process is what we consider to be the "home process" and it has been
12136 // replaced by a third-party app, clear the package preferred activities from packages
12137 // with a home activity running in the process to prevent a repeatedly crashing app
12138 // from blocking the user to manually clear the list.
12139 final ArrayList<ActivityRecord> activities = app.activities;
12140 if (app == mHomeProcess && activities.size() > 0
12141 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
12142 for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
12143 final ActivityRecord r = activities.get(activityNdx);
12144 if (r.isHomeActivity()) {
12145 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
12147 ActivityThread.getPackageManager()
12148 .clearPackagePreferredActivities(r.packageName);
12149 } catch (RemoteException c) {
12150 // pm is in same process, this will never happen.
12156 if (!app.isolated) {
12157 // XXX Can't keep track of crash times for isolated processes,
12158 // because they don't have a perisistent identity.
12159 mProcessCrashTimes.put(app.info.processName, app.uid, now);
12162 if (app.crashHandler != null) mHandler.post(app.crashHandler);
12166 void startAppProblemLocked(ProcessRecord app) {
12167 // If this app is not running under the current user, then we
12168 // can't give it a report button because that would require
12169 // launching the report UI under a different user.
12170 app.errorReportReceiver = null;
12172 for (int userId : mCurrentProfileIds) {
12173 if (app.userId == userId) {
12174 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
12175 mContext, app.info.packageName, app.info.flags);
12178 skipCurrentReceiverLocked(app);
12181 void skipCurrentReceiverLocked(ProcessRecord app) {
12182 for (BroadcastQueue queue : mBroadcastQueues) {
12183 queue.skipCurrentReceiverLocked(app);
12188 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12189 * The application process will exit immediately after this call returns.
12190 * @param app object of the crashing app, null for the system server
12191 * @param crashInfo describing the exception
12193 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12194 ProcessRecord r = findAppProcess(app, "Crash");
12195 final String processName = app == null ? "system_server"
12196 : (r == null ? "unknown" : r.processName);
12198 handleApplicationCrashInner("crash", r, processName, crashInfo);
12201 /* Native crash reporting uses this inner version because it needs to be somewhat
12202 * decoupled from the AM-managed cleanup lifecycle
12204 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12205 ApplicationErrorReport.CrashInfo crashInfo) {
12206 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
12207 UserHandle.getUserId(Binder.getCallingUid()), processName,
12208 r == null ? -1 : r.info.flags,
12209 crashInfo.exceptionClassName,
12210 crashInfo.exceptionMessage,
12211 crashInfo.throwFileName,
12212 crashInfo.throwLineNumber);
12214 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
12216 crashApplication(r, crashInfo);
12219 public void handleApplicationStrictModeViolation(
12222 StrictMode.ViolationInfo info) {
12223 ProcessRecord r = findAppProcess(app, "StrictMode");
12228 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
12229 Integer stackFingerprint = info.hashCode();
12230 boolean logIt = true;
12231 synchronized (mAlreadyLoggedViolatedStacks) {
12232 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
12234 // TODO: sub-sample into EventLog for these, with
12235 // the info.durationMillis? Then we'd get
12236 // the relative pain numbers, without logging all
12237 // the stack traces repeatedly. We'd want to do
12238 // likewise in the client code, which also does
12239 // dup suppression, before the Binder call.
12241 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
12242 mAlreadyLoggedViolatedStacks.clear();
12244 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
12248 logStrictModeViolationToDropBox(r, info);
12252 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
12253 AppErrorResult result = new AppErrorResult();
12254 synchronized (this) {
12255 final long origId = Binder.clearCallingIdentity();
12257 Message msg = Message.obtain();
12258 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
12259 HashMap<String, Object> data = new HashMap<String, Object>();
12260 data.put("result", result);
12261 data.put("app", r);
12262 data.put("violationMask", violationMask);
12263 data.put("info", info);
12265 mUiHandler.sendMessage(msg);
12267 Binder.restoreCallingIdentity(origId);
12269 int res = result.get();
12270 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
12274 // Depending on the policy in effect, there could be a bunch of
12275 // these in quick succession so we try to batch these together to
12276 // minimize disk writes, number of dropbox entries, and maximize
12277 // compression, by having more fewer, larger records.
12278 private void logStrictModeViolationToDropBox(
12279 ProcessRecord process,
12280 StrictMode.ViolationInfo info) {
12281 if (info == null) {
12284 final boolean isSystemApp = process == null ||
12285 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
12286 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
12287 final String processName = process == null ? "unknown" : process.processName;
12288 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
12289 final DropBoxManager dbox = (DropBoxManager)
12290 mContext.getSystemService(Context.DROPBOX_SERVICE);
12292 // Exit early if the dropbox isn't configured to accept this report type.
12293 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12295 boolean bufferWasEmpty;
12296 boolean needsFlush;
12297 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
12298 synchronized (sb) {
12299 bufferWasEmpty = sb.length() == 0;
12300 appendDropBoxProcessHeaders(process, processName, sb);
12301 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12302 sb.append("System-App: ").append(isSystemApp).append("\n");
12303 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
12304 if (info.violationNumThisLoop != 0) {
12305 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
12307 if (info.numAnimationsRunning != 0) {
12308 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
12310 if (info.broadcastIntentAction != null) {
12311 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
12313 if (info.durationMillis != -1) {
12314 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
12316 if (info.numInstances != -1) {
12317 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
12319 if (info.tags != null) {
12320 for (String tag : info.tags) {
12321 sb.append("Span-Tag: ").append(tag).append("\n");
12325 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
12326 sb.append(info.crashInfo.stackTrace);
12329 if (info.message != null) {
12330 sb.append(info.message);
12334 // Only buffer up to ~64k. Various logging bits truncate
12336 needsFlush = (sb.length() > 64 * 1024);
12339 // Flush immediately if the buffer's grown too large, or this
12340 // is a non-system app. Non-system apps are isolated with a
12341 // different tag & policy and not batched.
12343 // Batching is useful during internal testing with
12344 // StrictMode settings turned up high. Without batching,
12345 // thousands of separate files could be created on boot.
12346 if (!isSystemApp || needsFlush) {
12347 new Thread("Error dump: " + dropboxTag) {
12349 public void run() {
12351 synchronized (sb) {
12352 report = sb.toString();
12353 sb.delete(0, sb.length());
12356 if (report.length() != 0) {
12357 dbox.addText(dropboxTag, report);
12364 // System app batching:
12365 if (!bufferWasEmpty) {
12366 // An existing dropbox-writing thread is outstanding, so
12367 // we don't need to start it up. The existing thread will
12368 // catch the buffer appends we just did.
12372 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
12373 // (After this point, we shouldn't access AMS internal data structures.)
12374 new Thread("Error dump: " + dropboxTag) {
12376 public void run() {
12377 // 5 second sleep to let stacks arrive and be batched together
12379 Thread.sleep(5000); // 5 seconds
12380 } catch (InterruptedException e) {}
12382 String errorReport;
12383 synchronized (mStrictModeBuffer) {
12384 errorReport = mStrictModeBuffer.toString();
12385 if (errorReport.length() == 0) {
12388 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
12389 mStrictModeBuffer.trimToSize();
12391 dbox.addText(dropboxTag, errorReport);
12397 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
12398 * @param app object of the crashing app, null for the system server
12399 * @param tag reported by the caller
12400 * @param system whether this wtf is coming from the system
12401 * @param crashInfo describing the context of the error
12402 * @return true if the process should exit immediately (WTF is fatal)
12404 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
12405 final ApplicationErrorReport.CrashInfo crashInfo) {
12406 final int callingUid = Binder.getCallingUid();
12407 final int callingPid = Binder.getCallingPid();
12410 // If this is coming from the system, we could very well have low-level
12411 // system locks held, so we want to do this all asynchronously. And we
12412 // never want this to become fatal, so there is that too.
12413 mHandler.post(new Runnable() {
12414 @Override public void run() {
12415 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
12421 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
12424 if (r != null && r.pid != Process.myPid() &&
12425 Settings.Global.getInt(mContext.getContentResolver(),
12426 Settings.Global.WTF_IS_FATAL, 0) != 0) {
12427 crashApplication(r, crashInfo);
12434 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
12435 final ApplicationErrorReport.CrashInfo crashInfo) {
12436 final ProcessRecord r = findAppProcess(app, "WTF");
12437 final String processName = app == null ? "system_server"
12438 : (r == null ? "unknown" : r.processName);
12440 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
12441 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
12443 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
12449 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
12450 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
12452 private ProcessRecord findAppProcess(IBinder app, String reason) {
12457 synchronized (this) {
12458 final int NP = mProcessNames.getMap().size();
12459 for (int ip=0; ip<NP; ip++) {
12460 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
12461 final int NA = apps.size();
12462 for (int ia=0; ia<NA; ia++) {
12463 ProcessRecord p = apps.valueAt(ia);
12464 if (p.thread != null && p.thread.asBinder() == app) {
12470 Slog.w(TAG, "Can't find mystery application for " + reason
12471 + " from pid=" + Binder.getCallingPid()
12472 + " uid=" + Binder.getCallingUid() + ": " + app);
12478 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
12479 * to append various headers to the dropbox log text.
12481 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
12482 StringBuilder sb) {
12483 // Watchdog thread ends up invoking this function (with
12484 // a null ProcessRecord) to add the stack file to dropbox.
12485 // Do not acquire a lock on this (am) in such cases, as it
12486 // could cause a potential deadlock, if and when watchdog
12487 // is invoked due to unavailability of lock on am and it
12488 // would prevent watchdog from killing system_server.
12489 if (process == null) {
12490 sb.append("Process: ").append(processName).append("\n");
12493 // Note: ProcessRecord 'process' is guarded by the service
12494 // instance. (notably process.pkgList, which could otherwise change
12495 // concurrently during execution of this method)
12496 synchronized (this) {
12497 sb.append("Process: ").append(processName).append("\n");
12498 int flags = process.info.flags;
12499 IPackageManager pm = AppGlobals.getPackageManager();
12500 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
12501 for (int ip=0; ip<process.pkgList.size(); ip++) {
12502 String pkg = process.pkgList.keyAt(ip);
12503 sb.append("Package: ").append(pkg);
12505 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
12507 sb.append(" v").append(pi.versionCode);
12508 if (pi.versionName != null) {
12509 sb.append(" (").append(pi.versionName).append(")");
12512 } catch (RemoteException e) {
12513 Slog.e(TAG, "Error getting package info: " + pkg, e);
12520 private static String processClass(ProcessRecord process) {
12521 if (process == null || process.pid == MY_PID) {
12522 return "system_server";
12523 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
12524 return "system_app";
12531 * Write a description of an error (crash, WTF, ANR) to the drop box.
12532 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
12533 * @param process which caused the error, null means the system server
12534 * @param activity which triggered the error, null if unknown
12535 * @param parent activity related to the error, null if unknown
12536 * @param subject line related to the error, null if absent
12537 * @param report in long form describing the error, null if absent
12538 * @param logFile to include in the report, null if none
12539 * @param crashInfo giving an application stack trace, null if absent
12541 public void addErrorToDropBox(String eventType,
12542 ProcessRecord process, String processName, ActivityRecord activity,
12543 ActivityRecord parent, String subject,
12544 final String report, final File logFile,
12545 final ApplicationErrorReport.CrashInfo crashInfo) {
12546 // NOTE -- this must never acquire the ActivityManagerService lock,
12547 // otherwise the watchdog may be prevented from resetting the system.
12549 final String dropboxTag = processClass(process) + "_" + eventType;
12550 final DropBoxManager dbox = (DropBoxManager)
12551 mContext.getSystemService(Context.DROPBOX_SERVICE);
12553 // Exit early if the dropbox isn't configured to accept this report type.
12554 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
12556 final StringBuilder sb = new StringBuilder(1024);
12557 appendDropBoxProcessHeaders(process, processName, sb);
12558 if (activity != null) {
12559 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
12561 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
12562 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
12564 if (parent != null && parent != activity) {
12565 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
12567 if (subject != null) {
12568 sb.append("Subject: ").append(subject).append("\n");
12570 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
12571 if (Debug.isDebuggerConnected()) {
12572 sb.append("Debugger: Connected\n");
12576 // Do the rest in a worker thread to avoid blocking the caller on I/O
12577 // (After this point, we shouldn't access AMS internal data structures.)
12578 Thread worker = new Thread("Error dump: " + dropboxTag) {
12580 public void run() {
12581 if (report != null) {
12584 if (logFile != null) {
12586 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
12587 "\n\n[[TRUNCATED]]"));
12588 } catch (IOException e) {
12589 Slog.e(TAG, "Error reading " + logFile, e);
12592 if (crashInfo != null && crashInfo.stackTrace != null) {
12593 sb.append(crashInfo.stackTrace);
12596 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
12597 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
12601 // Merge several logcat streams, and take the last N lines
12602 InputStreamReader input = null;
12604 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
12605 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
12607 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
12609 try { logcat.getOutputStream().close(); } catch (IOException e) {}
12610 try { logcat.getErrorStream().close(); } catch (IOException e) {}
12611 input = new InputStreamReader(logcat.getInputStream());
12614 char[] buf = new char[8192];
12615 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
12616 } catch (IOException e) {
12617 Slog.e(TAG, "Error running logcat", e);
12619 if (input != null) try { input.close(); } catch (IOException e) {}
12623 dbox.addText(dropboxTag, sb.toString());
12627 if (process == null) {
12628 // If process is null, we are being called from some internal code
12629 // and may be about to die -- run this synchronously.
12637 * Bring up the "unexpected error" dialog box for a crashing app.
12638 * Deal with edge cases (intercepts from instrumented applications,
12639 * ActivityController, error intent receivers, that sort of thing).
12640 * @param r the application crashing
12641 * @param crashInfo describing the failure
12643 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
12644 long timeMillis = System.currentTimeMillis();
12645 String shortMsg = crashInfo.exceptionClassName;
12646 String longMsg = crashInfo.exceptionMessage;
12647 String stackTrace = crashInfo.stackTrace;
12648 if (shortMsg != null && longMsg != null) {
12649 longMsg = shortMsg + ": " + longMsg;
12650 } else if (shortMsg != null) {
12651 longMsg = shortMsg;
12654 AppErrorResult result = new AppErrorResult();
12655 synchronized (this) {
12656 if (mController != null) {
12658 String name = r != null ? r.processName : null;
12659 int pid = r != null ? r.pid : Binder.getCallingPid();
12660 int uid = r != null ? r.info.uid : Binder.getCallingUid();
12661 if (!mController.appCrashed(name, pid,
12662 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
12663 if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
12664 && "Native crash".equals(crashInfo.exceptionClassName)) {
12665 Slog.w(TAG, "Skip killing native crashed app " + name
12666 + "(" + pid + ") during testing");
12668 Slog.w(TAG, "Force-killing crashed app " + name
12669 + " at watcher's request");
12671 r.kill("crash", true);
12674 Process.killProcess(pid);
12675 killProcessGroup(uid, pid);
12680 } catch (RemoteException e) {
12681 mController = null;
12682 Watchdog.getInstance().setActivityController(null);
12686 final long origId = Binder.clearCallingIdentity();
12688 // If this process is running instrumentation, finish it.
12689 if (r != null && r.instrumentationClass != null) {
12690 Slog.w(TAG, "Error in app " + r.processName
12691 + " running instrumentation " + r.instrumentationClass + ":");
12692 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
12693 if (longMsg != null) Slog.w(TAG, " " + longMsg);
12694 Bundle info = new Bundle();
12695 info.putString("shortMsg", shortMsg);
12696 info.putString("longMsg", longMsg);
12697 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
12698 Binder.restoreCallingIdentity(origId);
12702 // Log crash in battery stats.
12704 mBatteryStatsService.noteProcessCrash(r.processName, r.uid);
12707 // If we can't identify the process or it's already exceeded its crash quota,
12708 // quit right away without showing a crash dialog.
12709 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
12710 Binder.restoreCallingIdentity(origId);
12714 Message msg = Message.obtain();
12715 msg.what = SHOW_ERROR_MSG;
12716 HashMap data = new HashMap();
12717 data.put("result", result);
12718 data.put("app", r);
12720 mUiHandler.sendMessage(msg);
12722 Binder.restoreCallingIdentity(origId);
12725 int res = result.get();
12727 Intent appErrorIntent = null;
12728 synchronized (this) {
12729 if (r != null && !r.isolated) {
12730 // XXX Can't keep track of crash time for isolated processes,
12731 // since they don't have a persistent identity.
12732 mProcessCrashTimes.put(r.info.processName, r.uid,
12733 SystemClock.uptimeMillis());
12735 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
12736 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
12740 if (appErrorIntent != null) {
12742 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
12743 } catch (ActivityNotFoundException e) {
12744 Slog.w(TAG, "bug report receiver dissappeared", e);
12749 Intent createAppErrorIntentLocked(ProcessRecord r,
12750 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12751 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
12752 if (report == null) {
12755 Intent result = new Intent(Intent.ACTION_APP_ERROR);
12756 result.setComponent(r.errorReportReceiver);
12757 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
12758 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
12762 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
12763 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
12764 if (r.errorReportReceiver == null) {
12768 if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
12772 ApplicationErrorReport report = new ApplicationErrorReport();
12773 report.packageName = r.info.packageName;
12774 report.installerPackageName = r.errorReportReceiver.getPackageName();
12775 report.processName = r.processName;
12776 report.time = timeMillis;
12777 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
12779 if (r.crashing || r.forceCrashReport) {
12780 report.type = ApplicationErrorReport.TYPE_CRASH;
12781 report.crashInfo = crashInfo;
12782 } else if (r.notResponding) {
12783 report.type = ApplicationErrorReport.TYPE_ANR;
12784 report.anrInfo = new ApplicationErrorReport.AnrInfo();
12786 report.anrInfo.activity = r.notRespondingReport.tag;
12787 report.anrInfo.cause = r.notRespondingReport.shortMsg;
12788 report.anrInfo.info = r.notRespondingReport.longMsg;
12794 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
12795 enforceNotIsolatedCaller("getProcessesInErrorState");
12796 // assume our apps are happy - lazy create the list
12797 List<ActivityManager.ProcessErrorStateInfo> errList = null;
12799 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12800 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
12801 int userId = UserHandle.getUserId(Binder.getCallingUid());
12803 synchronized (this) {
12805 // iterate across all processes
12806 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12807 ProcessRecord app = mLruProcesses.get(i);
12808 if (!allUsers && app.userId != userId) {
12811 if ((app.thread != null) && (app.crashing || app.notResponding)) {
12812 // This one's in trouble, so we'll generate a report for it
12813 // crashes are higher priority (in case there's a crash *and* an anr)
12814 ActivityManager.ProcessErrorStateInfo report = null;
12815 if (app.crashing) {
12816 report = app.crashingReport;
12817 } else if (app.notResponding) {
12818 report = app.notRespondingReport;
12821 if (report != null) {
12822 if (errList == null) {
12823 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
12825 errList.add(report);
12827 Slog.w(TAG, "Missing app error report, app = " + app.processName +
12828 " crashing = " + app.crashing +
12829 " notResponding = " + app.notResponding);
12838 static int procStateToImportance(int procState, int memAdj,
12839 ActivityManager.RunningAppProcessInfo currApp) {
12840 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
12841 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
12842 currApp.lru = memAdj;
12849 private void fillInProcMemInfo(ProcessRecord app,
12850 ActivityManager.RunningAppProcessInfo outInfo) {
12851 outInfo.pid = app.pid;
12852 outInfo.uid = app.info.uid;
12853 if (mHeavyWeightProcess == app) {
12854 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
12856 if (app.persistent) {
12857 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
12859 if (app.activities.size() > 0) {
12860 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
12862 outInfo.lastTrimLevel = app.trimMemoryLevel;
12863 int adj = app.curAdj;
12864 int procState = app.curProcState;
12865 outInfo.importance = procStateToImportance(procState, adj, outInfo);
12866 outInfo.importanceReasonCode = app.adjTypeCode;
12867 outInfo.processState = app.curProcState;
12870 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
12871 enforceNotIsolatedCaller("getRunningAppProcesses");
12873 final int callingUid = Binder.getCallingUid();
12875 // Lazy instantiation of list
12876 List<ActivityManager.RunningAppProcessInfo> runList = null;
12877 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
12878 callingUid) == PackageManager.PERMISSION_GRANTED;
12879 final int userId = UserHandle.getUserId(callingUid);
12880 final boolean allUids = isGetTasksAllowed(
12881 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
12883 synchronized (this) {
12884 // Iterate across all processes
12885 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
12886 ProcessRecord app = mLruProcesses.get(i);
12887 if ((!allUsers && app.userId != userId)
12888 || (!allUids && app.uid != callingUid)) {
12891 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
12892 // Generate process state info for running application
12893 ActivityManager.RunningAppProcessInfo currApp =
12894 new ActivityManager.RunningAppProcessInfo(app.processName,
12895 app.pid, app.getPackageList());
12896 fillInProcMemInfo(app, currApp);
12897 if (app.adjSource instanceof ProcessRecord) {
12898 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
12899 currApp.importanceReasonImportance =
12900 ActivityManager.RunningAppProcessInfo.procStateToImportance(
12901 app.adjSourceProcState);
12902 } else if (app.adjSource instanceof ActivityRecord) {
12903 ActivityRecord r = (ActivityRecord)app.adjSource;
12904 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
12906 if (app.adjTarget instanceof ComponentName) {
12907 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
12909 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
12910 // + " lru=" + currApp.lru);
12911 if (runList == null) {
12912 runList = new ArrayList<>();
12914 runList.add(currApp);
12921 public List<ApplicationInfo> getRunningExternalApplications() {
12922 enforceNotIsolatedCaller("getRunningExternalApplications");
12923 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12924 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12925 if (runningApps != null && runningApps.size() > 0) {
12926 Set<String> extList = new HashSet<String>();
12927 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12928 if (app.pkgList != null) {
12929 for (String pkg : app.pkgList) {
12934 IPackageManager pm = AppGlobals.getPackageManager();
12935 for (String pkg : extList) {
12937 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12938 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12941 } catch (RemoteException e) {
12949 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12950 enforceNotIsolatedCaller("getMyMemoryState");
12951 synchronized (this) {
12952 ProcessRecord proc;
12953 synchronized (mPidsSelfLocked) {
12954 proc = mPidsSelfLocked.get(Binder.getCallingPid());
12956 fillInProcMemInfo(proc, outInfo);
12961 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12962 if (checkCallingPermission(android.Manifest.permission.DUMP)
12963 != PackageManager.PERMISSION_GRANTED) {
12964 pw.println("Permission Denial: can't dump ActivityManager from from pid="
12965 + Binder.getCallingPid()
12966 + ", uid=" + Binder.getCallingUid()
12967 + " without permission "
12968 + android.Manifest.permission.DUMP);
12972 boolean dumpAll = false;
12973 boolean dumpClient = false;
12974 String dumpPackage = null;
12977 while (opti < args.length) {
12978 String opt = args[opti];
12979 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12983 if ("-a".equals(opt)) {
12985 } else if ("-c".equals(opt)) {
12987 } else if ("-p".equals(opt)) {
12988 if (opti < args.length) {
12989 dumpPackage = args[opti];
12992 pw.println("Error: -p option requires package argument");
12996 } else if ("-h".equals(opt)) {
12997 pw.println("Activity manager dump options:");
12998 pw.println(" [-a] [-c] [-p package] [-h] [cmd] ...");
12999 pw.println(" cmd may be one of:");
13000 pw.println(" a[ctivities]: activity stack state");
13001 pw.println(" r[recents]: recent activities state");
13002 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
13003 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
13004 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
13005 pw.println(" o[om]: out of memory management");
13006 pw.println(" perm[issions]: URI permission grant state");
13007 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
13008 pw.println(" provider [COMP_SPEC]: provider client-side state");
13009 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
13010 pw.println(" as[sociations]: tracked app associations");
13011 pw.println(" service [COMP_SPEC]: service client-side state");
13012 pw.println(" package [PACKAGE_NAME]: all state related to given package");
13013 pw.println(" all: dump all activities");
13014 pw.println(" top: dump the top activity");
13015 pw.println(" write: write all pending state to storage");
13016 pw.println(" track-associations: enable association tracking");
13017 pw.println(" untrack-associations: disable and clear association tracking");
13018 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
13019 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
13020 pw.println(" a partial substring in a component name, a");
13021 pw.println(" hex object identifier.");
13022 pw.println(" -a: include all available server state.");
13023 pw.println(" -c: include client state.");
13024 pw.println(" -p: limit output to given package.");
13027 pw.println("Unknown argument: " + opt + "; use -h for help");
13031 long origId = Binder.clearCallingIdentity();
13032 boolean more = false;
13033 // Is the caller requesting to dump a particular piece of data?
13034 if (opti < args.length) {
13035 String cmd = args[opti];
13037 if ("activities".equals(cmd) || "a".equals(cmd)) {
13038 synchronized (this) {
13039 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13041 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13042 synchronized (this) {
13043 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13045 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13048 if (opti >= args.length) {
13050 newArgs = EMPTY_STRING_ARRAY;
13052 dumpPackage = args[opti];
13054 newArgs = new String[args.length - opti];
13055 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13056 args.length - opti);
13058 synchronized (this) {
13059 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13061 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13064 if (opti >= args.length) {
13066 newArgs = EMPTY_STRING_ARRAY;
13068 dumpPackage = args[opti];
13070 newArgs = new String[args.length - opti];
13071 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13072 args.length - opti);
13074 synchronized (this) {
13075 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13077 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13080 if (opti >= args.length) {
13082 newArgs = EMPTY_STRING_ARRAY;
13084 dumpPackage = args[opti];
13086 newArgs = new String[args.length - opti];
13087 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13088 args.length - opti);
13090 synchronized (this) {
13091 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13093 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13094 synchronized (this) {
13095 dumpOomLocked(fd, pw, args, opti, true);
13097 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13098 synchronized (this) {
13099 dumpPermissionsLocked(fd, pw, args, opti, true, null);
13101 } else if ("provider".equals(cmd)) {
13104 if (opti >= args.length) {
13106 newArgs = EMPTY_STRING_ARRAY;
13110 newArgs = new String[args.length - opti];
13111 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13113 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13114 pw.println("No providers match: " + name);
13115 pw.println("Use -h for help.");
13117 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13118 synchronized (this) {
13119 dumpProvidersLocked(fd, pw, args, opti, true, null);
13121 } else if ("service".equals(cmd)) {
13124 if (opti >= args.length) {
13126 newArgs = EMPTY_STRING_ARRAY;
13130 newArgs = new String[args.length - opti];
13131 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13132 args.length - opti);
13134 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13135 pw.println("No services match: " + name);
13136 pw.println("Use -h for help.");
13138 } else if ("package".equals(cmd)) {
13140 if (opti >= args.length) {
13141 pw.println("package: no package name specified");
13142 pw.println("Use -h for help.");
13144 dumpPackage = args[opti];
13146 newArgs = new String[args.length - opti];
13147 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13148 args.length - opti);
13153 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13154 synchronized (this) {
13155 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13157 } else if ("services".equals(cmd) || "s".equals(cmd)) {
13158 synchronized (this) {
13159 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13161 } else if ("write".equals(cmd)) {
13162 mTaskPersister.flush();
13163 pw.println("All tasks persisted.");
13165 } else if ("track-associations".equals(cmd)) {
13166 synchronized (this) {
13167 if (!mTrackingAssociations) {
13168 mTrackingAssociations = true;
13169 pw.println("Association tracking started.");
13171 pw.println("Association tracking already enabled.");
13175 } else if ("untrack-associations".equals(cmd)) {
13176 synchronized (this) {
13177 if (mTrackingAssociations) {
13178 mTrackingAssociations = false;
13179 mAssociations.clear();
13180 pw.println("Association tracking stopped.");
13182 pw.println("Association tracking not running.");
13187 // Dumping a single activity?
13188 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13189 pw.println("Bad activity command, or no activities match: " + cmd);
13190 pw.println("Use -h for help.");
13194 Binder.restoreCallingIdentity(origId);
13199 // No piece of data specified, dump everything.
13200 synchronized (this) {
13201 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13204 pw.println("-------------------------------------------------------------------------------");
13206 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13209 pw.println("-------------------------------------------------------------------------------");
13211 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13214 pw.println("-------------------------------------------------------------------------------");
13216 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13219 pw.println("-------------------------------------------------------------------------------");
13221 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13224 pw.println("-------------------------------------------------------------------------------");
13226 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13229 pw.println("-------------------------------------------------------------------------------");
13231 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13232 if (mAssociations.size() > 0) {
13235 pw.println("-------------------------------------------------------------------------------");
13237 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13241 pw.println("-------------------------------------------------------------------------------");
13243 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13245 Binder.restoreCallingIdentity(origId);
13248 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13249 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13250 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13252 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13254 boolean needSep = printedAnything;
13256 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13257 dumpPackage, needSep, " mFocusedActivity: ");
13259 printedAnything = true;
13263 if (dumpPackage == null) {
13268 printedAnything = true;
13269 mStackSupervisor.dump(pw, " ");
13272 if (!printedAnything) {
13273 pw.println(" (nothing)");
13277 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13278 int opti, boolean dumpAll, String dumpPackage) {
13279 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13281 boolean printedAnything = false;
13283 if (mRecentTasks != null && mRecentTasks.size() > 0) {
13284 boolean printedHeader = false;
13286 final int N = mRecentTasks.size();
13287 for (int i=0; i<N; i++) {
13288 TaskRecord tr = mRecentTasks.get(i);
13289 if (dumpPackage != null) {
13290 if (tr.realActivity == null ||
13291 !dumpPackage.equals(tr.realActivity)) {
13295 if (!printedHeader) {
13296 pw.println(" Recent tasks:");
13297 printedHeader = true;
13298 printedAnything = true;
13300 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
13303 mRecentTasks.get(i).dump(pw, " ");
13308 if (!printedAnything) {
13309 pw.println(" (nothing)");
13313 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13314 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13315 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13318 if (dumpPackage != null) {
13319 IPackageManager pm = AppGlobals.getPackageManager();
13321 dumpUid = pm.getPackageUid(dumpPackage, 0);
13322 } catch (RemoteException e) {
13326 boolean printedAnything = false;
13328 final long now = SystemClock.uptimeMillis();
13330 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13331 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13332 = mAssociations.valueAt(i1);
13333 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13334 SparseArray<ArrayMap<String, Association>> sourceUids
13335 = targetComponents.valueAt(i2);
13336 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13337 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13338 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13339 Association ass = sourceProcesses.valueAt(i4);
13340 if (dumpPackage != null) {
13341 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13342 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13346 printedAnything = true;
13348 pw.print(ass.mTargetProcess);
13350 UserHandle.formatUid(pw, ass.mTargetUid);
13352 pw.print(ass.mSourceProcess);
13354 UserHandle.formatUid(pw, ass.mSourceUid);
13357 pw.print(ass.mTargetComponent.flattenToShortString());
13360 long dur = ass.mTime;
13361 if (ass.mNesting > 0) {
13362 dur += now - ass.mStartTime;
13364 TimeUtils.formatDuration(dur, pw);
13366 pw.print(ass.mCount);
13367 pw.println(" times)");
13368 if (ass.mNesting > 0) {
13370 pw.print(" Currently active: ");
13371 TimeUtils.formatDuration(now - ass.mStartTime, pw);
13380 if (!printedAnything) {
13381 pw.println(" (nothing)");
13385 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13386 int opti, boolean dumpAll, String dumpPackage) {
13387 boolean needSep = false;
13388 boolean printedAnything = false;
13391 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
13394 final int NP = mProcessNames.getMap().size();
13395 for (int ip=0; ip<NP; ip++) {
13396 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
13397 final int NA = procs.size();
13398 for (int ia=0; ia<NA; ia++) {
13399 ProcessRecord r = procs.valueAt(ia);
13400 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13404 pw.println(" All known processes:");
13406 printedAnything = true;
13408 pw.print(r.persistent ? " *PERS*" : " *APP*");
13409 pw.print(" UID "); pw.print(procs.keyAt(ia));
13410 pw.print(" "); pw.println(r);
13412 if (r.persistent) {
13419 if (mIsolatedProcesses.size() > 0) {
13420 boolean printed = false;
13421 for (int i=0; i<mIsolatedProcesses.size(); i++) {
13422 ProcessRecord r = mIsolatedProcesses.valueAt(i);
13423 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13430 pw.println(" Isolated process list (sorted by uid):");
13431 printedAnything = true;
13435 pw.println(String.format("%sIsolated #%2d: %s",
13436 " ", i, r.toString()));
13440 if (mActiveUids.size() > 0) {
13444 pw.println(" UID states:");
13445 for (int i=0; i<mActiveUids.size(); i++) {
13446 UidRecord uidRec = mActiveUids.valueAt(i);
13447 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
13448 pw.print(": "); pw.println(uidRec);
13451 printedAnything = true;
13454 if (mLruProcesses.size() > 0) {
13458 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
13459 pw.print(" total, non-act at ");
13460 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13461 pw.print(", non-svc at ");
13462 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13464 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
13466 printedAnything = true;
13469 if (dumpAll || dumpPackage != null) {
13470 synchronized (mPidsSelfLocked) {
13471 boolean printed = false;
13472 for (int i=0; i<mPidsSelfLocked.size(); i++) {
13473 ProcessRecord r = mPidsSelfLocked.valueAt(i);
13474 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13478 if (needSep) pw.println();
13480 pw.println(" PID mappings:");
13482 printedAnything = true;
13484 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
13485 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
13490 if (mForegroundProcesses.size() > 0) {
13491 synchronized (mPidsSelfLocked) {
13492 boolean printed = false;
13493 for (int i=0; i<mForegroundProcesses.size(); i++) {
13494 ProcessRecord r = mPidsSelfLocked.get(
13495 mForegroundProcesses.valueAt(i).pid);
13496 if (dumpPackage != null && (r == null
13497 || !r.pkgList.containsKey(dumpPackage))) {
13501 if (needSep) pw.println();
13503 pw.println(" Foreground Processes:");
13505 printedAnything = true;
13507 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
13508 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
13513 if (mPersistentStartingProcesses.size() > 0) {
13514 if (needSep) pw.println();
13516 printedAnything = true;
13517 pw.println(" Persisent processes that are starting:");
13518 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
13519 "Starting Norm", "Restarting PERS", dumpPackage);
13522 if (mRemovedProcesses.size() > 0) {
13523 if (needSep) pw.println();
13525 printedAnything = true;
13526 pw.println(" Processes that are being removed:");
13527 dumpProcessList(pw, this, mRemovedProcesses, " ",
13528 "Removed Norm", "Removed PERS", dumpPackage);
13531 if (mProcessesOnHold.size() > 0) {
13532 if (needSep) pw.println();
13534 printedAnything = true;
13535 pw.println(" Processes that are on old until the system is ready:");
13536 dumpProcessList(pw, this, mProcessesOnHold, " ",
13537 "OnHold Norm", "OnHold PERS", dumpPackage);
13540 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
13542 if (mProcessCrashTimes.getMap().size() > 0) {
13543 boolean printed = false;
13544 long now = SystemClock.uptimeMillis();
13545 final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
13546 final int NP = pmap.size();
13547 for (int ip=0; ip<NP; ip++) {
13548 String pname = pmap.keyAt(ip);
13549 SparseArray<Long> uids = pmap.valueAt(ip);
13550 final int N = uids.size();
13551 for (int i=0; i<N; i++) {
13552 int puid = uids.keyAt(i);
13553 ProcessRecord r = mProcessNames.get(pname, puid);
13554 if (dumpPackage != null && (r == null
13555 || !r.pkgList.containsKey(dumpPackage))) {
13559 if (needSep) pw.println();
13561 pw.println(" Time since processes crashed:");
13563 printedAnything = true;
13565 pw.print(" Process "); pw.print(pname);
13566 pw.print(" uid "); pw.print(puid);
13567 pw.print(": last crashed ");
13568 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
13569 pw.println(" ago");
13574 if (mBadProcesses.getMap().size() > 0) {
13575 boolean printed = false;
13576 final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
13577 final int NP = pmap.size();
13578 for (int ip=0; ip<NP; ip++) {
13579 String pname = pmap.keyAt(ip);
13580 SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
13581 final int N = uids.size();
13582 for (int i=0; i<N; i++) {
13583 int puid = uids.keyAt(i);
13584 ProcessRecord r = mProcessNames.get(pname, puid);
13585 if (dumpPackage != null && (r == null
13586 || !r.pkgList.containsKey(dumpPackage))) {
13590 if (needSep) pw.println();
13592 pw.println(" Bad processes:");
13593 printedAnything = true;
13595 BadProcessInfo info = uids.valueAt(i);
13596 pw.print(" Bad process "); pw.print(pname);
13597 pw.print(" uid "); pw.print(puid);
13598 pw.print(": crashed at time "); pw.println(info.time);
13599 if (info.shortMsg != null) {
13600 pw.print(" Short msg: "); pw.println(info.shortMsg);
13602 if (info.longMsg != null) {
13603 pw.print(" Long msg: "); pw.println(info.longMsg);
13605 if (info.stack != null) {
13606 pw.println(" Stack:");
13608 for (int pos=0; pos<info.stack.length(); pos++) {
13609 if (info.stack.charAt(pos) == '\n') {
13611 pw.write(info.stack, lastPos, pos-lastPos);
13616 if (lastPos < info.stack.length()) {
13618 pw.write(info.stack, lastPos, info.stack.length()-lastPos);
13626 if (dumpPackage == null) {
13629 pw.println(" mStartedUsers:");
13630 for (int i=0; i<mStartedUsers.size(); i++) {
13631 UserState uss = mStartedUsers.valueAt(i);
13632 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
13633 pw.print(": "); uss.dump("", pw);
13635 pw.print(" mStartedUserArray: [");
13636 for (int i=0; i<mStartedUserArray.length; i++) {
13637 if (i > 0) pw.print(", ");
13638 pw.print(mStartedUserArray[i]);
13641 pw.print(" mUserLru: [");
13642 for (int i=0; i<mUserLru.size(); i++) {
13643 if (i > 0) pw.print(", ");
13644 pw.print(mUserLru.get(i));
13648 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
13650 synchronized (mUserProfileGroupIdsSelfLocked) {
13651 if (mUserProfileGroupIdsSelfLocked.size() > 0) {
13652 pw.println(" mUserProfileGroupIds:");
13653 for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
13654 pw.print(" User #");
13655 pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
13656 pw.print(" -> profile #");
13657 pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
13662 if (mHomeProcess != null && (dumpPackage == null
13663 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
13668 pw.println(" mHomeProcess: " + mHomeProcess);
13670 if (mPreviousProcess != null && (dumpPackage == null
13671 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
13676 pw.println(" mPreviousProcess: " + mPreviousProcess);
13679 StringBuilder sb = new StringBuilder(128);
13680 sb.append(" mPreviousProcessVisibleTime: ");
13681 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
13684 if (mHeavyWeightProcess != null && (dumpPackage == null
13685 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
13690 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13692 if (dumpPackage == null) {
13693 pw.println(" mConfiguration: " + mConfiguration);
13696 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
13697 if (mCompatModePackages.getPackages().size() > 0) {
13698 boolean printed = false;
13699 for (Map.Entry<String, Integer> entry
13700 : mCompatModePackages.getPackages().entrySet()) {
13701 String pkg = entry.getKey();
13702 int mode = entry.getValue();
13703 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
13707 pw.println(" mScreenCompatPackages:");
13710 pw.print(" "); pw.print(pkg); pw.print(": ");
13711 pw.print(mode); pw.println();
13715 if (dumpPackage == null) {
13716 pw.println(" mWakefulness="
13717 + PowerManagerInternal.wakefulnessToString(mWakefulness));
13718 pw.println(" mSleepTokens=" + mSleepTokens);
13719 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
13720 + lockScreenShownToString());
13721 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
13722 if (mRunningVoice != null) {
13723 pw.println(" mRunningVoice=" + mRunningVoice);
13724 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
13727 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
13728 || mOrigWaitForDebugger) {
13729 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
13730 || dumpPackage.equals(mOrigDebugApp)) {
13735 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
13736 + " mDebugTransient=" + mDebugTransient
13737 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
13740 if (mCurAppTimeTracker != null) {
13741 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
13743 if (mMemWatchProcesses.getMap().size() > 0) {
13744 pw.println(" Mem watch processes:");
13745 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
13746 = mMemWatchProcesses.getMap();
13747 for (int i=0; i<procs.size(); i++) {
13748 final String proc = procs.keyAt(i);
13749 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
13750 for (int j=0; j<uids.size(); j++) {
13755 StringBuilder sb = new StringBuilder();
13756 sb.append(" ").append(proc).append('/');
13757 UserHandle.formatUid(sb, uids.keyAt(j));
13758 Pair<Long, String> val = uids.valueAt(j);
13759 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
13760 if (val.second != null) {
13761 sb.append(", report to ").append(val.second);
13763 pw.println(sb.toString());
13766 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
13767 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
13768 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
13769 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
13771 if (mOpenGlTraceApp != null) {
13772 if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
13777 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
13780 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
13781 || mProfileFd != null) {
13782 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
13787 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
13788 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
13789 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
13790 + mAutoStopProfiler);
13791 pw.println(" mProfileType=" + mProfileType);
13794 if (dumpPackage == null) {
13795 if (mAlwaysFinishActivities || mController != null) {
13796 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
13797 + " mController=" + mController);
13800 pw.println(" Total persistent processes: " + numPers);
13801 pw.println(" mProcessesReady=" + mProcessesReady
13802 + " mSystemReady=" + mSystemReady
13803 + " mBooted=" + mBooted
13804 + " mFactoryTest=" + mFactoryTest);
13805 pw.println(" mBooting=" + mBooting
13806 + " mCallFinishBooting=" + mCallFinishBooting
13807 + " mBootAnimationComplete=" + mBootAnimationComplete);
13808 pw.print(" mLastPowerCheckRealtime=");
13809 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
13811 pw.print(" mLastPowerCheckUptime=");
13812 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
13814 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
13815 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
13816 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
13817 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
13818 + " (" + mLruProcesses.size() + " total)"
13819 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
13820 + " mNumServiceProcs=" + mNumServiceProcs
13821 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
13822 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
13823 + " mLastMemoryLevel" + mLastMemoryLevel
13824 + " mLastNumProcesses" + mLastNumProcesses);
13825 long now = SystemClock.uptimeMillis();
13826 pw.print(" mLastIdleTime=");
13827 TimeUtils.formatDuration(now, mLastIdleTime, pw);
13828 pw.print(" mLowRamSinceLastIdle=");
13829 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
13834 if (!printedAnything) {
13835 pw.println(" (nothing)");
13839 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
13840 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
13841 if (mProcessesToGc.size() > 0) {
13842 boolean printed = false;
13843 long now = SystemClock.uptimeMillis();
13844 for (int i=0; i<mProcessesToGc.size(); i++) {
13845 ProcessRecord proc = mProcessesToGc.get(i);
13846 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
13850 if (needSep) pw.println();
13852 pw.println(" Processes that are waiting to GC:");
13855 pw.print(" Process "); pw.println(proc);
13856 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
13857 pw.print(", last gced=");
13858 pw.print(now-proc.lastRequestedGc);
13859 pw.print(" ms ago, last lowMem=");
13860 pw.print(now-proc.lastLowMemory);
13861 pw.println(" ms ago");
13868 void printOomLevel(PrintWriter pw, String name, int adj) {
13872 if (adj < 10) pw.print(' ');
13874 if (adj > -10) pw.print(' ');
13880 pw.print(mProcessList.getMemLevel(adj)/1024);
13881 pw.println(" kB)");
13884 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13885 int opti, boolean dumpAll) {
13886 boolean needSep = false;
13888 if (mLruProcesses.size() > 0) {
13889 if (needSep) pw.println();
13891 pw.println(" OOM levels:");
13892 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
13893 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
13894 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
13895 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
13896 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
13897 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
13898 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
13899 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
13900 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
13901 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
13902 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
13903 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
13904 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
13905 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
13907 if (needSep) pw.println();
13908 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
13909 pw.print(" total, non-act at ");
13910 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
13911 pw.print(", non-svc at ");
13912 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
13914 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
13918 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
13921 pw.println(" mHomeProcess: " + mHomeProcess);
13922 pw.println(" mPreviousProcess: " + mPreviousProcess);
13923 if (mHeavyWeightProcess != null) {
13924 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
13931 * There are three ways to call this:
13932 * - no provider specified: dump all the providers
13933 * - a flattened component name that matched an existing provider was specified as the
13934 * first arg: dump that one provider
13935 * - the first arg isn't the flattened component name of an existing provider:
13936 * dump all providers whose component contains the first arg as a substring
13938 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
13939 int opti, boolean dumpAll) {
13940 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
13943 static class ItemMatcher {
13944 ArrayList<ComponentName> components;
13945 ArrayList<String> strings;
13946 ArrayList<Integer> objects;
13953 void build(String name) {
13954 ComponentName componentName = ComponentName.unflattenFromString(name);
13955 if (componentName != null) {
13956 if (components == null) {
13957 components = new ArrayList<ComponentName>();
13959 components.add(componentName);
13963 // Not a '/' separated full component name; maybe an object ID?
13965 objectId = Integer.parseInt(name, 16);
13966 if (objects == null) {
13967 objects = new ArrayList<Integer>();
13969 objects.add(objectId);
13971 } catch (RuntimeException e) {
13972 // Not an integer; just do string match.
13973 if (strings == null) {
13974 strings = new ArrayList<String>();
13982 int build(String[] args, int opti) {
13983 for (; opti<args.length; opti++) {
13984 String name = args[opti];
13985 if ("--".equals(name)) {
13993 boolean match(Object object, ComponentName comp) {
13997 if (components != null) {
13998 for (int i=0; i<components.size(); i++) {
13999 if (components.get(i).equals(comp)) {
14004 if (objects != null) {
14005 for (int i=0; i<objects.size(); i++) {
14006 if (System.identityHashCode(object) == objects.get(i)) {
14011 if (strings != null) {
14012 String flat = comp.flattenToString();
14013 for (int i=0; i<strings.size(); i++) {
14014 if (flat.contains(strings.get(i))) {
14024 * There are three things that cmd can be:
14025 * - a flattened component name that matches an existing activity
14026 * - the cmd arg isn't the flattened component name of an existing activity:
14027 * dump all activity whose component contains the cmd as a substring
14028 * - A hex number of the ActivityRecord object instance.
14030 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14031 int opti, boolean dumpAll) {
14032 ArrayList<ActivityRecord> activities;
14034 synchronized (this) {
14035 activities = mStackSupervisor.getDumpActivitiesLocked(name);
14038 if (activities.size() <= 0) {
14042 String[] newArgs = new String[args.length - opti];
14043 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14045 TaskRecord lastTask = null;
14046 boolean needSep = false;
14047 for (int i=activities.size()-1; i>=0; i--) {
14048 ActivityRecord r = activities.get(i);
14053 synchronized (this) {
14054 if (lastTask != r.task) {
14056 pw.print("TASK "); pw.print(lastTask.affinity);
14057 pw.print(" id="); pw.println(lastTask.taskId);
14059 lastTask.dump(pw, " ");
14063 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
14069 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14070 * there is a thread associated with the activity.
14072 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14073 final ActivityRecord r, String[] args, boolean dumpAll) {
14074 String innerPrefix = prefix + " ";
14075 synchronized (this) {
14076 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14077 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14079 if (r.app != null) pw.println(r.app.pid);
14080 else pw.println("(not running)");
14082 r.dump(pw, innerPrefix);
14085 if (r.app != null && r.app.thread != null) {
14086 // flush anything that is already in the PrintWriter since the thread is going
14087 // to write to the file descriptor directly
14090 TransferPipe tp = new TransferPipe();
14092 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14093 r.appToken, innerPrefix, args);
14098 } catch (IOException e) {
14099 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14100 } catch (RemoteException e) {
14101 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14106 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14107 int opti, boolean dumpAll, String dumpPackage) {
14108 boolean needSep = false;
14109 boolean onlyHistory = false;
14110 boolean printedAnything = false;
14112 if ("history".equals(dumpPackage)) {
14113 if (opti < args.length && "-s".equals(args[opti])) {
14116 onlyHistory = true;
14117 dumpPackage = null;
14120 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14121 if (!onlyHistory && dumpAll) {
14122 if (mRegisteredReceivers.size() > 0) {
14123 boolean printed = false;
14124 Iterator it = mRegisteredReceivers.values().iterator();
14125 while (it.hasNext()) {
14126 ReceiverList r = (ReceiverList)it.next();
14127 if (dumpPackage != null && (r.app == null ||
14128 !dumpPackage.equals(r.app.info.packageName))) {
14132 pw.println(" Registered Receivers:");
14135 printedAnything = true;
14137 pw.print(" * "); pw.println(r);
14142 if (mReceiverResolver.dump(pw, needSep ?
14143 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
14144 " ", dumpPackage, false, false)) {
14146 printedAnything = true;
14150 for (BroadcastQueue q : mBroadcastQueues) {
14151 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14152 printedAnything |= needSep;
14157 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14158 for (int user=0; user<mStickyBroadcasts.size(); user++) {
14163 printedAnything = true;
14164 pw.print(" Sticky broadcasts for user ");
14165 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14166 StringBuilder sb = new StringBuilder(128);
14167 for (Map.Entry<String, ArrayList<Intent>> ent
14168 : mStickyBroadcasts.valueAt(user).entrySet()) {
14169 pw.print(" * Sticky action "); pw.print(ent.getKey());
14172 ArrayList<Intent> intents = ent.getValue();
14173 final int N = intents.size();
14174 for (int i=0; i<N; i++) {
14176 sb.append(" Intent: ");
14177 intents.get(i).toShortString(sb, false, true, false, false);
14178 pw.println(sb.toString());
14179 Bundle bundle = intents.get(i).getExtras();
14180 if (bundle != null) {
14182 pw.println(bundle.toString());
14192 if (!onlyHistory && dumpAll) {
14194 for (BroadcastQueue queue : mBroadcastQueues) {
14195 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
14196 + queue.mBroadcastsScheduled);
14198 pw.println(" mHandler:");
14199 mHandler.dump(new PrintWriterPrinter(pw), " ");
14201 printedAnything = true;
14204 if (!printedAnything) {
14205 pw.println(" (nothing)");
14209 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14210 int opti, boolean dumpAll, String dumpPackage) {
14212 boolean printedAnything = false;
14214 ItemMatcher matcher = new ItemMatcher();
14215 matcher.build(args, opti);
14217 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14219 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14220 printedAnything |= needSep;
14222 if (mLaunchingProviders.size() > 0) {
14223 boolean printed = false;
14224 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14225 ContentProviderRecord r = mLaunchingProviders.get(i);
14226 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14230 if (needSep) pw.println();
14232 pw.println(" Launching content providers:");
14234 printedAnything = true;
14236 pw.print(" Launching #"); pw.print(i); pw.print(": ");
14241 if (!printedAnything) {
14242 pw.println(" (nothing)");
14246 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14247 int opti, boolean dumpAll, String dumpPackage) {
14248 boolean needSep = false;
14249 boolean printedAnything = false;
14251 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14253 if (mGrantedUriPermissions.size() > 0) {
14254 boolean printed = false;
14256 if (dumpPackage != null) {
14258 dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
14259 } catch (NameNotFoundException e) {
14263 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14264 int uid = mGrantedUriPermissions.keyAt(i);
14265 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14268 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14270 if (needSep) pw.println();
14272 pw.println(" Granted Uri Permissions:");
14274 printedAnything = true;
14276 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
14277 for (UriPermission perm : perms.values()) {
14278 pw.print(" "); pw.println(perm);
14280 perm.dump(pw, " ");
14286 if (!printedAnything) {
14287 pw.println(" (nothing)");
14291 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14292 int opti, boolean dumpAll, String dumpPackage) {
14293 boolean printed = false;
14295 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14297 if (mIntentSenderRecords.size() > 0) {
14298 Iterator<WeakReference<PendingIntentRecord>> it
14299 = mIntentSenderRecords.values().iterator();
14300 while (it.hasNext()) {
14301 WeakReference<PendingIntentRecord> ref = it.next();
14302 PendingIntentRecord rec = ref != null ? ref.get(): null;
14303 if (dumpPackage != null && (rec == null
14304 || !dumpPackage.equals(rec.key.packageName))) {
14309 pw.print(" * "); pw.println(rec);
14314 pw.print(" * "); pw.println(ref);
14320 pw.println(" (nothing)");
14324 private static final int dumpProcessList(PrintWriter pw,
14325 ActivityManagerService service, List list,
14326 String prefix, String normalLabel, String persistentLabel,
14327 String dumpPackage) {
14329 final int N = list.size()-1;
14330 for (int i=N; i>=0; i--) {
14331 ProcessRecord r = (ProcessRecord)list.get(i);
14332 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14335 pw.println(String.format("%s%s #%2d: %s",
14336 prefix, (r.persistent ? persistentLabel : normalLabel),
14338 if (r.persistent) {
14345 private static final boolean dumpProcessOomList(PrintWriter pw,
14346 ActivityManagerService service, List<ProcessRecord> origList,
14347 String prefix, String normalLabel, String persistentLabel,
14348 boolean inclDetails, String dumpPackage) {
14350 ArrayList<Pair<ProcessRecord, Integer>> list
14351 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14352 for (int i=0; i<origList.size(); i++) {
14353 ProcessRecord r = origList.get(i);
14354 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14357 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14360 if (list.size() <= 0) {
14364 Comparator<Pair<ProcessRecord, Integer>> comparator
14365 = new Comparator<Pair<ProcessRecord, Integer>>() {
14367 public int compare(Pair<ProcessRecord, Integer> object1,
14368 Pair<ProcessRecord, Integer> object2) {
14369 if (object1.first.setAdj != object2.first.setAdj) {
14370 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14372 if (object1.second.intValue() != object2.second.intValue()) {
14373 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14379 Collections.sort(list, comparator);
14381 final long curRealtime = SystemClock.elapsedRealtime();
14382 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14383 final long curUptime = SystemClock.uptimeMillis();
14384 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14386 for (int i=list.size()-1; i>=0; i--) {
14387 ProcessRecord r = list.get(i).first;
14388 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14390 switch (r.setSchedGroup) {
14391 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
14394 case Process.THREAD_GROUP_DEFAULT:
14402 if (r.foregroundActivities) {
14404 } else if (r.foregroundServices) {
14409 String procState = ProcessList.makeProcStateString(r.curProcState);
14411 pw.print(r.persistent ? persistentLabel : normalLabel);
14413 int num = (origList.size()-1)-list.get(i).second;
14414 if (num < 10) pw.print(' ');
14419 pw.print(schedGroup);
14421 pw.print(foreground);
14423 pw.print(procState);
14425 if (r.trimMemoryLevel < 10) pw.print(' ');
14426 pw.print(r.trimMemoryLevel);
14428 pw.print(r.toShortString());
14430 pw.print(r.adjType);
14432 if (r.adjSource != null || r.adjTarget != null) {
14435 if (r.adjTarget instanceof ComponentName) {
14436 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14437 } else if (r.adjTarget != null) {
14438 pw.print(r.adjTarget.toString());
14440 pw.print("{null}");
14443 if (r.adjSource instanceof ProcessRecord) {
14445 pw.print(((ProcessRecord)r.adjSource).toShortString());
14447 } else if (r.adjSource != null) {
14448 pw.println(r.adjSource.toString());
14450 pw.println("{null}");
14456 pw.print("oom: max="); pw.print(r.maxAdj);
14457 pw.print(" curRaw="); pw.print(r.curRawAdj);
14458 pw.print(" setRaw="); pw.print(r.setRawAdj);
14459 pw.print(" cur="); pw.print(r.curAdj);
14460 pw.print(" set="); pw.println(r.setAdj);
14463 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
14464 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
14465 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
14466 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
14470 pw.print("cached="); pw.print(r.cached);
14471 pw.print(" empty="); pw.print(r.empty);
14472 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
14474 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
14475 if (r.lastWakeTime != 0) {
14477 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
14478 synchronized (stats) {
14479 wtime = stats.getProcessWakeTime(r.info.uid,
14480 r.pid, curRealtime);
14482 long timeUsed = wtime - r.lastWakeTime;
14485 pw.print("keep awake over ");
14486 TimeUtils.formatDuration(realtimeSince, pw);
14487 pw.print(" used ");
14488 TimeUtils.formatDuration(timeUsed, pw);
14490 pw.print((timeUsed*100)/realtimeSince);
14493 if (r.lastCpuTime != 0) {
14494 long timeUsed = r.curCpuTime - r.lastCpuTime;
14497 pw.print("run cpu over ");
14498 TimeUtils.formatDuration(uptimeSince, pw);
14499 pw.print(" used ");
14500 TimeUtils.formatDuration(timeUsed, pw);
14502 pw.print((timeUsed*100)/uptimeSince);
14511 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
14513 ArrayList<ProcessRecord> procs;
14514 synchronized (this) {
14515 if (args != null && args.length > start
14516 && args[start].charAt(0) != '-') {
14517 procs = new ArrayList<ProcessRecord>();
14520 pid = Integer.parseInt(args[start]);
14521 } catch (NumberFormatException e) {
14523 for (int i=mLruProcesses.size()-1; i>=0; i--) {
14524 ProcessRecord proc = mLruProcesses.get(i);
14525 if (proc.pid == pid) {
14527 } else if (allPkgs && proc.pkgList != null
14528 && proc.pkgList.containsKey(args[start])) {
14530 } else if (proc.processName.equals(args[start])) {
14534 if (procs.size() <= 0) {
14538 procs = new ArrayList<ProcessRecord>(mLruProcesses);
14544 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
14545 PrintWriter pw, String[] args) {
14546 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14547 if (procs == null) {
14548 pw.println("No process found for: " + args[0]);
14552 long uptime = SystemClock.uptimeMillis();
14553 long realtime = SystemClock.elapsedRealtime();
14554 pw.println("Applications Graphics Acceleration Info:");
14555 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14557 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14558 ProcessRecord r = procs.get(i);
14559 if (r.thread != null) {
14560 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
14563 TransferPipe tp = new TransferPipe();
14565 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
14570 } catch (IOException e) {
14571 pw.println("Failure while dumping the app: " + r);
14573 } catch (RemoteException e) {
14574 pw.println("Got a RemoteException while dumping the app " + r);
14581 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
14582 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
14583 if (procs == null) {
14584 pw.println("No process found for: " + args[0]);
14588 pw.println("Applications Database Info:");
14590 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14591 ProcessRecord r = procs.get(i);
14592 if (r.thread != null) {
14593 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
14596 TransferPipe tp = new TransferPipe();
14598 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
14603 } catch (IOException e) {
14604 pw.println("Failure while dumping the app: " + r);
14606 } catch (RemoteException e) {
14607 pw.println("Got a RemoteException while dumping the app " + r);
14614 final static class MemItem {
14615 final boolean isProc;
14616 final String label;
14617 final String shortLabel;
14620 final boolean hasActivities;
14621 ArrayList<MemItem> subitems;
14623 public MemItem(String _label, String _shortLabel, long _pss, int _id,
14624 boolean _hasActivities) {
14627 shortLabel = _shortLabel;
14630 hasActivities = _hasActivities;
14633 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
14636 shortLabel = _shortLabel;
14639 hasActivities = false;
14643 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
14644 ArrayList<MemItem> items, boolean sort, boolean isCompact) {
14645 if (sort && !isCompact) {
14646 Collections.sort(items, new Comparator<MemItem>() {
14648 public int compare(MemItem lhs, MemItem rhs) {
14649 if (lhs.pss < rhs.pss) {
14651 } else if (lhs.pss > rhs.pss) {
14659 for (int i=0; i<items.size(); i++) {
14660 MemItem mi = items.get(i);
14662 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
14663 } else if (mi.isProc) {
14664 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
14665 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
14666 pw.println(mi.hasActivities ? ",a" : ",e");
14668 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
14669 pw.println(mi.pss);
14671 if (mi.subitems != null) {
14672 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
14678 // These are in KB.
14679 static final long[] DUMP_MEM_BUCKETS = new long[] {
14680 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
14681 120*1024, 160*1024, 200*1024,
14682 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
14683 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
14686 static final void appendMemBucket(StringBuilder out, long memKB, String label,
14687 boolean stackLike) {
14688 int start = label.lastIndexOf('.');
14689 if (start >= 0) start++;
14691 int end = label.length();
14692 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
14693 if (DUMP_MEM_BUCKETS[i] >= memKB) {
14694 long bucket = DUMP_MEM_BUCKETS[i]/1024;
14695 out.append(bucket);
14696 out.append(stackLike ? "MB." : "MB ");
14697 out.append(label, start, end);
14701 out.append(memKB/1024);
14702 out.append(stackLike ? "MB." : "MB ");
14703 out.append(label, start, end);
14706 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
14707 ProcessList.NATIVE_ADJ,
14708 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
14709 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
14710 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
14711 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
14712 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
14713 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
14715 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
14717 "System", "Persistent", "Persistent Service", "Foreground",
14718 "Visible", "Perceptible",
14719 "Heavy Weight", "Backup",
14720 "A Services", "Home",
14721 "Previous", "B Services", "Cached"
14723 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
14725 "sys", "pers", "persvc", "fore",
14728 "servicea", "home",
14729 "prev", "serviceb", "cached"
14732 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
14733 long realtime, boolean isCheckinRequest, boolean isCompact) {
14734 if (isCheckinRequest || isCompact) {
14735 // short checkin version
14736 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
14738 pw.println("Applications Memory Usage (kB):");
14739 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
14743 private static final int KSM_SHARED = 0;
14744 private static final int KSM_SHARING = 1;
14745 private static final int KSM_UNSHARED = 2;
14746 private static final int KSM_VOLATILE = 3;
14748 private final long[] getKsmInfo() {
14749 long[] longOut = new long[4];
14750 final int[] SINGLE_LONG_FORMAT = new int[] {
14751 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14753 long[] longTmp = new long[1];
14754 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14755 SINGLE_LONG_FORMAT, null, longTmp, null);
14756 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14758 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14759 SINGLE_LONG_FORMAT, null, longTmp, null);
14760 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14762 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14763 SINGLE_LONG_FORMAT, null, longTmp, null);
14764 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14766 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14767 SINGLE_LONG_FORMAT, null, longTmp, null);
14768 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
14772 final void dumpApplicationMemoryUsage(FileDescriptor fd,
14773 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
14774 boolean dumpDetails = false;
14775 boolean dumpFullDetails = false;
14776 boolean dumpDalvik = false;
14777 boolean dumpSummaryOnly = false;
14778 boolean oomOnly = false;
14779 boolean isCompact = false;
14780 boolean localOnly = false;
14781 boolean packages = false;
14784 while (opti < args.length) {
14785 String opt = args[opti];
14786 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14790 if ("-a".equals(opt)) {
14791 dumpDetails = true;
14792 dumpFullDetails = true;
14794 } else if ("-d".equals(opt)) {
14796 } else if ("-c".equals(opt)) {
14798 } else if ("-s".equals(opt)) {
14799 dumpDetails = true;
14800 dumpSummaryOnly = true;
14801 } else if ("--oom".equals(opt)) {
14803 } else if ("--local".equals(opt)) {
14805 } else if ("--package".equals(opt)) {
14807 } else if ("-h".equals(opt)) {
14808 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
14809 pw.println(" -a: include all available information for each process.");
14810 pw.println(" -d: include dalvik details.");
14811 pw.println(" -c: dump in a compact machine-parseable representation.");
14812 pw.println(" -s: dump only summary of application memory usage.");
14813 pw.println(" --oom: only show processes organized by oom adj.");
14814 pw.println(" --local: only collect details locally, don't call process.");
14815 pw.println(" --package: interpret process arg as package, dumping all");
14816 pw.println(" processes that have loaded that package.");
14817 pw.println("If [process] is specified it can be the name or ");
14818 pw.println("pid of a specific process to dump.");
14821 pw.println("Unknown argument: " + opt + "; use -h for help");
14825 final boolean isCheckinRequest = scanArgs(args, "--checkin");
14826 long uptime = SystemClock.uptimeMillis();
14827 long realtime = SystemClock.elapsedRealtime();
14828 final long[] tmpLong = new long[1];
14830 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
14831 if (procs == null) {
14832 // No Java processes. Maybe they want to print a native process.
14833 if (args != null && args.length > opti
14834 && args[opti].charAt(0) != '-') {
14835 ArrayList<ProcessCpuTracker.Stats> nativeProcs
14836 = new ArrayList<ProcessCpuTracker.Stats>();
14837 updateCpuStatsNow();
14840 findPid = Integer.parseInt(args[opti]);
14841 } catch (NumberFormatException e) {
14843 synchronized (mProcessCpuTracker) {
14844 final int N = mProcessCpuTracker.countStats();
14845 for (int i=0; i<N; i++) {
14846 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
14847 if (st.pid == findPid || (st.baseName != null
14848 && st.baseName.equals(args[opti]))) {
14849 nativeProcs.add(st);
14853 if (nativeProcs.size() > 0) {
14854 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
14856 Debug.MemoryInfo mi = null;
14857 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
14858 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
14859 final int pid = r.pid;
14860 if (!isCheckinRequest && dumpDetails) {
14861 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
14864 mi = new Debug.MemoryInfo();
14866 if (dumpDetails || (!brief && !oomOnly)) {
14867 Debug.getMemoryInfo(pid, mi);
14869 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14870 mi.dalvikPrivateDirty = (int)tmpLong[0];
14872 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14873 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
14874 if (isCheckinRequest) {
14881 pw.println("No process found for: " + args[opti]);
14885 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
14886 dumpDetails = true;
14889 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
14891 String[] innerArgs = new String[args.length-opti];
14892 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
14894 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
14895 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
14896 long nativePss = 0;
14897 long dalvikPss = 0;
14898 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
14901 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
14903 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
14904 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
14905 new ArrayList[DUMP_MEM_OOM_LABEL.length];
14908 long cachedPss = 0;
14910 Debug.MemoryInfo mi = null;
14911 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
14912 final ProcessRecord r = procs.get(i);
14913 final IApplicationThread thread;
14916 final boolean hasActivities;
14917 synchronized (this) {
14920 oomAdj = r.getSetAdjWithServices();
14921 hasActivities = r.activities.size() > 0;
14923 if (thread != null) {
14924 if (!isCheckinRequest && dumpDetails) {
14925 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
14928 mi = new Debug.MemoryInfo();
14930 if (dumpDetails || (!brief && !oomOnly)) {
14931 Debug.getMemoryInfo(pid, mi);
14933 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
14934 mi.dalvikPrivateDirty = (int)tmpLong[0];
14938 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
14939 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
14940 if (isCheckinRequest) {
14946 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
14947 dumpDalvik, dumpSummaryOnly, innerArgs);
14948 } catch (RemoteException e) {
14949 if (!isCheckinRequest) {
14950 pw.println("Got RemoteException!");
14957 final long myTotalPss = mi.getTotalPss();
14958 final long myTotalUss = mi.getTotalUss();
14960 synchronized (this) {
14961 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
14962 // Record this for posterity if the process has been stable.
14963 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
14967 if (!isCheckinRequest && mi != null) {
14968 totalPss += myTotalPss;
14969 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
14970 (hasActivities ? " / activities)" : ")"),
14971 r.processName, myTotalPss, pid, hasActivities);
14972 procMems.add(pssItem);
14973 procMemsMap.put(pid, pssItem);
14975 nativePss += mi.nativePss;
14976 dalvikPss += mi.dalvikPss;
14977 for (int j=0; j<dalvikSubitemPss.length; j++) {
14978 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
14980 otherPss += mi.otherPss;
14981 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
14982 long mem = mi.getOtherPss(j);
14987 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
14988 cachedPss += myTotalPss;
14991 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
14992 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
14993 || oomIndex == (oomPss.length-1)) {
14994 oomPss[oomIndex] += myTotalPss;
14995 if (oomProcs[oomIndex] == null) {
14996 oomProcs[oomIndex] = new ArrayList<MemItem>();
14998 oomProcs[oomIndex].add(pssItem);
15006 long nativeProcTotalPss = 0;
15008 if (!isCheckinRequest && procs.size() > 1 && !packages) {
15009 // If we are showing aggregations, also look for native processes to
15010 // include so that our aggregations are more accurate.
15011 updateCpuStatsNow();
15013 synchronized (mProcessCpuTracker) {
15014 final int N = mProcessCpuTracker.countStats();
15015 for (int i=0; i<N; i++) {
15016 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15017 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15019 mi = new Debug.MemoryInfo();
15021 if (!brief && !oomOnly) {
15022 Debug.getMemoryInfo(st.pid, mi);
15024 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15025 mi.nativePrivateDirty = (int)tmpLong[0];
15028 final long myTotalPss = mi.getTotalPss();
15029 totalPss += myTotalPss;
15030 nativeProcTotalPss += myTotalPss;
15032 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15033 st.name, myTotalPss, st.pid, false);
15034 procMems.add(pssItem);
15036 nativePss += mi.nativePss;
15037 dalvikPss += mi.dalvikPss;
15038 for (int j=0; j<dalvikSubitemPss.length; j++) {
15039 dalvikSubitemPss[j] += mi.getOtherPss(
15040 Debug.MemoryInfo.NUM_OTHER_STATS + j);
15042 otherPss += mi.otherPss;
15043 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15044 long mem = mi.getOtherPss(j);
15048 oomPss[0] += myTotalPss;
15049 if (oomProcs[0] == null) {
15050 oomProcs[0] = new ArrayList<MemItem>();
15052 oomProcs[0].add(pssItem);
15057 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15059 catMems.add(new MemItem("Native", "Native", nativePss, -1));
15060 final MemItem dalvikItem = new MemItem("Dalvik", "Dalvik", dalvikPss, -2);
15061 if (dalvikSubitemPss.length > 0) {
15062 dalvikItem.subitems = new ArrayList<MemItem>();
15063 for (int j=0; j<dalvikSubitemPss.length; j++) {
15064 final String name = Debug.MemoryInfo.getOtherLabel(
15065 Debug.MemoryInfo.NUM_OTHER_STATS + j);
15066 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j], j));
15069 catMems.add(dalvikItem);
15070 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
15071 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15072 String label = Debug.MemoryInfo.getOtherLabel(j);
15073 catMems.add(new MemItem(label, label, miscPss[j], j));
15076 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15077 for (int j=0; j<oomPss.length; j++) {
15078 if (oomPss[j] != 0) {
15079 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15080 : DUMP_MEM_OOM_LABEL[j];
15081 MemItem item = new MemItem(label, label, oomPss[j],
15082 DUMP_MEM_OOM_ADJ[j]);
15083 item.subitems = oomProcs[j];
15088 if (!brief && !oomOnly && !isCompact) {
15090 pw.println("Total PSS by process:");
15091 dumpMemItems(pw, " ", "proc", procMems, true, isCompact);
15095 pw.println("Total PSS by OOM adjustment:");
15097 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact);
15098 if (!brief && !oomOnly) {
15099 PrintWriter out = categoryPw != null ? categoryPw : pw;
15102 out.println("Total PSS by category:");
15104 dumpMemItems(out, " ", "cat", catMems, true, isCompact);
15109 MemInfoReader memInfo = new MemInfoReader();
15110 memInfo.readMemInfo();
15111 if (nativeProcTotalPss > 0) {
15112 synchronized (this) {
15113 final long cachedKb = memInfo.getCachedSizeKb();
15114 final long freeKb = memInfo.getFreeSizeKb();
15115 final long zramKb = memInfo.getZramTotalSizeKb();
15116 final long kernelKb = memInfo.getKernelUsedSizeKb();
15117 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15118 kernelKb*1024, nativeProcTotalPss*1024);
15119 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15120 nativeProcTotalPss);
15125 pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
15126 pw.print(" kB (status ");
15127 switch (mLastMemoryLevel) {
15128 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15129 pw.println("normal)");
15131 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15132 pw.println("moderate)");
15134 case ProcessStats.ADJ_MEM_FACTOR_LOW:
15135 pw.println("low)");
15137 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15138 pw.println("critical)");
15141 pw.print(mLastMemoryLevel);
15145 pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
15146 + memInfo.getFreeSizeKb()); pw.print(" kB (");
15147 pw.print(cachedPss); pw.print(" cached pss + ");
15148 pw.print(memInfo.getCachedSizeKb()); pw.print(" cached kernel + ");
15149 pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
15151 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15152 pw.print(cachedPss + memInfo.getCachedSizeKb()
15153 + memInfo.getFreeSizeKb()); pw.print(",");
15154 pw.println(totalPss - cachedPss);
15158 pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
15159 + memInfo.getKernelUsedSizeKb()); pw.print(" kB (");
15160 pw.print(totalPss - cachedPss); pw.print(" used pss + ");
15161 pw.print(memInfo.getKernelUsedSizeKb()); pw.print(" kernel)\n");
15162 pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
15163 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15164 - memInfo.getKernelUsedSizeKb()); pw.println(" kB");
15166 pw.print("lostram,"); pw.println(memInfo.getTotalSizeKb()
15167 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15168 - memInfo.getKernelUsedSizeKb());
15171 if (memInfo.getZramTotalSizeKb() != 0) {
15173 pw.print(" ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
15174 pw.print(" kB physical used for ");
15175 pw.print(memInfo.getSwapTotalSizeKb()
15176 - memInfo.getSwapFreeSizeKb());
15177 pw.print(" kB in swap (");
15178 pw.print(memInfo.getSwapTotalSizeKb());
15179 pw.println(" kB total swap)");
15181 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15182 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15183 pw.println(memInfo.getSwapFreeSizeKb());
15186 final long[] ksm = getKsmInfo();
15188 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15189 || ksm[KSM_VOLATILE] != 0) {
15190 pw.print(" KSM: "); pw.print(ksm[KSM_SHARING]);
15191 pw.print(" kB saved from shared ");
15192 pw.print(ksm[KSM_SHARED]); pw.println(" kB");
15193 pw.print(" "); pw.print(ksm[KSM_UNSHARED]);
15194 pw.print(" kB unshared; ");
15195 pw.print(ksm[KSM_VOLATILE]); pw.println(" kB volatile");
15197 pw.print(" Tuning: ");
15198 pw.print(ActivityManager.staticGetMemoryClass());
15199 pw.print(" (large ");
15200 pw.print(ActivityManager.staticGetLargeMemoryClass());
15201 pw.print("), oom ");
15202 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15204 pw.print(", restore limit ");
15205 pw.print(mProcessList.getCachedRestoreThresholdKb());
15207 if (ActivityManager.isLowRamDeviceStatic()) {
15208 pw.print(" (low-ram)");
15210 if (ActivityManager.isHighEndGfx()) {
15211 pw.print(" (high-end-gfx)");
15215 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15216 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15217 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15218 pw.print("tuning,");
15219 pw.print(ActivityManager.staticGetMemoryClass());
15221 pw.print(ActivityManager.staticGetLargeMemoryClass());
15223 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15224 if (ActivityManager.isLowRamDeviceStatic()) {
15225 pw.print(",low-ram");
15227 if (ActivityManager.isHighEndGfx()) {
15228 pw.print(",high-end-gfx");
15236 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15237 long memtrack, String name) {
15239 sb.append(ProcessList.makeOomAdjString(oomAdj));
15241 sb.append(ProcessList.makeProcStateString(procState));
15243 ProcessList.appendRamKb(sb, pss);
15244 sb.append(" kB: ");
15246 if (memtrack > 0) {
15248 sb.append(memtrack);
15249 sb.append(" kB memtrack)");
15253 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15254 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15255 sb.append(" (pid ");
15258 sb.append(mi.adjType);
15260 if (mi.adjReason != null) {
15262 sb.append(mi.adjReason);
15267 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15268 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15269 for (int i=0, N=memInfos.size(); i<N; i++) {
15270 ProcessMemInfo mi = memInfos.get(i);
15271 infoMap.put(mi.pid, mi);
15273 updateCpuStatsNow();
15274 long[] memtrackTmp = new long[1];
15275 synchronized (mProcessCpuTracker) {
15276 final int N = mProcessCpuTracker.countStats();
15277 for (int i=0; i<N; i++) {
15278 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15279 if (st.vsize > 0) {
15280 long pss = Debug.getPss(st.pid, null, memtrackTmp);
15282 if (infoMap.indexOfKey(st.pid) < 0) {
15283 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15284 ProcessList.NATIVE_ADJ, -1, "native", null);
15286 mi.memtrack = memtrackTmp[0];
15295 long totalMemtrack = 0;
15296 for (int i=0, N=memInfos.size(); i<N; i++) {
15297 ProcessMemInfo mi = memInfos.get(i);
15299 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15300 mi.memtrack = memtrackTmp[0];
15302 totalPss += mi.pss;
15303 totalMemtrack += mi.memtrack;
15305 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15306 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15307 if (lhs.oomAdj != rhs.oomAdj) {
15308 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15310 if (lhs.pss != rhs.pss) {
15311 return lhs.pss < rhs.pss ? 1 : -1;
15317 StringBuilder tag = new StringBuilder(128);
15318 StringBuilder stack = new StringBuilder(128);
15319 tag.append("Low on memory -- ");
15320 appendMemBucket(tag, totalPss, "total", false);
15321 appendMemBucket(stack, totalPss, "total", true);
15323 StringBuilder fullNativeBuilder = new StringBuilder(1024);
15324 StringBuilder shortNativeBuilder = new StringBuilder(1024);
15325 StringBuilder fullJavaBuilder = new StringBuilder(1024);
15327 boolean firstLine = true;
15328 int lastOomAdj = Integer.MIN_VALUE;
15329 long extraNativeRam = 0;
15330 long extraNativeMemtrack = 0;
15331 long cachedPss = 0;
15332 for (int i=0, N=memInfos.size(); i<N; i++) {
15333 ProcessMemInfo mi = memInfos.get(i);
15335 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15336 cachedPss += mi.pss;
15339 if (mi.oomAdj != ProcessList.NATIVE_ADJ
15340 && (mi.oomAdj < ProcessList.SERVICE_ADJ
15341 || mi.oomAdj == ProcessList.HOME_APP_ADJ
15342 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15343 if (lastOomAdj != mi.oomAdj) {
15344 lastOomAdj = mi.oomAdj;
15345 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15348 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15353 stack.append("\n\t at ");
15361 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15362 appendMemBucket(tag, mi.pss, mi.name, false);
15364 appendMemBucket(stack, mi.pss, mi.name, true);
15365 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
15366 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
15368 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
15369 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
15370 stack.append(DUMP_MEM_OOM_LABEL[k]);
15372 stack.append(DUMP_MEM_OOM_ADJ[k]);
15379 appendMemInfo(fullNativeBuilder, mi);
15380 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
15381 // The short form only has native processes that are >= 512K.
15382 if (mi.pss >= 512) {
15383 appendMemInfo(shortNativeBuilder, mi);
15385 extraNativeRam += mi.pss;
15386 extraNativeMemtrack += mi.memtrack;
15389 // Short form has all other details, but if we have collected RAM
15390 // from smaller native processes let's dump a summary of that.
15391 if (extraNativeRam > 0) {
15392 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
15393 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
15394 shortNativeBuilder.append('\n');
15395 extraNativeRam = 0;
15397 appendMemInfo(fullJavaBuilder, mi);
15401 fullJavaBuilder.append(" ");
15402 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
15403 fullJavaBuilder.append(" kB: TOTAL");
15404 if (totalMemtrack > 0) {
15405 fullJavaBuilder.append(" (");
15406 fullJavaBuilder.append(totalMemtrack);
15407 fullJavaBuilder.append(" kB memtrack)");
15410 fullJavaBuilder.append("\n");
15412 MemInfoReader memInfo = new MemInfoReader();
15413 memInfo.readMemInfo();
15414 final long[] infos = memInfo.getRawInfo();
15416 StringBuilder memInfoBuilder = new StringBuilder(1024);
15417 Debug.getMemInfo(infos);
15418 memInfoBuilder.append(" MemInfo: ");
15419 memInfoBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
15420 memInfoBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
15421 memInfoBuilder.append(infos[Debug.MEMINFO_VM_ALLOC_USED]).append(" kB vm alloc, ");
15422 memInfoBuilder.append(infos[Debug.MEMINFO_PAGE_TABLES]).append(" kB page tables ");
15423 memInfoBuilder.append(infos[Debug.MEMINFO_KERNEL_STACK]).append(" kB kernel stack\n");
15424 memInfoBuilder.append(" ");
15425 memInfoBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
15426 memInfoBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
15427 memInfoBuilder.append(infos[Debug.MEMINFO_MAPPED]).append(" kB mapped, ");
15428 memInfoBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
15429 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
15430 memInfoBuilder.append(" ZRAM: ");
15431 memInfoBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
15432 memInfoBuilder.append(" kB RAM, ");
15433 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
15434 memInfoBuilder.append(" kB swap total, ");
15435 memInfoBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
15436 memInfoBuilder.append(" kB swap free\n");
15438 final long[] ksm = getKsmInfo();
15439 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15440 || ksm[KSM_VOLATILE] != 0) {
15441 memInfoBuilder.append(" KSM: "); memInfoBuilder.append(ksm[KSM_SHARING]);
15442 memInfoBuilder.append(" kB saved from shared ");
15443 memInfoBuilder.append(ksm[KSM_SHARED]); memInfoBuilder.append(" kB\n");
15444 memInfoBuilder.append(" "); memInfoBuilder.append(ksm[KSM_UNSHARED]);
15445 memInfoBuilder.append(" kB unshared; ");
15446 memInfoBuilder.append(ksm[KSM_VOLATILE]); memInfoBuilder.append(" kB volatile\n");
15448 memInfoBuilder.append(" Free RAM: ");
15449 memInfoBuilder.append(cachedPss + memInfo.getCachedSizeKb()
15450 + memInfo.getFreeSizeKb());
15451 memInfoBuilder.append(" kB\n");
15452 memInfoBuilder.append(" Used RAM: ");
15453 memInfoBuilder.append(totalPss - cachedPss + memInfo.getKernelUsedSizeKb());
15454 memInfoBuilder.append(" kB\n");
15455 memInfoBuilder.append(" Lost RAM: ");
15456 memInfoBuilder.append(memInfo.getTotalSizeKb()
15457 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15458 - memInfo.getKernelUsedSizeKb());
15459 memInfoBuilder.append(" kB\n");
15460 Slog.i(TAG, "Low on memory:");
15461 Slog.i(TAG, shortNativeBuilder.toString());
15462 Slog.i(TAG, fullJavaBuilder.toString());
15463 Slog.i(TAG, memInfoBuilder.toString());
15465 StringBuilder dropBuilder = new StringBuilder(1024);
15467 StringWriter oomSw = new StringWriter();
15468 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
15469 StringWriter catSw = new StringWriter();
15470 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15471 String[] emptyArgs = new String[] { };
15472 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
15474 String oomString = oomSw.toString();
15476 dropBuilder.append("Low on memory:");
15477 dropBuilder.append(stack);
15478 dropBuilder.append('\n');
15479 dropBuilder.append(fullNativeBuilder);
15480 dropBuilder.append(fullJavaBuilder);
15481 dropBuilder.append('\n');
15482 dropBuilder.append(memInfoBuilder);
15483 dropBuilder.append('\n');
15485 dropBuilder.append(oomString);
15486 dropBuilder.append('\n');
15488 StringWriter catSw = new StringWriter();
15489 synchronized (ActivityManagerService.this) {
15490 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
15491 String[] emptyArgs = new String[] { };
15493 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
15495 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
15496 false, false, null);
15498 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
15501 dropBuilder.append(catSw.toString());
15502 addErrorToDropBox("lowmem", null, "system_server", null,
15503 null, tag.toString(), dropBuilder.toString(), null, null);
15504 //Slog.i(TAG, "Sent to dropbox:");
15505 //Slog.i(TAG, dropBuilder.toString());
15506 synchronized (ActivityManagerService.this) {
15507 long now = SystemClock.uptimeMillis();
15508 if (mLastMemUsageReportTime < now) {
15509 mLastMemUsageReportTime = now;
15515 * Searches array of arguments for the specified string
15516 * @param args array of argument strings
15517 * @param value value to search for
15518 * @return true if the value is contained in the array
15520 private static boolean scanArgs(String[] args, String value) {
15521 if (args != null) {
15522 for (String arg : args) {
15523 if (value.equals(arg)) {
15531 private final boolean removeDyingProviderLocked(ProcessRecord proc,
15532 ContentProviderRecord cpr, boolean always) {
15533 final boolean inLaunching = mLaunchingProviders.contains(cpr);
15535 if (!inLaunching || always) {
15536 synchronized (cpr) {
15537 cpr.launchingApp = null;
15540 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
15541 String names[] = cpr.info.authority.split(";");
15542 for (int j = 0; j < names.length; j++) {
15543 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
15547 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
15548 ContentProviderConnection conn = cpr.connections.get(i);
15549 if (conn.waiting) {
15550 // If this connection is waiting for the provider, then we don't
15551 // need to mess with its process unless we are always removing
15552 // or for some reason the provider is not currently launching.
15553 if (inLaunching && !always) {
15557 ProcessRecord capp = conn.client;
15559 if (conn.stableCount > 0) {
15560 if (!capp.persistent && capp.thread != null
15562 && capp.pid != MY_PID) {
15563 capp.kill("depends on provider "
15564 + cpr.name.flattenToShortString()
15565 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
15567 } else if (capp.thread != null && conn.provider.provider != null) {
15569 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
15570 } catch (RemoteException e) {
15572 // In the protocol here, we don't expect the client to correctly
15573 // clean up this connection, we'll just remove it.
15574 cpr.connections.remove(i);
15575 if (conn.client.conProviders.remove(conn)) {
15576 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
15581 if (inLaunching && always) {
15582 mLaunchingProviders.remove(cpr);
15584 return inLaunching;
15588 * Main code for cleaning up a process when it has gone away. This is
15589 * called both as a result of the process dying, or directly when stopping
15590 * a process when running in single process mode.
15592 * @return Returns true if the given process has been restarted, so the
15593 * app that was passed in must remain on the process lists.
15595 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
15596 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
15597 Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
15599 removeLruProcessLocked(app);
15600 ProcessList.remove(app.pid);
15603 mProcessesToGc.remove(app);
15604 mPendingPssProcesses.remove(app);
15606 // Dismiss any open dialogs.
15607 if (app.crashDialog != null && !app.forceCrashReport) {
15608 app.crashDialog.dismiss();
15609 app.crashDialog = null;
15611 if (app.anrDialog != null) {
15612 app.anrDialog.dismiss();
15613 app.anrDialog = null;
15615 if (app.waitDialog != null) {
15616 app.waitDialog.dismiss();
15617 app.waitDialog = null;
15620 app.crashing = false;
15621 app.notResponding = false;
15623 app.resetPackageList(mProcessStats);
15624 app.unlinkDeathRecipient();
15625 app.makeInactive(mProcessStats);
15626 app.waitingToKill = null;
15627 app.forcingToForeground = null;
15628 updateProcessForegroundLocked(app, false, false);
15629 app.foregroundActivities = false;
15630 app.hasShownUi = false;
15631 app.treatLikeActivity = false;
15632 app.hasAboveClient = false;
15633 app.hasClientActivities = false;
15635 mServices.killServicesLocked(app, allowRestart);
15637 boolean restart = false;
15639 // Remove published content providers.
15640 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
15641 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
15642 final boolean always = app.bad || !allowRestart;
15643 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
15644 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
15645 // We left the provider in the launching list, need to
15650 cpr.provider = null;
15653 app.pubProviders.clear();
15655 // Take care of any launching providers waiting for this process.
15656 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
15660 // Unregister from connected content providers.
15661 if (!app.conProviders.isEmpty()) {
15662 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
15663 ContentProviderConnection conn = app.conProviders.get(i);
15664 conn.provider.connections.remove(conn);
15665 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
15666 conn.provider.name);
15668 app.conProviders.clear();
15671 // At this point there may be remaining entries in mLaunchingProviders
15672 // where we were the only one waiting, so they are no longer of use.
15673 // Look for these and clean up if found.
15674 // XXX Commented out for now. Trying to figure out a way to reproduce
15675 // the actual situation to identify what is actually going on.
15677 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15678 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15679 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
15680 synchronized (cpr) {
15681 cpr.launchingApp = null;
15688 skipCurrentReceiverLocked(app);
15690 // Unregister any receivers.
15691 for (int i = app.receivers.size() - 1; i >= 0; i--) {
15692 removeReceiverLocked(app.receivers.valueAt(i));
15694 app.receivers.clear();
15696 // If the app is undergoing backup, tell the backup manager about it
15697 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
15698 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
15699 + mBackupTarget.appInfo + " died during backup");
15701 IBackupManager bm = IBackupManager.Stub.asInterface(
15702 ServiceManager.getService(Context.BACKUP_SERVICE));
15703 bm.agentDisconnected(app.info.packageName);
15704 } catch (RemoteException e) {
15705 // can't happen; backup manager is local
15709 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
15710 ProcessChangeItem item = mPendingProcessChanges.get(i);
15711 if (item.pid == app.pid) {
15712 mPendingProcessChanges.remove(i);
15713 mAvailProcessChanges.add(item);
15716 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
15718 // If the caller is restarting this app, then leave it in its
15719 // current lists and let the caller take care of it.
15724 if (!app.persistent || app.isolated) {
15725 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
15726 "Removing non-persistent process during cleanup: " + app);
15727 if (!replacingPid) {
15728 removeProcessNameLocked(app.processName, app.uid);
15730 if (mHeavyWeightProcess == app) {
15731 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
15732 mHeavyWeightProcess.userId, 0));
15733 mHeavyWeightProcess = null;
15735 } else if (!app.removed) {
15736 // This app is persistent, so we need to keep its record around.
15737 // If it is not already on the pending app list, add it there
15738 // and start a new process for it.
15739 if (mPersistentStartingProcesses.indexOf(app) < 0) {
15740 mPersistentStartingProcesses.add(app);
15744 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
15745 TAG_CLEANUP, "Clean-up removing on hold: " + app);
15746 mProcessesOnHold.remove(app);
15748 if (app == mHomeProcess) {
15749 mHomeProcess = null;
15751 if (app == mPreviousProcess) {
15752 mPreviousProcess = null;
15755 if (restart && !app.isolated) {
15756 // We have components that still need to be running in the
15757 // process, so re-launch it.
15759 ProcessList.remove(app.pid);
15761 addProcessNameLocked(app);
15762 startProcessLocked(app, "restart", app.processName);
15764 } else if (app.pid > 0 && app.pid != MY_PID) {
15767 synchronized (mPidsSelfLocked) {
15768 mPidsSelfLocked.remove(app.pid);
15769 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
15771 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
15772 if (app.isolated) {
15773 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
15780 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
15781 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15782 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15783 if (cpr.launchingApp == app) {
15790 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
15791 // Look through the content providers we are waiting to have launched,
15792 // and if any run in this process then either schedule a restart of
15793 // the process or kill the client waiting for it if this process has
15795 boolean restart = false;
15796 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
15797 ContentProviderRecord cpr = mLaunchingProviders.get(i);
15798 if (cpr.launchingApp == app) {
15799 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
15802 removeDyingProviderLocked(app, cpr, true);
15809 // =========================================================
15811 // =========================================================
15814 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
15816 enforceNotIsolatedCaller("getServices");
15817 synchronized (this) {
15818 return mServices.getRunningServiceInfoLocked(maxNum, flags);
15823 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
15824 enforceNotIsolatedCaller("getRunningServiceControlPanel");
15825 synchronized (this) {
15826 return mServices.getRunningServiceControlPanelLocked(name);
15831 public ComponentName startService(IApplicationThread caller, Intent service,
15832 String resolvedType, String callingPackage, int userId)
15833 throws TransactionTooLargeException {
15834 enforceNotIsolatedCaller("startService");
15835 // Refuse possible leaked file descriptors
15836 if (service != null && service.hasFileDescriptors() == true) {
15837 throw new IllegalArgumentException("File descriptors passed in Intent");
15840 if (callingPackage == null) {
15841 throw new IllegalArgumentException("callingPackage cannot be null");
15844 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15845 "startService: " + service + " type=" + resolvedType);
15846 synchronized(this) {
15847 final int callingPid = Binder.getCallingPid();
15848 final int callingUid = Binder.getCallingUid();
15849 final long origId = Binder.clearCallingIdentity();
15850 ComponentName res = mServices.startServiceLocked(caller, service,
15851 resolvedType, callingPid, callingUid, callingPackage, userId);
15852 Binder.restoreCallingIdentity(origId);
15857 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
15858 String callingPackage, int userId)
15859 throws TransactionTooLargeException {
15860 synchronized(this) {
15861 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
15862 "startServiceInPackage: " + service + " type=" + resolvedType);
15863 final long origId = Binder.clearCallingIdentity();
15864 ComponentName res = mServices.startServiceLocked(null, service,
15865 resolvedType, -1, uid, callingPackage, userId);
15866 Binder.restoreCallingIdentity(origId);
15872 public int stopService(IApplicationThread caller, Intent service,
15873 String resolvedType, int userId) {
15874 enforceNotIsolatedCaller("stopService");
15875 // Refuse possible leaked file descriptors
15876 if (service != null && service.hasFileDescriptors() == true) {
15877 throw new IllegalArgumentException("File descriptors passed in Intent");
15880 synchronized(this) {
15881 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
15886 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
15887 enforceNotIsolatedCaller("peekService");
15888 // Refuse possible leaked file descriptors
15889 if (service != null && service.hasFileDescriptors() == true) {
15890 throw new IllegalArgumentException("File descriptors passed in Intent");
15893 if (callingPackage == null) {
15894 throw new IllegalArgumentException("callingPackage cannot be null");
15897 synchronized(this) {
15898 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
15903 public boolean stopServiceToken(ComponentName className, IBinder token,
15905 synchronized(this) {
15906 return mServices.stopServiceTokenLocked(className, token, startId);
15911 public void setServiceForeground(ComponentName className, IBinder token,
15912 int id, Notification notification, boolean removeNotification) {
15913 synchronized(this) {
15914 mServices.setServiceForegroundLocked(className, token, id, notification,
15915 removeNotification);
15920 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15921 boolean requireFull, String name, String callerPackage) {
15922 return handleIncomingUser(callingPid, callingUid, userId, allowAll,
15923 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
15926 int unsafeConvertIncomingUser(int userId) {
15927 return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
15928 ? mCurrentUserId : userId;
15931 int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
15932 int allowMode, String name, String callerPackage) {
15933 final int callingUserId = UserHandle.getUserId(callingUid);
15934 if (callingUserId == userId) {
15938 // Note that we may be accessing mCurrentUserId outside of a lock...
15939 // shouldn't be a big deal, if this is being called outside
15940 // of a locked context there is intrinsically a race with
15941 // the value the caller will receive and someone else changing it.
15942 // We assume that USER_CURRENT_OR_SELF will use the current user; later
15943 // we will switch to the calling user if access to the current user fails.
15944 int targetUserId = unsafeConvertIncomingUser(userId);
15946 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
15947 final boolean allow;
15948 if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
15949 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
15950 // If the caller has this permission, they always pass go. And collect $200.
15952 } else if (allowMode == ALLOW_FULL_ONLY) {
15953 // We require full access, sucks to be you.
15955 } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
15956 callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
15957 // If the caller does not have either permission, they are always doomed.
15959 } else if (allowMode == ALLOW_NON_FULL) {
15960 // We are blanket allowing non-full access, you lucky caller!
15962 } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
15963 // We may or may not allow this depending on whether the two users are
15964 // in the same profile.
15965 synchronized (mUserProfileGroupIdsSelfLocked) {
15966 int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
15967 UserInfo.NO_PROFILE_GROUP_ID);
15968 int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
15969 UserInfo.NO_PROFILE_GROUP_ID);
15970 allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
15971 && callingProfile == targetProfile;
15974 throw new IllegalArgumentException("Unknown mode: " + allowMode);
15977 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
15978 // In this case, they would like to just execute as their
15979 // owner user instead of failing.
15980 targetUserId = callingUserId;
15982 StringBuilder builder = new StringBuilder(128);
15983 builder.append("Permission Denial: ");
15984 builder.append(name);
15985 if (callerPackage != null) {
15986 builder.append(" from ");
15987 builder.append(callerPackage);
15989 builder.append(" asks to run as user ");
15990 builder.append(userId);
15991 builder.append(" but is calling from user ");
15992 builder.append(UserHandle.getUserId(callingUid));
15993 builder.append("; this requires ");
15994 builder.append(INTERACT_ACROSS_USERS_FULL);
15995 if (allowMode != ALLOW_FULL_ONLY) {
15996 builder.append(" or ");
15997 builder.append(INTERACT_ACROSS_USERS);
15999 String msg = builder.toString();
16001 throw new SecurityException(msg);
16005 if (!allowAll && targetUserId < 0) {
16006 throw new IllegalArgumentException(
16007 "Call does not support special user #" + targetUserId);
16009 // Check shell permission
16010 if (callingUid == Process.SHELL_UID && targetUserId >= UserHandle.USER_OWNER) {
16011 if (mUserManager.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES,
16013 throw new SecurityException("Shell does not have permission to access user "
16014 + targetUserId + "\n " + Debug.getCallers(3));
16017 return targetUserId;
16020 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16021 String className, int flags) {
16022 boolean result = false;
16023 // For apps that don't have pre-defined UIDs, check for permission
16024 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16025 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16026 if (ActivityManager.checkUidPermission(
16027 INTERACT_ACROSS_USERS,
16028 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16029 ComponentName comp = new ComponentName(aInfo.packageName, className);
16030 String msg = "Permission Denial: Component " + comp.flattenToShortString()
16031 + " requests FLAG_SINGLE_USER, but app does not hold "
16032 + INTERACT_ACROSS_USERS;
16034 throw new SecurityException(msg);
16036 // Permission passed
16039 } else if ("system".equals(componentProcessName)) {
16041 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16042 // Phone app and persistent apps are allowed to export singleuser providers.
16043 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16044 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16046 if (DEBUG_MU) Slog.v(TAG_MU,
16047 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16048 + Integer.toHexString(flags) + ") = " + result);
16053 * Checks to see if the caller is in the same app as the singleton
16054 * component, or the component is in a special app. It allows special apps
16055 * to export singleton components but prevents exporting singleton
16056 * components for regular apps.
16058 boolean isValidSingletonCall(int callingUid, int componentUid) {
16059 int componentAppId = UserHandle.getAppId(componentUid);
16060 return UserHandle.isSameApp(callingUid, componentUid)
16061 || componentAppId == Process.SYSTEM_UID
16062 || componentAppId == Process.PHONE_UID
16063 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16064 == PackageManager.PERMISSION_GRANTED;
16067 public int bindService(IApplicationThread caller, IBinder token, Intent service,
16068 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16069 int userId) throws TransactionTooLargeException {
16070 enforceNotIsolatedCaller("bindService");
16072 // Refuse possible leaked file descriptors
16073 if (service != null && service.hasFileDescriptors() == true) {
16074 throw new IllegalArgumentException("File descriptors passed in Intent");
16077 if (callingPackage == null) {
16078 throw new IllegalArgumentException("callingPackage cannot be null");
16081 synchronized(this) {
16082 return mServices.bindServiceLocked(caller, token, service,
16083 resolvedType, connection, flags, callingPackage, userId);
16087 public boolean unbindService(IServiceConnection connection) {
16088 synchronized (this) {
16089 return mServices.unbindServiceLocked(connection);
16093 public void publishService(IBinder token, Intent intent, IBinder service) {
16094 // Refuse possible leaked file descriptors
16095 if (intent != null && intent.hasFileDescriptors() == true) {
16096 throw new IllegalArgumentException("File descriptors passed in Intent");
16099 synchronized(this) {
16100 if (!(token instanceof ServiceRecord)) {
16101 throw new IllegalArgumentException("Invalid service token");
16103 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16107 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16108 // Refuse possible leaked file descriptors
16109 if (intent != null && intent.hasFileDescriptors() == true) {
16110 throw new IllegalArgumentException("File descriptors passed in Intent");
16113 synchronized(this) {
16114 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16118 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16119 synchronized(this) {
16120 if (!(token instanceof ServiceRecord)) {
16121 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16122 throw new IllegalArgumentException("Invalid service token");
16124 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16128 // =========================================================
16129 // BACKUP AND RESTORE
16130 // =========================================================
16132 // Cause the target app to be launched if necessary and its backup agent
16133 // instantiated. The backup agent will invoke backupAgentCreated() on the
16134 // activity manager to announce its creation.
16135 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
16136 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
16137 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16139 IPackageManager pm = AppGlobals.getPackageManager();
16140 ApplicationInfo app = null;
16142 app = pm.getApplicationInfo(packageName, 0, userId);
16143 } catch (RemoteException e) {
16144 // can't happen; package manager is process-local
16147 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
16151 synchronized(this) {
16152 // !!! TODO: currently no check here that we're already bound
16153 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16154 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16155 synchronized (stats) {
16156 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16159 // Backup agent is now in use, its package can't be stopped.
16161 AppGlobals.getPackageManager().setPackageStoppedState(
16162 app.packageName, false, UserHandle.getUserId(app.uid));
16163 } catch (RemoteException e) {
16164 } catch (IllegalArgumentException e) {
16165 Slog.w(TAG, "Failed trying to unstop package "
16166 + app.packageName + ": " + e);
16169 BackupRecord r = new BackupRecord(ss, app, backupMode);
16170 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16171 ? new ComponentName(app.packageName, app.backupAgentName)
16172 : new ComponentName("android", "FullBackupAgent");
16173 // startProcessLocked() returns existing proc's record if it's already running
16174 ProcessRecord proc = startProcessLocked(app.processName, app,
16175 false, 0, "backup", hostingName, false, false, false);
16176 if (proc == null) {
16177 Slog.e(TAG, "Unable to start backup agent process " + r);
16183 mBackupAppName = app.packageName;
16185 // Try not to kill the process during backup
16186 updateOomAdjLocked(proc);
16188 // If the process is already attached, schedule the creation of the backup agent now.
16189 // If it is not yet live, this will be done when it attaches to the framework.
16190 if (proc.thread != null) {
16191 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16193 proc.thread.scheduleCreateBackupAgent(app,
16194 compatibilityInfoForPackageLocked(app), backupMode);
16195 } catch (RemoteException e) {
16196 // Will time out on the backup manager side
16199 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16201 // Invariants: at this point, the target app process exists and the application
16202 // is either already running or in the process of coming up. mBackupTarget and
16203 // mBackupAppName describe the app, so that when it binds back to the AM we
16204 // know that it's scheduled for a backup-agent operation.
16211 public void clearPendingBackup() {
16212 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16213 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16215 synchronized (this) {
16216 mBackupTarget = null;
16217 mBackupAppName = null;
16221 // A backup agent has just come up
16222 public void backupAgentCreated(String agentPackageName, IBinder agent) {
16223 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16226 synchronized(this) {
16227 if (!agentPackageName.equals(mBackupAppName)) {
16228 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16233 long oldIdent = Binder.clearCallingIdentity();
16235 IBackupManager bm = IBackupManager.Stub.asInterface(
16236 ServiceManager.getService(Context.BACKUP_SERVICE));
16237 bm.agentConnected(agentPackageName, agent);
16238 } catch (RemoteException e) {
16239 // can't happen; the backup manager service is local
16240 } catch (Exception e) {
16241 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16242 e.printStackTrace();
16244 Binder.restoreCallingIdentity(oldIdent);
16248 // done with this agent
16249 public void unbindBackupAgent(ApplicationInfo appInfo) {
16250 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16251 if (appInfo == null) {
16252 Slog.w(TAG, "unbind backup agent for null app");
16256 synchronized(this) {
16258 if (mBackupAppName == null) {
16259 Slog.w(TAG, "Unbinding backup agent with no active backup");
16263 if (!mBackupAppName.equals(appInfo.packageName)) {
16264 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16268 // Not backing this app up any more; reset its OOM adjustment
16269 final ProcessRecord proc = mBackupTarget.app;
16270 updateOomAdjLocked(proc);
16272 // If the app crashed during backup, 'thread' will be null here
16273 if (proc.thread != null) {
16275 proc.thread.scheduleDestroyBackupAgent(appInfo,
16276 compatibilityInfoForPackageLocked(appInfo));
16277 } catch (Exception e) {
16278 Slog.e(TAG, "Exception when unbinding backup agent:");
16279 e.printStackTrace();
16283 mBackupTarget = null;
16284 mBackupAppName = null;
16288 // =========================================================
16290 // =========================================================
16292 boolean isPendingBroadcastProcessLocked(int pid) {
16293 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16294 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16297 void skipPendingBroadcastLocked(int pid) {
16298 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16299 for (BroadcastQueue queue : mBroadcastQueues) {
16300 queue.skipPendingBroadcastLocked(pid);
16304 // The app just attached; send any pending broadcasts that it should receive
16305 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16306 boolean didSomething = false;
16307 for (BroadcastQueue queue : mBroadcastQueues) {
16308 didSomething |= queue.sendPendingBroadcastsLocked(app);
16310 return didSomething;
16313 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16314 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16315 enforceNotIsolatedCaller("registerReceiver");
16316 ArrayList<Intent> stickyIntents = null;
16317 ProcessRecord callerApp = null;
16320 synchronized(this) {
16321 if (caller != null) {
16322 callerApp = getRecordForAppLocked(caller);
16323 if (callerApp == null) {
16324 throw new SecurityException(
16325 "Unable to find app for caller " + caller
16326 + " (pid=" + Binder.getCallingPid()
16327 + ") when registering receiver " + receiver);
16329 if (callerApp.info.uid != Process.SYSTEM_UID &&
16330 !callerApp.pkgList.containsKey(callerPackage) &&
16331 !"android".equals(callerPackage)) {
16332 throw new SecurityException("Given caller package " + callerPackage
16333 + " is not running in process " + callerApp);
16335 callingUid = callerApp.info.uid;
16336 callingPid = callerApp.pid;
16338 callerPackage = null;
16339 callingUid = Binder.getCallingUid();
16340 callingPid = Binder.getCallingPid();
16343 userId = handleIncomingUser(callingPid, callingUid, userId,
16344 true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16346 Iterator<String> actions = filter.actionsIterator();
16347 if (actions == null) {
16348 ArrayList<String> noAction = new ArrayList<String>(1);
16349 noAction.add(null);
16350 actions = noAction.iterator();
16353 // Collect stickies of users
16354 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16355 while (actions.hasNext()) {
16356 String action = actions.next();
16357 for (int id : userIds) {
16358 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16359 if (stickies != null) {
16360 ArrayList<Intent> intents = stickies.get(action);
16361 if (intents != null) {
16362 if (stickyIntents == null) {
16363 stickyIntents = new ArrayList<Intent>();
16365 stickyIntents.addAll(intents);
16372 ArrayList<Intent> allSticky = null;
16373 if (stickyIntents != null) {
16374 final ContentResolver resolver = mContext.getContentResolver();
16375 // Look for any matching sticky broadcasts...
16376 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16377 Intent intent = stickyIntents.get(i);
16378 // If intent has scheme "content", it will need to acccess
16379 // provider that needs to lock mProviderMap in ActivityThread
16380 // and also it may need to wait application response, so we
16381 // cannot lock ActivityManagerService here.
16382 if (filter.match(resolver, intent, true, TAG) >= 0) {
16383 if (allSticky == null) {
16384 allSticky = new ArrayList<Intent>();
16386 allSticky.add(intent);
16391 // The first sticky in the list is returned directly back to the client.
16392 Intent sticky = allSticky != null ? allSticky.get(0) : null;
16393 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16394 if (receiver == null) {
16398 synchronized (this) {
16399 if (callerApp != null && (callerApp.thread == null
16400 || callerApp.thread.asBinder() != caller.asBinder())) {
16401 // Original caller already died
16404 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16406 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16408 if (rl.app != null) {
16409 rl.app.receivers.add(rl);
16412 receiver.asBinder().linkToDeath(rl, 0);
16413 } catch (RemoteException e) {
16416 rl.linkedToDeath = true;
16418 mRegisteredReceivers.put(receiver.asBinder(), rl);
16419 } else if (rl.uid != callingUid) {
16420 throw new IllegalArgumentException(
16421 "Receiver requested to register for uid " + callingUid
16422 + " was previously registered for uid " + rl.uid);
16423 } else if (rl.pid != callingPid) {
16424 throw new IllegalArgumentException(
16425 "Receiver requested to register for pid " + callingPid
16426 + " was previously registered for pid " + rl.pid);
16427 } else if (rl.userId != userId) {
16428 throw new IllegalArgumentException(
16429 "Receiver requested to register for user " + userId
16430 + " was previously registered for user " + rl.userId);
16432 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16433 permission, callingUid, userId);
16435 if (!bf.debugCheck()) {
16436 Slog.w(TAG, "==> For Dynamic broadcast");
16438 mReceiverResolver.addFilter(bf);
16440 // Enqueue broadcasts for all existing stickies that match
16442 if (allSticky != null) {
16443 ArrayList receivers = new ArrayList();
16446 final int stickyCount = allSticky.size();
16447 for (int i = 0; i < stickyCount; i++) {
16448 Intent intent = allSticky.get(i);
16449 BroadcastQueue queue = broadcastQueueForIntent(intent);
16450 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16451 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16452 null, 0, null, null, false, true, true, -1);
16453 queue.enqueueParallelBroadcastLocked(r);
16454 queue.scheduleBroadcastsLocked();
16462 public void unregisterReceiver(IIntentReceiver receiver) {
16463 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
16465 final long origId = Binder.clearCallingIdentity();
16467 boolean doTrim = false;
16469 synchronized(this) {
16470 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16472 final BroadcastRecord r = rl.curBroadcast;
16473 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
16474 final boolean doNext = r.queue.finishReceiverLocked(
16475 r, r.resultCode, r.resultData, r.resultExtras,
16476 r.resultAbort, false);
16479 r.queue.processNextBroadcast(false);
16483 if (rl.app != null) {
16484 rl.app.receivers.remove(rl);
16486 removeReceiverLocked(rl);
16487 if (rl.linkedToDeath) {
16488 rl.linkedToDeath = false;
16489 rl.receiver.asBinder().unlinkToDeath(rl, 0);
16494 // If we actually concluded any broadcasts, we might now be able
16495 // to trim the recipients' apps from our working set
16497 trimApplications();
16502 Binder.restoreCallingIdentity(origId);
16506 void removeReceiverLocked(ReceiverList rl) {
16507 mRegisteredReceivers.remove(rl.receiver.asBinder());
16508 for (int i = rl.size() - 1; i >= 0; i--) {
16509 mReceiverResolver.removeFilter(rl.get(i));
16513 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
16514 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16515 ProcessRecord r = mLruProcesses.get(i);
16516 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
16518 r.thread.dispatchPackageBroadcast(cmd, packages);
16519 } catch (RemoteException ex) {
16525 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
16526 int callingUid, int[] users) {
16527 List<ResolveInfo> receivers = null;
16529 HashSet<ComponentName> singleUserReceivers = null;
16530 boolean scannedFirstReceivers = false;
16531 for (int user : users) {
16532 // Skip users that have Shell restrictions
16533 if (callingUid == Process.SHELL_UID
16534 && getUserManagerLocked().hasUserRestriction(
16535 UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
16538 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
16539 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
16540 if (user != UserHandle.USER_OWNER && newReceivers != null) {
16541 // If this is not the primary user, we need to check for
16542 // any receivers that should be filtered out.
16543 for (int i=0; i<newReceivers.size(); i++) {
16544 ResolveInfo ri = newReceivers.get(i);
16545 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
16546 newReceivers.remove(i);
16551 if (newReceivers != null && newReceivers.size() == 0) {
16552 newReceivers = null;
16554 if (receivers == null) {
16555 receivers = newReceivers;
16556 } else if (newReceivers != null) {
16557 // We need to concatenate the additional receivers
16558 // found with what we have do far. This would be easy,
16559 // but we also need to de-dup any receivers that are
16561 if (!scannedFirstReceivers) {
16562 // Collect any single user receivers we had already retrieved.
16563 scannedFirstReceivers = true;
16564 for (int i=0; i<receivers.size(); i++) {
16565 ResolveInfo ri = receivers.get(i);
16566 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16567 ComponentName cn = new ComponentName(
16568 ri.activityInfo.packageName, ri.activityInfo.name);
16569 if (singleUserReceivers == null) {
16570 singleUserReceivers = new HashSet<ComponentName>();
16572 singleUserReceivers.add(cn);
16576 // Add the new results to the existing results, tracking
16577 // and de-dupping single user receivers.
16578 for (int i=0; i<newReceivers.size(); i++) {
16579 ResolveInfo ri = newReceivers.get(i);
16580 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
16581 ComponentName cn = new ComponentName(
16582 ri.activityInfo.packageName, ri.activityInfo.name);
16583 if (singleUserReceivers == null) {
16584 singleUserReceivers = new HashSet<ComponentName>();
16586 if (!singleUserReceivers.contains(cn)) {
16587 singleUserReceivers.add(cn);
16596 } catch (RemoteException ex) {
16597 // pm is in same process, this will never happen.
16602 private final int broadcastIntentLocked(ProcessRecord callerApp,
16603 String callerPackage, Intent intent, String resolvedType,
16604 IIntentReceiver resultTo, int resultCode, String resultData,
16605 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,
16606 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
16607 intent = new Intent(intent);
16609 // By default broadcasts do not go to stopped apps.
16610 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
16612 // If we have not finished booting, don't allow this to launch new processes.
16613 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
16614 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16617 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
16618 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
16619 + " ordered=" + ordered + " userid=" + userId);
16620 if ((resultTo != null) && !ordered) {
16621 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
16624 userId = handleIncomingUser(callingPid, callingUid, userId,
16625 true, ALLOW_NON_FULL, "broadcast", callerPackage);
16627 // Make sure that the user who is receiving this broadcast is running.
16628 // If not, we will just skip it. Make an exception for shutdown broadcasts
16629 // and upgrade steps.
16631 if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {
16632 if ((callingUid != Process.SYSTEM_UID
16633 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
16634 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
16635 Slog.w(TAG, "Skipping broadcast of " + intent
16636 + ": user " + userId + " is stopped");
16637 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
16641 BroadcastOptions brOptions = null;
16642 if (options != null) {
16643 brOptions = new BroadcastOptions(options);
16644 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
16645 // See if the caller is allowed to do this. Note we are checking against
16646 // the actual real caller (not whoever provided the operation as say a
16647 // PendingIntent), because that who is actually supplied the arguments.
16648 if (checkComponentPermission(
16649 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
16650 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
16651 != PackageManager.PERMISSION_GRANTED) {
16652 String msg = "Permission Denial: " + intent.getAction()
16653 + " broadcast from " + callerPackage + " (pid=" + callingPid
16654 + ", uid=" + callingUid + ")"
16656 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
16658 throw new SecurityException(msg);
16664 * Prevent non-system code (defined here to be non-persistent
16665 * processes) from sending protected broadcasts.
16667 int callingAppId = UserHandle.getAppId(callingUid);
16668 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
16669 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
16670 || callingAppId == Process.NFC_UID || callingUid == 0) {
16672 } else if (callerApp == null || !callerApp.persistent) {
16674 if (AppGlobals.getPackageManager().isProtectedBroadcast(
16675 intent.getAction())) {
16676 String msg = "Permission Denial: not allowed to send broadcast "
16677 + intent.getAction() + " from pid="
16678 + callingPid + ", uid=" + callingUid;
16680 throw new SecurityException(msg);
16681 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
16682 // Special case for compatibility: we don't want apps to send this,
16683 // but historically it has not been protected and apps may be using it
16684 // to poke their own app widget. So, instead of making it protected,
16685 // just limit it to the caller.
16686 if (callerApp == null) {
16687 String msg = "Permission Denial: not allowed to send broadcast "
16688 + intent.getAction() + " from unknown caller.";
16690 throw new SecurityException(msg);
16691 } else if (intent.getComponent() != null) {
16692 // They are good enough to send to an explicit component... verify
16693 // it is being sent to the calling app.
16694 if (!intent.getComponent().getPackageName().equals(
16695 callerApp.info.packageName)) {
16696 String msg = "Permission Denial: not allowed to send broadcast "
16697 + intent.getAction() + " to "
16698 + intent.getComponent().getPackageName() + " from "
16699 + callerApp.info.packageName;
16701 throw new SecurityException(msg);
16704 // Limit broadcast to their own package.
16705 intent.setPackage(callerApp.info.packageName);
16708 } catch (RemoteException e) {
16709 Slog.w(TAG, "Remote exception", e);
16710 return ActivityManager.BROADCAST_SUCCESS;
16714 final String action = intent.getAction();
16715 if (action != null) {
16717 case Intent.ACTION_UID_REMOVED:
16718 case Intent.ACTION_PACKAGE_REMOVED:
16719 case Intent.ACTION_PACKAGE_CHANGED:
16720 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16721 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16722 // Handle special intents: if this broadcast is from the package
16723 // manager about a package being removed, we need to remove all of
16724 // its activities from the history stack.
16725 if (checkComponentPermission(
16726 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
16727 callingPid, callingUid, -1, true)
16728 != PackageManager.PERMISSION_GRANTED) {
16729 String msg = "Permission Denial: " + intent.getAction()
16730 + " broadcast from " + callerPackage + " (pid=" + callingPid
16731 + ", uid=" + callingUid + ")"
16733 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
16735 throw new SecurityException(msg);
16738 case Intent.ACTION_UID_REMOVED:
16739 final Bundle intentExtras = intent.getExtras();
16740 final int uid = intentExtras != null
16741 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
16743 mBatteryStatsService.removeUid(uid);
16744 mAppOpsService.uidRemoved(uid);
16747 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
16748 // If resources are unavailable just force stop all those packages
16749 // and flush the attribute cache as well.
16751 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
16752 if (list != null && list.length > 0) {
16753 for (int i = 0; i < list.length; i++) {
16754 forceStopPackageLocked(list[i], -1, false, true, true,
16755 false, false, userId, "storage unmount");
16757 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16758 sendPackageBroadcastLocked(
16759 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
16763 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
16764 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
16766 case Intent.ACTION_PACKAGE_REMOVED:
16767 case Intent.ACTION_PACKAGE_CHANGED:
16768 Uri data = intent.getData();
16770 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
16771 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
16772 boolean fullUninstall = removed &&
16773 !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16774 final boolean killProcess =
16775 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
16777 forceStopPackageLocked(ssp, UserHandle.getAppId(
16778 intent.getIntExtra(Intent.EXTRA_UID, -1)),
16779 false, true, true, false, fullUninstall, userId,
16780 removed ? "pkg removed" : "pkg changed");
16783 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
16784 new String[] {ssp}, userId);
16785 if (fullUninstall) {
16786 mAppOpsService.packageRemoved(
16787 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
16789 // Remove all permissions granted from/to this package
16790 removeUriPermissionsForPackageLocked(ssp, userId, true);
16792 removeTasksByPackageNameLocked(ssp, userId);
16793 mBatteryStatsService.notePackageUninstalled(ssp);
16796 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
16797 intent.getStringArrayExtra(
16798 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
16804 case Intent.ACTION_PACKAGE_ADDED:
16805 // Special case for adding a package: by default turn on compatibility mode.
16806 Uri data = intent.getData();
16808 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
16809 final boolean replacing =
16810 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
16811 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
16814 ApplicationInfo ai = AppGlobals.getPackageManager().
16815 getApplicationInfo(ssp, 0, 0);
16816 mBatteryStatsService.notePackageInstalled(ssp,
16817 ai != null ? ai.versionCode : 0);
16818 } catch (RemoteException e) {
16822 case Intent.ACTION_TIMEZONE_CHANGED:
16823 // If this is the time zone changed action, queue up a message that will reset
16824 // the timezone of all currently running processes. This message will get
16825 // queued up before the broadcast happens.
16826 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
16828 case Intent.ACTION_TIME_CHANGED:
16829 // If the user set the time, let all running processes know.
16830 final int is24Hour =
16831 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
16833 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
16834 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16835 synchronized (stats) {
16836 stats.noteCurrentTimeChangedLocked();
16839 case Intent.ACTION_CLEAR_DNS_CACHE:
16840 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
16842 case Proxy.PROXY_CHANGE_ACTION:
16843 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
16844 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
16849 // Add to the sticky list if requested.
16851 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
16852 callingPid, callingUid)
16853 != PackageManager.PERMISSION_GRANTED) {
16854 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
16855 + callingPid + ", uid=" + callingUid
16856 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
16858 throw new SecurityException(msg);
16860 if (requiredPermissions != null && requiredPermissions.length > 0) {
16861 Slog.w(TAG, "Can't broadcast sticky intent " + intent
16862 + " and enforce permissions " + Arrays.toString(requiredPermissions));
16863 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
16865 if (intent.getComponent() != null) {
16866 throw new SecurityException(
16867 "Sticky broadcasts can't target a specific component");
16869 // We use userId directly here, since the "all" target is maintained
16870 // as a separate set of sticky broadcasts.
16871 if (userId != UserHandle.USER_ALL) {
16872 // But first, if this is not a broadcast to all users, then
16873 // make sure it doesn't conflict with an existing broadcast to
16875 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
16876 UserHandle.USER_ALL);
16877 if (stickies != null) {
16878 ArrayList<Intent> list = stickies.get(intent.getAction());
16879 if (list != null) {
16880 int N = list.size();
16882 for (i=0; i<N; i++) {
16883 if (intent.filterEquals(list.get(i))) {
16884 throw new IllegalArgumentException(
16885 "Sticky broadcast " + intent + " for user "
16886 + userId + " conflicts with existing global broadcast");
16892 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
16893 if (stickies == null) {
16894 stickies = new ArrayMap<>();
16895 mStickyBroadcasts.put(userId, stickies);
16897 ArrayList<Intent> list = stickies.get(intent.getAction());
16898 if (list == null) {
16899 list = new ArrayList<>();
16900 stickies.put(intent.getAction(), list);
16902 final int stickiesCount = list.size();
16904 for (i = 0; i < stickiesCount; i++) {
16905 if (intent.filterEquals(list.get(i))) {
16906 // This sticky already exists, replace it.
16907 list.set(i, new Intent(intent));
16911 if (i >= stickiesCount) {
16912 list.add(new Intent(intent));
16917 if (userId == UserHandle.USER_ALL) {
16918 // Caller wants broadcast to go to all started users.
16919 users = mStartedUserArray;
16921 // Caller wants broadcast to go to one specific user.
16922 users = new int[] {userId};
16925 // Figure out who all will receive this broadcast.
16926 List receivers = null;
16927 List<BroadcastFilter> registeredReceivers = null;
16928 // Need to resolve the intent to interested receivers...
16929 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
16931 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
16933 if (intent.getComponent() == null) {
16934 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
16935 // Query one target user at a time, excluding shell-restricted users
16936 UserManagerService ums = getUserManagerLocked();
16937 for (int i = 0; i < users.length; i++) {
16938 if (ums.hasUserRestriction(
16939 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
16942 List<BroadcastFilter> registeredReceiversForUser =
16943 mReceiverResolver.queryIntent(intent,
16944 resolvedType, false, users[i]);
16945 if (registeredReceivers == null) {
16946 registeredReceivers = registeredReceiversForUser;
16947 } else if (registeredReceiversForUser != null) {
16948 registeredReceivers.addAll(registeredReceiversForUser);
16952 registeredReceivers = mReceiverResolver.queryIntent(intent,
16953 resolvedType, false, userId);
16957 final boolean replacePending =
16958 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
16960 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
16961 + " replacePending=" + replacePending);
16963 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
16964 if (!ordered && NR > 0) {
16965 // If we are not serializing this broadcast, then send the
16966 // registered receivers separately so they don't wait for the
16967 // components to be launched.
16968 final BroadcastQueue queue = broadcastQueueForIntent(intent);
16969 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
16970 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
16971 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
16972 resultExtras, ordered, sticky, false, userId);
16973 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
16974 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
16976 queue.enqueueParallelBroadcastLocked(r);
16977 queue.scheduleBroadcastsLocked();
16979 registeredReceivers = null;
16983 // Merge into one list.
16985 if (receivers != null) {
16986 // A special case for PACKAGE_ADDED: do not allow the package
16987 // being added to see this broadcast. This prevents them from
16988 // using this as a back door to get run as soon as they are
16989 // installed. Maybe in the future we want to have a special install
16990 // broadcast or such for apps, but we'd like to deliberately make
16992 String skipPackages[] = null;
16993 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
16994 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
16995 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
16996 Uri data = intent.getData();
16997 if (data != null) {
16998 String pkgName = data.getSchemeSpecificPart();
16999 if (pkgName != null) {
17000 skipPackages = new String[] { pkgName };
17003 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17004 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17006 if (skipPackages != null && (skipPackages.length > 0)) {
17007 for (String skipPackage : skipPackages) {
17008 if (skipPackage != null) {
17009 int NT = receivers.size();
17010 for (int it=0; it<NT; it++) {
17011 ResolveInfo curt = (ResolveInfo)receivers.get(it);
17012 if (curt.activityInfo.packageName.equals(skipPackage)) {
17013 receivers.remove(it);
17022 int NT = receivers != null ? receivers.size() : 0;
17024 ResolveInfo curt = null;
17025 BroadcastFilter curr = null;
17026 while (it < NT && ir < NR) {
17027 if (curt == null) {
17028 curt = (ResolveInfo)receivers.get(it);
17030 if (curr == null) {
17031 curr = registeredReceivers.get(ir);
17033 if (curr.getPriority() >= curt.priority) {
17034 // Insert this broadcast record into the final list.
17035 receivers.add(it, curr);
17041 // Skip to the next ResolveInfo in the final list.
17048 if (receivers == null) {
17049 receivers = new ArrayList();
17051 receivers.add(registeredReceivers.get(ir));
17055 if ((receivers != null && receivers.size() > 0)
17056 || resultTo != null) {
17057 BroadcastQueue queue = broadcastQueueForIntent(intent);
17058 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17059 callerPackage, callingPid, callingUid, resolvedType,
17060 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17061 resultData, resultExtras, ordered, sticky, false, userId);
17063 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17064 + ": prev had " + queue.mOrderedBroadcasts.size());
17065 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17066 "Enqueueing broadcast " + r.intent.getAction());
17068 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17070 queue.enqueueOrderedBroadcastLocked(r);
17071 queue.scheduleBroadcastsLocked();
17075 return ActivityManager.BROADCAST_SUCCESS;
17078 final Intent verifyBroadcastLocked(Intent intent) {
17079 // Refuse possible leaked file descriptors
17080 if (intent != null && intent.hasFileDescriptors() == true) {
17081 throw new IllegalArgumentException("File descriptors passed in Intent");
17084 int flags = intent.getFlags();
17086 if (!mProcessesReady) {
17087 // if the caller really truly claims to know what they're doing, go
17088 // ahead and allow the broadcast without launching any receivers
17089 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17090 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17091 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17092 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17093 + " before boot completion");
17094 throw new IllegalStateException("Cannot broadcast before boot completed");
17098 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17099 throw new IllegalArgumentException(
17100 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17106 public final int broadcastIntent(IApplicationThread caller,
17107 Intent intent, String resolvedType, IIntentReceiver resultTo,
17108 int resultCode, String resultData, Bundle resultExtras,
17109 String[] requiredPermissions, int appOp, Bundle options,
17110 boolean serialized, boolean sticky, int userId) {
17111 enforceNotIsolatedCaller("broadcastIntent");
17112 synchronized(this) {
17113 intent = verifyBroadcastLocked(intent);
17115 final ProcessRecord callerApp = getRecordForAppLocked(caller);
17116 final int callingPid = Binder.getCallingPid();
17117 final int callingUid = Binder.getCallingUid();
17118 final long origId = Binder.clearCallingIdentity();
17119 int res = broadcastIntentLocked(callerApp,
17120 callerApp != null ? callerApp.info.packageName : null,
17121 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17122 requiredPermissions, appOp, null, serialized, sticky,
17123 callingPid, callingUid, userId);
17124 Binder.restoreCallingIdentity(origId);
17130 int broadcastIntentInPackage(String packageName, int uid,
17131 Intent intent, String resolvedType, IIntentReceiver resultTo,
17132 int resultCode, String resultData, Bundle resultExtras,
17133 String requiredPermission, Bundle options, boolean serialized, boolean sticky,
17135 synchronized(this) {
17136 intent = verifyBroadcastLocked(intent);
17138 final long origId = Binder.clearCallingIdentity();
17139 String[] requiredPermissions = requiredPermission == null ? null
17140 : new String[] {requiredPermission};
17141 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17142 resultTo, resultCode, resultData, resultExtras,
17143 requiredPermissions, AppOpsManager.OP_NONE, options, serialized,
17144 sticky, -1, uid, userId);
17145 Binder.restoreCallingIdentity(origId);
17150 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17151 // Refuse possible leaked file descriptors
17152 if (intent != null && intent.hasFileDescriptors() == true) {
17153 throw new IllegalArgumentException("File descriptors passed in Intent");
17156 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17157 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17159 synchronized(this) {
17160 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17161 != PackageManager.PERMISSION_GRANTED) {
17162 String msg = "Permission Denial: unbroadcastIntent() from pid="
17163 + Binder.getCallingPid()
17164 + ", uid=" + Binder.getCallingUid()
17165 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17167 throw new SecurityException(msg);
17169 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17170 if (stickies != null) {
17171 ArrayList<Intent> list = stickies.get(intent.getAction());
17172 if (list != null) {
17173 int N = list.size();
17175 for (i=0; i<N; i++) {
17176 if (intent.filterEquals(list.get(i))) {
17181 if (list.size() <= 0) {
17182 stickies.remove(intent.getAction());
17185 if (stickies.size() <= 0) {
17186 mStickyBroadcasts.remove(userId);
17192 void backgroundServicesFinishedLocked(int userId) {
17193 for (BroadcastQueue queue : mBroadcastQueues) {
17194 queue.backgroundServicesFinishedLocked(userId);
17198 public void finishReceiver(IBinder who, int resultCode, String resultData,
17199 Bundle resultExtras, boolean resultAbort, int flags) {
17200 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17202 // Refuse possible leaked file descriptors
17203 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17204 throw new IllegalArgumentException("File descriptors passed in Bundle");
17207 final long origId = Binder.clearCallingIdentity();
17209 boolean doNext = false;
17212 synchronized(this) {
17213 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17214 ? mFgBroadcastQueue : mBgBroadcastQueue;
17215 r = queue.getMatchingOrderedReceiver(who);
17217 doNext = r.queue.finishReceiverLocked(r, resultCode,
17218 resultData, resultExtras, resultAbort, true);
17223 r.queue.processNextBroadcast(false);
17225 trimApplications();
17227 Binder.restoreCallingIdentity(origId);
17231 // =========================================================
17233 // =========================================================
17235 public boolean startInstrumentation(ComponentName className,
17236 String profileFile, int flags, Bundle arguments,
17237 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17238 int userId, String abiOverride) {
17239 enforceNotIsolatedCaller("startInstrumentation");
17240 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17241 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17242 // Refuse possible leaked file descriptors
17243 if (arguments != null && arguments.hasFileDescriptors()) {
17244 throw new IllegalArgumentException("File descriptors passed in Bundle");
17247 synchronized(this) {
17248 InstrumentationInfo ii = null;
17249 ApplicationInfo ai = null;
17251 ii = mContext.getPackageManager().getInstrumentationInfo(
17252 className, STOCK_PM_FLAGS);
17253 ai = AppGlobals.getPackageManager().getApplicationInfo(
17254 ii.targetPackage, STOCK_PM_FLAGS, userId);
17255 } catch (PackageManager.NameNotFoundException e) {
17256 } catch (RemoteException e) {
17259 reportStartInstrumentationFailure(watcher, className,
17260 "Unable to find instrumentation info for: " + className);
17264 reportStartInstrumentationFailure(watcher, className,
17265 "Unable to find instrumentation target package: " + ii.targetPackage);
17269 int match = mContext.getPackageManager().checkSignatures(
17270 ii.targetPackage, ii.packageName);
17271 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17272 String msg = "Permission Denial: starting instrumentation "
17273 + className + " from pid="
17274 + Binder.getCallingPid()
17275 + ", uid=" + Binder.getCallingPid()
17276 + " not allowed because package " + ii.packageName
17277 + " does not have a signature matching the target "
17278 + ii.targetPackage;
17279 reportStartInstrumentationFailure(watcher, className, msg);
17280 throw new SecurityException(msg);
17283 final long origId = Binder.clearCallingIdentity();
17284 // Instrumentation can kill and relaunch even persistent processes
17285 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17287 ProcessRecord app = addAppLocked(ai, false, abiOverride);
17288 app.instrumentationClass = className;
17289 app.instrumentationInfo = ai;
17290 app.instrumentationProfileFile = profileFile;
17291 app.instrumentationArguments = arguments;
17292 app.instrumentationWatcher = watcher;
17293 app.instrumentationUiAutomationConnection = uiAutomationConnection;
17294 app.instrumentationResultClass = className;
17295 Binder.restoreCallingIdentity(origId);
17302 * Report errors that occur while attempting to start Instrumentation. Always writes the
17303 * error to the logs, but if somebody is watching, send the report there too. This enables
17304 * the "am" command to report errors with more information.
17306 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
17307 * @param cn The component name of the instrumentation.
17308 * @param report The error report.
17310 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
17311 ComponentName cn, String report) {
17312 Slog.w(TAG, report);
17314 if (watcher != null) {
17315 Bundle results = new Bundle();
17316 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17317 results.putString("Error", report);
17318 watcher.instrumentationStatus(cn, -1, results);
17320 } catch (RemoteException e) {
17325 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17326 if (app.instrumentationWatcher != null) {
17328 // NOTE: IInstrumentationWatcher *must* be oneway here
17329 app.instrumentationWatcher.instrumentationFinished(
17330 app.instrumentationClass,
17333 } catch (RemoteException e) {
17337 // Can't call out of the system process with a lock held, so post a message.
17338 if (app.instrumentationUiAutomationConnection != null) {
17339 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17340 app.instrumentationUiAutomationConnection).sendToTarget();
17343 app.instrumentationWatcher = null;
17344 app.instrumentationUiAutomationConnection = null;
17345 app.instrumentationClass = null;
17346 app.instrumentationInfo = null;
17347 app.instrumentationProfileFile = null;
17348 app.instrumentationArguments = null;
17350 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17354 public void finishInstrumentation(IApplicationThread target,
17355 int resultCode, Bundle results) {
17356 int userId = UserHandle.getCallingUserId();
17357 // Refuse possible leaked file descriptors
17358 if (results != null && results.hasFileDescriptors()) {
17359 throw new IllegalArgumentException("File descriptors passed in Intent");
17362 synchronized(this) {
17363 ProcessRecord app = getRecordForAppLocked(target);
17365 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17368 final long origId = Binder.clearCallingIdentity();
17369 finishInstrumentationLocked(app, resultCode, results);
17370 Binder.restoreCallingIdentity(origId);
17374 // =========================================================
17376 // =========================================================
17378 public ConfigurationInfo getDeviceConfigurationInfo() {
17379 ConfigurationInfo config = new ConfigurationInfo();
17380 synchronized (this) {
17381 config.reqTouchScreen = mConfiguration.touchscreen;
17382 config.reqKeyboardType = mConfiguration.keyboard;
17383 config.reqNavigation = mConfiguration.navigation;
17384 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
17385 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
17386 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
17388 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
17389 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
17390 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
17392 config.reqGlEsVersion = GL_ES_VERSION;
17397 ActivityStack getFocusedStack() {
17398 return mStackSupervisor.getFocusedStack();
17402 public int getFocusedStackId() throws RemoteException {
17403 ActivityStack focusedStack = getFocusedStack();
17404 if (focusedStack != null) {
17405 return focusedStack.getStackId();
17410 public Configuration getConfiguration() {
17412 synchronized(this) {
17413 ci = new Configuration(mConfiguration);
17414 ci.userSetLocale = false;
17419 public void updatePersistentConfiguration(Configuration values) {
17420 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17421 "updateConfiguration()");
17422 enforceWriteSettingsPermission("updateConfiguration()");
17423 if (values == null) {
17424 throw new NullPointerException("Configuration must not be null");
17427 synchronized(this) {
17428 final long origId = Binder.clearCallingIdentity();
17429 updateConfigurationLocked(values, null, true, false);
17430 Binder.restoreCallingIdentity(origId);
17434 private void enforceWriteSettingsPermission(String func) {
17435 int uid = Binder.getCallingUid();
17436 if (uid == Process.ROOT_UID) {
17440 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
17441 Settings.getPackageNameForUid(mContext, uid), false)) {
17445 String msg = "Permission Denial: " + func + " from pid="
17446 + Binder.getCallingPid()
17448 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
17450 throw new SecurityException(msg);
17453 public void updateConfiguration(Configuration values) {
17454 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
17455 "updateConfiguration()");
17457 synchronized(this) {
17458 if (values == null && mWindowManager != null) {
17459 // sentinel: fetch the current configuration from the window manager
17460 values = mWindowManager.computeNewConfiguration();
17463 if (mWindowManager != null) {
17464 mProcessList.applyDisplaySize(mWindowManager);
17467 final long origId = Binder.clearCallingIdentity();
17468 if (values != null) {
17469 Settings.System.clearConfiguration(values);
17471 updateConfigurationLocked(values, null, false, false);
17472 Binder.restoreCallingIdentity(origId);
17477 * Do either or both things: (1) change the current configuration, and (2)
17478 * make sure the given activity is running with the (now) current
17479 * configuration. Returns true if the activity has been left running, or
17480 * false if <var>starting</var> is being destroyed to match the new
17482 * @param persistent TODO
17484 boolean updateConfigurationLocked(Configuration values,
17485 ActivityRecord starting, boolean persistent, boolean initLocale) {
17488 if (values != null) {
17489 Configuration newConfig = new Configuration(mConfiguration);
17490 changes = newConfig.updateFrom(values);
17491 if (changes != 0) {
17492 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
17493 "Updating configuration to: " + values);
17495 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
17497 if (!initLocale && values.locale != null && values.userSetLocale) {
17498 final String languageTag = values.locale.toLanguageTag();
17499 SystemProperties.set("persist.sys.locale", languageTag);
17500 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
17504 mConfigurationSeq++;
17505 if (mConfigurationSeq <= 0) {
17506 mConfigurationSeq = 1;
17508 newConfig.seq = mConfigurationSeq;
17509 mConfiguration = newConfig;
17510 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
17511 mUsageStatsService.reportConfigurationChange(newConfig, mCurrentUserId);
17512 //mUsageStatsService.noteStartConfig(newConfig);
17514 final Configuration configCopy = new Configuration(mConfiguration);
17516 // TODO: If our config changes, should we auto dismiss any currently
17517 // showing dialogs?
17518 mShowDialogs = shouldShowDialogs(newConfig);
17520 AttributeCache ac = AttributeCache.instance();
17522 ac.updateConfiguration(configCopy);
17525 // Make sure all resources in our process are updated
17526 // right now, so that anyone who is going to retrieve
17527 // resource values after we return will be sure to get
17528 // the new ones. This is especially important during
17529 // boot, where the first config change needs to guarantee
17530 // all resources have that config before following boot
17531 // code is executed.
17532 mSystemThread.applyConfigurationToResources(configCopy);
17534 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
17535 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
17536 msg.obj = new Configuration(configCopy);
17537 mHandler.sendMessage(msg);
17540 for (int i=mLruProcesses.size()-1; i>=0; i--) {
17541 ProcessRecord app = mLruProcesses.get(i);
17543 if (app.thread != null) {
17544 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
17545 + app.processName + " new config " + mConfiguration);
17546 app.thread.scheduleConfigurationChanged(configCopy);
17548 } catch (Exception e) {
17551 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
17552 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17553 | Intent.FLAG_RECEIVER_REPLACE_PENDING
17554 | Intent.FLAG_RECEIVER_FOREGROUND);
17555 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
17556 null, AppOpsManager.OP_NONE, null, false, false,
17557 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17558 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
17559 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
17560 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17561 if (!mProcessesReady) {
17562 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17564 broadcastIntentLocked(null, null, intent,
17565 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17566 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17571 boolean kept = true;
17572 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
17573 // mainStack is null during startup.
17574 if (mainStack != null) {
17575 if (changes != 0 && starting == null) {
17576 // If the configuration changed, and the caller is not already
17577 // in the process of starting an activity, then find the top
17578 // activity to check if its configuration needs to change.
17579 starting = mainStack.topRunningActivityLocked(null);
17582 if (starting != null) {
17583 kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
17584 // And we need to make sure at this point that all other activities
17585 // are made visible with the correct configuration.
17586 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
17590 if (values != null && mWindowManager != null) {
17591 mWindowManager.setNewConfiguration(mConfiguration);
17598 * Decide based on the configuration whether we should shouw the ANR,
17599 * crash, etc dialogs. The idea is that if there is no affordnace to
17600 * press the on-screen buttons, we shouldn't show the dialog.
17602 * A thought: SystemUI might also want to get told about this, the Power
17603 * dialog / global actions also might want different behaviors.
17605 private static final boolean shouldShowDialogs(Configuration config) {
17606 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
17607 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
17608 && config.navigation == Configuration.NAVIGATION_NONAV);
17612 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
17613 synchronized (this) {
17614 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
17615 if (srec != null) {
17616 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
17622 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
17623 Intent resultData) {
17625 synchronized (this) {
17626 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
17628 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
17634 public int getLaunchedFromUid(IBinder activityToken) {
17635 ActivityRecord srec;
17636 synchronized (this) {
17637 srec = ActivityRecord.forTokenLocked(activityToken);
17639 if (srec == null) {
17642 return srec.launchedFromUid;
17645 public String getLaunchedFromPackage(IBinder activityToken) {
17646 ActivityRecord srec;
17647 synchronized (this) {
17648 srec = ActivityRecord.forTokenLocked(activityToken);
17650 if (srec == null) {
17653 return srec.launchedFromPackage;
17656 // =========================================================
17657 // LIFETIME MANAGEMENT
17658 // =========================================================
17660 // Returns which broadcast queue the app is the current [or imminent] receiver
17661 // on, or 'null' if the app is not an active broadcast recipient.
17662 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
17663 BroadcastRecord r = app.curReceiver;
17668 // It's not the current receiver, but it might be starting up to become one
17669 synchronized (this) {
17670 for (BroadcastQueue queue : mBroadcastQueues) {
17671 r = queue.mPendingBroadcast;
17672 if (r != null && r.curApp == app) {
17673 // found it; report which queue it's in
17682 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17683 ComponentName targetComponent, String targetProcess) {
17684 if (!mTrackingAssociations) {
17687 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17688 = mAssociations.get(targetUid);
17689 if (components == null) {
17690 components = new ArrayMap<>();
17691 mAssociations.put(targetUid, components);
17693 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17694 if (sourceUids == null) {
17695 sourceUids = new SparseArray<>();
17696 components.put(targetComponent, sourceUids);
17698 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17699 if (sourceProcesses == null) {
17700 sourceProcesses = new ArrayMap<>();
17701 sourceUids.put(sourceUid, sourceProcesses);
17703 Association ass = sourceProcesses.get(sourceProcess);
17705 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
17707 sourceProcesses.put(sourceProcess, ass);
17711 if (ass.mNesting == 1) {
17712 ass.mStartTime = SystemClock.uptimeMillis();
17717 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
17718 ComponentName targetComponent) {
17719 if (!mTrackingAssociations) {
17722 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
17723 = mAssociations.get(targetUid);
17724 if (components == null) {
17727 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
17728 if (sourceUids == null) {
17731 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
17732 if (sourceProcesses == null) {
17735 Association ass = sourceProcesses.get(sourceProcess);
17736 if (ass == null || ass.mNesting <= 0) {
17740 if (ass.mNesting == 0) {
17741 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
17745 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
17746 boolean doingAll, long now) {
17747 if (mAdjSeq == app.adjSeq) {
17748 // This adjustment has already been computed.
17749 return app.curRawAdj;
17752 if (app.thread == null) {
17753 app.adjSeq = mAdjSeq;
17754 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17755 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17756 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
17759 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
17760 app.adjSource = null;
17761 app.adjTarget = null;
17763 app.cached = false;
17765 final int activitiesSize = app.activities.size();
17767 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
17768 // The max adjustment doesn't allow this app to be anything
17769 // below foreground, so it is not worth doing work for it.
17770 app.adjType = "fixed";
17771 app.adjSeq = mAdjSeq;
17772 app.curRawAdj = app.maxAdj;
17773 app.foregroundActivities = false;
17774 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
17775 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
17776 // System processes can do UI, and when they do we want to have
17777 // them trim their memory after the user leaves the UI. To
17778 // facilitate this, here we need to determine whether or not it
17779 // is currently showing UI.
17780 app.systemNoUi = true;
17781 if (app == TOP_APP) {
17782 app.systemNoUi = false;
17783 } else if (activitiesSize > 0) {
17784 for (int j = 0; j < activitiesSize; j++) {
17785 final ActivityRecord r = app.activities.get(j);
17787 app.systemNoUi = false;
17791 if (!app.systemNoUi) {
17792 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
17794 return (app.curAdj=app.maxAdj);
17797 app.systemNoUi = false;
17799 final int PROCESS_STATE_TOP = mTopProcessState;
17801 // Determine the importance of the process, starting with most
17802 // important to least, and assign an appropriate OOM adjustment.
17806 boolean foregroundActivities = false;
17807 BroadcastQueue queue;
17808 if (app == TOP_APP) {
17809 // The last app on the list is the foreground app.
17810 adj = ProcessList.FOREGROUND_APP_ADJ;
17811 schedGroup = Process.THREAD_GROUP_DEFAULT;
17812 app.adjType = "top-activity";
17813 foregroundActivities = true;
17814 procState = PROCESS_STATE_TOP;
17815 } else if (app.instrumentationClass != null) {
17816 // Don't want to kill running instrumentation.
17817 adj = ProcessList.FOREGROUND_APP_ADJ;
17818 schedGroup = Process.THREAD_GROUP_DEFAULT;
17819 app.adjType = "instrumentation";
17820 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17821 } else if ((queue = isReceivingBroadcast(app)) != null) {
17822 // An app that is currently receiving a broadcast also
17823 // counts as being in the foreground for OOM killer purposes.
17824 // It's placed in a sched group based on the nature of the
17825 // broadcast as reflected by which queue it's active in.
17826 adj = ProcessList.FOREGROUND_APP_ADJ;
17827 schedGroup = (queue == mFgBroadcastQueue)
17828 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17829 app.adjType = "broadcast";
17830 procState = ActivityManager.PROCESS_STATE_RECEIVER;
17831 } else if (app.executingServices.size() > 0) {
17832 // An app that is currently executing a service callback also
17833 // counts as being in the foreground.
17834 adj = ProcessList.FOREGROUND_APP_ADJ;
17835 schedGroup = app.execServicesFg ?
17836 Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
17837 app.adjType = "exec-service";
17838 procState = ActivityManager.PROCESS_STATE_SERVICE;
17839 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
17841 // As far as we know the process is empty. We may change our mind later.
17842 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17843 // At this point we don't actually know the adjustment. Use the cached adj
17844 // value that the caller wants us to.
17846 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
17849 app.adjType = "cch-empty";
17852 // Examine all activities if not already foreground.
17853 if (!foregroundActivities && activitiesSize > 0) {
17854 for (int j = 0; j < activitiesSize; j++) {
17855 final ActivityRecord r = app.activities.get(j);
17856 if (r.app != app) {
17857 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
17858 + app + "?!? Using " + r.app + " instead.");
17862 // App has a visible activity; only upgrade adjustment.
17863 if (adj > ProcessList.VISIBLE_APP_ADJ) {
17864 adj = ProcessList.VISIBLE_APP_ADJ;
17865 app.adjType = "visible";
17867 if (procState > PROCESS_STATE_TOP) {
17868 procState = PROCESS_STATE_TOP;
17870 schedGroup = Process.THREAD_GROUP_DEFAULT;
17871 app.cached = false;
17873 foregroundActivities = true;
17875 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
17876 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17877 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17878 app.adjType = "pausing";
17880 if (procState > PROCESS_STATE_TOP) {
17881 procState = PROCESS_STATE_TOP;
17883 schedGroup = Process.THREAD_GROUP_DEFAULT;
17884 app.cached = false;
17886 foregroundActivities = true;
17887 } else if (r.state == ActivityState.STOPPING) {
17888 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17889 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17890 app.adjType = "stopping";
17892 // For the process state, we will at this point consider the
17893 // process to be cached. It will be cached either as an activity
17894 // or empty depending on whether the activity is finishing. We do
17895 // this so that we can treat the process as cached for purposes of
17896 // memory trimming (determing current memory level, trim command to
17897 // send to process) since there can be an arbitrary number of stopping
17898 // processes and they should soon all go into the cached state.
17899 if (!r.finishing) {
17900 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17901 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17904 app.cached = false;
17906 foregroundActivities = true;
17908 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
17909 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
17910 app.adjType = "cch-act";
17916 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
17917 if (app.foregroundServices) {
17918 // The user is aware of this app, so make it visible.
17919 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17920 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
17921 app.cached = false;
17922 app.adjType = "fg-service";
17923 schedGroup = Process.THREAD_GROUP_DEFAULT;
17924 } else if (app.forcingToForeground != null) {
17925 // The user is aware of this app, so make it visible.
17926 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
17927 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
17928 app.cached = false;
17929 app.adjType = "force-fg";
17930 app.adjSource = app.forcingToForeground;
17931 schedGroup = Process.THREAD_GROUP_DEFAULT;
17935 if (app == mHeavyWeightProcess) {
17936 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
17937 // We don't want to kill the current heavy-weight process.
17938 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
17939 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17940 app.cached = false;
17941 app.adjType = "heavy";
17943 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17944 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
17948 if (app == mHomeProcess) {
17949 if (adj > ProcessList.HOME_APP_ADJ) {
17950 // This process is hosting what we currently consider to be the
17951 // home app, so we don't want to let it go into the background.
17952 adj = ProcessList.HOME_APP_ADJ;
17953 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17954 app.cached = false;
17955 app.adjType = "home";
17957 if (procState > ActivityManager.PROCESS_STATE_HOME) {
17958 procState = ActivityManager.PROCESS_STATE_HOME;
17962 if (app == mPreviousProcess && app.activities.size() > 0) {
17963 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
17964 // This was the previous process that showed UI to the user.
17965 // We want to try to keep it around more aggressively, to give
17966 // a good experience around switching between two apps.
17967 adj = ProcessList.PREVIOUS_APP_ADJ;
17968 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
17969 app.cached = false;
17970 app.adjType = "previous";
17972 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
17973 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
17977 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
17978 + " reason=" + app.adjType);
17980 // By default, we use the computed adjustment. It may be changed if
17981 // there are applications dependent on our services or providers, but
17982 // this gives us a baseline and makes sure we don't get into an
17983 // infinite recursion.
17984 app.adjSeq = mAdjSeq;
17985 app.curRawAdj = adj;
17986 app.hasStartedServices = false;
17988 if (mBackupTarget != null && app == mBackupTarget.app) {
17989 // If possible we want to avoid killing apps while they're being backed up
17990 if (adj > ProcessList.BACKUP_APP_ADJ) {
17991 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
17992 adj = ProcessList.BACKUP_APP_ADJ;
17993 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
17994 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
17996 app.adjType = "backup";
17997 app.cached = false;
17999 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18000 procState = ActivityManager.PROCESS_STATE_BACKUP;
18004 boolean mayBeTop = false;
18006 for (int is = app.services.size()-1;
18007 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18008 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18009 || procState > ActivityManager.PROCESS_STATE_TOP);
18011 ServiceRecord s = app.services.valueAt(is);
18012 if (s.startRequested) {
18013 app.hasStartedServices = true;
18014 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18015 procState = ActivityManager.PROCESS_STATE_SERVICE;
18017 if (app.hasShownUi && app != mHomeProcess) {
18018 // If this process has shown some UI, let it immediately
18019 // go to the LRU list because it may be pretty heavy with
18020 // UI stuff. We'll tag it with a label just to help
18021 // debug and understand what is going on.
18022 if (adj > ProcessList.SERVICE_ADJ) {
18023 app.adjType = "cch-started-ui-services";
18026 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18027 // This service has seen some activity within
18028 // recent memory, so we will keep its process ahead
18029 // of the background processes.
18030 if (adj > ProcessList.SERVICE_ADJ) {
18031 adj = ProcessList.SERVICE_ADJ;
18032 app.adjType = "started-services";
18033 app.cached = false;
18036 // If we have let the service slide into the background
18037 // state, still have some text describing what it is doing
18038 // even though the service no longer has an impact.
18039 if (adj > ProcessList.SERVICE_ADJ) {
18040 app.adjType = "cch-started-services";
18044 for (int conni = s.connections.size()-1;
18045 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18046 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18047 || procState > ActivityManager.PROCESS_STATE_TOP);
18049 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18051 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18052 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18053 || procState > ActivityManager.PROCESS_STATE_TOP);
18055 // XXX should compute this based on the max of
18056 // all connected clients.
18057 ConnectionRecord cr = clist.get(i);
18058 if (cr.binding.client == app) {
18059 // Binding to ourself is not interesting.
18062 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18063 ProcessRecord client = cr.binding.client;
18064 int clientAdj = computeOomAdjLocked(client, cachedAdj,
18065 TOP_APP, doingAll, now);
18066 int clientProcState = client.curProcState;
18067 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18068 // If the other app is cached for any reason, for purposes here
18069 // we are going to consider it empty. The specific cached state
18070 // doesn't propagate except under certain conditions.
18071 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18073 String adjType = null;
18074 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18075 // Not doing bind OOM management, so treat
18076 // this guy more like a started service.
18077 if (app.hasShownUi && app != mHomeProcess) {
18078 // If this process has shown some UI, let it immediately
18079 // go to the LRU list because it may be pretty heavy with
18080 // UI stuff. We'll tag it with a label just to help
18081 // debug and understand what is going on.
18082 if (adj > clientAdj) {
18083 adjType = "cch-bound-ui-services";
18085 app.cached = false;
18087 clientProcState = procState;
18089 if (now >= (s.lastActivity
18090 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18091 // This service has not seen activity within
18092 // recent memory, so allow it to drop to the
18093 // LRU list if there is no other reason to keep
18094 // it around. We'll also tag it with a label just
18095 // to help debug and undertand what is going on.
18096 if (adj > clientAdj) {
18097 adjType = "cch-bound-services";
18103 if (adj > clientAdj) {
18104 // If this process has recently shown UI, and
18105 // the process that is binding to it is less
18106 // important than being visible, then we don't
18107 // care about the binding as much as we care
18108 // about letting this process get into the LRU
18109 // list to be killed and restarted if needed for
18111 if (app.hasShownUi && app != mHomeProcess
18112 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18113 adjType = "cch-bound-ui-services";
18115 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18116 |Context.BIND_IMPORTANT)) != 0) {
18117 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18118 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18119 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18120 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18121 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18122 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18123 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
18126 if (adj > ProcessList.VISIBLE_APP_ADJ) {
18127 adj = ProcessList.VISIBLE_APP_ADJ;
18130 if (!client.cached) {
18131 app.cached = false;
18133 adjType = "service";
18136 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18137 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18138 schedGroup = Process.THREAD_GROUP_DEFAULT;
18140 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18141 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18142 // Special handling of clients who are in the top state.
18143 // We *may* want to consider this process to be in the
18144 // top state as well, but only if there is not another
18145 // reason for it to be running. Being on the top is a
18146 // special state, meaning you are specifically running
18147 // for the current top app. If the process is already
18148 // running in the background for some other reason, it
18149 // is more important to continue considering it to be
18150 // in the background state.
18152 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18154 // Special handling for above-top states (persistent
18155 // processes). These should not bring the current process
18156 // into the top state, since they are not on top. Instead
18157 // give them the best state after that.
18158 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18160 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18161 } else if (mWakefulness
18162 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18163 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18166 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18169 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18174 if (clientProcState <
18175 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18177 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18180 if (procState > clientProcState) {
18181 procState = clientProcState;
18183 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18184 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18185 app.pendingUiClean = true;
18187 if (adjType != null) {
18188 app.adjType = adjType;
18189 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18190 .REASON_SERVICE_IN_USE;
18191 app.adjSource = cr.binding.client;
18192 app.adjSourceProcState = clientProcState;
18193 app.adjTarget = s.name;
18196 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18197 app.treatLikeActivity = true;
18199 final ActivityRecord a = cr.activity;
18200 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18201 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18202 (a.visible || a.state == ActivityState.RESUMED
18203 || a.state == ActivityState.PAUSING)) {
18204 adj = ProcessList.FOREGROUND_APP_ADJ;
18205 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18206 schedGroup = Process.THREAD_GROUP_DEFAULT;
18208 app.cached = false;
18209 app.adjType = "service";
18210 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18211 .REASON_SERVICE_IN_USE;
18213 app.adjSourceProcState = procState;
18214 app.adjTarget = s.name;
18221 for (int provi = app.pubProviders.size()-1;
18222 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18223 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18224 || procState > ActivityManager.PROCESS_STATE_TOP);
18226 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18227 for (int i = cpr.connections.size()-1;
18228 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18229 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
18230 || procState > ActivityManager.PROCESS_STATE_TOP);
18232 ContentProviderConnection conn = cpr.connections.get(i);
18233 ProcessRecord client = conn.client;
18234 if (client == app) {
18235 // Being our own client is not interesting.
18238 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18239 int clientProcState = client.curProcState;
18240 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18241 // If the other app is cached for any reason, for purposes here
18242 // we are going to consider it empty.
18243 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18245 if (adj > clientAdj) {
18246 if (app.hasShownUi && app != mHomeProcess
18247 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18248 app.adjType = "cch-ui-provider";
18250 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
18251 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
18252 app.adjType = "provider";
18254 app.cached &= client.cached;
18255 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18256 .REASON_PROVIDER_IN_USE;
18257 app.adjSource = client;
18258 app.adjSourceProcState = clientProcState;
18259 app.adjTarget = cpr.name;
18261 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18262 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18263 // Special handling of clients who are in the top state.
18264 // We *may* want to consider this process to be in the
18265 // top state as well, but only if there is not another
18266 // reason for it to be running. Being on the top is a
18267 // special state, meaning you are specifically running
18268 // for the current top app. If the process is already
18269 // running in the background for some other reason, it
18270 // is more important to continue considering it to be
18271 // in the background state.
18273 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18275 // Special handling for above-top states (persistent
18276 // processes). These should not bring the current process
18277 // into the top state, since they are not on top. Instead
18278 // give them the best state after that.
18280 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18283 if (procState > clientProcState) {
18284 procState = clientProcState;
18286 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
18287 schedGroup = Process.THREAD_GROUP_DEFAULT;
18290 // If the provider has external (non-framework) process
18291 // dependencies, ensure that its adjustment is at least
18292 // FOREGROUND_APP_ADJ.
18293 if (cpr.hasExternalProcessHandles()) {
18294 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
18295 adj = ProcessList.FOREGROUND_APP_ADJ;
18296 schedGroup = Process.THREAD_GROUP_DEFAULT;
18297 app.cached = false;
18298 app.adjType = "provider";
18299 app.adjTarget = cpr.name;
18301 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
18302 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18307 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
18308 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18309 adj = ProcessList.PREVIOUS_APP_ADJ;
18310 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
18311 app.cached = false;
18312 app.adjType = "provider";
18314 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18315 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18319 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
18320 // A client of one of our services or providers is in the top state. We
18321 // *may* want to be in the top state, but not if we are already running in
18322 // the background for some other reason. For the decision here, we are going
18323 // to pick out a few specific states that we want to remain in when a client
18324 // is top (states that tend to be longer-term) and otherwise allow it to go
18325 // to the top state.
18326 switch (procState) {
18327 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
18328 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
18329 case ActivityManager.PROCESS_STATE_SERVICE:
18330 // These all are longer-term states, so pull them up to the top
18331 // of the background states, but not all the way to the top state.
18332 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18335 // Otherwise, top is a better choice, so take it.
18336 procState = ActivityManager.PROCESS_STATE_TOP;
18341 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
18342 if (app.hasClientActivities) {
18343 // This is a cached process, but with client activities. Mark it so.
18344 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
18345 app.adjType = "cch-client-act";
18346 } else if (app.treatLikeActivity) {
18347 // This is a cached process, but somebody wants us to treat it like it has
18348 // an activity, okay!
18349 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18350 app.adjType = "cch-as-act";
18354 if (adj == ProcessList.SERVICE_ADJ) {
18356 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
18357 mNewNumServiceProcs++;
18358 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
18359 if (!app.serviceb) {
18360 // This service isn't far enough down on the LRU list to
18361 // normally be a B service, but if we are low on RAM and it
18362 // is large we want to force it down since we would prefer to
18363 // keep launcher over it.
18364 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
18365 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
18366 app.serviceHighRam = true;
18367 app.serviceb = true;
18368 //Slog.i(TAG, "ADJ " + app + " high ram!");
18370 mNewNumAServiceProcs++;
18371 //Slog.i(TAG, "ADJ " + app + " not high ram!");
18374 app.serviceHighRam = false;
18377 if (app.serviceb) {
18378 adj = ProcessList.SERVICE_B_ADJ;
18382 app.curRawAdj = adj;
18384 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
18385 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
18386 if (adj > app.maxAdj) {
18388 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
18389 schedGroup = Process.THREAD_GROUP_DEFAULT;
18393 // Do final modification to adj. Everything we do between here and applying
18394 // the final setAdj must be done in this function, because we will also use
18395 // it when computing the final cached adj later. Note that we don't need to
18396 // worry about this for max adj above, since max adj will always be used to
18397 // keep it out of the cached vaues.
18398 app.curAdj = app.modifyRawOomAdj(adj);
18399 app.curSchedGroup = schedGroup;
18400 app.curProcState = procState;
18401 app.foregroundActivities = foregroundActivities;
18403 return app.curRawAdj;
18407 * Record new PSS sample for a process.
18409 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long now) {
18410 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024);
18411 proc.lastPssTime = now;
18412 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
18413 if (DEBUG_PSS) Slog.d(TAG_PSS,
18414 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
18415 + " state=" + ProcessList.makeProcStateString(procState));
18416 if (proc.initialIdlePss == 0) {
18417 proc.initialIdlePss = pss;
18419 proc.lastPss = pss;
18420 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
18421 proc.lastCachedPss = pss;
18424 final SparseArray<Pair<Long, String>> watchUids
18425 = mMemWatchProcesses.getMap().get(proc.processName);
18427 if (watchUids != null) {
18428 Pair<Long, String> val = watchUids.get(proc.uid);
18430 val = watchUids.get(0);
18436 if (check != null) {
18437 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
18438 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
18439 if (!isDebuggable) {
18440 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
18441 isDebuggable = true;
18444 if (isDebuggable) {
18445 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
18446 final ProcessRecord myProc = proc;
18447 final File heapdumpFile = DumpHeapProvider.getJavaFile();
18448 mMemWatchDumpProcName = proc.processName;
18449 mMemWatchDumpFile = heapdumpFile.toString();
18450 mMemWatchDumpPid = proc.pid;
18451 mMemWatchDumpUid = proc.uid;
18452 BackgroundThread.getHandler().post(new Runnable() {
18454 public void run() {
18455 revokeUriPermission(ActivityThread.currentActivityThread()
18456 .getApplicationThread(),
18457 DumpHeapActivity.JAVA_URI,
18458 Intent.FLAG_GRANT_READ_URI_PERMISSION
18459 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
18460 UserHandle.myUserId());
18461 ParcelFileDescriptor fd = null;
18463 heapdumpFile.delete();
18464 fd = ParcelFileDescriptor.open(heapdumpFile,
18465 ParcelFileDescriptor.MODE_CREATE |
18466 ParcelFileDescriptor.MODE_TRUNCATE |
18467 ParcelFileDescriptor.MODE_WRITE_ONLY |
18468 ParcelFileDescriptor.MODE_APPEND);
18469 IApplicationThread thread = myProc.thread;
18470 if (thread != null) {
18472 if (DEBUG_PSS) Slog.d(TAG_PSS,
18473 "Requesting dump heap from "
18474 + myProc + " to " + heapdumpFile);
18475 thread.dumpHeap(true, heapdumpFile.toString(), fd);
18476 } catch (RemoteException e) {
18479 } catch (FileNotFoundException e) {
18480 e.printStackTrace();
18485 } catch (IOException e) {
18492 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
18493 + ", but debugging not enabled");
18500 * Schedule PSS collection of a process.
18502 void requestPssLocked(ProcessRecord proc, int procState) {
18503 if (mPendingPssProcesses.contains(proc)) {
18506 if (mPendingPssProcesses.size() == 0) {
18507 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18509 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
18510 proc.pssProcState = procState;
18511 mPendingPssProcesses.add(proc);
18515 * Schedule PSS collection of all processes.
18517 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
18519 if (now < (mLastFullPssTime +
18520 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
18524 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
18525 mLastFullPssTime = now;
18526 mFullPssPending = true;
18527 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
18528 mPendingPssProcesses.clear();
18529 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
18530 ProcessRecord app = mLruProcesses.get(i);
18531 if (app.thread == null
18532 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
18535 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
18536 app.pssProcState = app.setProcState;
18537 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18538 mTestPssMode, isSleeping(), now);
18539 mPendingPssProcesses.add(app);
18542 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
18545 public void setTestPssMode(boolean enabled) {
18546 synchronized (this) {
18547 mTestPssMode = enabled;
18549 // Whenever we enable the mode, we want to take a snapshot all of current
18550 // process mem use.
18551 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
18557 * Ask a given process to GC right now.
18559 final void performAppGcLocked(ProcessRecord app) {
18561 app.lastRequestedGc = SystemClock.uptimeMillis();
18562 if (app.thread != null) {
18563 if (app.reportLowMemory) {
18564 app.reportLowMemory = false;
18565 app.thread.scheduleLowMemory();
18567 app.thread.processInBackground();
18570 } catch (Exception e) {
18576 * Returns true if things are idle enough to perform GCs.
18578 private final boolean canGcNowLocked() {
18579 boolean processingBroadcasts = false;
18580 for (BroadcastQueue q : mBroadcastQueues) {
18581 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
18582 processingBroadcasts = true;
18585 return !processingBroadcasts
18586 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
18590 * Perform GCs on all processes that are waiting for it, but only
18591 * if things are idle.
18593 final void performAppGcsLocked() {
18594 final int N = mProcessesToGc.size();
18598 if (canGcNowLocked()) {
18599 while (mProcessesToGc.size() > 0) {
18600 ProcessRecord proc = mProcessesToGc.remove(0);
18601 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
18602 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
18603 <= SystemClock.uptimeMillis()) {
18604 // To avoid spamming the system, we will GC processes one
18605 // at a time, waiting a few seconds between each.
18606 performAppGcLocked(proc);
18607 scheduleAppGcsLocked();
18610 // It hasn't been long enough since we last GCed this
18611 // process... put it in the list to wait for its time.
18612 addProcessToGcListLocked(proc);
18618 scheduleAppGcsLocked();
18623 * If all looks good, perform GCs on all processes waiting for them.
18625 final void performAppGcsIfAppropriateLocked() {
18626 if (canGcNowLocked()) {
18627 performAppGcsLocked();
18630 // Still not idle, wait some more.
18631 scheduleAppGcsLocked();
18635 * Schedule the execution of all pending app GCs.
18637 final void scheduleAppGcsLocked() {
18638 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
18640 if (mProcessesToGc.size() > 0) {
18641 // Schedule a GC for the time to the next process.
18642 ProcessRecord proc = mProcessesToGc.get(0);
18643 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
18645 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
18646 long now = SystemClock.uptimeMillis();
18647 if (when < (now+GC_TIMEOUT)) {
18648 when = now + GC_TIMEOUT;
18650 mHandler.sendMessageAtTime(msg, when);
18655 * Add a process to the array of processes waiting to be GCed. Keeps the
18656 * list in sorted order by the last GC time. The process can't already be
18659 final void addProcessToGcListLocked(ProcessRecord proc) {
18660 boolean added = false;
18661 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
18662 if (mProcessesToGc.get(i).lastRequestedGc <
18663 proc.lastRequestedGc) {
18665 mProcessesToGc.add(i+1, proc);
18670 mProcessesToGc.add(0, proc);
18675 * Set up to ask a process to GC itself. This will either do it
18676 * immediately, or put it on the list of processes to gc the next
18677 * time things are idle.
18679 final void scheduleAppGcLocked(ProcessRecord app) {
18680 long now = SystemClock.uptimeMillis();
18681 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
18684 if (!mProcessesToGc.contains(app)) {
18685 addProcessToGcListLocked(app);
18686 scheduleAppGcsLocked();
18690 final void checkExcessivePowerUsageLocked(boolean doKills) {
18691 updateCpuStatsNow();
18693 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18694 boolean doWakeKills = doKills;
18695 boolean doCpuKills = doKills;
18696 if (mLastPowerCheckRealtime == 0) {
18697 doWakeKills = false;
18699 if (mLastPowerCheckUptime == 0) {
18700 doCpuKills = false;
18702 if (stats.isScreenOn()) {
18703 doWakeKills = false;
18705 final long curRealtime = SystemClock.elapsedRealtime();
18706 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
18707 final long curUptime = SystemClock.uptimeMillis();
18708 final long uptimeSince = curUptime - mLastPowerCheckUptime;
18709 mLastPowerCheckRealtime = curRealtime;
18710 mLastPowerCheckUptime = curUptime;
18711 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
18712 doWakeKills = false;
18714 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
18715 doCpuKills = false;
18717 int i = mLruProcesses.size();
18720 ProcessRecord app = mLruProcesses.get(i);
18721 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18723 synchronized (stats) {
18724 wtime = stats.getProcessWakeTime(app.info.uid,
18725 app.pid, curRealtime);
18727 long wtimeUsed = wtime - app.lastWakeTime;
18728 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
18730 StringBuilder sb = new StringBuilder(128);
18731 sb.append("Wake for ");
18732 app.toShortString(sb);
18733 sb.append(": over ");
18734 TimeUtils.formatDuration(realtimeSince, sb);
18735 sb.append(" used ");
18736 TimeUtils.formatDuration(wtimeUsed, sb);
18738 sb.append((wtimeUsed*100)/realtimeSince);
18740 Slog.i(TAG_POWER, sb.toString());
18742 sb.append("CPU for ");
18743 app.toShortString(sb);
18744 sb.append(": over ");
18745 TimeUtils.formatDuration(uptimeSince, sb);
18746 sb.append(" used ");
18747 TimeUtils.formatDuration(cputimeUsed, sb);
18749 sb.append((cputimeUsed*100)/uptimeSince);
18751 Slog.i(TAG_POWER, sb.toString());
18753 // If a process has held a wake lock for more
18754 // than 50% of the time during this period,
18755 // that sounds bad. Kill!
18756 if (doWakeKills && realtimeSince > 0
18757 && ((wtimeUsed*100)/realtimeSince) >= 50) {
18758 synchronized (stats) {
18759 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
18760 realtimeSince, wtimeUsed);
18762 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
18763 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
18764 } else if (doCpuKills && uptimeSince > 0
18765 && ((cputimeUsed*100)/uptimeSince) >= 25) {
18766 synchronized (stats) {
18767 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
18768 uptimeSince, cputimeUsed);
18770 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
18771 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
18773 app.lastWakeTime = wtime;
18774 app.lastCpuTime = app.curCpuTime;
18780 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
18782 boolean success = true;
18784 if (app.curRawAdj != app.setRawAdj) {
18785 app.setRawAdj = app.curRawAdj;
18790 if (app.curAdj != app.setAdj) {
18791 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
18792 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18793 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
18795 app.setAdj = app.curAdj;
18798 if (app.setSchedGroup != app.curSchedGroup) {
18799 app.setSchedGroup = app.curSchedGroup;
18800 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18801 "Setting process group of " + app.processName
18802 + " to " + app.curSchedGroup);
18803 if (app.waitingToKill != null && app.curReceiver == null
18804 && app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
18805 app.kill(app.waitingToKill, true);
18809 long oldId = Binder.clearCallingIdentity();
18811 Process.setProcessGroup(app.pid, app.curSchedGroup);
18812 } catch (Exception e) {
18813 Slog.w(TAG, "Failed setting process group of " + app.pid
18814 + " to " + app.curSchedGroup);
18815 e.printStackTrace();
18817 Binder.restoreCallingIdentity(oldId);
18820 if (app.thread != null) {
18822 app.thread.setSchedulingGroup(app.curSchedGroup);
18823 } catch (RemoteException e) {
18827 Process.setSwappiness(app.pid,
18828 app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
18831 if (app.repForegroundActivities != app.foregroundActivities) {
18832 app.repForegroundActivities = app.foregroundActivities;
18833 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
18835 if (app.repProcState != app.curProcState) {
18836 app.repProcState = app.curProcState;
18837 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
18838 if (app.thread != null) {
18841 //RuntimeException h = new RuntimeException("here");
18842 Slog.i(TAG, "Sending new process state " + app.repProcState
18843 + " to " + app /*, h*/);
18845 app.thread.setProcessState(app.repProcState);
18846 } catch (RemoteException e) {
18850 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
18851 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
18852 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
18853 // Experimental code to more aggressively collect pss while
18854 // running test... the problem is that this tends to collect
18855 // the data right when a process is transitioning between process
18856 // states, which well tend to give noisy data.
18857 long start = SystemClock.uptimeMillis();
18858 long pss = Debug.getPss(app.pid, mTmpLong, null);
18859 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], now);
18860 mPendingPssProcesses.remove(app);
18861 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
18862 + " to " + app.curProcState + ": "
18863 + (SystemClock.uptimeMillis()-start) + "ms");
18865 app.lastStateTime = now;
18866 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
18867 mTestPssMode, isSleeping(), now);
18868 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
18869 + ProcessList.makeProcStateString(app.setProcState) + " to "
18870 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
18871 + (app.nextPssTime-now) + ": " + app);
18873 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
18874 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
18876 requestPssLocked(app, app.setProcState);
18877 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
18878 mTestPssMode, isSleeping(), now);
18879 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
18880 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
18882 if (app.setProcState != app.curProcState) {
18883 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
18884 "Proc state change of " + app.processName
18885 + " to " + app.curProcState);
18886 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
18887 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
18888 if (setImportant && !curImportant) {
18889 // This app is no longer something we consider important enough to allow to
18890 // use arbitrary amounts of battery power. Note
18891 // its current wake lock time to later know to kill it if
18892 // it is not behaving well.
18893 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18894 synchronized (stats) {
18895 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
18896 app.pid, nowElapsed);
18898 app.lastCpuTime = app.curCpuTime;
18901 // Inform UsageStats of important process state change
18902 // Must be called before updating setProcState
18903 maybeUpdateUsageStatsLocked(app, nowElapsed);
18905 app.setProcState = app.curProcState;
18906 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
18907 app.notCachedSinceIdle = false;
18910 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
18912 app.procStateChanged = true;
18914 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
18915 > USAGE_STATS_INTERACTION_INTERVAL) {
18916 // For apps that sit around for a long time in the interactive state, we need
18917 // to report this at least once a day so they don't go idle.
18918 maybeUpdateUsageStatsLocked(app, nowElapsed);
18921 if (changes != 0) {
18922 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18923 "Changes in " + app + ": " + changes);
18924 int i = mPendingProcessChanges.size()-1;
18925 ProcessChangeItem item = null;
18927 item = mPendingProcessChanges.get(i);
18928 if (item.pid == app.pid) {
18929 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18930 "Re-using existing item: " + item);
18936 // No existing item in pending changes; need a new one.
18937 final int NA = mAvailProcessChanges.size();
18939 item = mAvailProcessChanges.remove(NA-1);
18940 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18941 "Retrieving available item: " + item);
18943 item = new ProcessChangeItem();
18944 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18945 "Allocating new item: " + item);
18948 item.pid = app.pid;
18949 item.uid = app.info.uid;
18950 if (mPendingProcessChanges.size() == 0) {
18951 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18952 "*** Enqueueing dispatch processes changed!");
18953 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
18955 mPendingProcessChanges.add(item);
18957 item.changes |= changes;
18958 item.processState = app.repProcState;
18959 item.foregroundActivities = app.repForegroundActivities;
18960 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
18961 "Item " + Integer.toHexString(System.identityHashCode(item))
18962 + " " + app.toShortString() + ": changes=" + item.changes
18963 + " procState=" + item.processState
18964 + " foreground=" + item.foregroundActivities
18965 + " type=" + app.adjType + " source=" + app.adjSource
18966 + " target=" + app.adjTarget);
18972 private final void enqueueUidChangeLocked(UidRecord uidRec, boolean gone) {
18973 if (uidRec.pendingChange == null) {
18974 if (mPendingUidChanges.size() == 0) {
18975 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18976 "*** Enqueueing dispatch uid changed!");
18977 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_MSG).sendToTarget();
18979 final int NA = mAvailUidChanges.size();
18981 uidRec.pendingChange = mAvailUidChanges.remove(NA-1);
18982 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18983 "Retrieving available item: " + uidRec.pendingChange);
18985 uidRec.pendingChange = new UidRecord.ChangeItem();
18986 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
18987 "Allocating new item: " + uidRec.pendingChange);
18989 uidRec.pendingChange.uidRecord = uidRec;
18990 uidRec.pendingChange.uid = uidRec.uid;
18991 mPendingUidChanges.add(uidRec.pendingChange);
18993 uidRec.pendingChange.gone = gone;
18994 uidRec.pendingChange.processState = uidRec.setProcState;
18997 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
18998 String authority) {
18999 if (app == null) return;
19000 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19001 UserState userState = mStartedUsers.get(app.userId);
19002 if (userState == null) return;
19003 final long now = SystemClock.elapsedRealtime();
19004 Long lastReported = userState.mProviderLastReportedFg.get(authority);
19005 if (lastReported == null || lastReported < now - 60 * 1000L) {
19006 mUsageStatsService.reportContentProviderUsage(
19007 authority, providerPkgName, app.userId);
19008 userState.mProviderLastReportedFg.put(authority, now);
19013 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19014 if (DEBUG_USAGE_STATS) {
19015 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19016 + "] state changes: old = " + app.setProcState + ", new = "
19017 + app.curProcState);
19019 if (mUsageStatsService == null) {
19022 boolean isInteraction;
19023 // To avoid some abuse patterns, we are going to be careful about what we consider
19024 // to be an app interaction. Being the top activity doesn't count while the display
19025 // is sleeping, nor do short foreground services.
19026 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19027 isInteraction = true;
19028 app.fgInteractionTime = 0;
19029 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19030 if (app.fgInteractionTime == 0) {
19031 app.fgInteractionTime = nowElapsed;
19032 isInteraction = false;
19034 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19037 isInteraction = app.curProcState
19038 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19039 app.fgInteractionTime = 0;
19041 if (isInteraction && (!app.reportedInteraction
19042 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19043 app.interactionEventTime = nowElapsed;
19044 String[] packages = app.getPackageList();
19045 if (packages != null) {
19046 for (int i = 0; i < packages.length; i++) {
19047 mUsageStatsService.reportEvent(packages[i], app.userId,
19048 UsageEvents.Event.SYSTEM_INTERACTION);
19052 app.reportedInteraction = isInteraction;
19053 if (!isInteraction) {
19054 app.interactionEventTime = 0;
19058 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19059 if (proc.thread != null) {
19060 if (proc.baseProcessTracker != null) {
19061 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19063 if (proc.repProcState >= 0) {
19064 mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
19065 proc.repProcState);
19070 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19071 ProcessRecord TOP_APP, boolean doingAll, long now) {
19072 if (app.thread == null) {
19076 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19078 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19081 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19083 if (isForeground != proc.foregroundServices) {
19084 proc.foregroundServices = isForeground;
19085 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19087 if (isForeground) {
19088 if (curProcs == null) {
19089 curProcs = new ArrayList<ProcessRecord>();
19090 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19092 if (!curProcs.contains(proc)) {
19093 curProcs.add(proc);
19094 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19095 proc.info.packageName, proc.info.uid);
19098 if (curProcs != null) {
19099 if (curProcs.remove(proc)) {
19100 mBatteryStatsService.noteEvent(
19101 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19102 proc.info.packageName, proc.info.uid);
19103 if (curProcs.size() <= 0) {
19104 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19110 updateOomAdjLocked();
19115 private final ActivityRecord resumedAppLocked() {
19116 ActivityRecord act = mStackSupervisor.resumedAppLocked();
19120 pkg = act.packageName;
19121 uid = act.info.applicationInfo.uid;
19126 // Has the UID or resumed package name changed?
19127 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19128 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19129 if (mCurResumedPackage != null) {
19130 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19131 mCurResumedPackage, mCurResumedUid);
19133 mCurResumedPackage = pkg;
19134 mCurResumedUid = uid;
19135 if (mCurResumedPackage != null) {
19136 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19137 mCurResumedPackage, mCurResumedUid);
19143 final boolean updateOomAdjLocked(ProcessRecord app) {
19144 final ActivityRecord TOP_ACT = resumedAppLocked();
19145 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19146 final boolean wasCached = app.cached;
19150 // This is the desired cached adjusment we want to tell it to use.
19151 // If our app is currently cached, we know it, and that is it. Otherwise,
19152 // we don't know it yet, and it needs to now be cached we will then
19153 // need to do a complete oom adj.
19154 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19155 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19156 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19157 SystemClock.uptimeMillis());
19158 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19159 // Changed to/from cached state, so apps after it in the LRU
19160 // list may also be changed.
19161 updateOomAdjLocked();
19166 final void updateOomAdjLocked() {
19167 final ActivityRecord TOP_ACT = resumedAppLocked();
19168 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19169 final long now = SystemClock.uptimeMillis();
19170 final long nowElapsed = SystemClock.elapsedRealtime();
19171 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19172 final int N = mLruProcesses.size();
19175 RuntimeException e = new RuntimeException();
19176 e.fillInStackTrace();
19177 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19180 // Reset state in all uid records.
19181 for (int i=mActiveUids.size()-1; i>=0; i--) {
19182 final UidRecord uidRec = mActiveUids.valueAt(i);
19183 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19184 "Starting update of " + uidRec);
19189 mNewNumServiceProcs = 0;
19190 mNewNumAServiceProcs = 0;
19192 final int emptyProcessLimit;
19193 final int cachedProcessLimit;
19194 if (mProcessLimit <= 0) {
19195 emptyProcessLimit = cachedProcessLimit = 0;
19196 } else if (mProcessLimit == 1) {
19197 emptyProcessLimit = 1;
19198 cachedProcessLimit = 0;
19200 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19201 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19204 // Let's determine how many processes we have running vs.
19205 // how many slots we have for background processes; we may want
19206 // to put multiple processes in a slot of there are enough of
19208 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19209 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19210 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19211 if (numEmptyProcs > cachedProcessLimit) {
19212 // If there are more empty processes than our limit on cached
19213 // processes, then use the cached process limit for the factor.
19214 // This ensures that the really old empty processes get pushed
19215 // down to the bottom, so if we are running low on memory we will
19216 // have a better chance at keeping around more cached processes
19217 // instead of a gazillion empty processes.
19218 numEmptyProcs = cachedProcessLimit;
19220 int emptyFactor = numEmptyProcs/numSlots;
19221 if (emptyFactor < 1) emptyFactor = 1;
19222 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
19223 if (cachedFactor < 1) cachedFactor = 1;
19224 int stepCached = 0;
19228 int numTrimming = 0;
19230 mNumNonCachedProcs = 0;
19231 mNumCachedHiddenProcs = 0;
19233 // First update the OOM adjustment for each of the
19234 // application processes based on their current state.
19235 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
19236 int nextCachedAdj = curCachedAdj+1;
19237 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
19238 int nextEmptyAdj = curEmptyAdj+2;
19239 for (int i=N-1; i>=0; i--) {
19240 ProcessRecord app = mLruProcesses.get(i);
19241 if (!app.killedByAm && app.thread != null) {
19242 app.procStateChanged = false;
19243 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
19245 // If we haven't yet assigned the final cached adj
19246 // to the process, do that now.
19247 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
19248 switch (app.curProcState) {
19249 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19250 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19251 // This process is a cached process holding activities...
19252 // assign it the next cached value for that type, and then
19253 // step that cached level.
19254 app.curRawAdj = curCachedAdj;
19255 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
19256 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
19257 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
19259 if (curCachedAdj != nextCachedAdj) {
19261 if (stepCached >= cachedFactor) {
19263 curCachedAdj = nextCachedAdj;
19264 nextCachedAdj += 2;
19265 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19266 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
19272 // For everything else, assign next empty cached process
19273 // level and bump that up. Note that this means that
19274 // long-running services that have dropped down to the
19275 // cached level will be treated as empty (since their process
19276 // state is still as a service), which is what we want.
19277 app.curRawAdj = curEmptyAdj;
19278 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
19279 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
19280 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
19282 if (curEmptyAdj != nextEmptyAdj) {
19284 if (stepEmpty >= emptyFactor) {
19286 curEmptyAdj = nextEmptyAdj;
19288 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
19289 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
19297 applyOomAdjLocked(app, true, now, nowElapsed);
19299 // Count the number of process types.
19300 switch (app.curProcState) {
19301 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
19302 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
19303 mNumCachedHiddenProcs++;
19305 if (numCached > cachedProcessLimit) {
19306 app.kill("cached #" + numCached, true);
19309 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
19310 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
19311 && app.lastActivityTime < oldTime) {
19312 app.kill("empty for "
19313 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
19314 / 1000) + "s", true);
19317 if (numEmpty > emptyProcessLimit) {
19318 app.kill("empty #" + numEmpty, true);
19323 mNumNonCachedProcs++;
19327 if (app.isolated && app.services.size() <= 0) {
19328 // If this is an isolated process, and there are no
19329 // services running in it, then the process is no longer
19330 // needed. We agressively kill these because we can by
19331 // definition not re-use the same process again, and it is
19332 // good to avoid having whatever code was running in them
19333 // left sitting around after no longer needed.
19334 app.kill("isolated not needed", true);
19336 // Keeping this process, update its uid.
19337 final UidRecord uidRec = app.uidRecord;
19338 if (uidRec != null && uidRec.curProcState > app.curProcState) {
19339 uidRec.curProcState = app.curProcState;
19343 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19344 && !app.killedByAm) {
19350 mNumServiceProcs = mNewNumServiceProcs;
19352 // Now determine the memory trimming level of background processes.
19353 // Unfortunately we need to start at the back of the list to do this
19354 // properly. We only do this if the number of background apps we
19355 // are managing to keep around is less than half the maximum we desire;
19356 // if we are keeping a good number around, we'll let them use whatever
19357 // memory they want.
19358 final int numCachedAndEmpty = numCached + numEmpty;
19360 if (numCached <= ProcessList.TRIM_CACHED_APPS
19361 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
19362 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
19363 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
19364 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
19365 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
19367 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
19370 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
19372 // We always allow the memory level to go up (better). We only allow it to go
19373 // down if we are in a state where that is allowed, *and* the total number of processes
19374 // has gone down since last time.
19375 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
19376 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
19377 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
19378 if (memFactor > mLastMemoryLevel) {
19379 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
19380 memFactor = mLastMemoryLevel;
19381 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
19384 mLastMemoryLevel = memFactor;
19385 mLastNumProcesses = mLruProcesses.size();
19386 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
19387 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
19388 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
19389 if (mLowRamStartTime == 0) {
19390 mLowRamStartTime = now;
19394 switch (memFactor) {
19395 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
19396 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
19398 case ProcessStats.ADJ_MEM_FACTOR_LOW:
19399 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
19402 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
19405 int factor = numTrimming/3;
19407 if (mHomeProcess != null) minFactor++;
19408 if (mPreviousProcess != null) minFactor++;
19409 if (factor < minFactor) factor = minFactor;
19410 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
19411 for (int i=N-1; i>=0; i--) {
19412 ProcessRecord app = mLruProcesses.get(i);
19413 if (allChanged || app.procStateChanged) {
19414 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19415 app.procStateChanged = false;
19417 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
19418 && !app.killedByAm) {
19419 if (app.trimMemoryLevel < curLevel && app.thread != null) {
19421 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19422 "Trimming memory of " + app.processName + " to " + curLevel);
19423 app.thread.scheduleTrimMemory(curLevel);
19424 } catch (RemoteException e) {
19427 // For now we won't do this; our memory trimming seems
19428 // to be good enough at this point that destroying
19429 // activities causes more harm than good.
19430 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
19431 && app != mHomeProcess && app != mPreviousProcess) {
19432 // Need to do this on its own message because the stack may not
19433 // be in a consistent state at this point.
19434 // For these apps we will also finish their activities
19435 // to help them free memory.
19436 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
19440 app.trimMemoryLevel = curLevel;
19442 if (step >= factor) {
19444 switch (curLevel) {
19445 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
19446 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
19448 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
19449 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19453 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19454 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
19455 && app.thread != null) {
19457 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19458 "Trimming memory of heavy-weight " + app.processName
19459 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19460 app.thread.scheduleTrimMemory(
19461 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
19462 } catch (RemoteException e) {
19465 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
19467 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19468 || app.systemNoUi) && app.pendingUiClean) {
19469 // If this application is now in the background and it
19470 // had done UI, then give it the special trim level to
19471 // have it free UI resources.
19472 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
19473 if (app.trimMemoryLevel < level && app.thread != null) {
19475 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19476 "Trimming memory of bg-ui " + app.processName
19478 app.thread.scheduleTrimMemory(level);
19479 } catch (RemoteException e) {
19482 app.pendingUiClean = false;
19484 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
19486 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19487 "Trimming memory of fg " + app.processName
19488 + " to " + fgTrimLevel);
19489 app.thread.scheduleTrimMemory(fgTrimLevel);
19490 } catch (RemoteException e) {
19493 app.trimMemoryLevel = fgTrimLevel;
19497 if (mLowRamStartTime != 0) {
19498 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
19499 mLowRamStartTime = 0;
19501 for (int i=N-1; i>=0; i--) {
19502 ProcessRecord app = mLruProcesses.get(i);
19503 if (allChanged || app.procStateChanged) {
19504 setProcessTrackerStateLocked(app, trackerMemFactor, now);
19505 app.procStateChanged = false;
19507 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19508 || app.systemNoUi) && app.pendingUiClean) {
19509 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
19510 && app.thread != null) {
19512 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19513 "Trimming memory of ui hidden " + app.processName
19514 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19515 app.thread.scheduleTrimMemory(
19516 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
19517 } catch (RemoteException e) {
19520 app.pendingUiClean = false;
19522 app.trimMemoryLevel = 0;
19526 if (mAlwaysFinishActivities) {
19527 // Need to do this on its own message because the stack may not
19528 // be in a consistent state at this point.
19529 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
19533 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
19536 // Update from any uid changes.
19537 for (int i=mActiveUids.size()-1; i>=0; i--) {
19538 final UidRecord uidRec = mActiveUids.valueAt(i);
19539 if (uidRec.setProcState != uidRec.curProcState) {
19540 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19541 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
19542 + " to " + uidRec.curProcState);
19543 uidRec.setProcState = uidRec.curProcState;
19544 enqueueUidChangeLocked(uidRec, false);
19548 if (mProcessStats.shouldWriteNowLocked(now)) {
19549 mHandler.post(new Runnable() {
19550 @Override public void run() {
19551 synchronized (ActivityManagerService.this) {
19552 mProcessStats.writeStateAsyncLocked();
19558 if (DEBUG_OOM_ADJ) {
19559 final long duration = SystemClock.uptimeMillis() - now;
19561 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
19562 new RuntimeException("here").fillInStackTrace());
19564 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
19569 final void trimApplications() {
19570 synchronized (this) {
19573 // First remove any unused application processes whose package
19574 // has been removed.
19575 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
19576 final ProcessRecord app = mRemovedProcesses.get(i);
19577 if (app.activities.size() == 0
19578 && app.curReceiver == null && app.services.size() == 0) {
19580 TAG, "Exiting empty application process "
19581 + app.processName + " ("
19582 + (app.thread != null ? app.thread.asBinder() : null)
19584 if (app.pid > 0 && app.pid != MY_PID) {
19585 app.kill("empty", false);
19588 app.thread.scheduleExit();
19589 } catch (Exception e) {
19590 // Ignore exceptions.
19593 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
19594 mRemovedProcesses.remove(i);
19596 if (app.persistent) {
19597 addAppLocked(app.info, false, null /* ABI override */);
19602 // Now update the oom adj for all processes.
19603 updateOomAdjLocked();
19607 /** This method sends the specified signal to each of the persistent apps */
19608 public void signalPersistentProcesses(int sig) throws RemoteException {
19609 if (sig != Process.SIGNAL_USR1) {
19610 throw new SecurityException("Only SIGNAL_USR1 is allowed");
19613 synchronized (this) {
19614 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
19615 != PackageManager.PERMISSION_GRANTED) {
19616 throw new SecurityException("Requires permission "
19617 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
19620 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
19621 ProcessRecord r = mLruProcesses.get(i);
19622 if (r.thread != null && r.persistent) {
19623 Process.sendSignal(r.pid, sig);
19629 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
19630 if (proc == null || proc == mProfileProc) {
19631 proc = mProfileProc;
19632 profileType = mProfileType;
19633 clearProfilerLocked();
19635 if (proc == null) {
19639 proc.thread.profilerControl(false, null, profileType);
19640 } catch (RemoteException e) {
19641 throw new IllegalStateException("Process disappeared");
19645 private void clearProfilerLocked() {
19646 if (mProfileFd != null) {
19648 mProfileFd.close();
19649 } catch (IOException e) {
19652 mProfileApp = null;
19653 mProfileProc = null;
19654 mProfileFile = null;
19656 mAutoStopProfiler = false;
19657 mSamplingInterval = 0;
19660 public boolean profileControl(String process, int userId, boolean start,
19661 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
19664 synchronized (this) {
19665 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19666 // its own permission.
19667 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19668 != PackageManager.PERMISSION_GRANTED) {
19669 throw new SecurityException("Requires permission "
19670 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19673 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
19674 throw new IllegalArgumentException("null profile info or fd");
19677 ProcessRecord proc = null;
19678 if (process != null) {
19679 proc = findProcessLocked(process, userId, "profileControl");
19682 if (start && (proc == null || proc.thread == null)) {
19683 throw new IllegalArgumentException("Unknown process: " + process);
19687 stopProfilerLocked(null, 0);
19688 setProfileApp(proc.info, proc.processName, profilerInfo);
19689 mProfileProc = proc;
19690 mProfileType = profileType;
19691 ParcelFileDescriptor fd = profilerInfo.profileFd;
19694 } catch (IOException e) {
19697 profilerInfo.profileFd = fd;
19698 proc.thread.profilerControl(start, profilerInfo, profileType);
19702 stopProfilerLocked(proc, profileType);
19703 if (profilerInfo != null && profilerInfo.profileFd != null) {
19705 profilerInfo.profileFd.close();
19706 } catch (IOException e) {
19713 } catch (RemoteException e) {
19714 throw new IllegalStateException("Process disappeared");
19716 if (profilerInfo != null && profilerInfo.profileFd != null) {
19718 profilerInfo.profileFd.close();
19719 } catch (IOException e) {
19725 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
19726 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
19727 userId, true, ALLOW_FULL_ONLY, callName, null);
19728 ProcessRecord proc = null;
19730 int pid = Integer.parseInt(process);
19731 synchronized (mPidsSelfLocked) {
19732 proc = mPidsSelfLocked.get(pid);
19734 } catch (NumberFormatException e) {
19737 if (proc == null) {
19738 ArrayMap<String, SparseArray<ProcessRecord>> all
19739 = mProcessNames.getMap();
19740 SparseArray<ProcessRecord> procs = all.get(process);
19741 if (procs != null && procs.size() > 0) {
19742 proc = procs.valueAt(0);
19743 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
19744 for (int i=1; i<procs.size(); i++) {
19745 ProcessRecord thisProc = procs.valueAt(i);
19746 if (thisProc.userId == userId) {
19758 public boolean dumpHeap(String process, int userId, boolean managed,
19759 String path, ParcelFileDescriptor fd) throws RemoteException {
19762 synchronized (this) {
19763 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
19764 // its own permission (same as profileControl).
19765 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
19766 != PackageManager.PERMISSION_GRANTED) {
19767 throw new SecurityException("Requires permission "
19768 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
19772 throw new IllegalArgumentException("null fd");
19775 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
19776 if (proc == null || proc.thread == null) {
19777 throw new IllegalArgumentException("Unknown process: " + process);
19780 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19781 if (!isDebuggable) {
19782 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19783 throw new SecurityException("Process not debuggable: " + proc);
19787 proc.thread.dumpHeap(managed, path, fd);
19791 } catch (RemoteException e) {
19792 throw new IllegalStateException("Process disappeared");
19797 } catch (IOException e) {
19804 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
19805 String reportPackage) {
19806 if (processName != null) {
19807 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
19808 "setDumpHeapDebugLimit()");
19810 synchronized (mPidsSelfLocked) {
19811 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
19812 if (proc == null) {
19813 throw new SecurityException("No process found for calling pid "
19814 + Binder.getCallingPid());
19816 if (!Build.IS_DEBUGGABLE
19817 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
19818 throw new SecurityException("Not running a debuggable build");
19820 processName = proc.processName;
19822 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
19823 throw new SecurityException("Package " + reportPackage + " is not running in "
19828 synchronized (this) {
19829 if (maxMemSize > 0) {
19830 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
19833 mMemWatchProcesses.remove(processName, uid);
19835 mMemWatchProcesses.getMap().remove(processName);
19842 public void dumpHeapFinished(String path) {
19843 synchronized (this) {
19844 if (Binder.getCallingPid() != mMemWatchDumpPid) {
19845 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
19846 + " does not match last pid " + mMemWatchDumpPid);
19849 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
19850 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
19851 + " does not match last path " + mMemWatchDumpFile);
19854 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
19855 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
19859 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
19860 public void monitor() {
19861 synchronized (this) { }
19864 void onCoreSettingsChange(Bundle settings) {
19865 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19866 ProcessRecord processRecord = mLruProcesses.get(i);
19868 if (processRecord.thread != null) {
19869 processRecord.thread.setCoreSettings(settings);
19871 } catch (RemoteException re) {
19877 // Multi-user methods
19880 * Start user, if its not already running, but don't bring it to foreground.
19883 public boolean startUserInBackground(final int userId) {
19884 return startUser(userId, /* foreground */ false);
19888 * Start user, if its not already running, and bring it to foreground.
19890 boolean startUserInForeground(final int userId, Dialog dlg) {
19891 boolean result = startUser(userId, /* foreground */ true);
19897 * Refreshes the list of users related to the current user when either a
19898 * user switch happens or when a new related user is started in the
19901 private void updateCurrentProfileIdsLocked() {
19902 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19903 mCurrentUserId, false /* enabledOnly */);
19904 int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
19905 for (int i = 0; i < currentProfileIds.length; i++) {
19906 currentProfileIds[i] = profiles.get(i).id;
19908 mCurrentProfileIds = currentProfileIds;
19910 synchronized (mUserProfileGroupIdsSelfLocked) {
19911 mUserProfileGroupIdsSelfLocked.clear();
19912 final List<UserInfo> users = getUserManagerLocked().getUsers(false);
19913 for (int i = 0; i < users.size(); i++) {
19914 UserInfo user = users.get(i);
19915 if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
19916 mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
19922 private Set<Integer> getProfileIdsLocked(int userId) {
19923 Set<Integer> userIds = new HashSet<Integer>();
19924 final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
19925 userId, false /* enabledOnly */);
19926 for (UserInfo user : profiles) {
19927 userIds.add(Integer.valueOf(user.id));
19933 public boolean switchUser(final int userId) {
19934 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
19936 synchronized (this) {
19937 UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19938 if (userInfo == null) {
19939 Slog.w(TAG, "No user info for user #" + userId);
19942 if (userInfo.isManagedProfile()) {
19943 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19946 userName = userInfo.name;
19947 mTargetUserId = userId;
19949 mUiHandler.removeMessages(START_USER_SWITCH_MSG);
19950 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
19954 private void showUserSwitchDialog(int userId, String userName) {
19955 // The dialog will show and then initiate the user switch by calling startUserInForeground
19956 Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
19957 true /* above system */);
19961 private boolean startUser(final int userId, final boolean foreground) {
19962 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
19963 != PackageManager.PERMISSION_GRANTED) {
19964 String msg = "Permission Denial: switchUser() from pid="
19965 + Binder.getCallingPid()
19966 + ", uid=" + Binder.getCallingUid()
19967 + " requires " + INTERACT_ACROSS_USERS_FULL;
19969 throw new SecurityException(msg);
19972 if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
19974 final long ident = Binder.clearCallingIdentity();
19976 synchronized (this) {
19977 final int oldUserId = mCurrentUserId;
19978 if (oldUserId == userId) {
19982 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
19983 "startUser", false);
19985 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
19986 if (userInfo == null) {
19987 Slog.w(TAG, "No user info for user #" + userId);
19990 if (foreground && userInfo.isManagedProfile()) {
19991 Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
19996 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
19997 R.anim.screen_user_enter);
20000 boolean needStart = false;
20002 // If the user we are switching to is not currently started, then
20003 // we need to start it now.
20004 if (mStartedUsers.get(userId) == null) {
20005 mStartedUsers.put(userId, new UserState(new UserHandle(userId), false));
20006 updateStartedUserArrayLocked();
20010 final Integer userIdInt = Integer.valueOf(userId);
20011 mUserLru.remove(userIdInt);
20012 mUserLru.add(userIdInt);
20015 mCurrentUserId = userId;
20016 mTargetUserId = UserHandle.USER_NULL; // reset, mCurrentUserId has caught up
20017 updateCurrentProfileIdsLocked();
20018 mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
20019 // Once the internal notion of the active user has switched, we lock the device
20020 // with the option to show the user switcher on the keyguard.
20021 mWindowManager.lockNow(null);
20023 final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
20024 updateCurrentProfileIdsLocked();
20025 mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
20026 mUserLru.remove(currentUserIdInt);
20027 mUserLru.add(currentUserIdInt);
20030 final UserState uss = mStartedUsers.get(userId);
20032 // Make sure user is in the started state. If it is currently
20033 // stopping, we need to knock that off.
20034 if (uss.mState == UserState.STATE_STOPPING) {
20035 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
20036 // so we can just fairly silently bring the user back from
20037 // the almost-dead.
20038 uss.mState = UserState.STATE_RUNNING;
20039 updateStartedUserArrayLocked();
20041 } else if (uss.mState == UserState.STATE_SHUTDOWN) {
20042 // This means ACTION_SHUTDOWN has been sent, so we will
20043 // need to treat this as a new boot of the user.
20044 uss.mState = UserState.STATE_BOOTING;
20045 updateStartedUserArrayLocked();
20049 if (uss.mState == UserState.STATE_BOOTING) {
20050 // Booting up a new user, need to tell system services about it.
20051 // Note that this is on the same handler as scheduling of broadcasts,
20052 // which is important because it needs to go first.
20053 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
20057 mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
20059 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
20060 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20061 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
20062 oldUserId, userId, uss));
20063 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
20064 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
20068 // Send USER_STARTED broadcast
20069 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
20070 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20071 | Intent.FLAG_RECEIVER_FOREGROUND);
20072 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20073 broadcastIntentLocked(null, null, intent,
20074 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20075 null, false, false, MY_PID, Process.SYSTEM_UID, userId);
20078 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
20079 if (userId != UserHandle.USER_OWNER) {
20080 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
20081 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
20082 broadcastIntentLocked(null, null, intent, null,
20083 new IIntentReceiver.Stub() {
20084 public void performReceive(Intent intent, int resultCode,
20085 String data, Bundle extras, boolean ordered,
20086 boolean sticky, int sendingUser) {
20087 onUserInitialized(uss, foreground, oldUserId, userId);
20089 }, 0, null, null, null, AppOpsManager.OP_NONE,
20090 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20091 uss.initializing = true;
20093 getUserManagerLocked().makeInitialized(userInfo.id);
20098 if (!uss.initializing) {
20099 moveUserToForeground(uss, oldUserId, userId);
20102 mStackSupervisor.startBackgroundUserLocked(userId, uss);
20106 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
20107 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20108 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20109 broadcastIntentLocked(null, null, intent,
20110 null, new IIntentReceiver.Stub() {
20112 public void performReceive(Intent intent, int resultCode,
20113 String data, Bundle extras, boolean ordered, boolean sticky,
20114 int sendingUser) throws RemoteException {
20117 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20118 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20122 Binder.restoreCallingIdentity(ident);
20128 void dispatchForegroundProfileChanged(int userId) {
20129 final int N = mUserSwitchObservers.beginBroadcast();
20130 for (int i = 0; i < N; i++) {
20132 mUserSwitchObservers.getBroadcastItem(i).onForegroundProfileSwitch(userId);
20133 } catch (RemoteException e) {
20137 mUserSwitchObservers.finishBroadcast();
20140 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
20141 long ident = Binder.clearCallingIdentity();
20144 if (oldUserId >= 0) {
20145 // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
20146 List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
20147 int count = profiles.size();
20148 for (int i = 0; i < count; i++) {
20149 int profileUserId = profiles.get(i).id;
20150 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
20151 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20152 | Intent.FLAG_RECEIVER_FOREGROUND);
20153 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20154 broadcastIntentLocked(null, null, intent,
20155 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20156 null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20159 if (newUserId >= 0) {
20160 // Send USER_FOREGROUND broadcast to all profiles of the incoming user
20161 List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
20162 int count = profiles.size();
20163 for (int i = 0; i < count; i++) {
20164 int profileUserId = profiles.get(i).id;
20165 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
20166 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20167 | Intent.FLAG_RECEIVER_FOREGROUND);
20168 intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
20169 broadcastIntentLocked(null, null, intent,
20170 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
20171 null, false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
20173 intent = new Intent(Intent.ACTION_USER_SWITCHED);
20174 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
20175 | Intent.FLAG_RECEIVER_FOREGROUND);
20176 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
20177 broadcastIntentLocked(null, null, intent,
20178 null, null, 0, null, null,
20179 new String[] {android.Manifest.permission.MANAGE_USERS},
20180 AppOpsManager.OP_NONE, null, false, false, MY_PID, Process.SYSTEM_UID,
20181 UserHandle.USER_ALL);
20184 Binder.restoreCallingIdentity(ident);
20188 void dispatchUserSwitch(final UserState uss, final int oldUserId,
20189 final int newUserId) {
20190 final int N = mUserSwitchObservers.beginBroadcast();
20192 final IRemoteCallback callback = new IRemoteCallback.Stub() {
20195 public void sendResult(Bundle data) throws RemoteException {
20196 synchronized (ActivityManagerService.this) {
20197 if (mCurUserSwitchCallback == this) {
20200 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20206 synchronized (this) {
20207 uss.switching = true;
20208 mCurUserSwitchCallback = callback;
20210 for (int i=0; i<N; i++) {
20212 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
20213 newUserId, callback);
20214 } catch (RemoteException e) {
20218 synchronized (this) {
20219 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20222 mUserSwitchObservers.finishBroadcast();
20225 void timeoutUserSwitch(UserState uss, int oldUserId, int newUserId) {
20226 synchronized (this) {
20227 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
20228 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
20232 void sendContinueUserSwitchLocked(UserState uss, int oldUserId, int newUserId) {
20233 mCurUserSwitchCallback = null;
20234 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
20235 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
20236 oldUserId, newUserId, uss));
20239 void onUserInitialized(UserState uss, boolean foreground, int oldUserId, int newUserId) {
20240 synchronized (this) {
20242 moveUserToForeground(uss, oldUserId, newUserId);
20246 completeSwitchAndInitialize(uss, newUserId, true, false);
20249 void moveUserToForeground(UserState uss, int oldUserId, int newUserId) {
20250 boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
20252 startHomeActivityLocked(newUserId, "moveUserToFroreground");
20254 mStackSupervisor.resumeTopActivitiesLocked();
20256 EventLogTags.writeAmSwitchUser(newUserId);
20257 getUserManagerLocked().onUserForeground(newUserId);
20258 sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
20261 void continueUserSwitch(UserState uss, int oldUserId, int newUserId) {
20262 completeSwitchAndInitialize(uss, newUserId, false, true);
20265 void completeSwitchAndInitialize(UserState uss, int newUserId,
20266 boolean clearInitializing, boolean clearSwitching) {
20267 boolean unfrozen = false;
20268 synchronized (this) {
20269 if (clearInitializing) {
20270 uss.initializing = false;
20271 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
20273 if (clearSwitching) {
20274 uss.switching = false;
20276 if (!uss.switching && !uss.initializing) {
20277 mWindowManager.stopFreezingScreen();
20282 mHandler.removeMessages(REPORT_USER_SWITCH_COMPLETE_MSG);
20283 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_COMPLETE_MSG,
20286 stopGuestUserIfBackground();
20289 /** Called on handler thread */
20290 void dispatchUserSwitchComplete(int userId) {
20291 final int observerCount = mUserSwitchObservers.beginBroadcast();
20292 for (int i = 0; i < observerCount; i++) {
20294 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(userId);
20295 } catch (RemoteException e) {
20298 mUserSwitchObservers.finishBroadcast();
20302 * Stops the guest user if it has gone to the background.
20304 private void stopGuestUserIfBackground() {
20305 synchronized (this) {
20306 final int num = mUserLru.size();
20307 for (int i = 0; i < num; i++) {
20308 Integer oldUserId = mUserLru.get(i);
20309 UserState oldUss = mStartedUsers.get(oldUserId);
20310 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId
20311 || oldUss.mState == UserState.STATE_STOPPING
20312 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20315 UserInfo userInfo = mUserManager.getUserInfo(oldUserId);
20316 if (userInfo.isGuest()) {
20317 // This is a user to be stopped.
20318 stopUserLocked(oldUserId, null);
20325 void scheduleStartProfilesLocked() {
20326 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20327 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20328 DateUtils.SECOND_IN_MILLIS);
20332 void startProfilesLocked() {
20333 if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
20334 List<UserInfo> profiles = getUserManagerLocked().getProfiles(
20335 mCurrentUserId, false /* enabledOnly */);
20336 List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
20337 for (UserInfo user : profiles) {
20338 if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
20339 && user.id != mCurrentUserId) {
20343 final int n = toStart.size();
20345 for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
20346 startUserInBackground(toStart.get(i).id);
20349 Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
20353 void finishUserBoot(UserState uss) {
20354 synchronized (this) {
20355 if (uss.mState == UserState.STATE_BOOTING
20356 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
20357 uss.mState = UserState.STATE_RUNNING;
20358 final int userId = uss.mHandle.getIdentifier();
20359 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
20360 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20361 intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
20362 broadcastIntentLocked(null, null, intent,
20363 null, null, 0, null, null,
20364 new String[] {android.Manifest.permission.RECEIVE_BOOT_COMPLETED},
20365 AppOpsManager.OP_NONE, null, true, false, MY_PID, Process.SYSTEM_UID,
20371 void finishUserSwitch(UserState uss) {
20372 synchronized (this) {
20373 finishUserBoot(uss);
20375 startProfilesLocked();
20377 int num = mUserLru.size();
20379 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
20380 Integer oldUserId = mUserLru.get(i);
20381 UserState oldUss = mStartedUsers.get(oldUserId);
20382 if (oldUss == null) {
20383 // Shouldn't happen, but be sane if it does.
20384 mUserLru.remove(i);
20388 if (oldUss.mState == UserState.STATE_STOPPING
20389 || oldUss.mState == UserState.STATE_SHUTDOWN) {
20390 // This user is already stopping, doesn't count.
20395 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
20396 // Owner and current can't be stopped, but count as running.
20400 // This is a user to be stopped.
20401 stopUserLocked(oldUserId, null);
20409 public int stopUser(final int userId, final IStopUserCallback callback) {
20410 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20411 != PackageManager.PERMISSION_GRANTED) {
20412 String msg = "Permission Denial: switchUser() from pid="
20413 + Binder.getCallingPid()
20414 + ", uid=" + Binder.getCallingUid()
20415 + " requires " + INTERACT_ACROSS_USERS_FULL;
20417 throw new SecurityException(msg);
20419 if (userId < 0 || userId == UserHandle.USER_OWNER) {
20420 throw new IllegalArgumentException("Can't stop primary user " + userId);
20422 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, userId);
20423 synchronized (this) {
20424 return stopUserLocked(userId, callback);
20428 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
20429 if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
20430 if (mCurrentUserId == userId && mTargetUserId == UserHandle.USER_NULL) {
20431 return ActivityManager.USER_OP_IS_CURRENT;
20434 final UserState uss = mStartedUsers.get(userId);
20436 // User is not started, nothing to do... but we do need to
20437 // callback if requested.
20438 if (callback != null) {
20439 mHandler.post(new Runnable() {
20441 public void run() {
20443 callback.userStopped(userId);
20444 } catch (RemoteException e) {
20449 return ActivityManager.USER_OP_SUCCESS;
20452 if (callback != null) {
20453 uss.mStopCallbacks.add(callback);
20456 if (uss.mState != UserState.STATE_STOPPING
20457 && uss.mState != UserState.STATE_SHUTDOWN) {
20458 uss.mState = UserState.STATE_STOPPING;
20459 updateStartedUserArrayLocked();
20461 long ident = Binder.clearCallingIdentity();
20463 // We are going to broadcast ACTION_USER_STOPPING and then
20464 // once that is done send a final ACTION_SHUTDOWN and then
20466 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
20467 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
20468 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
20469 stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
20470 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
20471 // This is the result receiver for the final shutdown broadcast.
20472 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
20474 public void performReceive(Intent intent, int resultCode, String data,
20475 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20476 finishUserStop(uss);
20479 // This is the result receiver for the initial stopping broadcast.
20480 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
20482 public void performReceive(Intent intent, int resultCode, String data,
20483 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
20485 synchronized (ActivityManagerService.this) {
20486 if (uss.mState != UserState.STATE_STOPPING) {
20487 // Whoops, we are being started back up. Abort, abort!
20490 uss.mState = UserState.STATE_SHUTDOWN;
20492 mBatteryStatsService.noteEvent(
20493 BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
20494 Integer.toString(userId), userId);
20495 mSystemServiceManager.stopUser(userId);
20496 broadcastIntentLocked(null, null, shutdownIntent,
20497 null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
20498 null, true, false, MY_PID, Process.SYSTEM_UID, userId);
20501 // Kick things off.
20502 broadcastIntentLocked(null, null, stoppingIntent,
20503 null, stoppingReceiver, 0, null, null,
20504 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
20505 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
20507 Binder.restoreCallingIdentity(ident);
20511 return ActivityManager.USER_OP_SUCCESS;
20514 void finishUserStop(UserState uss) {
20515 final int userId = uss.mHandle.getIdentifier();
20517 ArrayList<IStopUserCallback> callbacks;
20518 synchronized (this) {
20519 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
20520 if (mStartedUsers.get(userId) != uss) {
20522 } else if (uss.mState != UserState.STATE_SHUTDOWN) {
20526 // User can no longer run.
20527 mStartedUsers.remove(userId);
20528 mUserLru.remove(Integer.valueOf(userId));
20529 updateStartedUserArrayLocked();
20531 // Clean up all state and processes associated with the user.
20532 // Kill all the processes for the user.
20533 forceStopUserLocked(userId, "finish user");
20536 // Explicitly remove the old information in mRecentTasks.
20537 mRecentTasks.removeTasksForUserLocked(userId);
20540 for (int i=0; i<callbacks.size(); i++) {
20542 if (stopped) callbacks.get(i).userStopped(userId);
20543 else callbacks.get(i).userStopAborted(userId);
20544 } catch (RemoteException e) {
20549 mSystemServiceManager.cleanupUser(userId);
20550 synchronized (this) {
20551 mStackSupervisor.removeUserLocked(userId);
20557 public UserInfo getCurrentUser() {
20558 if ((checkCallingPermission(INTERACT_ACROSS_USERS)
20559 != PackageManager.PERMISSION_GRANTED) && (
20560 checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20561 != PackageManager.PERMISSION_GRANTED)) {
20562 String msg = "Permission Denial: getCurrentUser() from pid="
20563 + Binder.getCallingPid()
20564 + ", uid=" + Binder.getCallingUid()
20565 + " requires " + INTERACT_ACROSS_USERS;
20567 throw new SecurityException(msg);
20569 synchronized (this) {
20570 int userId = mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20571 return getUserManagerLocked().getUserInfo(userId);
20575 int getCurrentUserIdLocked() {
20576 return mTargetUserId != UserHandle.USER_NULL ? mTargetUserId : mCurrentUserId;
20580 public boolean isUserRunning(int userId, boolean orStopped) {
20581 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20582 != PackageManager.PERMISSION_GRANTED) {
20583 String msg = "Permission Denial: isUserRunning() from pid="
20584 + Binder.getCallingPid()
20585 + ", uid=" + Binder.getCallingUid()
20586 + " requires " + INTERACT_ACROSS_USERS;
20588 throw new SecurityException(msg);
20590 synchronized (this) {
20591 return isUserRunningLocked(userId, orStopped);
20595 boolean isUserRunningLocked(int userId, boolean orStopped) {
20596 UserState state = mStartedUsers.get(userId);
20597 if (state == null) {
20603 return state.mState != UserState.STATE_STOPPING
20604 && state.mState != UserState.STATE_SHUTDOWN;
20608 public int[] getRunningUserIds() {
20609 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20610 != PackageManager.PERMISSION_GRANTED) {
20611 String msg = "Permission Denial: isUserRunning() from pid="
20612 + Binder.getCallingPid()
20613 + ", uid=" + Binder.getCallingUid()
20614 + " requires " + INTERACT_ACROSS_USERS;
20616 throw new SecurityException(msg);
20618 synchronized (this) {
20619 return mStartedUserArray;
20623 private void updateStartedUserArrayLocked() {
20625 for (int i=0; i<mStartedUsers.size(); i++) {
20626 UserState uss = mStartedUsers.valueAt(i);
20627 // This list does not include stopping users.
20628 if (uss.mState != UserState.STATE_STOPPING
20629 && uss.mState != UserState.STATE_SHUTDOWN) {
20633 mStartedUserArray = new int[num];
20635 for (int i=0; i<mStartedUsers.size(); i++) {
20636 UserState uss = mStartedUsers.valueAt(i);
20637 if (uss.mState != UserState.STATE_STOPPING
20638 && uss.mState != UserState.STATE_SHUTDOWN) {
20639 mStartedUserArray[num] = mStartedUsers.keyAt(i);
20646 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20647 if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
20648 != PackageManager.PERMISSION_GRANTED) {
20649 String msg = "Permission Denial: registerUserSwitchObserver() from pid="
20650 + Binder.getCallingPid()
20651 + ", uid=" + Binder.getCallingUid()
20652 + " requires " + INTERACT_ACROSS_USERS_FULL;
20654 throw new SecurityException(msg);
20657 mUserSwitchObservers.register(observer);
20661 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20662 mUserSwitchObservers.unregister(observer);
20665 int[] getUsersLocked() {
20666 UserManagerService ums = getUserManagerLocked();
20667 return ums != null ? ums.getUserIds() : new int[] { 0 };
20670 UserManagerService getUserManagerLocked() {
20671 if (mUserManager == null) {
20672 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
20673 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
20675 return mUserManager;
20678 private int applyUserId(int uid, int userId) {
20679 return UserHandle.getUid(userId, uid);
20682 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20683 if (info == null) return null;
20684 ApplicationInfo newInfo = new ApplicationInfo(info);
20685 newInfo.uid = applyUserId(info.uid, userId);
20686 newInfo.dataDir = Environment
20687 .getDataUserPackageDirectory(info.volumeUuid, userId, info.packageName)
20688 .getAbsolutePath();
20692 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20694 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20698 ActivityInfo info = new ActivityInfo(aInfo);
20699 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20703 private final class LocalService extends ActivityManagerInternal {
20705 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
20706 int targetUserId) {
20707 synchronized (ActivityManagerService.this) {
20708 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
20709 targetPkg, intent, null, targetUserId);
20714 public String checkContentProviderAccess(String authority, int userId) {
20715 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
20719 public void onWakefulnessChanged(int wakefulness) {
20720 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20724 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20725 String processName, String abiOverride, int uid, Runnable crashHandler) {
20726 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20727 processName, abiOverride, uid, crashHandler);
20731 public SleepToken acquireSleepToken(String tag) {
20732 Preconditions.checkNotNull(tag);
20734 synchronized (ActivityManagerService.this) {
20735 SleepTokenImpl token = new SleepTokenImpl(tag);
20736 mSleepTokens.add(token);
20737 updateSleepIfNeededLocked();
20743 public ComponentName getHomeActivityForUser(int userId) {
20744 synchronized (ActivityManagerService.this) {
20745 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20746 return homeActivity == null ? null : homeActivity.realActivity;
20751 private final class SleepTokenImpl extends SleepToken {
20752 private final String mTag;
20753 private final long mAcquireTime;
20755 public SleepTokenImpl(String tag) {
20757 mAcquireTime = SystemClock.uptimeMillis();
20761 public void release() {
20762 synchronized (ActivityManagerService.this) {
20763 if (mSleepTokens.remove(this)) {
20764 updateSleepIfNeededLocked();
20770 public String toString() {
20771 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
20776 * An implementation of IAppTask, that allows an app to manage its own tasks via
20777 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
20778 * only the process that calls getAppTasks() can call the AppTask methods.
20780 class AppTaskImpl extends IAppTask.Stub {
20781 private int mTaskId;
20782 private int mCallingUid;
20784 public AppTaskImpl(int taskId, int callingUid) {
20786 mCallingUid = callingUid;
20789 private void checkCaller() {
20790 if (mCallingUid != Binder.getCallingUid()) {
20791 throw new SecurityException("Caller " + mCallingUid
20792 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
20797 public void finishAndRemoveTask() {
20800 synchronized (ActivityManagerService.this) {
20801 long origId = Binder.clearCallingIdentity();
20803 if (!removeTaskByIdLocked(mTaskId, false)) {
20804 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20807 Binder.restoreCallingIdentity(origId);
20813 public ActivityManager.RecentTaskInfo getTaskInfo() {
20816 synchronized (ActivityManagerService.this) {
20817 long origId = Binder.clearCallingIdentity();
20819 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20821 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20823 return createRecentTaskInfoFromTaskRecord(tr);
20825 Binder.restoreCallingIdentity(origId);
20831 public void moveToFront() {
20833 // Will bring task to front if it already has a root activity.
20834 startActivityFromRecentsInner(mTaskId, null);
20838 public int startActivity(IBinder whoThread, String callingPackage,
20839 Intent intent, String resolvedType, Bundle options) {
20842 int callingUser = UserHandle.getCallingUserId();
20844 IApplicationThread appThread;
20845 synchronized (ActivityManagerService.this) {
20846 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20848 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20850 appThread = ApplicationThreadNative.asInterface(whoThread);
20851 if (appThread == null) {
20852 throw new IllegalArgumentException("Bad app thread " + appThread);
20855 return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
20856 resolvedType, null, null, null, null, 0, 0, null, null,
20857 null, options, false, callingUser, null, tr);
20861 public void setExcludeFromRecents(boolean exclude) {
20864 synchronized (ActivityManagerService.this) {
20865 long origId = Binder.clearCallingIdentity();
20867 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
20869 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
20871 Intent intent = tr.getBaseIntent();
20873 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20875 intent.setFlags(intent.getFlags()
20876 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
20879 Binder.restoreCallingIdentity(origId);